style 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[4], 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[4], 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:
669                 {       /* as extend, if clipped, set alpha to 0.0 */
670                         if (x < 0) { x = 0;  } /* TXF alpha: clip = 1; } */
671                         if (x >= ibuf->x) { x = ibuf->x - 1; } /* TXF alpha:  clip = 1; } */
672                         if (y < 0) { y = 0; } /* TXF alpha:  clip = 1; } */
673                         if (y >= ibuf->y) { y = ibuf->y - 1; } /* TXF alpha:  clip = 1; } */
674                 }
675         }
676
677         if (ibuf->rect_float) {
678                 const float* fp = ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels;
679                 if (ibuf->channels == 1)
680                         col[0] = col[1] = col[2] = col[3] = *fp;
681                 else {
682                         col[0] = fp[0];
683                         col[1] = fp[1];
684                         col[2] = fp[2];
685                         col[3] = clip ? 0.f : (ibuf->channels == 4 ? fp[3] : 1.f);
686                 }
687         }
688         else {
689                 char* rect = (char*)(ibuf->rect + x + y*ibuf->x);
690                 col[0] = rect[0]*(1.f/255.f);
691                 col[1] = rect[1]*(1.f/255.f);
692                 col[2] = rect[2]*(1.f/255.f);
693                 col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
694         }
695         return clip;
696 }
697
698 /* as above + bilerp */
699 static int ibuf_get_color_clip_bilerp(float col[4], ImBuf *ibuf, float u, float v, int intpol, int extflag)
700 {
701         if (intpol) {
702                 float c00[4], c01[4], c10[4], c11[4];
703                 const float ufl = floorf(u -= 0.5f), vfl = floorf(v -= 0.5f);
704                 const float uf = u - ufl, vf = v - vfl;
705                 const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
706                 const int x1 = (int)ufl, y1 = (int)vfl, x2 = x1 + 1, y2 = y1 + 1;
707                 int clip = ibuf_get_color_clip(c00, ibuf, x1, y1, extflag);
708                 clip |= ibuf_get_color_clip(c10, ibuf, x2, y1, extflag);
709                 clip |= ibuf_get_color_clip(c01, ibuf, x1, y2, extflag);
710                 clip |= ibuf_get_color_clip(c11, ibuf, x2, y2, extflag);
711                 col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
712                 col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
713                 col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
714                 col[3] = clip ? 0.f : w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
715                 return clip;
716         }
717         return ibuf_get_color_clip(col, ibuf, (int)u, (int)v, extflag);
718 }
719
720 static void area_sample(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
721 {
722         int xs, ys, clip = 0;
723         float tc[4], xsd, ysd, cw = 0.f;
724         const float ux = ibuf->x*AFD->dxt[0], uy = ibuf->y*AFD->dxt[1];
725         const float vx = ibuf->x*AFD->dyt[0], vy = ibuf->y*AFD->dyt[1];
726         int xsam = (int)(0.5f*sqrtf(ux*ux + uy*uy) + 0.5f);
727         int ysam = (int)(0.5f*sqrtf(vx*vx + vy*vy) + 0.5f);
728         const int minsam = AFD->intpol ? 2 : 4;
729         xsam = CLAMPIS(xsam, minsam, ibuf->x*2);
730         ysam = CLAMPIS(ysam, minsam, ibuf->y*2);
731         xsd = 1.f / xsam;
732         ysd = 1.f / ysam;
733         texr->tr = texr->tg = texr->tb = texr->ta = 0.f;
734         for (ys=0; ys<ysam; ++ys) {
735                 for (xs=0; xs<xsam; ++xs) {
736                         const float su = (xs + ((ys & 1) + 0.5f)*0.5f)*xsd - 0.5f;
737                         const float sv = (ys + ((xs & 1) + 0.5f)*0.5f)*ysd - 0.5f;
738                         const float pu = fx + su*AFD->dxt[0] + sv*AFD->dyt[0];
739                         const float pv = fy + su*AFD->dxt[1] + sv*AFD->dyt[1];
740                         const int out = ibuf_get_color_clip_bilerp(tc, ibuf, pu*ibuf->x, pv*ibuf->y, AFD->intpol, AFD->extflag);
741                         clip |= out;
742                         cw += out ? 0.f : 1.f;
743                         texr->tr += tc[0];
744                         texr->tg += tc[1];
745                         texr->tb += tc[2];
746                         texr->ta += texr->talpha ? tc[3] : 0.f;
747                 }
748         }
749         xsd *= ysd;
750         texr->tr *= xsd;
751         texr->tg *= xsd;
752         texr->tb *= xsd;
753         /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
754         texr->ta = texr->talpha ? texr->ta*xsd : (clip ? cw*xsd : 1.f);
755 }
756
757 /* table of (exp(ar) - exp(a)) / (1 - exp(a)) for r in range [0, 1] and a = -2
758  * used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible */
759 #define EWA_MAXIDX 255
760 static float EWA_WTS[EWA_MAXIDX + 1] =
761 { 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
762  0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
763  0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
764  0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
765  0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
766  0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
767  0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
768  0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
769  0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
770  0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
771  0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
772  0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
773  0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
774  0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
775  0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
776  0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
777  0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
778  0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
779  0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
780  0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
781  0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
782  0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
783  0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
784  0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
785  0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
786  0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
787  0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
788  0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
789  0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
790  0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
791  0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
792  0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f
793 };
794
795 /* test if a float value is 'nan'
796  * there is a C99 function for this: isnan(), but blender seems to use C90 (according to gcc warns),
797  * and may not be supported by other compilers either */
798 #ifndef ISNAN
799 #define ISNAN(x) ((x) != (x))
800 #endif
801 //static int ISNAN(float x) { return (x != x); }
802
803 static void radangle2imp(float a2, float b2, float th, float* A, float* B, float* C, float* F)
804 {
805         float ct2 = cosf(th);
806         const float st2 = 1.0f - ct2 * ct2;     /* <- sin(th)^2 */
807         ct2 *= ct2;
808         *A = a2*st2 + b2*ct2;
809         *B = (b2 - a2)*sinf(2.f*th);
810         *C = a2*ct2 + b2*st2;
811         *F = a2*b2;
812 }
813
814 /* all tests here are done to make sure possible overflows are hopefully minimized */
815 static void imp2radangle(float A, float B, float C, float F, float* a, float* b, float* th, float* ecc)
816 {
817         if (F <= 1e-5f) {       /* use arbitrary major radius, zero minor, infinite eccentricity */
818                 *a = sqrtf(A > C ? A : C);
819                 *b = 0.f;
820                 *ecc = 1e10f;
821                 *th = 0.5f*(atan2f(B, A - C) + (float)M_PI);
822         }
823         else {
824                 const float AmC = A - C, ApC = A + C, F2 = F*2.f;
825                 const float r = sqrtf(AmC*AmC + B*B);
826                 float d = ApC - r;
827                 *a = (d <= 0.f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d);
828                 d = ApC + r;
829                 if (d <= 0.f) {
830                         *b = 0.f;
831                         *ecc = 1e10f;
832                 }
833                 else {
834                         *b = sqrtf(F2 / d);
835                         *ecc = *a / *b;
836                 }
837                 /* incr theta by 0.5*pi (angle of major axis) */
838                 *th = 0.5f*(atan2f(B, AmC) + (float)M_PI);
839         }
840 }
841
842 static void ewa_eval(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
843 {
844         /* scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values,
845          * scaling by aspect ratio alone does the opposite, so try something in between instead... */
846         const float ff2 = ibuf->x, ff = sqrtf(ff2), q = ibuf->y / ff;
847         const float Ux = AFD->dxt[0]*ff, Vx = AFD->dxt[1]*q, Uy = AFD->dyt[0]*ff, Vy = AFD->dyt[1]*q;
848         float A = Vx*Vx + Vy*Vy;
849         float B = -2.f*(Ux*Vx + Uy*Vy);
850         float C = Ux*Ux + Uy*Uy;
851         float F = A*C - B*B*0.25f;
852         float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d; /* TXF alpha: cw = 0.f; */
853         int u, v, u1, u2, v1, v2; /* TXF alpha: clip = 0; */
854
855         /* The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
856          * so the ellipse always covers at least some texels. But since the filter is now always larger,
857          * it also means that everywhere else it's also more blurry then ideally should be the case.
858          * So instead here the ellipse radii are modified instead whenever either is too low.
859          * Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
860          * and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
861          * (minimum values: const float rmin = intpol ? 1.f : 0.5f;) */
862         const float rmin = (AFD->intpol ? 1.5625f : 0.765625f)/ff2;
863         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
864         if ((b2 = b*b) < rmin) {
865                 if ((a2 = a*a) < rmin) {
866                         B = 0.f;
867                         A = C = rmin;
868                         F = A*C;
869                 }
870                 else {
871                         b2 = rmin;
872                         radangle2imp(a2, b2, th, &A, &B, &C, &F);
873                 }
874         }
875
876         ue = ff*sqrtf(C);
877         ve = ff*sqrtf(A);
878         d = (float)(EWA_MAXIDX + 1) / (F*ff2);
879         A *= d;
880         B *= d;
881         C *= d;
882
883         U0 = fx*ibuf->x;
884         V0 = fy*ibuf->y;
885         u1 = (int)(floorf(U0 - ue));
886         u2 = (int)(ceilf(U0 + ue));
887         v1 = (int)(floorf(V0 - ve));
888         v2 = (int)(ceilf(V0 + ve));
889         U0 -= 0.5f;
890         V0 -= 0.5f;
891         DDQ = 2.f*A;
892         U = u1 - U0;
893         ac1 = A*(2.f*U + 1.f);
894         ac2 = A*U*U;
895         BU = B*U;
896
897         d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f;
898         for (v=v1; v<=v2; ++v) {
899                 const float V = v - V0;
900                 float DQ = ac1 + B*V;
901                 float Q = (C*V + BU)*V + ac2;
902                 for (u=u1; u<=u2; ++u) {
903                         if (Q < (float)(EWA_MAXIDX + 1)) {
904                                 float tc[4];
905                                 const float wt = EWA_WTS[(Q < 0.f) ? 0 : (unsigned int)Q];
906                                 /*const int out =*/ ibuf_get_color_clip(tc, ibuf, u, v, AFD->extflag);
907                                 /* TXF alpha: clip |= out;
908                                  * TXF alpha: cw += out ? 0.f : wt; */
909                                 texr->tr += tc[0]*wt;
910                                 texr->tg += tc[1]*wt;
911                                 texr->tb += tc[2]*wt;
912                                 texr->ta += texr->talpha ? tc[3]*wt : 0.f;
913                                 d += wt;
914                         }
915                         Q += DQ;
916                         DQ += DDQ;
917                 }
918         }
919
920         /* d should hopefully never be zero anymore */
921         d = 1.f/d;
922         texr->tr *= d;
923         texr->tg *= d;
924         texr->tb *= d;
925         /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
926         texr->ta = texr->talpha ? texr->ta*d : 1.f; /* TXF alpha (clip ? cw*d : 1.f); */
927 }
928
929 static void feline_eval(TexResult* texr, ImBuf* ibuf, float fx, float fy, afdata_t* AFD)
930 {
931         const int maxn = AFD->iProbes - 1;
932         const float ll = ((AFD->majrad == AFD->minrad) ? 2.f*AFD->majrad : 2.f*(AFD->majrad - AFD->minrad)) / (maxn ? (float)maxn : 1.f);
933         float du = maxn ? cosf(AFD->theta)*ll : 0.f;
934         float dv = maxn ? sinf(AFD->theta)*ll : 0.f;
935         /* const float D = -0.5f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad); */
936         const float D = (EWA_MAXIDX + 1)*0.25f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad);
937         float d; /* TXF alpha: cw = 0.f; */
938         int n; /* TXF alpha: clip = 0; */
939         /* have to use same scaling for du/dv here as for Ux/Vx/Uy/Vy (*after* D calc.) */
940         du *= AFD->dusc;
941         dv *= AFD->dvsc;
942         d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f;
943         for (n=-maxn; n<=maxn; n+=2) {
944                 float tc[4];
945                 const float hn = n*0.5f;
946                 const float u = fx + hn*du, v = fy + hn*dv;
947                 /*const float wt = expf(n*n*D);
948                  * can use ewa table here too */
949                 const float wt = EWA_WTS[(int)(n*n*D)];
950                 /*const int out =*/ ibuf_get_color_clip_bilerp(tc, ibuf, ibuf->x*u, ibuf->y*v, AFD->intpol, AFD->extflag);
951                 /* TXF alpha: clip |= out;
952                  * TXF alpha: cw += out ? 0.f : wt; */
953                 texr->tr += tc[0]*wt;
954                 texr->tg += tc[1]*wt;
955                 texr->tb += tc[2]*wt;
956                 texr->ta += texr->talpha ? tc[3]*wt : 0.f;
957                 d += wt;
958         }
959
960         d = 1.f/d;
961         texr->tr *= d;
962         texr->tg *= d;
963         texr->tb *= d;
964         /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
965         texr->ta = texr->talpha ? texr->ta*d : 1.f; // TXF alpha: (clip ? cw*d : 1.f);
966 }
967 #undef EWA_MAXIDX
968
969 static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, int extflag, TexResult *texres)
970 {
971         float alphaclip;
972         rctf rf;
973
974         /* TXF apha: we're doing the same alphaclip here as boxsample, but i'm doubting
975          * if this is actually correct for the all the filtering algorithms .. */
976
977         if (!(extflag == TXC_REPT || extflag == TXC_EXTD)) {
978                 rf.xmin = minx*(ibuf->x);
979                 rf.xmax = maxx*(ibuf->x);
980                 rf.ymin = miny*(ibuf->y);
981                 rf.ymax = maxy*(ibuf->y);
982
983                 alphaclip = clipx_rctf(&rf, 0.0, (float)(ibuf->x));
984                 alphaclip*= clipy_rctf(&rf, 0.0, (float)(ibuf->y));
985                 alphaclip= MAX2(alphaclip, 0.0f);
986
987                 if (alphaclip!=1.0f) {
988                         /* premul it all */
989                         texres->tr*= alphaclip;
990                         texres->tg*= alphaclip;
991                         texres->tb*= alphaclip;
992                         texres->ta*= alphaclip;
993                 }
994         }
995 }
996
997 static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
998 {
999         if (tex->imaflag & TEX_MIPMAP) {
1000                 if ((ibuf->flags & IB_fields) == 0) {
1001                         
1002                         if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
1003                                 BLI_lock_thread(LOCK_IMAGE);
1004                                 if (ibuf->userflags & IB_MIPMAP_INVALID) {
1005                                         IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
1006                                         ibuf->userflags &= ~IB_MIPMAP_INVALID;
1007                                 }                               
1008                                 BLI_unlock_thread(LOCK_IMAGE);
1009                         }
1010                         if (ibuf->mipmap[0] == NULL) {
1011                                 BLI_lock_thread(LOCK_IMAGE);
1012                                 if (ibuf->mipmap[0] == NULL) 
1013                                         IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
1014                                 BLI_unlock_thread(LOCK_IMAGE);
1015                         }
1016                 }
1017         }
1018         
1019 }
1020
1021 static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], float dxt[3], float dyt[3], TexResult *texres)
1022 {
1023         TexResult texr;
1024         float fx, fy, minx, maxx, miny, maxy;
1025         float maxd, val1, val2, val3;
1026         int curmap, retval, intpol, extflag = 0;
1027         afdata_t AFD;
1028
1029         void (*filterfunc)(TexResult*, ImBuf*, float, float, afdata_t*);
1030         switch (tex->texfilter) {
1031                 case TXF_EWA:
1032                         filterfunc = ewa_eval;
1033                         break;
1034                 case TXF_FELINE:
1035                         filterfunc = feline_eval;
1036                         break;
1037                 case TXF_AREA:
1038                 default:
1039                         filterfunc = area_sample;
1040         }
1041
1042         texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.f;
1043
1044         /* we need to set retval OK, otherwise texture code generates normals itself... */
1045         retval = texres->nor ? 3 : 1;
1046
1047         /* quick tests */
1048         if (ibuf==NULL && ima==NULL) return retval;
1049
1050         if (ima) {      /* hack for icon render */
1051                 if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
1052                 ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 
1053         }
1054
1055         if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
1056
1057         /* mipmap test */
1058         image_mipmap_test(tex, ibuf);
1059         
1060         if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
1061         texr.talpha = texres->talpha;
1062
1063         if (tex->imaflag & TEX_IMAROT) {
1064                 fy = texvec[0];
1065                 fx = texvec[1];
1066         }
1067         else {
1068                 fx = texvec[0];
1069                 fy = texvec[1];
1070         }
1071
1072         if (ibuf->flags & IB_fields) {
1073                 if (R.r.mode & R_FIELDS) {                      /* field render */
1074                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1075                                 /* fac1= 0.5/( (float)ibuf->y ); */
1076                                 /* fy-= fac1; */
1077                         }
1078                         else    /* first field */
1079                                 fy += 0.5f/( (float)ibuf->y );
1080                 }
1081         }
1082
1083         /* pixel coordinates */
1084         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1085         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1086         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1087         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1088
1089         /* tex_sharper has been removed */
1090         minx = (maxx - minx)*0.5f;
1091         miny = (maxy - miny)*0.5f;
1092
1093         if (tex->imaflag & TEX_FILTER_MIN) {
1094                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1095                 const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1096                 if (addval > minx) minx = addval;
1097                 if (addval > miny) miny = addval;
1098         }
1099         else if (tex->filtersize != 1.f) {
1100                 minx *= tex->filtersize;
1101                 miny *= tex->filtersize;
1102                 dxt[0] *= tex->filtersize;
1103                 dxt[1] *= tex->filtersize;
1104                 dyt[0] *= tex->filtersize;
1105                 dyt[1] *= tex->filtersize;
1106         }
1107
1108         if (tex->imaflag & TEX_IMAROT) {
1109                 float t;
1110                 SWAP(float, minx, miny);
1111                 /* must rotate dxt/dyt 90 deg
1112                  * yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1113                  * but it doesn't, it only swaps coords, so filter area will be incorrect in those cases. */
1114                 t = dxt[0];
1115                 dxt[0] = dxt[1];
1116                 dxt[1] = -t;
1117                 t = dyt[0];
1118                 dyt[0] = dyt[1];
1119                 dyt[1] = -t;
1120         }
1121
1122         /* side faces of unit-cube */
1123         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1124         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1125
1126         /* repeat and clip */
1127
1128         if (tex->extend == TEX_REPEAT) {
1129                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1130                         extflag = TXC_EXTD;
1131                 else if (tex->flag & TEX_REPEAT_XMIR)
1132                         extflag = TXC_XMIR;
1133                 else if (tex->flag & TEX_REPEAT_YMIR)
1134                         extflag = TXC_YMIR;
1135                 else
1136                         extflag = TXC_REPT;
1137         }
1138         else if (tex->extend == TEX_EXTEND)
1139                 extflag = TXC_EXTD;
1140
1141         if (tex->extend == TEX_CHECKER) {
1142                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1143                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1144                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1145                         fx -= xs;
1146                         fy -= ys;
1147                 }
1148                 else {
1149                         int xs1 = (int)floorf(fx - minx);
1150                         int ys1 = (int)floorf(fy - miny);
1151                         int xs2 = (int)floorf(fx + minx);
1152                         int ys2 = (int)floorf(fy + miny);
1153                         if ((xs1 != xs2) || (ys1 != ys2)) {
1154                                 if (tex->flag & TEX_CHECKER_ODD) {
1155                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1156                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1157                                 }
1158                                 if (tex->flag & TEX_CHECKER_EVEN) {
1159                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1160                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1161                                 }
1162                         }
1163                         else {
1164                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
1165                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
1166                                 fx -= xs;
1167                                 fy -= ys;
1168                         }
1169                 }
1170                 /* scale around center, (0.5, 0.5) */
1171                 if (tex->checkerdist < 1.f) {
1172                         const float omcd = 1.f / (1.f - tex->checkerdist);
1173                         fx = (fx - 0.5f)*omcd + 0.5f;
1174                         fy = (fy - 0.5f)*omcd + 0.5f;
1175                         minx *= omcd;
1176                         miny *= omcd;
1177                 }
1178         }
1179
1180         if (tex->extend == TEX_CLIPCUBE) {
1181                 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;
1182         }
1183         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1184                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
1185         }
1186         else {
1187                 if (tex->extend == TEX_EXTEND) {
1188                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1189                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1190                 }
1191                 else {
1192                         fx -= floorf(fx);
1193                         fy -= floorf(fy);
1194                 }
1195         }
1196
1197         intpol = tex->imaflag & TEX_INTERPOL;
1198
1199         /* warning no return! */
1200         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1201                 ibuf->rect += ibuf->x*ibuf->y;
1202
1203         /* struct common data */
1204         copy_v2_v2(AFD.dxt, dxt);
1205         copy_v2_v2(AFD.dyt, dyt);
1206         AFD.intpol = intpol;
1207         AFD.extflag = extflag;
1208
1209         /* brecht: added stupid clamping here, large dx/dy can give very large
1210          * filter sizes which take ages to render, it may be better to do this
1211          * more intelligently later in the code .. probably it's not noticeable */
1212         if (AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f)
1213                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1214         if (AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1215                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1216
1217         /* choice: */
1218         if (tex->imaflag & TEX_MIPMAP) {
1219                 ImBuf *previbuf, *curibuf;
1220                 float levf;
1221                 int maxlev;
1222                 ImBuf* mipmaps[IB_MIPMAP_LEVELS + 1];
1223
1224                 /* modify ellipse minor axis if too eccentric, use for area sampling as well
1225                  * scaling dxt/dyt as done in pbrt is not the same
1226                  * (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision) */
1227                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1228                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1229                 const float A = Vx*Vx + Vy*Vy;
1230                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1231                 const float C = Ux*Ux + Uy*Uy;
1232                 const float F = A*C - B*B*0.25f;
1233                 float a, b, th, ecc;
1234                 imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1235                 if (tex->texfilter == TXF_FELINE) {
1236                         float fProbes;
1237                         a *= ff;
1238                         b *= ff;
1239                         a = MAX2(a, 1.f);
1240                         b = MAX2(b, 1.f);
1241                         fProbes = 2.f*(a / b) - 1.f;
1242                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1243                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1244                         if (AFD.iProbes < fProbes)
1245                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1246                         AFD.majrad = a/ff;
1247                         AFD.minrad = b/ff;
1248                         AFD.theta = th;
1249                         AFD.dusc = 1.f/ff;
1250                         AFD.dvsc = ff / (float)ibuf->y;
1251                 }
1252                 else {  /* EWA & area */
1253                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1254                         b *= ff;
1255                 }
1256                 maxd = MAX2(b, 1e-8f);
1257                 levf = ((float)M_LOG2E)*logf(maxd);
1258
1259                 curmap = 0;
1260                 maxlev = 1;
1261                 mipmaps[0] = ibuf;
1262                 while (curmap < IB_MIPMAP_LEVELS) {
1263                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1264                         if (ibuf->mipmap[curmap]) maxlev++;
1265                         curmap++;
1266                 }
1267
1268                 /* mipmap level */
1269                 if (levf < 0.f) {  /* original image only */
1270                         previbuf = curibuf = mipmaps[0];
1271                         levf = 0.f;
1272                 }
1273                 else if (levf >= maxlev - 1) {
1274                         previbuf = curibuf = mipmaps[maxlev - 1];
1275                         levf = 0.f;
1276                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1277                 }
1278                 else {
1279                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1280                         curibuf = mipmaps[lev];
1281                         previbuf = mipmaps[lev + 1];
1282                         levf -= floorf(levf);
1283                 }
1284
1285                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1286
1287                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1288                         /* color & normal */
1289                         filterfunc(texres, curibuf, fx, fy, &AFD);
1290                         val1 = texres->tr + texres->tg + texres->tb;
1291                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1292                         val2 = texr.tr + texr.tg + texr.tb;
1293                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1294                         val3 = texr.tr + texr.tg + texr.tb;
1295                         /* don't switch x or y! */
1296                         texres->nor[0] = val1 - val2;
1297                         texres->nor[1] = val1 - val3;
1298                         if (previbuf != curibuf) {  /* interpolate */
1299                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1300                                 /* rgb */
1301                                 texres->tr += levf*(texr.tr - texres->tr);
1302                                 texres->tg += levf*(texr.tg - texres->tg);
1303                                 texres->tb += levf*(texr.tb - texres->tb);
1304                                 texres->ta += levf*(texr.ta - texres->ta);
1305                                 /* normal */
1306                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1307                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1308                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1309                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1310                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1311                                 texres->nor[0] = val1 - val2;  /* vals have been interpolated above! */
1312                                 texres->nor[1] = val1 - val3;
1313                         }
1314                 }
1315                 else {  /* color */
1316                         filterfunc(texres, curibuf, fx, fy, &AFD);
1317                         if (previbuf != curibuf) {  /* interpolate */
1318                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1319                                 texres->tr += levf*(texr.tr - texres->tr);
1320                                 texres->tg += levf*(texr.tg - texres->tg);
1321                                 texres->tb += levf*(texr.tb - texres->tb);
1322                                 texres->ta += levf*(texr.ta - texres->ta);
1323                         }
1324
1325                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1326                 }
1327         }
1328         else {  /* no mipmap */
1329                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1330                 if (tex->texfilter == TXF_FELINE) {
1331                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1332                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1333                         const float A = Vx*Vx + Vy*Vy;
1334                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1335                         const float C = Ux*Ux + Uy*Uy;
1336                         const float F = A*C - B*B*0.25f;
1337                         float a, b, th, ecc, fProbes;
1338                         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1339                         a *= ff;
1340                         b *= ff;
1341                         a = MAX2(a, 1.f);
1342                         b = MAX2(b, 1.f);
1343                         fProbes = 2.f*(a / b) - 1.f;
1344                         /* no limit to number of Probes here */
1345                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1346                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1347                         AFD.majrad = a/ff;
1348                         AFD.minrad = b/ff;
1349                         AFD.theta = th;
1350                         AFD.dusc = 1.f/ff;
1351                         AFD.dvsc = ff / (float)ibuf->y;
1352                 }
1353                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1354                         /* color & normal */
1355                         filterfunc(texres, ibuf, fx, fy, &AFD);
1356                         val1 = texres->tr + texres->tg + texres->tb;
1357                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1358                         val2 = texr.tr + texr.tg + texr.tb;
1359                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1360                         val3 = texr.tr + texr.tg + texr.tb;
1361                         /* don't switch x or y! */
1362                         texres->nor[0] = val1 - val2;
1363                         texres->nor[1] = val1 - val3;
1364                 }
1365                 else {
1366                         filterfunc(texres, ibuf, fx, fy, &AFD);
1367                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1368                 }
1369         }
1370
1371         if (tex->imaflag & TEX_CALCALPHA)
1372                 texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
1373         else
1374                 texres->tin = texres->ta;
1375         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1376         
1377         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1378                 ibuf->rect -= ibuf->x*ibuf->y;
1379
1380         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    /* normal from color */
1381                 /* The invert of the red channel is to make
1382                  * the normal map compliant with the outside world.
1383                  * It needs to be done because in Blender
1384                  * the normal used in the renderer points inward. It is generated
1385                  * this way in calc_vertexnormals(). Should this ever change
1386                  * this negate must be removed. */
1387                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1388                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1389                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1390         }
1391
1392         /* de-premul, this is being premulled in shade_input_do_shade()
1393          * TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1394          * also disabled in imagewraposa() to be able to compare results with blender's default texture filtering */
1395
1396         /* brecht: tried to fix this, see "TXF alpha" comments */
1397
1398         if (texres->ta != 1.f && (texres->ta > 1e-4f)) {
1399                 fx = 1.f/texres->ta;
1400                 texres->tr *= fx;
1401                 texres->tg *= fx;
1402                 texres->tb *= fx;
1403         }
1404
1405         BRICONTRGB;
1406         
1407         return retval;
1408 }
1409
1410
1411 int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[3], const float DYT[3], TexResult *texres)
1412 {
1413         TexResult texr;
1414         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3];
1415         float maxd, pixsize, val1, val2, val3;
1416         int curmap, retval, imaprepeat, imapextend;
1417
1418         /* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1419          * make a local copy here so that original vecs remain untouched */
1420         copy_v3_v3(dxt, DXT);
1421         copy_v3_v3(dyt, DYT);
1422
1423         /* anisotropic filtering */
1424         if (tex->texfilter != TXF_BOX)
1425                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres);
1426
1427         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1428         
1429         /* we need to set retval OK, otherwise texture code generates normals itself... */
1430         retval= texres->nor?3:1;
1431         
1432         /* quick tests */
1433         if (ibuf==NULL && ima==NULL)
1434                 return retval;
1435         if (ima) {
1436
1437                 /* hack for icon render */
1438                 if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
1439                         return retval;
1440                 
1441                 ibuf= BKE_image_get_ibuf(ima, &tex->iuser); 
1442
1443                 ima->flag|= IMA_USED_FOR_RENDER;
1444         }
1445         if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
1446                 return retval;
1447         
1448         /* mipmap test */
1449         image_mipmap_test(tex, ibuf);
1450
1451         if (tex->imaflag & TEX_USEALPHA) {
1452                 if (tex->imaflag & TEX_CALCALPHA);
1453                 else texres->talpha= 1;
1454         }
1455         
1456         texr.talpha= texres->talpha;
1457         
1458         if (tex->imaflag & TEX_IMAROT) {
1459                 fy= texvec[0];
1460                 fx= texvec[1];
1461         }
1462         else {
1463                 fx= texvec[0];
1464                 fy= texvec[1];
1465         }
1466         
1467         if (ibuf->flags & IB_fields) {
1468                 if (R.r.mode & R_FIELDS) {                      /* field render */
1469                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1470                                 /* fac1= 0.5/( (float)ibuf->y ); */
1471                                 /* fy-= fac1; */
1472                         }
1473                         else {                          /* first field */
1474                                 fy+= 0.5f/( (float)ibuf->y );
1475                         }
1476                 }
1477         }
1478         
1479         /* pixel coordinates */
1480
1481         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1482         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1483         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1484         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1485
1486         /* tex_sharper has been removed */
1487         minx= (maxx-minx)/2.0f;
1488         miny= (maxy-miny)/2.0f;
1489         
1490         if (tex->imaflag & TEX_FILTER_MIN) {
1491                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1492                 float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1493
1494                 if (addval > minx)
1495                         minx= addval;
1496                 if (addval > miny)
1497                         miny= addval;
1498         }
1499         else if (tex->filtersize!=1.0f) {
1500                 minx*= tex->filtersize;
1501                 miny*= tex->filtersize;
1502                 
1503                 dxt[0]*= tex->filtersize;
1504                 dxt[1]*= tex->filtersize;
1505                 dyt[0]*= tex->filtersize;
1506                 dyt[1]*= tex->filtersize;
1507         }
1508
1509         if (tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1510         
1511         if (minx>0.25f) minx= 0.25f;
1512         else if (minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
1513         if (miny>0.25f) miny= 0.25f;
1514         else if (miny<0.00001f) miny= 0.00001f;
1515
1516         
1517         /* repeat and clip */
1518         imaprepeat= (tex->extend==TEX_REPEAT);
1519         imapextend= (tex->extend==TEX_EXTEND);
1520
1521         if (tex->extend == TEX_REPEAT) {
1522                 if (tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1523                         imaprepeat= 0;
1524                         imapextend= 1;
1525                 }
1526         }
1527
1528         if (tex->extend == TEX_CHECKER) {
1529                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1530                 
1531                 xs= (int)floor(fx);
1532                 ys= (int)floor(fy);
1533                 
1534                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1535                 if ( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1536                         fx-= xs;
1537                         fy-= ys;
1538                 }
1539                 else {
1540                         
1541                         xs1= (int)floor(fx-minx);
1542                         ys1= (int)floor(fy-miny);
1543                         xs2= (int)floor(fx+minx);
1544                         ys2= (int)floor(fy+miny);
1545                         boundary= (xs1!=xs2) || (ys1!=ys2);
1546
1547                         if (boundary==0) {
1548                                 if ( (tex->flag & TEX_CHECKER_ODD)==0) {
1549                                         if ((xs+ys) & 1);
1550                                         else return retval;
1551                                 }
1552                                 if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
1553                                         if ((xs+ys) & 1) return retval;
1554                                 }
1555                                 fx-= xs;
1556                                 fy-= ys;
1557                         }
1558                         else {
1559                                 if (tex->flag & TEX_CHECKER_ODD) {
1560                                         if ((xs1+ys) & 1) fx-= xs2;
1561                                         else fx-= xs1;
1562                                         
1563                                         if ((ys1+xs) & 1) fy-= ys2;
1564                                         else fy-= ys1;
1565                                 }
1566                                 if (tex->flag & TEX_CHECKER_EVEN) {
1567                                         if ((xs1+ys) & 1) fx-= xs1;
1568                                         else fx-= xs2;
1569                                         
1570                                         if ((ys1+xs) & 1) fy-= ys1;
1571                                         else fy-= ys2;
1572                                 }
1573                         }
1574                 }
1575
1576                 /* scale around center, (0.5, 0.5) */
1577                 if (tex->checkerdist<1.0f) {
1578                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1579                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1580                         minx/= (1.0f-tex->checkerdist);
1581                         miny/= (1.0f-tex->checkerdist);
1582                 }
1583         }
1584
1585         if (tex->extend == TEX_CLIPCUBE) {
1586                 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) {
1587                         return retval;
1588                 }
1589         }
1590         else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1591                 if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
1592                         return retval;
1593                 }
1594         }
1595         else {
1596                 if (imapextend) {
1597                         if (fx>1.0f) fx = 1.0f;
1598                         else if (fx<0.0f) fx= 0.0f;
1599                 }
1600                 else {
1601                         if (fx>1.0f) fx -= (int)(fx);
1602                         else if (fx<0.0f) fx+= 1-(int)(fx);
1603                 }
1604                 
1605                 if (imapextend) {
1606                         if (fy>1.0f) fy = 1.0f;
1607                         else if (fy<0.0f) fy= 0.0f;
1608                 }
1609                 else {
1610                         if (fy>1.0f) fy -= (int)(fy);
1611                         else if (fy<0.0f) fy+= 1-(int)(fy);
1612                 }
1613         }
1614
1615         /* warning no return! */
1616         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1617                 ibuf->rect+= (ibuf->x*ibuf->y);
1618         }
1619
1620         /* choice:  */
1621         if (tex->imaflag & TEX_MIPMAP) {
1622                 ImBuf *previbuf, *curibuf;
1623                 float bumpscale;
1624                 
1625                 dx= minx;
1626                 dy= miny;
1627                 maxd= MAX2(dx, dy);
1628                 if (maxd>0.5f) maxd= 0.5f;
1629
1630                 pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
1631                 
1632                 bumpscale= pixsize/maxd;
1633                 if (bumpscale>1.0f) bumpscale= 1.0f;
1634                 else bumpscale*=bumpscale;
1635                 
1636                 curmap= 0;
1637                 previbuf= curibuf= ibuf;
1638                 while (curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1639                         if (maxd < pixsize) break;
1640                         previbuf= curibuf;
1641                         curibuf= ibuf->mipmap[curmap];
1642                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1643                         curmap++;
1644                 }
1645
1646                 if (previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1647                         /* sample at least 1 pixel */
1648                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1649                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1650                 }
1651                 
1652                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1653                         /* a bit extra filter */
1654                         //minx*= 1.35f;
1655                         //miny*= 1.35f;
1656                         
1657                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1658                         val1= texres->tr+texres->tg+texres->tb;
1659                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1660                         val2= texr.tr + texr.tg + texr.tb;
1661                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1662                         val3= texr.tr + texr.tg + texr.tb;
1663
1664                         /* don't switch x or y! */
1665                         texres->nor[0]= (val1-val2);
1666                         texres->nor[1]= (val1-val3);
1667                         
1668                         if (previbuf!=curibuf) {  /* interpolate */
1669                                 
1670                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1671                                 
1672                                 /* calc rgb */
1673                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1674                                 if (dx>=1.0f) {
1675                                         texres->ta= texr.ta; texres->tb= texr.tb;
1676                                         texres->tg= texr.tg; texres->tr= texr.tr;
1677                                 }
1678                                 else {
1679                                         dy= 1.0f-dx;
1680                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1681                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1682                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1683                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1684                                 }
1685                                 
1686                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1687                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1688                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1689                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1690                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1691                                 
1692                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1693                                 texres->nor[1]= (val1-val3);
1694                                 
1695                                 if (dx<1.0f) {
1696                                         dy= 1.0f-dx;
1697                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1698                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1699                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1700                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1701                                 }
1702                         }
1703                         texres->nor[0]*= bumpscale;
1704                         texres->nor[1]*= bumpscale;
1705                 }
1706                 else {
1707                         maxx= fx+minx;
1708                         minx= fx-minx;
1709                         maxy= fy+miny;
1710                         miny= fy-miny;
1711
1712                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1713
1714                         if (previbuf!=curibuf) {  /* interpolate */
1715                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1716                                 
1717                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1718                                 
1719                                 if (fx>=1.0f) {
1720                                         texres->ta= texr.ta; texres->tb= texr.tb;
1721                                         texres->tg= texr.tg; texres->tr= texr.tr;
1722                                 }
1723                                 else {
1724                                         fy= 1.0f-fx;
1725                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1726                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1727                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1728                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1729                                 }
1730                         }
1731                 }
1732         }
1733         else {
1734                 const int intpol = tex->imaflag & TEX_INTERPOL;
1735                 if (intpol) {
1736                         /* sample 1 pixel minimum */
1737                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1738                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1739                 }
1740
1741                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1742                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1743                         val1= texres->tr+texres->tg+texres->tb;
1744                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1745                         val2= texr.tr + texr.tg + texr.tb;
1746                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1747                         val3= texr.tr + texr.tg + texr.tb;
1748
1749                         /* don't switch x or y! */
1750                         texres->nor[0]= (val1-val2);
1751                         texres->nor[1]= (val1-val3);
1752                 }
1753                 else
1754                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1755         }
1756         
1757         if (tex->imaflag & TEX_CALCALPHA) {
1758                 texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
1759         }
1760         else texres->tin= texres->ta;
1761
1762         if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1763         
1764         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1765                 ibuf->rect-= (ibuf->x*ibuf->y);
1766         }
1767
1768         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1769                 /* qdn: normal from color
1770                  * The invert of the red channel is to make
1771                  * the normal map compliant with the outside world.
1772                  * It needs to be done because in Blender
1773                  * the normal used in the renderer points inward. It is generated
1774                  * this way in calc_vertexnormals(). Should this ever change
1775                  * this negate must be removed. */
1776                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1777                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1778                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1779         }
1780
1781         /* de-premul, this is being premulled in shade_input_do_shade() */
1782         if (texres->ta!=1.0f && texres->ta>1e-4f) {
1783                 fx= 1.0f/texres->ta;
1784                 texres->tr*= fx;
1785                 texres->tg*= fx;
1786                 texres->tb*= fx;
1787         }
1788
1789         BRICONTRGB;
1790         
1791         return retval;
1792 }
1793
1794 void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result)
1795 {
1796         TexResult texres;
1797         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1798         
1799         if (ibuf==NULL) {
1800                 result[0]= result[1]= result[2]= result[3]= 0.0f;
1801                 return;
1802         }
1803         
1804         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1805                 ibuf->rect+= (ibuf->x*ibuf->y);
1806
1807         texres.talpha= 1; /* boxsample expects to be initialized */
1808         boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
1809         result[0]= texres.tr;
1810         result[1]= texres.tg;
1811         result[2]= texres.tb;
1812         result[3]= texres.ta;
1813         
1814         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1815                 ibuf->rect-= (ibuf->x*ibuf->y);
1816
1817         ima->flag|= IMA_USED_FOR_RENDER;
1818 }
1819
1820 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result)
1821 {
1822         TexResult texres;
1823         afdata_t AFD;
1824         
1825         if (ibuf==NULL) {
1826                 return;
1827         }
1828         
1829         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1830         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1831         //copy_v2_v2(AFD.dxt, dx);
1832         //copy_v2_v2(AFD.dyt, dy);
1833         
1834         AFD.intpol = 1;
1835         AFD.extflag = TXC_EXTD;
1836         
1837         memset(&texres, 0, sizeof(texres));
1838         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1839         
1840         
1841         result[0]= texres.tr;
1842         result[1]= texres.tg;
1843         result[2]= texres.tb;
1844         result[3]= texres.ta;
1845 }