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