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