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