Merge with trunk r40409
[blender.git] / source / blender / render / intern / source / imagetexture.c
1 /*
2  *
3  * $Id$
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version. 
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * Contributors: 2004/2005/2006 Blender Foundation, full recode
25  *
26  * ***** END GPL/BL DUAL LICENSE BLOCK *****
27  */
28
29 /** \file blender/render/intern/source/imagetexture.c
30  *  \ingroup render
31  */
32
33
34
35
36 #include <stdio.h>
37 #include <string.h>
38 #include <fcntl.h>
39 #include <math.h>
40 #include <float.h>
41 #ifndef WIN32 
42 #include <unistd.h>
43 #else
44 #include <io.h>
45 #endif
46
47 #include "MEM_guardedalloc.h"
48
49 #include "IMB_imbuf_types.h"
50 #include "IMB_imbuf.h"
51
52 #include "DNA_image_types.h"
53 #include "DNA_scene_types.h"
54 #include "DNA_texture_types.h"
55
56 #include "BLI_math.h"
57 #include "BLI_blenlib.h"
58 #include "BLI_threads.h"
59 #include "BLI_utildefines.h"
60
61 #include "BKE_global.h"
62 #include "BKE_main.h"
63 #include "BKE_image.h"
64 #include "BKE_texture.h"
65 #include "BKE_library.h"
66
67 #include "RE_render_ext.h"
68
69 #include "renderpipeline.h"
70 #include "render_types.h"
71 #include "texture.h"
72
73 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
74 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
75 /* only to be used here in this file, it's for speed */
76 extern struct Render R;
77 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
78
79 static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend);
80
81 /* *********** IMAGEWRAPPING ****************** */
82
83
84 /* x and y have to be checked for image size */
85 static void ibuf_get_color(float *col, struct ImBuf *ibuf, int x, int y)
86 {
87         int ofs = y * ibuf->x + x;
88         
89         if(ibuf->rect_float) {
90                 if(ibuf->channels==4) {
91                         float *fp= ibuf->rect_float + 4*ofs;
92                         QUATCOPY(col, fp);
93                 }
94                 else if(ibuf->channels==3) {
95                         float *fp= ibuf->rect_float + 3*ofs;
96                         VECCOPY(col, fp);
97                         col[3]= 1.0f;
98                 }
99                 else {
100                         float *fp= ibuf->rect_float + ofs;
101                         col[0]= col[1]= col[2]= col[3]= *fp;
102                 }
103         }
104         else {
105                 char *rect = (char *)( ibuf->rect+ ofs);
106
107                 col[0] = ((float)rect[0])*(1.0f/255.0f);
108                 col[1] = ((float)rect[1])*(1.0f/255.0f);
109                 col[2] = ((float)rect[2])*(1.0f/255.0f);
110                 col[3] = ((float)rect[3])*(1.0f/255.0f);
111         }       
112 }
113
114 int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres)
115 {
116         float fx, fy, val1, val2, val3;
117         int x, y, retval;
118         int xi, yi; /* original values */
119
120         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
121         
122         /* we need to set retval OK, otherwise texture code generates normals itself... */
123         retval= texres->nor?3:1;
124         
125         /* quick tests */
126         if(ibuf==NULL && ima==NULL)
127                 return retval;
128         if(ima) {
129                 
130                 /* hack for icon render */
131                 if(ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
132                         return retval;
133                 
134                 ibuf= BKE_image_get_ibuf(ima, &tex->iuser);
135         }
136         if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
137                 return retval;
138         
139         /* setup mapping */
140         if(tex->imaflag & TEX_IMAROT) {
141                 fy= texvec[0];
142                 fx= texvec[1];
143         }
144         else {
145                 fx= texvec[0];
146                 fy= texvec[1];
147         }
148         
149         if(tex->extend == TEX_CHECKER) {
150                 int xs, ys;
151                 
152                 xs= (int)floor(fx);
153                 ys= (int)floor(fy);
154                 fx-= xs;
155                 fy-= ys;
156
157                 if( (tex->flag & TEX_CHECKER_ODD)==0) {
158                         if((xs+ys) & 1);else return retval;
159                 }
160                 if( (tex->flag & TEX_CHECKER_EVEN)==0) {
161                         if((xs+ys) & 1) return retval; 
162                 }
163                 /* scale around center, (0.5, 0.5) */
164                 if(tex->checkerdist<1.0f) {
165                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
166                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
167                 }
168         }
169
170         x= xi= (int)floorf(fx*ibuf->x);
171         y= yi= (int)floorf(fy*ibuf->y);
172
173         if(tex->extend == TEX_CLIPCUBE) {
174                 if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) {
175                         return retval;
176                 }
177         }
178         else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
179                 if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
180                         return retval;
181                 }
182         }
183         else {
184                 if(tex->extend==TEX_EXTEND) {
185                         if(x>=ibuf->x) x = ibuf->x-1;
186                         else if(x<0) x= 0;
187                 }
188                 else {
189                         x= x % ibuf->x;
190                         if(x<0) x+= ibuf->x;
191                 }
192                 if(tex->extend==TEX_EXTEND) {
193                         if(y>=ibuf->y) y = ibuf->y-1;
194                         else if(y<0) y= 0;
195                 }
196                 else {
197                         y= y % ibuf->y;
198                         if(y<0) y+= ibuf->y;
199                 }
200         }
201         
202         /* warning, no return before setting back! */
203         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
204                 ibuf->rect+= (ibuf->x*ibuf->y);
205         }
206
207         /* interpolate */
208         if (tex->imaflag & TEX_INTERPOL) {
209                 float filterx, filtery;
210                 filterx = (0.5f * tex->filtersize) / ibuf->x;
211                 filtery = (0.5f * tex->filtersize) / ibuf->y;
212
213                 /* important that this value is wrapped [#27782]
214                  * this applies the modifications made by the checks above,
215                  * back to the floating point values */
216                 fx -= (float)(xi - x) / (float)ibuf->x;
217                 fy -= (float)(yi - y) / (float)ibuf->y;
218
219                 boxsample(ibuf, fx-filterx, fy-filtery, fx+filterx, fy+filtery, texres, (tex->extend==TEX_REPEAT), (tex->extend==TEX_EXTEND));
220         }
221         else { /* no filtering */
222                 ibuf_get_color(&texres->tr, ibuf, x, y);
223         }
224         
225         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
226                 ibuf->rect-= (ibuf->x*ibuf->y);
227         }
228
229         if(tex->imaflag & TEX_USEALPHA) {
230                 if(tex->imaflag & TEX_CALCALPHA);
231                 else texres->talpha= 1;
232         }
233         
234         if(texres->nor) {
235                 if(tex->imaflag & TEX_NORMALMAP) {
236                         // qdn: normal from color
237                         // The invert of the red channel is to make
238                         // the normal map compliant with the outside world.
239                         // It needs to be done because in Blender
240                         // the normal used in the renderer points inward. It is generated
241                         // this way in calc_vertexnormals(). Should this ever change
242                         // this negate must be removed.
243                         texres->nor[0] = -2.f*(texres->tr - 0.5f);
244                         texres->nor[1] = 2.f*(texres->tg - 0.5f);
245                         texres->nor[2] = 2.f*(texres->tb - 0.5f);
246                 }
247                 else {
248                         /* bump: take three samples */
249                         val1= texres->tr+texres->tg+texres->tb;
250
251                         if(x<ibuf->x-1) {
252                                 float col[4];
253                                 ibuf_get_color(col, ibuf, x+1, y);
254                                 val2= (col[0]+col[1]+col[2]);
255                         }
256                         else val2= val1;
257
258                         if(y<ibuf->y-1) {
259                                 float col[4];
260                                 ibuf_get_color(col, ibuf, x, y+1);
261                                 val3= (col[0]+col[1]+col[2]);
262                         }
263                         else val3= val1;
264
265                         /* do not mix up x and y here! */
266                         texres->nor[0]= (val1-val2);
267                         texres->nor[1]= (val1-val3);
268                 }
269         }
270
271         if(texres->talpha) texres->tin= texres->ta;
272         else if(tex->imaflag & TEX_CALCALPHA) {
273                 texres->ta= texres->tin= MAX3(texres->tr, texres->tg, texres->tb);
274         }
275         else texres->ta= texres->tin= 1.0;
276         
277         if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
278
279         /* de-premul, this is being premulled in shade_input_do_shade() */
280         if(texres->ta!=1.0f && texres->ta>1e-4f) {
281                 fx= 1.0f/texres->ta;
282                 texres->tr*= fx;
283                 texres->tg*= fx;
284                 texres->tb*= fx;
285         }
286         
287         BRICONTRGB;
288         
289         return retval;
290 }
291
292 static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
293 {
294         rctf *rf, *newrct;
295         short a;
296
297         a= *count;
298         rf= stack;
299         for(;a>0;a--) {
300                 if(rf->xmin<x1) {
301                         if(rf->xmax<x1) {
302                                 rf->xmin+= (x2-x1);
303                                 rf->xmax+= (x2-x1);
304                         }
305                         else {
306                                 if(rf->xmax>x2) rf->xmax= x2;
307                                 newrct= stack+ *count;
308                                 (*count)++;
309
310                                 newrct->xmax= x2;
311                                 newrct->xmin= rf->xmin+(x2-x1);
312                                 newrct->ymin= rf->ymin;
313                                 newrct->ymax= rf->ymax;
314                                 
315                                 if(newrct->xmin==newrct->xmax) (*count)--;
316                                 
317                                 rf->xmin= x1;
318                         }
319                 }
320                 else if(rf->xmax>x2) {
321                         if(rf->xmin>x2) {
322                                 rf->xmin-= (x2-x1);
323                                 rf->xmax-= (x2-x1);
324                         }
325                         else {
326                                 if(rf->xmin<x1) rf->xmin= x1;
327                                 newrct= stack+ *count;
328                                 (*count)++;
329
330                                 newrct->xmin= x1;
331                                 newrct->xmax= rf->xmax-(x2-x1);
332                                 newrct->ymin= rf->ymin;
333                                 newrct->ymax= rf->ymax;
334
335                                 if(newrct->xmin==newrct->xmax) (*count)--;
336
337                                 rf->xmax= x2;
338                         }
339                 }
340                 rf++;
341         }
342
343 }
344
345 static void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2)
346 {
347         rctf *rf, *newrct;
348         short a;
349
350         a= *count;
351         rf= stack;
352         for(;a>0;a--) {
353                 if(rf->ymin<y1) {
354                         if(rf->ymax<y1) {
355                                 rf->ymin+= (y2-y1);
356                                 rf->ymax+= (y2-y1);
357                         }
358                         else {
359                                 if(rf->ymax>y2) rf->ymax= y2;
360                                 newrct= stack+ *count;
361                                 (*count)++;
362
363                                 newrct->ymax= y2;
364                                 newrct->ymin= rf->ymin+(y2-y1);
365                                 newrct->xmin= rf->xmin;
366                                 newrct->xmax= rf->xmax;
367
368                                 if(newrct->ymin==newrct->ymax) (*count)--;
369
370                                 rf->ymin= y1;
371                         }
372                 }
373                 else if(rf->ymax>y2) {
374                         if(rf->ymin>y2) {
375                                 rf->ymin-= (y2-y1);
376                                 rf->ymax-= (y2-y1);
377                         }
378                         else {
379                                 if(rf->ymin<y1) rf->ymin= y1;
380                                 newrct= stack+ *count;
381                                 (*count)++;
382
383                                 newrct->ymin= y1;
384                                 newrct->ymax= rf->ymax-(y2-y1);
385                                 newrct->xmin= rf->xmin;
386                                 newrct->xmax= rf->xmax;
387
388                                 if(newrct->ymin==newrct->ymax) (*count)--;
389
390                                 rf->ymax= y2;
391                         }
392                 }
393                 rf++;
394         }
395 }
396
397 static float square_rctf(rctf *rf)
398 {
399         float x, y;
400
401         x= rf->xmax- rf->xmin;
402         y= rf->ymax- rf->ymin;
403         return (x*y);
404 }
405
406 static float clipx_rctf(rctf *rf, float x1, float x2)
407 {
408         float size;
409
410         size= rf->xmax - rf->xmin;
411
412         if(rf->xmin<x1) {
413                 rf->xmin= x1;
414         }
415         if(rf->xmax>x2) {
416                 rf->xmax= x2;
417         }
418         if(rf->xmin > rf->xmax) {
419                 rf->xmin = rf->xmax;
420                 return 0.0;
421         }
422         else if(size!=0.0f) {
423                 return (rf->xmax - rf->xmin)/size;
424         }
425         return 1.0;
426 }
427
428 static float clipy_rctf(rctf *rf, float y1, float y2)
429 {
430         float size;
431
432         size= rf->ymax - rf->ymin;
433
434         if(rf->ymin<y1) {
435                 rf->ymin= y1;
436         }
437         if(rf->ymax>y2) {
438                 rf->ymax= y2;
439         }
440
441         if(rf->ymin > rf->ymax) {
442                 rf->ymin = rf->ymax;
443                 return 0.0;
444         }
445         else if(size!=0.0f) {
446                 return (rf->ymax - rf->ymin)/size;
447         }
448         return 1.0;
449
450 }
451
452 static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
453 {
454         /* sample box, is clipped already, and minx etc. have been set at ibuf size.
455            Enlarge with antialiased edges of the pixels */
456
457         float muly, mulx, div, col[4];
458         int x, y, startx, endx, starty, endy;
459
460         startx= (int)floor(rf->xmin);
461         endx= (int)floor(rf->xmax);
462         starty= (int)floor(rf->ymin);
463         endy= (int)floor(rf->ymax);
464
465         if(startx < 0) startx= 0;
466         if(starty < 0) starty= 0;
467         if(endx>=ibuf->x) endx= ibuf->x-1;
468         if(endy>=ibuf->y) endy= ibuf->y-1;
469
470         if(starty==endy && startx==endx) {
471                 ibuf_get_color(&texres->tr, ibuf, startx, starty);
472         }
473         else {
474                 div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0;
475                 for(y=starty; y<=endy; y++) {
476                         
477                         muly= 1.0;
478
479                         if(starty==endy);
480                         else {
481                                 if(y==starty) muly= 1.0f-(rf->ymin - y);
482                                 if(y==endy) muly= (rf->ymax - y);
483                         }
484                         
485                         if(startx==endx) {
486                                 mulx= muly;
487                                 
488                                 ibuf_get_color(col, ibuf, startx, y);
489
490                                 texres->ta+= mulx*col[3];
491                                 texres->tr+= mulx*col[0];
492                                 texres->tg+= mulx*col[1];
493                                 texres->tb+= mulx*col[2];
494                                 div+= mulx;
495                         }
496                         else {
497                                 for(x=startx; x<=endx; x++) {
498                                         mulx= muly;
499                                         if(x==startx) mulx*= 1.0f-(rf->xmin - x);
500                                         if(x==endx) mulx*= (rf->xmax - x);
501
502                                         ibuf_get_color(col, ibuf, x, y);
503                                         
504                                         if(mulx==1.0f) {
505                                                 texres->ta+= col[3];
506                                                 texres->tr+= col[0];
507                                                 texres->tg+= col[1];
508                                                 texres->tb+= col[2];
509                                                 div+= 1.0f;
510                                         }
511                                         else {
512                                                 texres->ta+= mulx*col[3];
513                                                 texres->tr+= mulx*col[0];
514                                                 texres->tg+= mulx*col[1];
515                                                 texres->tb+= mulx*col[2];
516                                                 div+= mulx;
517                                         }
518                                 }
519                         }
520                 }
521
522                 if(div!=0.0f) {
523                         div= 1.0f/div;
524                         texres->tb*= div;
525                         texres->tg*= div;
526                         texres->tr*= div;
527                         texres->ta*= div;
528                 }
529                 else {
530                         texres->tr= texres->tg= texres->tb= texres->ta= 0.0f;
531                 }
532         }
533 }
534
535 static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend)
536 {
537         /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 .
538          * Enlarge with antialiased edges of pixels.
539          * If variable 'imaprepeat' has been set, the
540          * clipped-away parts are sampled as well.
541          */
542         /* note: actually minx etc isnt in the proper range... this due to filter size and offset vectors for bump */
543         /* note: talpha must be initialized */
544         /* note: even when 'imaprepeat' is set, this can only repeate once in any direction.
545          * the point which min/max is derived from is assumed to be wrapped */
546         TexResult texr;
547         rctf *rf, stack[8];
548         float opp, tot, alphaclip= 1.0;
549         short count=1;
550
551         rf= stack;
552         rf->xmin= minx*(ibuf->x);
553         rf->xmax= maxx*(ibuf->x);
554         rf->ymin= miny*(ibuf->y);
555         rf->ymax= maxy*(ibuf->y);
556
557         texr.talpha= texres->talpha;    /* is read by boxsample_clip */
558         
559         if(imapextend) {
560                 CLAMP(rf->xmin, 0.0f, ibuf->x-1);
561                 CLAMP(rf->xmax, 0.0f, ibuf->x-1);
562         }
563         else if(imaprepeat) 
564                 clipx_rctf_swap(stack, &count, 0.0, (float)(ibuf->x));
565         else {
566                 alphaclip= clipx_rctf(rf, 0.0, (float)(ibuf->x));
567
568                 if(alphaclip<=0.0f) {
569                         texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
570                         return;
571                 }
572         }
573
574         if(imapextend) {
575                 CLAMP(rf->ymin, 0.0f, ibuf->y-1);
576                 CLAMP(rf->ymax, 0.0f, ibuf->y-1);
577         }
578         else if(imaprepeat) 
579                 clipy_rctf_swap(stack, &count, 0.0, (float)(ibuf->y));
580         else {
581                 alphaclip*= clipy_rctf(rf, 0.0, (float)(ibuf->y));
582
583                 if(alphaclip<=0.0f) {
584                         texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
585                         return;
586                 }
587         }
588
589         if(count>1) {
590                 tot= texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
591                 while(count--) {
592                         boxsampleclip(ibuf, rf, &texr);
593                         
594                         opp= square_rctf(rf);
595                         tot+= opp;
596
597                         texres->tr+= opp*texr.tr;
598                         texres->tg+= opp*texr.tg;
599                         texres->tb+= opp*texr.tb;
600                         if(texres->talpha) texres->ta+= opp*texr.ta;
601                         rf++;
602                 }
603                 if(tot!= 0.0f) {
604                         texres->tr/= tot;
605                         texres->tg/= tot;
606                         texres->tb/= tot;
607                         if(texres->talpha) texres->ta/= tot;
608                 }
609         }
610         else
611                 boxsampleclip(ibuf, rf, texres);
612
613         if(texres->talpha==0) texres->ta= 1.0;
614         
615         if(alphaclip!=1.0f) {
616                 /* premul it all */
617                 texres->tr*= alphaclip;
618                 texres->tg*= alphaclip;
619                 texres->tb*= alphaclip;
620                 texres->ta*= alphaclip;
621         }
622 }       
623
624 //-----------------------------------------------------------------------------------------------------------------
625 // from here, some functions only used for the new filtering
626
627 // anisotropic filters, data struct used instead of long line of (possibly unused) func args
628 typedef struct afdata_t {
629         float dxt[2], dyt[2];
630         int intpol, extflag;
631         // feline only
632         float majrad, minrad, theta;
633         int iProbes;
634         float dusc, dvsc;
635 } afdata_t;
636
637 // this only used here to make it easier to pass extend flags as single int
638 enum {TXC_XMIR=1, TXC_YMIR, TXC_REPT, TXC_EXTD};
639
640 // similar to ibuf_get_color() but clips/wraps coords according to repeat/extend flags
641 // returns true if out of range in clipmode
642 static int ibuf_get_color_clip(float *col, ImBuf *ibuf, int x, int y, int extflag)
643 {
644         int clip = 0;
645         switch (extflag) {
646                 case TXC_XMIR:  // y rep
647                         x %= 2*ibuf->x;
648                         x += x < 0 ? 2*ibuf->x : 0;
649                         x = x >= ibuf->x ? 2*ibuf->x - x - 1 : x;
650                         y %= ibuf->y;
651                         y += y < 0 ? ibuf->y : 0;
652                         break;
653                 case TXC_YMIR:  // x rep
654                         x %= ibuf->x;
655                         x += x < 0 ? ibuf->x : 0;
656                         y %= 2*ibuf->y;
657                         y += y < 0 ? 2*ibuf->y : 0;
658                         y = y >= ibuf->y ? 2*ibuf->y - y - 1 : y;
659                         break;
660                 case TXC_EXTD:
661                         x = (x < 0) ? 0 : ((x >= ibuf->x) ? (ibuf->x - 1) : x);
662                         y = (y < 0) ? 0 : ((y >= ibuf->y) ? (ibuf->y - 1) : y);
663                         break;
664                 case TXC_REPT:
665                         x %= ibuf->x;
666                         x += (x < 0) ? ibuf->x : 0;
667                         y %= ibuf->y;
668                         y += (y < 0) ? ibuf->y : 0;
669                         break;
670                 default:        {       // as extend, if clipped, set alpha to 0.0
671                         if (x < 0) { x = 0;  } // TXF alpha: clip = 1; }
672                         if (x >= ibuf->x) { x = ibuf->x - 1; } // TXF alpha:  clip = 1; }
673                         if (y < 0) { y = 0; } // TXF alpha:  clip = 1; }
674                         if (y >= ibuf->y) { y = ibuf->y - 1; } // TXF alpha:  clip = 1; }
675                 }
676         }
677
678         if (ibuf->rect_float) {
679                 const float* fp = ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels;
680                 if (ibuf->channels == 1)
681                         col[0] = col[1] = col[2] = col[3] = *fp;
682                 else {
683                         col[0] = fp[0];
684                         col[1] = fp[1];
685                         col[2] = fp[2];
686                         col[3] = clip ? 0.f : (ibuf->channels == 4 ? fp[3] : 1.f);
687                 }
688         }
689         else {
690                 char* rect = (char*)(ibuf->rect + x + y*ibuf->x);
691                 col[0] = rect[0]*(1.f/255.f);
692                 col[1] = rect[1]*(1.f/255.f);
693                 col[2] = rect[2]*(1.f/255.f);
694                 col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
695         }
696         return clip;
697 }
698
699 // as above + bilerp
700 static int ibuf_get_color_clip_bilerp(float *col, ImBuf *ibuf, float u, float v, int intpol, int extflag)
701 {
702         if (intpol) {
703                 float c00[4], c01[4], c10[4], c11[4];
704                 const float ufl = floorf(u -= 0.5f), vfl = floorf(v -= 0.5f);
705                 const float uf = u - ufl, vf = v - vfl;
706                 const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
707                 const int x1 = (int)ufl, y1 = (int)vfl, x2 = x1 + 1, y2 = y1 + 1;
708                 int clip = ibuf_get_color_clip(c00, ibuf, x1, y1, extflag);
709                 clip |= ibuf_get_color_clip(c10, ibuf, x2, y1, extflag);
710                 clip |= ibuf_get_color_clip(c01, ibuf, x1, y2, extflag);
711                 clip |= ibuf_get_color_clip(c11, ibuf, x2, y2, extflag);
712                 col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
713                 col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
714                 col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
715                 col[3] = clip ? 0.f : w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
716                 return clip;
717         }
718         return ibuf_get_color_clip(col, ibuf, (int)u, (int)v, extflag);
719 }
720
721 static void area_sample(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
722 {
723         int xs, ys, clip = 0;
724         float tc[4], xsd, ysd, cw = 0.f;
725         const float ux = ibuf->x*AFD->dxt[0], uy = ibuf->y*AFD->dxt[1];
726         const float vx = ibuf->x*AFD->dyt[0], vy = ibuf->y*AFD->dyt[1];
727         int xsam = (int)(0.5f*sqrtf(ux*ux + uy*uy) + 0.5f);
728         int ysam = (int)(0.5f*sqrtf(vx*vx + vy*vy) + 0.5f);
729         const int minsam = AFD->intpol ? 2 : 4;
730         xsam = CLAMPIS(xsam, minsam, ibuf->x*2);
731         ysam = CLAMPIS(ysam, minsam, ibuf->y*2);
732         xsd = 1.f / xsam;
733         ysd = 1.f / ysam;
734         texr->tr = texr->tg = texr->tb = texr->ta = 0.f;
735         for (ys=0; ys<ysam; ++ys) {
736                 for (xs=0; xs<xsam; ++xs) {
737                         const float su = (xs + ((ys & 1) + 0.5f)*0.5f)*xsd - 0.5f;
738                         const float sv = (ys + ((xs & 1) + 0.5f)*0.5f)*ysd - 0.5f;
739                         const float pu = fx + su*AFD->dxt[0] + sv*AFD->dyt[0];
740                         const float pv = fy + su*AFD->dxt[1] + sv*AFD->dyt[1];
741                         const int out = ibuf_get_color_clip_bilerp(tc, ibuf, pu*ibuf->x, pv*ibuf->y, AFD->intpol, AFD->extflag);
742                         clip |= out;
743                         cw += out ? 0.f : 1.f;
744                         texr->tr += tc[0];
745                         texr->tg += tc[1];
746                         texr->tb += tc[2];
747                         texr->ta += texr->talpha ? tc[3] : 0.f;
748                 }
749         }
750         xsd *= ysd;
751         texr->tr *= xsd;
752         texr->tg *= xsd;
753         texr->tb *= xsd;
754         // clipping can be ignored if alpha used, texr->ta already includes filtered edge
755         texr->ta = texr->talpha ? texr->ta*xsd : (clip ? cw*xsd : 1.f);
756 }
757
758 // table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
759 // used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible
760 #define EWA_MAXIDX 255
761 static float EWA_WTS[EWA_MAXIDX + 1] =
762 { 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
763  0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
764  0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
765  0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
766  0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
767  0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
768  0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
769  0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
770  0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
771  0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
772  0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
773  0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
774  0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
775  0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
776  0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
777  0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
778  0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
779  0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
780  0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
781  0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
782  0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
783  0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
784  0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
785  0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
786  0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
787  0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
788  0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
789  0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
790  0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
791  0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
792  0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
793  0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
794 };
795
796 // test if a float value is 'nan'
797 // there is a C99 function for this: isnan(), but blender seems to use C90 (according to gcc warns),
798 // and may not be supported by other compilers either
799 #ifndef ISNAN
800 #define ISNAN(x) ((x) != (x))
801 #endif
802 //static int ISNAN(float x) { return (x != x); }
803
804 static void radangle2imp(float a2, float b2, float th, float* A, float* B, float* C, float* F)
805 {
806         float ct2 = cosf(th);
807         const float st2 = 1.f - ct2*ct2;        // <- sin(th)^2
808         ct2 *= ct2;
809         *A = a2*st2 + b2*ct2;
810         *B = (b2 - a2)*sinf(2.f*th);
811         *C = a2*ct2 + b2*st2;
812         *F = a2*b2;
813 }
814
815 // all tests here are done to make sure possible overflows are hopefully minimized
816 static void imp2radangle(float A, float B, float C, float F, float* a, float* b, float* th, float* ecc)
817 {
818         if (F <= 1e-5f) {       // use arbitrary major radius, zero minor, infinite eccentricity
819                 *a = sqrtf(A > C ? A : C);
820                 *b = 0.f;
821                 *ecc = 1e10f;
822                 *th = 0.5f*(atan2f(B, A - C) + (float)M_PI);
823         }
824         else {
825                 const float AmC = A - C, ApC = A + C, F2 = F*2.f;
826                 const float r = sqrtf(AmC*AmC + B*B);
827                 float d = ApC - r;
828                 *a = (d <= 0.f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d);
829                 d = ApC + r;
830                 if (d <= 0.f) {
831                         *b = 0.f;
832                         *ecc = 1e10f;
833                 }
834                 else {
835                         *b = sqrtf(F2 / d);
836                         *ecc = *a / *b;
837                 }
838                 // incr theta by 0.5*pi (angle of major axis)
839                 *th = 0.5f*(atan2f(B, AmC) + (float)M_PI);
840         }
841 }
842
843 static void ewa_eval(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
844 {
845         // scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
846         // scaling by aspect ratio alone does the opposite, so try something in between instead...
847         const float ff2 = ibuf->x, ff = sqrtf(ff2), q = ibuf->y / ff;
848         const float Ux = AFD->dxt[0]*ff, Vx = AFD->dxt[1]*q, Uy = AFD->dyt[0]*ff, Vy = AFD->dyt[1]*q;
849         float A = Vx*Vx + Vy*Vy;
850         float B = -2.f*(Ux*Vx + Uy*Vy);
851         float C = Ux*Ux + Uy*Uy;
852         float F = A*C - B*B*0.25f;
853         float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d; // TXF alpha: cw = 0.f;
854         int u, v, u1, u2, v1, v2; // TXF alpha: clip = 0;
855
856         // The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
857         // so the ellipse always covers at least some texels. But since the filter is now always larger,
858         // it also means that everywhere else it's also more blurry then ideally should be the case.
859         // So instead here the ellipse radii are modified instead whenever either is too low.
860         // Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
861         // and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
862         // (minimum values: const float rmin = intpol ? 1.f : 0.5f;)
863         const float rmin = (AFD->intpol ? 1.5625f : 0.765625f)/ff2;
864         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
865         if ((b2 = b*b) < rmin) {
866                 if ((a2 = a*a) < rmin) {
867                         B = 0.f;
868                         A = C = rmin;
869                         F = A*C;
870                 }
871                 else {
872                         b2 = rmin;
873                         radangle2imp(a2, b2, th, &A, &B, &C, &F);
874                 }
875         }
876
877         ue = ff*sqrtf(C);
878         ve = ff*sqrtf(A);
879         d = (float)(EWA_MAXIDX + 1) / (F*ff2);
880         A *= d;
881         B *= d;
882         C *= d;
883
884         U0 = fx*ibuf->x;
885         V0 = fy*ibuf->y;
886         u1 = (int)(floorf(U0 - ue));
887         u2 = (int)(ceilf(U0 + ue));
888         v1 = (int)(floorf(V0 - ve));
889         v2 = (int)(ceilf(V0 + ve));
890         U0 -= 0.5f;
891         V0 -= 0.5f;
892         DDQ = 2.f*A;
893         U = u1 - U0;
894         ac1 = A*(2.f*U + 1.f);
895         ac2 = A*U*U;
896         BU = B*U;
897
898         d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f;
899         for (v=v1; v<=v2; ++v) {
900                 const float V = v - V0;
901                 float DQ = ac1 + B*V;
902                 float Q = (C*V + BU)*V + ac2;
903                 for (u=u1; u<=u2; ++u) {
904                         if (Q < (float)(EWA_MAXIDX + 1)) {
905                                 float tc[4];
906                                 const float wt = EWA_WTS[(Q < 0.f) ? 0 : (unsigned int)Q];
907                                 /*const int out =*/ ibuf_get_color_clip(tc, ibuf, u, v, AFD->extflag);
908                                 // TXF alpha: clip |= out;
909                                 // TXF alpha: cw += out ? 0.f : wt;
910                                 texr->tr += tc[0]*wt;
911                                 texr->tg += tc[1]*wt;
912                                 texr->tb += tc[2]*wt;
913                                 texr->ta += texr->talpha ? tc[3]*wt : 0.f;
914                                 d += wt;
915                         }
916                         Q += DQ;
917                         DQ += DDQ;
918                 }
919         }
920
921         // d should hopefully never be zero anymore
922         d = 1.f/d;
923         texr->tr *= d;
924         texr->tg *= d;
925         texr->tb *= d;
926         // clipping can be ignored if alpha used, texr->ta already includes filtered edge
927         texr->ta = texr->talpha ? texr->ta*d : 1.f; // TXF alpha (clip ? cw*d : 1.f);
928 }
929
930 static void feline_eval(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
931 {
932         const int maxn = AFD->iProbes - 1;
933         const float ll = ((AFD->majrad == AFD->minrad) ? 2.f*AFD->majrad : 2.f*(AFD->majrad - AFD->minrad)) / (maxn ? (float)maxn : 1.f);
934         float du = maxn ? cosf(AFD->theta)*ll : 0.f;
935         float dv = maxn ? sinf(AFD->theta)*ll : 0.f;
936         //const float D = -0.5f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad);
937         const float D = (EWA_MAXIDX + 1)*0.25f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad);
938         float d; // TXF alpha: cw = 0.f;
939         int n; // TXF alpha: clip = 0;
940         // have to use same scaling for du/dv here as for Ux/Vx/Uy/Vy (*after* D calc.)
941         du *= AFD->dusc;
942         dv *= AFD->dvsc;
943         d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f;
944         for (n=-maxn; n<=maxn; n+=2) {
945                 float tc[4];
946                 const float hn = n*0.5f;
947                 const float u = fx + hn*du, v = fy + hn*dv;
948                 //const float wt = expf(n*n*D);
949                 // can use ewa table here too
950                 const float wt = EWA_WTS[(int)(n*n*D)];
951                 /*const int out =*/ ibuf_get_color_clip_bilerp(tc, ibuf, ibuf->x*u, ibuf->y*v, AFD->intpol, AFD->extflag);
952                 // TXF alpha: clip |= out;
953                 // TXF alpha: cw += out ? 0.f : wt;
954                 texr->tr += tc[0]*wt;
955                 texr->tg += tc[1]*wt;
956                 texr->tb += tc[2]*wt;
957                 texr->ta += texr->talpha ? tc[3]*wt : 0.f;
958                 d += wt;
959         }
960
961         d = 1.f/d;
962         texr->tr *= d;
963         texr->tg *= d;
964         texr->tb *= d;
965         // clipping can be ignored if alpha used, texr->ta already includes filtered edge
966         texr->ta = texr->talpha ? texr->ta*d : 1.f; // TXF alpha: (clip ? cw*d : 1.f);
967 }
968 #undef EWA_MAXIDX
969
970 static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, int extflag, TexResult *texres)
971 {
972         float alphaclip;
973         rctf rf;
974
975         // TXF apha: we're doing the same alphaclip here as boxsample, but i'm doubting
976         // if this is actually correct for the all the filtering algorithms ..
977
978         if(!(extflag == TXC_REPT || extflag == TXC_EXTD)) {
979                 rf.xmin= minx*(ibuf->x);
980                 rf.xmax= maxx*(ibuf->x);
981                 rf.ymin= miny*(ibuf->y);
982                 rf.ymax= maxy*(ibuf->y);
983
984                 alphaclip = clipx_rctf(&rf, 0.0, (float)(ibuf->x));
985                 alphaclip*= clipy_rctf(&rf, 0.0, (float)(ibuf->y));
986                 alphaclip= MAX2(alphaclip, 0.0f);
987
988                 if(alphaclip!=1.0f) {
989                         /* premul it all */
990                         texres->tr*= alphaclip;
991                         texres->tg*= alphaclip;
992                         texres->tb*= alphaclip;
993                         texres->ta*= alphaclip;
994                 }
995         }
996 }
997
998 static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
999 {
1000         if (tex->imaflag & TEX_MIPMAP) {
1001                 if ((ibuf->flags & IB_fields) == 0) {
1002                         
1003                         if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
1004                                 BLI_lock_thread(LOCK_IMAGE);
1005                                 if (ibuf->userflags & IB_MIPMAP_INVALID) {
1006                                         IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
1007                                         ibuf->userflags &= ~IB_MIPMAP_INVALID;
1008                                 }                               
1009                                 BLI_unlock_thread(LOCK_IMAGE);
1010                         }
1011                         if (ibuf->mipmap[0] == NULL) {
1012                                 BLI_lock_thread(LOCK_IMAGE);
1013                                 if (ibuf->mipmap[0] == NULL) 
1014                                         IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
1015                                 BLI_unlock_thread(LOCK_IMAGE);
1016                         }
1017                 }
1018         }
1019         
1020 }
1021
1022 static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[3], float dyt[3], TexResult *texres)
1023 {
1024         TexResult texr;
1025         float fx, fy, minx, maxx, miny, maxy;
1026         float maxd, val1, val2, val3;
1027         int curmap, retval, intpol, extflag = 0;
1028         afdata_t AFD;
1029
1030         void (*filterfunc)(TexResult*, ImBuf*, float, float, afdata_t*);
1031         switch (tex->texfilter) {
1032                 case TXF_EWA:
1033                         filterfunc = ewa_eval;
1034                         break;
1035                 case TXF_FELINE:
1036                         filterfunc = feline_eval;
1037                         break;
1038                 case TXF_AREA:
1039                 default:
1040                         filterfunc = area_sample;
1041         }
1042
1043         texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.f;
1044
1045         // we need to set retval OK, otherwise texture code generates normals itself...
1046         retval = texres->nor ? 3 : 1;
1047
1048         // quick tests
1049         if (ibuf==NULL && ima==NULL) return retval;
1050
1051         if (ima) {      // hack for icon render
1052                 if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
1053                 ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 
1054         }
1055
1056         if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
1057
1058         /* mipmap test */
1059         image_mipmap_test(tex, ibuf);
1060         
1061         if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
1062         texr.talpha = texres->talpha;
1063
1064         if (tex->imaflag & TEX_IMAROT) {
1065                 fy = texvec[0];
1066                 fx = texvec[1];
1067         }
1068         else {
1069                 fx = texvec[0];
1070                 fy = texvec[1];
1071         }
1072
1073         if (ibuf->flags & IB_fields) {
1074                 if (R.r.mode & R_FIELDS) {                      /* field render */
1075                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1076                                 /* fac1= 0.5/( (float)ibuf->y ); */
1077                                 /* fy-= fac1; */
1078                         }
1079                         else    /* first field */
1080                                 fy += 0.5f/( (float)ibuf->y );
1081                 }
1082         }
1083
1084         // pixel coordinates
1085         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1086         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1087         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1088         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1089
1090         // tex_sharper has been removed
1091         minx = (maxx - minx)*0.5f;
1092         miny = (maxy - miny)*0.5f;
1093
1094         if (tex->imaflag & TEX_FILTER_MIN) {
1095                 // make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy)
1096                  const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1097                 if (addval > minx) minx = addval;
1098                 if (addval > miny) miny = addval;
1099         }
1100         else if (tex->filtersize != 1.f) {
1101                 minx *= tex->filtersize;
1102                 miny *= tex->filtersize;
1103                 dxt[0] *= tex->filtersize;
1104                 dxt[1] *= tex->filtersize;
1105                 dyt[0] *= tex->filtersize;
1106                 dyt[1] *= tex->filtersize;
1107         }
1108
1109         if (tex->imaflag & TEX_IMAROT) {
1110                 float t;
1111                 SWAP(float, minx, miny);
1112                 // must rotate dxt/dyt 90 deg
1113                 // yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1114                 // but it doesn't, it only swaps coords, so filter area will be incorrect in those cases.
1115                 t = dxt[0];
1116                 dxt[0] = dxt[1];
1117                 dxt[1] = -t;
1118                 t = dyt[0];
1119                 dyt[0] = dyt[1];
1120                 dyt[1] = -t;
1121         }
1122
1123         // side faces of unit-cube
1124         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1125         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1126
1127         // repeat and clip
1128
1129         if (tex->extend == TEX_REPEAT) {
1130                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1131                         extflag = TXC_EXTD;
1132                 else if (tex->flag & TEX_REPEAT_XMIR)
1133                         extflag = TXC_XMIR;
1134                 else if (tex->flag & TEX_REPEAT_YMIR)
1135                         extflag = TXC_YMIR;
1136                 else
1137                         extflag = TXC_REPT;
1138         }
1139         else if (tex->extend == TEX_EXTEND)
1140                 extflag = TXC_EXTD;
1141
1142         if (tex->extend == TEX_CHECKER) {
1143                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1144                 // both checkers available, no boundary exceptions, checkerdist will eat aliasing
1145                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1146                         fx -= xs;
1147                         fy -= ys;
1148                 }
1149                 else {
1150                         int xs1 = (int)floorf(fx - minx);
1151                         int ys1 = (int)floorf(fy - miny);
1152                         int xs2 = (int)floorf(fx + minx);
1153                         int ys2 = (int)floorf(fy + miny);
1154                         if ((xs1 != xs2) || (ys1 != ys2)) {
1155                                 if (tex->flag & TEX_CHECKER_ODD) {
1156                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1157                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1158                                 }
1159                                 if (tex->flag & TEX_CHECKER_EVEN) {
1160                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1161                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1162                                 }
1163                         }
1164                         else {
1165                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
1166                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
1167                                 fx -= xs;
1168                                 fy -= ys;
1169                         }
1170                 }
1171                 // scale around center, (0.5, 0.5)
1172                 if (tex->checkerdist < 1.f) {
1173                         const float omcd = 1.f / (1.f - tex->checkerdist);
1174                         fx = (fx - 0.5f)*omcd + 0.5f;
1175                         fy = (fy - 0.5f)*omcd + 0.5f;
1176                         minx *= omcd;
1177                         miny *= omcd;
1178                 }
1179         }
1180
1181         if (tex->extend == TEX_CLIPCUBE) {
1182                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f || texvec[2] < -1.f || texvec[2] > 1.f) return retval;
1183         }
1184         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1185                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
1186         }
1187         else {
1188                 if (tex->extend == TEX_EXTEND) {
1189                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1190                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1191                 }
1192                 else {
1193                         fx -= floorf(fx);
1194                         fy -= floorf(fy);
1195                 }
1196         }
1197
1198         intpol = tex->imaflag & TEX_INTERPOL;
1199
1200         // warning no return!
1201         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1202                 ibuf->rect += ibuf->x*ibuf->y;
1203
1204         // struct common data
1205         copy_v2_v2(AFD.dxt, dxt);
1206         copy_v2_v2(AFD.dyt, dyt);
1207         AFD.intpol = intpol;
1208         AFD.extflag = extflag;
1209
1210         // brecht: added stupid clamping here, large dx/dy can give very large
1211         // filter sizes which take ages to render, it may be better to do this
1212         // more intelligently later in the code .. probably it's not noticeable
1213         if(AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f)
1214                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1215         if(AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1216                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1217
1218         // choice:
1219         if (tex->imaflag & TEX_MIPMAP) {
1220                 ImBuf *previbuf, *curibuf;
1221                 float levf;
1222                 int maxlev;
1223                 ImBuf* mipmaps[IB_MIPMAP_LEVELS + 1];
1224
1225                 // modify ellipse minor axis if too eccentric, use for area sampling as well
1226                 // scaling dxt/dyt as done in pbrt is not the same
1227                 // (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision)
1228                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1229                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1230                 const float A = Vx*Vx + Vy*Vy;
1231                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1232                 const float C = Ux*Ux + Uy*Uy;
1233                 const float F = A*C - B*B*0.25f;
1234                 float a, b, th, ecc;
1235                 imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1236                 if (tex->texfilter == TXF_FELINE) {
1237                         float fProbes;
1238                         a *= ff;
1239                         b *= ff;
1240                         a = MAX2(a, 1.f);
1241                         b = MAX2(b, 1.f);
1242                         fProbes = 2.f*(a / b) - 1.f;
1243                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1244                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1245                         if (AFD.iProbes < fProbes)
1246                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1247                         AFD.majrad = a/ff;
1248                         AFD.minrad = b/ff;
1249                         AFD.theta = th;
1250                         AFD.dusc = 1.f/ff;
1251                         AFD.dvsc = ff / (float)ibuf->y;
1252                 }
1253                 else {  // EWA & area
1254                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1255                         b *= ff;
1256                 }
1257                 maxd = MAX2(b, 1e-8f);
1258                 levf = ((float)M_LOG2E)*logf(maxd);
1259
1260                 curmap = 0;
1261                 maxlev = 1;
1262                 mipmaps[0] = ibuf;
1263                 while (curmap < IB_MIPMAP_LEVELS) {
1264                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1265                         if (ibuf->mipmap[curmap]) maxlev++;
1266                         curmap++;
1267                 }
1268
1269                 // mipmap level
1270                 if (levf < 0.f) {       // original image only
1271                         previbuf = curibuf = mipmaps[0];
1272                         levf = 0.f;
1273                 }
1274                 else if (levf >= maxlev - 1) {
1275                         previbuf = curibuf = mipmaps[maxlev - 1];
1276                         levf = 0.f;
1277                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1278                 }
1279                 else {
1280                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1281                         curibuf = mipmaps[lev];
1282                         previbuf = mipmaps[lev + 1];
1283                         levf -= floorf(levf);
1284                 }
1285
1286                 // filter functions take care of interpolation themselves, no need to modify dxt/dyt here
1287
1288                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1289                         // color & normal
1290                         filterfunc(texres, curibuf, fx, fy, &AFD);
1291                         val1 = texres->tr + texres->tg + texres->tb;
1292                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1293                         val2 = texr.tr + texr.tg + texr.tb;
1294                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1295                         val3 = texr.tr + texr.tg + texr.tb;
1296                         // don't switch x or y!
1297                         texres->nor[0] = val1 - val2;
1298                         texres->nor[1] = val1 - val3;
1299                         if (previbuf != curibuf) {  // interpolate
1300                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1301                                 // rgb
1302                                 texres->tr += levf*(texr.tr - texres->tr);
1303                                 texres->tg += levf*(texr.tg - texres->tg);
1304                                 texres->tb += levf*(texr.tb - texres->tb);
1305                                 texres->ta += levf*(texr.ta - texres->ta);
1306                                 // normal
1307                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1308                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1309                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1310                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1311                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1312                                 texres->nor[0] = val1 - val2;   // vals have been interpolated above!
1313                                 texres->nor[1] = val1 - val3;
1314                         }
1315                 }
1316                 else {  // color
1317                         filterfunc(texres, curibuf, fx, fy, &AFD);
1318                         if (previbuf != curibuf) {  // interpolate
1319                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1320                                 texres->tr += levf*(texr.tr - texres->tr);
1321                                 texres->tg += levf*(texr.tg - texres->tg);
1322                                 texres->tb += levf*(texr.tb - texres->tb);
1323                                 texres->ta += levf*(texr.ta - texres->ta);
1324                         }
1325
1326                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1327                 }
1328         }
1329         else {  // no mipmap
1330                 // filter functions take care of interpolation themselves, no need to modify dxt/dyt here
1331                 if (tex->texfilter == TXF_FELINE) {
1332                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1333                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1334                         const float A = Vx*Vx + Vy*Vy;
1335                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1336                         const float C = Ux*Ux + Uy*Uy;
1337                         const float F = A*C - B*B*0.25f;
1338                         float a, b, th, ecc, fProbes;
1339                         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1340                         a *= ff;
1341                         b *= ff;
1342                         a = MAX2(a, 1.f);
1343                         b = MAX2(b, 1.f);
1344                         fProbes = 2.f*(a / b) - 1.f;
1345                         // no limit to number of Probes here
1346                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1347                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1348                         AFD.majrad = a/ff;
1349                         AFD.minrad = b/ff;
1350                         AFD.theta = th;
1351                         AFD.dusc = 1.f/ff;
1352                         AFD.dvsc = ff / (float)ibuf->y;
1353                 }
1354                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1355                         // color & normal
1356                         filterfunc(texres, ibuf, fx, fy, &AFD);
1357                         val1 = texres->tr + texres->tg + texres->tb;
1358                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1359                         val2 = texr.tr + texr.tg + texr.tb;
1360                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1361                         val3 = texr.tr + texr.tg + texr.tb;
1362                         // don't switch x or y!
1363                         texres->nor[0] = val1 - val2;
1364                         texres->nor[1] = val1 - val3;
1365                 }
1366                 else {
1367                         filterfunc(texres, ibuf, fx, fy, &AFD);
1368                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1369                 }
1370         }
1371
1372         if (tex->imaflag & TEX_CALCALPHA)
1373                 texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
1374         else
1375                 texres->tin = texres->ta;
1376         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1377         
1378         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1379                 ibuf->rect -= ibuf->x*ibuf->y;
1380
1381         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    // normal from color
1382                 // The invert of the red channel is to make
1383                 // the normal map compliant with the outside world.
1384                 // It needs to be done because in Blender
1385                 // the normal used in the renderer points inward. It is generated
1386                 // this way in calc_vertexnormals(). Should this ever change
1387                 // this negate must be removed.
1388                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1389                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1390                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1391         }
1392         
1393         // de-premul, this is being premulled in shade_input_do_shade()
1394         // TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1395         // also disabled in imagewraposa() to be able to compare results with blender's default texture filtering
1396
1397         // brecht: tried to fix this, see "TXF alpha" comments
1398
1399         if (texres->ta != 1.f && (texres->ta > 1e-4f)) {
1400                 fx = 1.f/texres->ta;
1401                 texres->tr *= fx;
1402                 texres->tg *= fx;
1403                 texres->tb *= fx;
1404         }
1405
1406         BRICONTRGB;
1407         
1408         return retval;
1409 }
1410
1411
1412 int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[3], const float DYT[3], TexResult *texres)
1413 {
1414         TexResult texr;
1415         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3];
1416         float maxd, pixsize, val1, val2, val3;
1417         int curmap, retval, imaprepeat, imapextend;
1418
1419         // TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1420         // make a local copy here so that original vecs remain untouched
1421         copy_v3_v3(dxt, DXT);
1422         copy_v3_v3(dyt, DYT);
1423
1424         // anisotropic filtering
1425         if (tex->texfilter != TXF_BOX)
1426                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres);
1427
1428         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1429         
1430         /* we need to set retval OK, otherwise texture code generates normals itself... */
1431         retval= texres->nor?3:1;
1432         
1433         /* quick tests */
1434         if(ibuf==NULL && ima==NULL)
1435                 return retval;
1436         if(ima) {
1437
1438                 /* hack for icon render */
1439                 if(ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
1440                         return retval;
1441                 
1442                 ibuf= BKE_image_get_ibuf(ima, &tex->iuser); 
1443         }
1444         if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
1445                 return retval;
1446         
1447         /* mipmap test */
1448         image_mipmap_test(tex, ibuf);
1449
1450         if(tex->imaflag & TEX_USEALPHA) {
1451                 if(tex->imaflag & TEX_CALCALPHA);
1452                 else texres->talpha= 1;
1453         }
1454         
1455         texr.talpha= texres->talpha;
1456         
1457         if(tex->imaflag & TEX_IMAROT) {
1458                 fy= texvec[0];
1459                 fx= texvec[1];
1460         }
1461         else {
1462                 fx= texvec[0];
1463                 fy= texvec[1];
1464         }
1465         
1466         if(ibuf->flags & IB_fields) {
1467                 if(R.r.mode & R_FIELDS) {                       /* field render */
1468                         if(R.flag & R_SEC_FIELD) {              /* correction for 2nd field */
1469                                 /* fac1= 0.5/( (float)ibuf->y ); */
1470                                 /* fy-= fac1; */
1471                         }
1472                         else {                          /* first field */
1473                                 fy+= 0.5f/( (float)ibuf->y );
1474                         }
1475                 }
1476         }
1477         
1478         /* pixel coordinates */
1479
1480         minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1481         maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1482         miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1483         maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1484
1485         /* tex_sharper has been removed */
1486         minx= (maxx-minx)/2.0f;
1487         miny= (maxy-miny)/2.0f;
1488         
1489         if(tex->imaflag & TEX_FILTER_MIN) {
1490                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1491                 float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1492
1493                 if(addval > minx)
1494                         minx= addval;
1495                 if(addval > miny)
1496                         miny= addval;
1497         }
1498         else if(tex->filtersize!=1.0f) {
1499                 minx*= tex->filtersize;
1500                 miny*= tex->filtersize;
1501                 
1502                 dxt[0]*= tex->filtersize;
1503                 dxt[1]*= tex->filtersize;
1504                 dyt[0]*= tex->filtersize;
1505                 dyt[1]*= tex->filtersize;
1506         }
1507
1508         if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1509         
1510         if(minx>0.25f) minx= 0.25f;
1511         else if(minx<0.00001f) minx= 0.00001f;  /* side faces of unit-cube */
1512         if(miny>0.25f) miny= 0.25f;
1513         else if(miny<0.00001f) miny= 0.00001f;
1514
1515         
1516         /* repeat and clip */
1517         imaprepeat= (tex->extend==TEX_REPEAT);
1518         imapextend= (tex->extend==TEX_EXTEND);
1519
1520         if(tex->extend == TEX_REPEAT) {
1521                 if(tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1522                         imaprepeat= 0;
1523                         imapextend= 1;
1524                 }
1525         }
1526
1527         if(tex->extend == TEX_CHECKER) {
1528                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1529                 
1530                 xs= (int)floor(fx);
1531                 ys= (int)floor(fy);
1532                 
1533                 // both checkers available, no boundary exceptions, checkerdist will eat aliasing
1534                 if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1535                         fx-= xs;
1536                         fy-= ys;
1537                 }
1538                 else {
1539                         
1540                         xs1= (int)floor(fx-minx);
1541                         ys1= (int)floor(fy-miny);
1542                         xs2= (int)floor(fx+minx);
1543                         ys2= (int)floor(fy+miny);
1544                         boundary= (xs1!=xs2) || (ys1!=ys2);
1545
1546                         if(boundary==0) {
1547                                 if( (tex->flag & TEX_CHECKER_ODD)==0) {
1548                                         if((xs+ys) & 1); 
1549                                         else return retval;
1550                                 }
1551                                 if( (tex->flag & TEX_CHECKER_EVEN)==0) {
1552                                         if((xs+ys) & 1) return retval;
1553                                 }
1554                                 fx-= xs;
1555                                 fy-= ys;
1556                         }
1557                         else {
1558                                 if(tex->flag & TEX_CHECKER_ODD) {
1559                                         if((xs1+ys) & 1) fx-= xs2;
1560                                         else fx-= xs1;
1561                                         
1562                                         if((ys1+xs) & 1) fy-= ys2;
1563                                         else fy-= ys1;
1564                                 }
1565                                 if(tex->flag & TEX_CHECKER_EVEN) {
1566                                         if((xs1+ys) & 1) fx-= xs1;
1567                                         else fx-= xs2;
1568                                         
1569                                         if((ys1+xs) & 1) fy-= ys1;
1570                                         else fy-= ys2;
1571                                 }
1572                         }
1573                 }
1574
1575                 /* scale around center, (0.5, 0.5) */
1576                 if(tex->checkerdist<1.0f) {
1577                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1578                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1579                         minx/= (1.0f-tex->checkerdist);
1580                         miny/= (1.0f-tex->checkerdist);
1581                 }
1582         }
1583
1584         if(tex->extend == TEX_CLIPCUBE) {
1585                 if(fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f || texvec[2]<-1.0f || texvec[2]>1.0f) {
1586                         return retval;
1587                 }
1588         }
1589         else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1590                 if(fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
1591                         return retval;
1592                 }
1593         }
1594         else {
1595                 if(imapextend) {
1596                         if(fx>1.0f) fx = 1.0f;
1597                         else if(fx<0.0f) fx= 0.0f;
1598                 }
1599                 else {
1600                         if(fx>1.0f) fx -= (int)(fx);
1601                         else if(fx<0.0f) fx+= 1-(int)(fx);
1602                 }
1603                 
1604                 if(imapextend) {
1605                         if(fy>1.0f) fy = 1.0f;
1606                         else if(fy<0.0f) fy= 0.0f;
1607                 }
1608                 else {
1609                         if(fy>1.0f) fy -= (int)(fy);
1610                         else if(fy<0.0f) fy+= 1-(int)(fy);
1611                 }
1612         }
1613
1614         /* warning no return! */
1615         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1616                 ibuf->rect+= (ibuf->x*ibuf->y);
1617         }
1618
1619         /* choice:  */
1620         if(tex->imaflag & TEX_MIPMAP) {
1621                 ImBuf *previbuf, *curibuf;
1622                 float bumpscale;
1623                 
1624                 dx= minx;
1625                 dy= miny;
1626                 maxd= MAX2(dx, dy);
1627                 if(maxd>0.5f) maxd= 0.5f;
1628
1629                 pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
1630                 
1631                 bumpscale= pixsize/maxd;
1632                 if(bumpscale>1.0f) bumpscale= 1.0f;
1633                 else bumpscale*=bumpscale;
1634                 
1635                 curmap= 0;
1636                 previbuf= curibuf= ibuf;
1637                 while(curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1638                         if(maxd < pixsize) break;
1639                         previbuf= curibuf;
1640                         curibuf= ibuf->mipmap[curmap];
1641                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1642                         curmap++;
1643                 }
1644
1645                 if(previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1646                         /* sample at least 1 pixel */
1647                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1648                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1649                 }
1650                 
1651                 if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1652                         /* a bit extra filter */
1653                         //minx*= 1.35f;
1654                         //miny*= 1.35f;
1655                         
1656                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1657                         val1= texres->tr+texres->tg+texres->tb;
1658                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1659                         val2= texr.tr + texr.tg + texr.tb;
1660                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1661                         val3= texr.tr + texr.tg + texr.tb;
1662
1663                         /* don't switch x or y! */
1664                         texres->nor[0]= (val1-val2);
1665                         texres->nor[1]= (val1-val3);
1666                         
1667                         if(previbuf!=curibuf) {  /* interpolate */
1668                                 
1669                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1670                                 
1671                                 /* calc rgb */
1672                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1673                                 if(dx>=1.0f) {
1674                                         texres->ta= texr.ta; texres->tb= texr.tb;
1675                                         texres->tg= texr.tg; texres->tr= texr.tr;
1676                                 }
1677                                 else {
1678                                         dy= 1.0f-dx;
1679                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1680                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1681                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1682                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1683                                 }
1684                                 
1685                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1686                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1687                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1688                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1689                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1690                                 
1691                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1692                                 texres->nor[1]= (val1-val3);
1693                                 
1694                                 if(dx<1.0f) {
1695                                         dy= 1.0f-dx;
1696                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1697                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1698                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1699                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1700                                 }
1701                         }
1702                         texres->nor[0]*= bumpscale;
1703                         texres->nor[1]*= bumpscale;
1704                 }
1705                 else {
1706                         maxx= fx+minx;
1707                         minx= fx-minx;
1708                         maxy= fy+miny;
1709                         miny= fy-miny;
1710
1711                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1712
1713                         if(previbuf!=curibuf) {  /* interpolate */
1714                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1715                                 
1716                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1717                                 
1718                                 if(fx>=1.0f) {
1719                                         texres->ta= texr.ta; texres->tb= texr.tb;
1720                                         texres->tg= texr.tg; texres->tr= texr.tr;
1721                                 } else {
1722                                         fy= 1.0f-fx;
1723                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1724                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1725                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1726                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1727                                 }
1728                         }
1729                 }
1730         }
1731         else {
1732                 const int intpol = tex->imaflag & TEX_INTERPOL;
1733                 if (intpol) {
1734                         /* sample 1 pixel minimum */
1735                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1736                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1737                 }
1738
1739                 if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1740                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1741                         val1= texres->tr+texres->tg+texres->tb;
1742                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1743                         val2= texr.tr + texr.tg + texr.tb;
1744                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1745                         val3= texr.tr + texr.tg + texr.tb;
1746
1747                         /* don't switch x or y! */
1748                         texres->nor[0]= (val1-val2);
1749                         texres->nor[1]= (val1-val3);
1750                 }
1751                 else
1752                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1753         }
1754         
1755         if(tex->imaflag & TEX_CALCALPHA) {
1756                 texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
1757         }
1758         else texres->tin= texres->ta;
1759
1760         if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1761         
1762         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1763                 ibuf->rect-= (ibuf->x*ibuf->y);
1764         }
1765
1766         if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1767                 // qdn: normal from color
1768                 // The invert of the red channel is to make
1769                 // the normal map compliant with the outside world.
1770                 // It needs to be done because in Blender
1771                 // the normal used in the renderer points inward. It is generated
1772                 // this way in calc_vertexnormals(). Should this ever change
1773                 // this negate must be removed.
1774                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1775                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1776                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1777         }
1778         
1779         /* de-premul, this is being premulled in shade_input_do_shade() */
1780         if(texres->ta!=1.0f && texres->ta>1e-4f) {
1781                 fx= 1.0f/texres->ta;
1782                 texres->tr*= fx;
1783                 texres->tg*= fx;
1784                 texres->tb*= fx;
1785         }
1786
1787         BRICONTRGB;
1788         
1789         return retval;
1790 }
1791
1792 void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result)
1793 {
1794         TexResult texres;
1795         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1796         
1797         if(ibuf==NULL) {
1798                 result[0]= result[1]= result[2]= result[3]= 0.0f;
1799                 return;
1800         }
1801         
1802         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1803                 ibuf->rect+= (ibuf->x*ibuf->y);
1804
1805         texres.talpha= 1; /* boxsample expects to be initialized */
1806         boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
1807         result[0]= texres.tr;
1808         result[1]= texres.tg;
1809         result[2]= texres.tb;
1810         result[3]= texres.ta;
1811         
1812         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1813                 ibuf->rect-= (ibuf->x*ibuf->y);
1814 }
1815
1816 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result)
1817 {
1818         TexResult texres;
1819         afdata_t AFD;
1820         
1821         if(ibuf==NULL) {
1822                 return;
1823         }
1824         
1825         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1826         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1827         //copy_v2_v2(AFD.dxt, dx);
1828         //copy_v2_v2(AFD.dyt, dy);
1829         
1830         AFD.intpol = 1;
1831         AFD.extflag = TXC_EXTD;
1832         
1833         memset(&texres, 0, sizeof(texres));
1834         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1835         
1836         
1837         result[0]= texres.tr;
1838         result[1]= texres.tg;
1839         result[2]= texres.tb;
1840         result[3]= texres.ta;
1841 }