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