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