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