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