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