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