Merging r50522 through r50572 from trunk into soc-2011-tomato
[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 = BLI_RCT_SIZE_X(rf);
400         y = BLI_RCT_SIZE_Y(rf);
401         return x * y;
402 }
403
404 static float clipx_rctf(rctf *rf, float x1, float x2)
405 {
406         float size;
407
408         size = BLI_RCT_SIZE_X(rf);
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 BLI_RCT_SIZE_X(rf) / 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 = BLI_RCT_SIZE_Y(rf);
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 BLI_RCT_SIZE_Y(rf) / 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 repeat 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  = maxf(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         ima->flag |= IMA_USED_FOR_RENDER;
1058
1059         /* mipmap test */
1060         image_mipmap_test(tex, ibuf);
1061         
1062         if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
1063         texr.talpha = texres->talpha;
1064
1065         if (tex->imaflag & TEX_IMAROT) {
1066                 fy = texvec[0];
1067                 fx = texvec[1];
1068         }
1069         else {
1070                 fx = texvec[0];
1071                 fy = texvec[1];
1072         }
1073
1074         if (ibuf->flags & IB_fields) {
1075                 if (R.r.mode & R_FIELDS) {                      /* field render */
1076                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1077                                 /* fac1= 0.5/( (float)ibuf->y ); */
1078                                 /* fy-= fac1; */
1079                         }
1080                         else    /* first field */
1081                                 fy += 0.5f/( (float)ibuf->y );
1082                 }
1083         }
1084
1085         /* pixel coordinates */
1086         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1087         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1088         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1089         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1090
1091         /* tex_sharper has been removed */
1092         minx = (maxx - minx)*0.5f;
1093         miny = (maxy - miny)*0.5f;
1094
1095         if (tex->imaflag & TEX_FILTER_MIN) {
1096                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1097                 const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1098                 if (addval > minx) minx = addval;
1099                 if (addval > miny) miny = addval;
1100         }
1101         else if (tex->filtersize != 1.f) {
1102                 minx *= tex->filtersize;
1103                 miny *= tex->filtersize;
1104                 dxt[0] *= tex->filtersize;
1105                 dxt[1] *= tex->filtersize;
1106                 dyt[0] *= tex->filtersize;
1107                 dyt[1] *= tex->filtersize;
1108         }
1109
1110         if (tex->imaflag & TEX_IMAROT) {
1111                 float t;
1112                 SWAP(float, minx, miny);
1113                 /* must rotate dxt/dyt 90 deg
1114                  * yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1115                  * but it doesn't, it only swaps coords, so filter area will be incorrect in those cases. */
1116                 t = dxt[0];
1117                 dxt[0] = dxt[1];
1118                 dxt[1] = -t;
1119                 t = dyt[0];
1120                 dyt[0] = dyt[1];
1121                 dyt[1] = -t;
1122         }
1123
1124         /* side faces of unit-cube */
1125         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1126         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1127
1128         /* repeat and clip */
1129
1130         if (tex->extend == TEX_REPEAT) {
1131                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1132                         extflag = TXC_EXTD;
1133                 else if (tex->flag & TEX_REPEAT_XMIR)
1134                         extflag = TXC_XMIR;
1135                 else if (tex->flag & TEX_REPEAT_YMIR)
1136                         extflag = TXC_YMIR;
1137                 else
1138                         extflag = TXC_REPT;
1139         }
1140         else if (tex->extend == TEX_EXTEND)
1141                 extflag = TXC_EXTD;
1142
1143         if (tex->extend == TEX_CHECKER) {
1144                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1145                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1146                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1147                         fx -= xs;
1148                         fy -= ys;
1149                 }
1150                 else {
1151                         int xs1 = (int)floorf(fx - minx);
1152                         int ys1 = (int)floorf(fy - miny);
1153                         int xs2 = (int)floorf(fx + minx);
1154                         int ys2 = (int)floorf(fy + miny);
1155                         if ((xs1 != xs2) || (ys1 != ys2)) {
1156                                 if (tex->flag & TEX_CHECKER_ODD) {
1157                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1158                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1159                                 }
1160                                 if (tex->flag & TEX_CHECKER_EVEN) {
1161                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1162                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1163                                 }
1164                         }
1165                         else {
1166                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
1167                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
1168                                 fx -= xs;
1169                                 fy -= ys;
1170                         }
1171                 }
1172                 /* scale around center, (0.5, 0.5) */
1173                 if (tex->checkerdist < 1.f) {
1174                         const float omcd = 1.f / (1.f - tex->checkerdist);
1175                         fx = (fx - 0.5f)*omcd + 0.5f;
1176                         fy = (fy - 0.5f)*omcd + 0.5f;
1177                         minx *= omcd;
1178                         miny *= omcd;
1179                 }
1180         }
1181
1182         if (tex->extend == TEX_CLIPCUBE) {
1183                 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;
1184         }
1185         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1186                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
1187         }
1188         else {
1189                 if (tex->extend == TEX_EXTEND) {
1190                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1191                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1192                 }
1193                 else {
1194                         fx -= floorf(fx);
1195                         fy -= floorf(fy);
1196                 }
1197         }
1198
1199         intpol = tex->imaflag & TEX_INTERPOL;
1200
1201         /* warning no return! */
1202         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1203                 ibuf->rect += ibuf->x*ibuf->y;
1204
1205         /* struct common data */
1206         copy_v2_v2(AFD.dxt, dxt);
1207         copy_v2_v2(AFD.dyt, dyt);
1208         AFD.intpol = intpol;
1209         AFD.extflag = extflag;
1210
1211         /* brecht: added stupid clamping here, large dx/dy can give very large
1212          * filter sizes which take ages to render, it may be better to do this
1213          * more intelligently later in the code .. probably it's not noticeable */
1214         if (AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f)
1215                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1216         if (AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1217                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1218
1219         /* choice: */
1220         if (tex->imaflag & TEX_MIPMAP) {
1221                 ImBuf *previbuf, *curibuf;
1222                 float levf;
1223                 int maxlev;
1224                 ImBuf *mipmaps[IB_MIPMAP_LEVELS + 1];
1225
1226                 /* modify ellipse minor axis if too eccentric, use for area sampling as well
1227                  * scaling dxt/dyt as done in pbrt is not the same
1228                  * (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision) */
1229                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1230                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1231                 const float A = Vx*Vx + Vy*Vy;
1232                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1233                 const float C = Ux*Ux + Uy*Uy;
1234                 const float F = A*C - B*B*0.25f;
1235                 float a, b, th, ecc;
1236                 imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1237                 if (tex->texfilter == TXF_FELINE) {
1238                         float fProbes;
1239                         a *= ff;
1240                         b *= ff;
1241                         a = maxf(a, 1.0f);
1242                         b = maxf(b, 1.0f);
1243                         fProbes = 2.f*(a / b) - 1.f;
1244                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1245                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1246                         if (AFD.iProbes < fProbes)
1247                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1248                         AFD.majrad = a/ff;
1249                         AFD.minrad = b/ff;
1250                         AFD.theta = th;
1251                         AFD.dusc = 1.f/ff;
1252                         AFD.dvsc = ff / (float)ibuf->y;
1253                 }
1254                 else {  /* EWA & area */
1255                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1256                         b *= ff;
1257                 }
1258                 maxd = maxf(b, 1e-8f);
1259                 levf = ((float)M_LOG2E) * logf(maxd);
1260
1261                 curmap = 0;
1262                 maxlev = 1;
1263                 mipmaps[0] = ibuf;
1264                 while (curmap < IB_MIPMAP_LEVELS) {
1265                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1266                         if (ibuf->mipmap[curmap]) maxlev++;
1267                         curmap++;
1268                 }
1269
1270                 /* mipmap level */
1271                 if (levf < 0.f) {  /* original image only */
1272                         previbuf = curibuf = mipmaps[0];
1273                         levf = 0.f;
1274                 }
1275                 else if (levf >= maxlev - 1) {
1276                         previbuf = curibuf = mipmaps[maxlev - 1];
1277                         levf = 0.f;
1278                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1279                 }
1280                 else {
1281                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1282                         curibuf = mipmaps[lev];
1283                         previbuf = mipmaps[lev + 1];
1284                         levf -= floorf(levf);
1285                 }
1286
1287                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1288
1289                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1290                         /* color & normal */
1291                         filterfunc(texres, curibuf, fx, fy, &AFD);
1292                         val1 = texres->tr + texres->tg + texres->tb;
1293                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1294                         val2 = texr.tr + texr.tg + texr.tb;
1295                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1296                         val3 = texr.tr + texr.tg + texr.tb;
1297                         /* don't switch x or y! */
1298                         texres->nor[0] = val1 - val2;
1299                         texres->nor[1] = val1 - val3;
1300                         if (previbuf != curibuf) {  /* interpolate */
1301                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1302                                 /* rgb */
1303                                 texres->tr += levf*(texr.tr - texres->tr);
1304                                 texres->tg += levf*(texr.tg - texres->tg);
1305                                 texres->tb += levf*(texr.tb - texres->tb);
1306                                 texres->ta += levf*(texr.ta - texres->ta);
1307                                 /* normal */
1308                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1309                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1310                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1311                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1312                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1313                                 texres->nor[0] = val1 - val2;  /* vals have been interpolated above! */
1314                                 texres->nor[1] = val1 - val3;
1315                         }
1316                 }
1317                 else {  /* color */
1318                         filterfunc(texres, curibuf, fx, fy, &AFD);
1319                         if (previbuf != curibuf) {  /* interpolate */
1320                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1321                                 texres->tr += levf*(texr.tr - texres->tr);
1322                                 texres->tg += levf*(texr.tg - texres->tg);
1323                                 texres->tb += levf*(texr.tb - texres->tb);
1324                                 texres->ta += levf*(texr.ta - texres->ta);
1325                         }
1326
1327                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1328                 }
1329         }
1330         else {  /* no mipmap */
1331                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1332                 if (tex->texfilter == TXF_FELINE) {
1333                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1334                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1335                         const float A = Vx*Vx + Vy*Vy;
1336                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1337                         const float C = Ux*Ux + Uy*Uy;
1338                         const float F = A*C - B*B*0.25f;
1339                         float a, b, th, ecc, fProbes;
1340                         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1341                         a *= ff;
1342                         b *= ff;
1343                         a = maxf(a, 1.0f);
1344                         b = maxf(b, 1.0f);
1345                         fProbes = 2.f*(a / b) - 1.f;
1346                         /* no limit to number of Probes here */
1347                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1348                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1349                         AFD.majrad = a/ff;
1350                         AFD.minrad = b/ff;
1351                         AFD.theta = th;
1352                         AFD.dusc = 1.f/ff;
1353                         AFD.dvsc = ff / (float)ibuf->y;
1354                 }
1355                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1356                         /* color & normal */
1357                         filterfunc(texres, ibuf, fx, fy, &AFD);
1358                         val1 = texres->tr + texres->tg + texres->tb;
1359                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1360                         val2 = texr.tr + texr.tg + texr.tb;
1361                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1362                         val3 = texr.tr + texr.tg + texr.tb;
1363                         /* don't switch x or y! */
1364                         texres->nor[0] = val1 - val2;
1365                         texres->nor[1] = val1 - val3;
1366                 }
1367                 else {
1368                         filterfunc(texres, ibuf, fx, fy, &AFD);
1369                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1370                 }
1371         }
1372
1373         if (tex->imaflag & TEX_CALCALPHA)
1374                 texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
1375         else
1376                 texres->tin = texres->ta;
1377         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1378         
1379         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1380                 ibuf->rect -= ibuf->x*ibuf->y;
1381
1382         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    /* normal from color */
1383                 /* The invert of the red channel is to make
1384                  * the normal map compliant with the outside world.
1385                  * It needs to be done because in Blender
1386                  * the normal used in the renderer points inward. It is generated
1387                  * this way in calc_vertexnormals(). Should this ever change
1388                  * this negate must be removed. */
1389                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1390                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1391                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1392         }
1393
1394         /* de-premul, this is being premulled in shade_input_do_shade()
1395          * TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1396          * also disabled in imagewraposa() to be able to compare results with blender's default texture filtering */
1397
1398         /* brecht: tried to fix this, see "TXF alpha" comments */
1399
1400         if (texres->ta != 1.f && (texres->ta > 1e-4f)) {
1401                 fx = 1.f/texres->ta;
1402                 texres->tr *= fx;
1403                 texres->tg *= fx;
1404                 texres->tb *= fx;
1405         }
1406
1407         BRICONTRGB;
1408         
1409         return retval;
1410 }
1411
1412
1413 int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const float DXT[3], const float DYT[3], TexResult *texres)
1414 {
1415         TexResult texr;
1416         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3];
1417         float maxd, pixsize, val1, val2, val3;
1418         int curmap, retval, imaprepeat, imapextend;
1419
1420         /* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1421          * make a local copy here so that original vecs remain untouched */
1422         copy_v3_v3(dxt, DXT);
1423         copy_v3_v3(dyt, DYT);
1424
1425         /* anisotropic filtering */
1426         if (tex->texfilter != TXF_BOX)
1427                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres);
1428
1429         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1430         
1431         /* we need to set retval OK, otherwise texture code generates normals itself... */
1432         retval= texres->nor?3:1;
1433         
1434         /* quick tests */
1435         if (ibuf==NULL && ima==NULL)
1436                 return retval;
1437         if (ima) {
1438
1439                 /* hack for icon render */
1440                 if (ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
1441                         return retval;
1442                 
1443                 ibuf= BKE_image_get_ibuf(ima, &tex->iuser); 
1444
1445                 ima->flag|= IMA_USED_FOR_RENDER;
1446         }
1447         if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
1448                 return retval;
1449         
1450         /* mipmap test */
1451         image_mipmap_test(tex, ibuf);
1452
1453         if (tex->imaflag & TEX_USEALPHA) {
1454                 if (tex->imaflag & TEX_CALCALPHA);
1455                 else texres->talpha= 1;
1456         }
1457         
1458         texr.talpha= texres->talpha;
1459         
1460         if (tex->imaflag & TEX_IMAROT) {
1461                 fy= texvec[0];
1462                 fx= texvec[1];
1463         }
1464         else {
1465                 fx= texvec[0];
1466                 fy= texvec[1];
1467         }
1468         
1469         if (ibuf->flags & IB_fields) {
1470                 if (R.r.mode & R_FIELDS) {                      /* field render */
1471                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1472                                 /* fac1= 0.5/( (float)ibuf->y ); */
1473                                 /* fy-= fac1; */
1474                         }
1475                         else {                          /* first field */
1476                                 fy+= 0.5f/( (float)ibuf->y );
1477                         }
1478                 }
1479         }
1480         
1481         /* pixel coordinates */
1482
1483         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1484         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1485         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1486         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1487
1488         /* tex_sharper has been removed */
1489         minx= (maxx-minx)/2.0f;
1490         miny= (maxy-miny)/2.0f;
1491         
1492         if (tex->imaflag & TEX_FILTER_MIN) {
1493                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1494                 float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1495
1496                 if (addval > minx)
1497                         minx= addval;
1498                 if (addval > miny)
1499                         miny= addval;
1500         }
1501         else if (tex->filtersize!=1.0f) {
1502                 minx*= tex->filtersize;
1503                 miny*= tex->filtersize;
1504                 
1505                 dxt[0]*= tex->filtersize;
1506                 dxt[1]*= tex->filtersize;
1507                 dyt[0]*= tex->filtersize;
1508                 dyt[1]*= tex->filtersize;
1509         }
1510
1511         if (tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1512         
1513         if (minx>0.25f) minx= 0.25f;
1514         else if (minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
1515         if (miny>0.25f) miny= 0.25f;
1516         else if (miny<0.00001f) miny= 0.00001f;
1517
1518         
1519         /* repeat and clip */
1520         imaprepeat= (tex->extend==TEX_REPEAT);
1521         imapextend= (tex->extend==TEX_EXTEND);
1522
1523         if (tex->extend == TEX_REPEAT) {
1524                 if (tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1525                         imaprepeat= 0;
1526                         imapextend= 1;
1527                 }
1528         }
1529
1530         if (tex->extend == TEX_CHECKER) {
1531                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1532                 
1533                 xs= (int)floor(fx);
1534                 ys= (int)floor(fy);
1535                 
1536                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1537                 if ( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1538                         fx-= xs;
1539                         fy-= ys;
1540                 }
1541                 else {
1542                         
1543                         xs1= (int)floor(fx-minx);
1544                         ys1= (int)floor(fy-miny);
1545                         xs2= (int)floor(fx+minx);
1546                         ys2= (int)floor(fy+miny);
1547                         boundary= (xs1!=xs2) || (ys1!=ys2);
1548
1549                         if (boundary==0) {
1550                                 if ( (tex->flag & TEX_CHECKER_ODD)==0) {
1551                                         if ((xs+ys) & 1);
1552                                         else return retval;
1553                                 }
1554                                 if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
1555                                         if ((xs+ys) & 1) return retval;
1556                                 }
1557                                 fx-= xs;
1558                                 fy-= ys;
1559                         }
1560                         else {
1561                                 if (tex->flag & TEX_CHECKER_ODD) {
1562                                         if ((xs1+ys) & 1) fx-= xs2;
1563                                         else fx-= xs1;
1564                                         
1565                                         if ((ys1+xs) & 1) fy-= ys2;
1566                                         else fy-= ys1;
1567                                 }
1568                                 if (tex->flag & TEX_CHECKER_EVEN) {
1569                                         if ((xs1+ys) & 1) fx-= xs1;
1570                                         else fx-= xs2;
1571                                         
1572                                         if ((ys1+xs) & 1) fy-= ys1;
1573                                         else fy-= ys2;
1574                                 }
1575                         }
1576                 }
1577
1578                 /* scale around center, (0.5, 0.5) */
1579                 if (tex->checkerdist<1.0f) {
1580                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1581                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1582                         minx/= (1.0f-tex->checkerdist);
1583                         miny/= (1.0f-tex->checkerdist);
1584                 }
1585         }
1586
1587         if (tex->extend == TEX_CLIPCUBE) {
1588                 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) {
1589                         return retval;
1590                 }
1591         }
1592         else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1593                 if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
1594                         return retval;
1595                 }
1596         }
1597         else {
1598                 if (imapextend) {
1599                         if (fx>1.0f) fx = 1.0f;
1600                         else if (fx<0.0f) fx= 0.0f;
1601                 }
1602                 else {
1603                         if (fx>1.0f) fx -= (int)(fx);
1604                         else if (fx<0.0f) fx+= 1-(int)(fx);
1605                 }
1606                 
1607                 if (imapextend) {
1608                         if (fy>1.0f) fy = 1.0f;
1609                         else if (fy<0.0f) fy= 0.0f;
1610                 }
1611                 else {
1612                         if (fy>1.0f) fy -= (int)(fy);
1613                         else if (fy<0.0f) fy+= 1-(int)(fy);
1614                 }
1615         }
1616
1617         /* warning no return! */
1618         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1619                 ibuf->rect+= (ibuf->x*ibuf->y);
1620         }
1621
1622         /* choice:  */
1623         if (tex->imaflag & TEX_MIPMAP) {
1624                 ImBuf *previbuf, *curibuf;
1625                 float bumpscale;
1626                 
1627                 dx = minx;
1628                 dy = miny;
1629                 maxd = maxf(dx, dy);
1630                 if (maxd > 0.5f) maxd = 0.5f;
1631
1632                 pixsize = 1.0f / (float) MIN2(ibuf->x, ibuf->y);
1633                 
1634                 bumpscale= pixsize/maxd;
1635                 if (bumpscale>1.0f) bumpscale= 1.0f;
1636                 else bumpscale*=bumpscale;
1637                 
1638                 curmap= 0;
1639                 previbuf= curibuf= ibuf;
1640                 while (curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1641                         if (maxd < pixsize) break;
1642                         previbuf= curibuf;
1643                         curibuf= ibuf->mipmap[curmap];
1644                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1645                         curmap++;
1646                 }
1647
1648                 if (previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1649                         /* sample at least 1 pixel */
1650                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1651                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1652                 }
1653                 
1654                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1655                         /* a bit extra filter */
1656                         //minx*= 1.35f;
1657                         //miny*= 1.35f;
1658                         
1659                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1660                         val1= texres->tr+texres->tg+texres->tb;
1661                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1662                         val2= texr.tr + texr.tg + texr.tb;
1663                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1664                         val3= texr.tr + texr.tg + texr.tb;
1665
1666                         /* don't switch x or y! */
1667                         texres->nor[0]= (val1-val2);
1668                         texres->nor[1]= (val1-val3);
1669                         
1670                         if (previbuf!=curibuf) {  /* interpolate */
1671                                 
1672                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1673                                 
1674                                 /* calc rgb */
1675                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1676                                 if (dx>=1.0f) {
1677                                         texres->ta= texr.ta; texres->tb= texr.tb;
1678                                         texres->tg= texr.tg; texres->tr= texr.tr;
1679                                 }
1680                                 else {
1681                                         dy= 1.0f-dx;
1682                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1683                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1684                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1685                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1686                                 }
1687                                 
1688                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1689                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1690                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1691                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1692                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1693                                 
1694                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1695                                 texres->nor[1]= (val1-val3);
1696                                 
1697                                 if (dx<1.0f) {
1698                                         dy= 1.0f-dx;
1699                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1700                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1701                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1702                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1703                                 }
1704                         }
1705                         texres->nor[0]*= bumpscale;
1706                         texres->nor[1]*= bumpscale;
1707                 }
1708                 else {
1709                         maxx= fx+minx;
1710                         minx= fx-minx;
1711                         maxy= fy+miny;
1712                         miny= fy-miny;
1713
1714                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1715
1716                         if (previbuf!=curibuf) {  /* interpolate */
1717                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1718                                 
1719                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1720                                 
1721                                 if (fx>=1.0f) {
1722                                         texres->ta= texr.ta; texres->tb= texr.tb;
1723                                         texres->tg= texr.tg; texres->tr= texr.tr;
1724                                 }
1725                                 else {
1726                                         fy= 1.0f-fx;
1727                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1728                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1729                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1730                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1731                                 }
1732                         }
1733                 }
1734         }
1735         else {
1736                 const int intpol = tex->imaflag & TEX_INTERPOL;
1737                 if (intpol) {
1738                         /* sample 1 pixel minimum */
1739                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1740                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1741                 }
1742
1743                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1744                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1745                         val1= texres->tr+texres->tg+texres->tb;
1746                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1747                         val2= texr.tr + texr.tg + texr.tb;
1748                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1749                         val3= texr.tr + texr.tg + texr.tb;
1750
1751                         /* don't switch x or y! */
1752                         texres->nor[0]= (val1-val2);
1753                         texres->nor[1]= (val1-val3);
1754                 }
1755                 else
1756                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1757         }
1758         
1759         if (tex->imaflag & TEX_CALCALPHA) {
1760                 texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
1761         }
1762         else texres->tin= texres->ta;
1763
1764         if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1765         
1766         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1767                 ibuf->rect-= (ibuf->x*ibuf->y);
1768         }
1769
1770         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1771                 /* qdn: normal from color
1772                  * The invert of the red channel is to make
1773                  * the normal map compliant with the outside world.
1774                  * It needs to be done because in Blender
1775                  * the normal used in the renderer points inward. It is generated
1776                  * this way in calc_vertexnormals(). Should this ever change
1777                  * this negate must be removed. */
1778                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1779                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1780                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1781         }
1782
1783         /* de-premul, this is being premulled in shade_input_do_shade() */
1784         if (texres->ta != 1.0f && texres->ta > 1e-4f) {
1785                 mul_v3_fl(&texres->tr, 1.0f / texres->ta);
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[4])
1794 {
1795         TexResult texres;
1796         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1797         
1798         if (UNLIKELY(ibuf == NULL)) {
1799                 zero_v4(result);
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 = TRUE; /* boxsample expects to be initialized */
1807         boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
1808         copy_v4_v4(result, &texres.tr);
1809         
1810         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1811                 ibuf->rect-= (ibuf->x*ibuf->y);
1812
1813         ima->flag|= IMA_USED_FOR_RENDER;
1814 }
1815
1816 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
1817 {
1818         TexResult texres = {0};
1819         afdata_t AFD;
1820
1821         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1822         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1823         //copy_v2_v2(AFD.dxt, dx);
1824         //copy_v2_v2(AFD.dyt, dy);
1825         
1826         AFD.intpol = 1;
1827         AFD.extflag = TXC_EXTD;
1828
1829         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1830         
1831         copy_v4_v4(result, &texres.tr);
1832 }