Bugfix #22040
[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)floorf(fx*ibuf->x);
161         y = (int)floorf(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)
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 void image_mipmap_test(Tex *tex, ImBuf *ibuf)
964 {
965         if (tex->imaflag & TEX_MIPMAP) {
966                 if ((ibuf->flags & IB_fields) == 0) {
967                         
968                         if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
969                                 BLI_lock_thread(LOCK_IMAGE);
970                                 if (ibuf->userflags & IB_MIPMAP_INVALID) {
971                                         IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
972                                         ibuf->userflags &= ~IB_MIPMAP_INVALID;
973                                 }                               
974                                 BLI_unlock_thread(LOCK_IMAGE);
975                         }
976                         if (ibuf->mipmap[0] == NULL) {
977                                 BLI_lock_thread(LOCK_IMAGE);
978                                 if (ibuf->mipmap[0] == NULL) 
979                                         IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
980                                 BLI_unlock_thread(LOCK_IMAGE);
981                         }
982                 }
983         }
984         
985 }
986
987 static int imagewraposa_aniso(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *dxt, float *dyt, TexResult *texres)
988 {
989         TexResult texr;
990         float fx, fy, minx, maxx, miny, maxy;
991         float maxd, val1, val2, val3;
992         int curmap, retval, intpol, extflag = 0;
993         afdata_t AFD;
994
995         void (*filterfunc)(TexResult*, ImBuf*, float, float, afdata_t*);
996         switch (tex->texfilter) {
997                 case TXF_EWA:
998                         filterfunc = ewa_eval;
999                         break;
1000                 case TXF_FELINE:
1001                         filterfunc = feline_eval;
1002                         break;
1003                 case TXF_AREA:
1004                 default:
1005                         filterfunc = area_sample;
1006         }
1007
1008         texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.f;
1009
1010         // we need to set retval OK, otherwise texture code generates normals itself...
1011         retval = texres->nor ? 3 : 1;
1012
1013         // quick tests
1014         if (ibuf==NULL && ima==NULL) return retval;
1015
1016         if (ima) {      // hack for icon render
1017                 if ((ima->ibufs.first == NULL) && (R.r.scemode & R_NO_IMAGE_LOAD)) return retval;
1018                 ibuf = BKE_image_get_ibuf(ima, &tex->iuser); 
1019         }
1020
1021         if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) return retval;
1022
1023         /* mipmap test */
1024         image_mipmap_test(tex, ibuf);
1025         
1026         if ((tex->imaflag & TEX_USEALPHA) && ((tex->imaflag & TEX_CALCALPHA) == 0)) texres->talpha = 1;
1027         texr.talpha = texres->talpha;
1028
1029         if (tex->imaflag & TEX_IMAROT) {
1030                 fy = texvec[0];
1031                 fx = texvec[1];
1032         }
1033         else {
1034                 fx = texvec[0];
1035                 fy = texvec[1];
1036         }
1037
1038         if (ibuf->flags & IB_fields) {
1039                 if (R.r.mode & R_FIELDS) {                      /* field render */
1040                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1041                                 /* fac1= 0.5/( (float)ibuf->y ); */
1042                                 /* fy-= fac1; */
1043                         }
1044                         else    /* first field */
1045                                 fy += 0.5f/( (float)ibuf->y );
1046                 }
1047         }
1048
1049         // pixel coordinates
1050         minx = MIN3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1051         maxx = MAX3(dxt[0], dyt[0], dxt[0] + dyt[0]);
1052         miny = MIN3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1053         maxy = MAX3(dxt[1], dyt[1], dxt[1] + dyt[1]);
1054
1055         // tex_sharper has been removed
1056         minx = (maxx - minx)*0.5f;
1057         miny = (maxy - miny)*0.5f;
1058
1059         if (tex->imaflag & TEX_FILTER_MIN) {
1060                 // make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy)
1061                  const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1062                 if (addval > minx) minx = addval;
1063                 if (addval > miny) miny = addval;
1064         }
1065         else if (tex->filtersize != 1.f) {
1066                 minx *= tex->filtersize;
1067                 miny *= tex->filtersize;
1068                 dxt[0] *= tex->filtersize;
1069                 dxt[1] *= tex->filtersize;
1070                 dyt[0] *= tex->filtersize;
1071                 dyt[1] *= tex->filtersize;
1072         }
1073
1074         if (tex->imaflag & TEX_IMAROT) {
1075                 float t;
1076                 SWAP(float, minx, miny);
1077                 // must rotate dxt/dyt 90 deg
1078                 // yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1079                 // but it doesn't, it only swaps coords, so filter area will be incorrect in those cases.
1080                 t = dxt[0];
1081                 dxt[0] = dxt[1];
1082                 dxt[1] = -t;
1083                 t = dyt[0];
1084                 dyt[0] = dyt[1];
1085                 dyt[1] = -t;
1086         }
1087
1088         // side faces of unit-cube
1089         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5 : minx);
1090         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5 : miny);
1091
1092         // repeat and clip
1093
1094         if (tex->extend == TEX_REPEAT) {
1095                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1096                         extflag = TXC_EXTD;
1097                 else if (tex->flag & TEX_REPEAT_XMIR)
1098                         extflag = TXC_XMIR;
1099                 else if (tex->flag & TEX_REPEAT_YMIR)
1100                         extflag = TXC_YMIR;
1101                 else
1102                         extflag = TXC_REPT;
1103         }
1104         else if (tex->extend == TEX_EXTEND)
1105                 extflag = TXC_EXTD;
1106
1107         if (tex->extend == TEX_CHECKER) {
1108                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1109                 // both checkers available, no boundary exceptions, checkerdist will eat aliasing
1110                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1111                         fx -= xs;
1112                         fy -= ys;
1113                 }
1114                 else {
1115                         int xs1 = (int)floorf(fx - minx);
1116                         int ys1 = (int)floorf(fy - miny);
1117                         int xs2 = (int)floorf(fx + minx);
1118                         int ys2 = (int)floorf(fy + miny);
1119                         if ((xs1 != xs2) || (ys1 != ys2)) {
1120                                 if (tex->flag & TEX_CHECKER_ODD) {
1121                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1122                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1123                                 }
1124                                 if (tex->flag & TEX_CHECKER_EVEN) {
1125                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1126                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1127                                 }
1128                         }
1129                         else {
1130                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) return retval;
1131                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) return retval;
1132                                 fx -= xs;
1133                                 fy -= ys;
1134                         }
1135                 }
1136                 // scale around center, (0.5, 0.5)
1137                 if (tex->checkerdist < 1.f) {
1138                         const float omcd = 1.f / (1.f - tex->checkerdist);
1139                         fx = (fx - 0.5f)*omcd + 0.5f;
1140                         fy = (fy - 0.5f)*omcd + 0.5f;
1141                         minx *= omcd;
1142                         miny *= omcd;
1143                 }
1144         }
1145
1146         if (tex->extend == TEX_CLIPCUBE) {
1147                 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;
1148         }
1149         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1150                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) return retval;
1151         }
1152         else {
1153                 if (tex->extend == TEX_EXTEND) {
1154                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1155                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1156                 }
1157                 else {
1158                         fx -= floorf(fx);
1159                         fy -= floorf(fy);
1160                 }
1161         }
1162
1163         intpol = tex->imaflag & TEX_INTERPOL;
1164
1165         // warning no return!
1166         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1167                 ibuf->rect += ibuf->x*ibuf->y;
1168
1169         // struct common data
1170         copy_v2_v2(AFD.dxt, dxt);
1171         copy_v2_v2(AFD.dyt, dyt);
1172         AFD.intpol = intpol;
1173         AFD.extflag = extflag;
1174
1175         // brecht: added stupid clamping here, large dx/dy can give very large
1176         // filter sizes which take ages to render, it may be better to do this
1177         // more intelligently later in the code .. probably it's not noticeable
1178         if(AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f) {
1179                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1180                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1181         }
1182         if(AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1183                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1184
1185         // choice:
1186         if (tex->imaflag & TEX_MIPMAP) {
1187                 ImBuf *previbuf, *curibuf;
1188                 float levf;
1189                 int maxlev;
1190                 ImBuf* mipmaps[IB_MIPMAP_LEVELS + 1];
1191
1192                 // modify ellipse minor axis if too eccentric, use for area sampling as well
1193                 // scaling dxt/dyt as done in pbrt is not the same
1194                 // (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision)
1195                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1196                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1197                 const float A = Vx*Vx + Vy*Vy;
1198                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1199                 const float C = Ux*Ux + Uy*Uy;
1200                 const float F = A*C - B*B*0.25f;
1201                 float a, b, th, ecc;
1202                 imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1203                 if (tex->texfilter == TXF_FELINE) {
1204                         float fProbes;
1205                         a *= ff;
1206                         b *= ff;
1207                         a = MAX2(a, 1.f);
1208                         b = MAX2(b, 1.f);
1209                         fProbes = 2.f*(a / b) - 1.f;
1210                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1211                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1212                         if (AFD.iProbes < fProbes)
1213                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1214                         AFD.majrad = a/ff;
1215                         AFD.minrad = b/ff;
1216                         AFD.theta = th;
1217                         AFD.dusc = 1.f/ff;
1218                         AFD.dvsc = ff / (float)ibuf->y;
1219                 }
1220                 else {  // EWA & area
1221                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1222                         b *= ff;
1223                 }
1224                 maxd = MAX2(b, 1e-8f);
1225                 levf = ((float)M_LOG2E)*logf(maxd);
1226
1227                 curmap = 0;
1228                 maxlev = 1;
1229                 mipmaps[0] = ibuf;
1230                 while (curmap < IB_MIPMAP_LEVELS) {
1231                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1232                         if (ibuf->mipmap[curmap]) maxlev++;
1233                         curmap++;
1234                 }
1235
1236                 // mipmap level
1237                 if (levf < 0.f) {       // original image only
1238                         previbuf = curibuf = mipmaps[0];
1239                         levf = 0.f;
1240                 }
1241                 else if (levf >= maxlev - 1) {
1242                         previbuf = curibuf = mipmaps[maxlev - 1];
1243                         levf = 0.f;
1244                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1245                 }
1246                 else {
1247                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1248                         curibuf = mipmaps[lev];
1249                         previbuf = mipmaps[lev + 1];
1250                         levf -= floorf(levf);
1251                 }
1252
1253                 // filter functions take care of interpolation themselves, no need to modify dxt/dyt here
1254
1255                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1256                         // color & normal
1257                         filterfunc(texres, curibuf, fx, fy, &AFD);
1258                         val1 = texres->tr + texres->tg + texres->tb;
1259                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1260                         val2 = texr.tr + texr.tg + texr.tb;
1261                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1262                         val3 = texr.tr + texr.tg + texr.tb;
1263                         // don't switch x or y!
1264                         texres->nor[0] = val1 - val2;
1265                         texres->nor[1] = val1 - val3;
1266                         if (previbuf != curibuf) {  // interpolate
1267                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1268                                 // rgb
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                                 // normal
1274                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1275                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1276                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1277                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1278                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1279                                 texres->nor[0] = val1 - val2;   // vals have been interpolated above!
1280                                 texres->nor[1] = val1 - val3;
1281                         }
1282                 }
1283                 else {  // color
1284                         filterfunc(texres, curibuf, fx, fy, &AFD);
1285                         if (previbuf != curibuf) {  // interpolate
1286                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1287                                 texres->tr += levf*(texr.tr - texres->tr);
1288                                 texres->tg += levf*(texr.tg - texres->tg);
1289                                 texres->tb += levf*(texr.tb - texres->tb);
1290                                 texres->ta += levf*(texr.ta - texres->ta);
1291                         }
1292
1293                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1294                 }
1295         }
1296         else {  // no mipmap
1297                 // filter functions take care of interpolation themselves, no need to modify dxt/dyt here
1298                 if (tex->texfilter == TXF_FELINE) {
1299                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1300                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1301                         const float A = Vx*Vx + Vy*Vy;
1302                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1303                         const float C = Ux*Ux + Uy*Uy;
1304                         const float F = A*C - B*B*0.25f;
1305                         float a, b, th, ecc, fProbes;
1306                         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1307                         a *= ff;
1308                         b *= ff;
1309                         a = MAX2(a, 1.f);
1310                         b = MAX2(b, 1.f);
1311                         fProbes = 2.f*(a / b) - 1.f;
1312                         // no limit to number of Probes here
1313                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1314                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1315                         AFD.majrad = a/ff;
1316                         AFD.minrad = b/ff;
1317                         AFD.theta = th;
1318                         AFD.dusc = 1.f/ff;
1319                         AFD.dvsc = ff / (float)ibuf->y;
1320                 }
1321                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1322                         // color & normal
1323                         filterfunc(texres, ibuf, fx, fy, &AFD);
1324                         val1 = texres->tr + texres->tg + texres->tb;
1325                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1326                         val2 = texr.tr + texr.tg + texr.tb;
1327                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1328                         val3 = texr.tr + texr.tg + texr.tb;
1329                         // don't switch x or y!
1330                         texres->nor[0] = val1 - val2;
1331                         texres->nor[1] = val1 - val3;
1332                 }
1333                 else {
1334                         filterfunc(texres, ibuf, fx, fy, &AFD);
1335                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1336                 }
1337         }
1338
1339         if (tex->imaflag & TEX_CALCALPHA)
1340                 texres->ta = texres->tin = texres->ta * MAX3(texres->tr, texres->tg, texres->tb);
1341         else
1342                 texres->tin = texres->ta;
1343         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1344         
1345         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1346                 ibuf->rect -= ibuf->x*ibuf->y;
1347
1348         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    // normal from color
1349                 texres->nor[0] = 2.f*(texres->tr - 0.5f);
1350                 texres->nor[1] = 2.f*(0.5f - texres->tg);
1351                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1352         }
1353         
1354         // de-premul, this is being premulled in shade_input_do_shade()
1355         // TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1356         // also disabled in imagewraposa() to be able to compare results with blender's default texture filtering
1357
1358         // brecht: tried to fix this, see "TXF alpha" comments
1359
1360         if (texres->ta != 1.f && (texres->ta > FLT_EPSILON)) {
1361                 fx = 1.f/texres->ta;
1362                 texres->tr *= fx;
1363                 texres->tg *= fx;
1364                 texres->tb *= fx;
1365         }
1366
1367         BRICONTRGB;
1368         
1369         return retval;
1370 }
1371
1372
1373 int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, float *texvec, float *DXT, float *DYT, TexResult *texres)
1374 {
1375         TexResult texr;
1376         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[3], dyt[3];
1377         float maxd, pixsize, val1, val2, val3;
1378         int curmap, retval, imaprepeat, imapextend;
1379
1380         // TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1381         // make a local copy here so that original vecs remain untouched
1382         VECCOPY(dxt, DXT);
1383         VECCOPY(dyt, DYT);
1384
1385         // anisotropic filtering
1386         if (tex->texfilter != TXF_BOX)
1387                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres);
1388
1389         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1390         
1391         /* we need to set retval OK, otherwise texture code generates normals itself... */
1392         retval= texres->nor?3:1;
1393         
1394         /* quick tests */
1395         if(ibuf==NULL && ima==NULL)
1396                 return retval;
1397         if(ima) {
1398
1399                 /* hack for icon render */
1400                 if(ima->ibufs.first==NULL && (R.r.scemode & R_NO_IMAGE_LOAD))
1401                         return retval;
1402                 
1403                 ibuf= BKE_image_get_ibuf(ima, &tex->iuser); 
1404         }
1405         if(ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL))
1406            return retval;
1407         
1408         /* mipmap test */
1409         image_mipmap_test(tex, ibuf);
1410
1411         if(tex->imaflag & TEX_USEALPHA) {
1412                 if(tex->imaflag & TEX_CALCALPHA);
1413                 else texres->talpha= 1;
1414         }
1415         
1416         texr.talpha= texres->talpha;
1417         
1418         if(tex->imaflag & TEX_IMAROT) {
1419                 fy= texvec[0];
1420                 fx= texvec[1];
1421         }
1422         else {
1423                 fx= texvec[0];
1424                 fy= texvec[1];
1425         }
1426         
1427         if(ibuf->flags & IB_fields) {
1428                 if(R.r.mode & R_FIELDS) {                       /* field render */
1429                         if(R.flag & R_SEC_FIELD) {              /* correction for 2nd field */
1430                                 /* fac1= 0.5/( (float)ibuf->y ); */
1431                                 /* fy-= fac1; */
1432                         }
1433                         else {                          /* first field */
1434                                 fy+= 0.5f/( (float)ibuf->y );
1435                         }
1436                 }
1437         }
1438         
1439         /* pixel coordinates */
1440
1441         minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1442         maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1443         miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1444         maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1445
1446         /* tex_sharper has been removed */
1447         minx= (maxx-minx)/2.0f;
1448         miny= (maxy-miny)/2.0f;
1449         
1450         if(tex->imaflag & TEX_FILTER_MIN) {
1451                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1452                  float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1453                 
1454                 if(addval > minx)
1455                         minx= addval;
1456                 if(addval > miny)
1457                         miny= addval;
1458         }
1459         else if(tex->filtersize!=1.0f) {
1460                 minx*= tex->filtersize;
1461                 miny*= tex->filtersize;
1462                 
1463                 dxt[0]*= tex->filtersize;
1464                 dxt[1]*= tex->filtersize;
1465                 dyt[0]*= tex->filtersize;
1466                 dyt[1]*= tex->filtersize;
1467         }
1468
1469         if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1470         
1471         if(minx>0.25) minx= 0.25;
1472         else if(minx<0.00001f) minx= 0.00001f;  /* side faces of unit-cube */
1473         if(miny>0.25) miny= 0.25;
1474         else if(miny<0.00001f) miny= 0.00001f;
1475
1476         
1477         /* repeat and clip */
1478         imaprepeat= (tex->extend==TEX_REPEAT);
1479         imapextend= (tex->extend==TEX_EXTEND);
1480
1481         if(tex->extend == TEX_REPEAT) {
1482                 if(tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1483                         imaprepeat= 0;
1484                         imapextend= 1;
1485                 }
1486         }
1487
1488         if(tex->extend == TEX_CHECKER) {
1489                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1490                 
1491                 xs= (int)floor(fx);
1492                 ys= (int)floor(fy);
1493                 
1494                 // both checkers available, no boundary exceptions, checkerdist will eat aliasing
1495                 if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1496                         fx-= xs;
1497                         fy-= ys;
1498                 }
1499                 else {
1500                         
1501                         xs1= (int)floor(fx-minx);
1502                         ys1= (int)floor(fy-miny);
1503                         xs2= (int)floor(fx+minx);
1504                         ys2= (int)floor(fy+miny);
1505                         boundary= (xs1!=xs2) || (ys1!=ys2);
1506
1507                         if(boundary==0) {
1508                                 if( (tex->flag & TEX_CHECKER_ODD)==0) {
1509                                         if((xs+ys) & 1); 
1510                                         else return retval;
1511                                 }
1512                                 if( (tex->flag & TEX_CHECKER_EVEN)==0) {
1513                                         if((xs+ys) & 1) return retval;
1514                                 }
1515                                 fx-= xs;
1516                                 fy-= ys;
1517                         }
1518                         else {
1519                                 if(tex->flag & TEX_CHECKER_ODD) {
1520                                         if((xs1+ys) & 1) fx-= xs2;
1521                                         else fx-= xs1;
1522                                         
1523                                         if((ys1+xs) & 1) fy-= ys2;
1524                                         else fy-= ys1;
1525                                 }
1526                                 if(tex->flag & TEX_CHECKER_EVEN) {
1527                                         if((xs1+ys) & 1) fx-= xs1;
1528                                         else fx-= xs2;
1529                                         
1530                                         if((ys1+xs) & 1) fy-= ys1;
1531                                         else fy-= ys2;
1532                                 }
1533                         }
1534                 }
1535
1536                 /* scale around center, (0.5, 0.5) */
1537                 if(tex->checkerdist<1.0) {
1538                         fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
1539                         fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
1540                         minx/= (1.0-tex->checkerdist);
1541                         miny/= (1.0-tex->checkerdist);
1542                 }
1543         }
1544
1545         if(tex->extend == TEX_CLIPCUBE) {
1546                 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) {
1547                         return retval;
1548                 }
1549         }
1550         else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1551                 if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) {
1552                         return retval;
1553                 }
1554         }
1555         else {
1556                 if(imapextend) {
1557                         if(fx>1.0) fx = 1.0;
1558                         else if(fx<0.0) fx= 0.0;
1559                 }
1560                 else {
1561                         if(fx>1.0) fx -= (int)(fx);
1562                         else if(fx<0.0) fx+= 1-(int)(fx);
1563                 }
1564                 
1565                 if(imapextend) {
1566                         if(fy>1.0) fy = 1.0;
1567                         else if(fy<0.0) fy= 0.0;
1568                 }
1569                 else {
1570                         if(fy>1.0) fy -= (int)(fy);
1571                         else if(fy<0.0) fy+= 1-(int)(fy);
1572                 }
1573         }
1574
1575         /* warning no return! */
1576         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1577                 ibuf->rect+= (ibuf->x*ibuf->y);
1578         }
1579
1580         /* choice:  */
1581         if(tex->imaflag & TEX_MIPMAP) {
1582                 ImBuf *previbuf, *curibuf;
1583                 float bumpscale;
1584                 
1585                 dx= minx;
1586                 dy= miny;
1587                 maxd= MAX2(dx, dy);
1588                 if(maxd>0.5) maxd= 0.5;
1589
1590                 pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
1591                 
1592                 bumpscale= pixsize/maxd;
1593                 if(bumpscale>1.0f) bumpscale= 1.0f;
1594                 else bumpscale*=bumpscale;
1595                 
1596                 curmap= 0;
1597                 previbuf= curibuf= ibuf;
1598                 while(curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1599                         if(maxd < pixsize) break;
1600                         previbuf= curibuf;
1601                         curibuf= ibuf->mipmap[curmap];
1602                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1603                         curmap++;
1604                 }
1605
1606                 if(previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1607                         /* sample at least 1 pixel */
1608                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1609                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1610                 }
1611                 
1612                 if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1613                         /* a bit extra filter */
1614                         //minx*= 1.35f;
1615                         //miny*= 1.35f;
1616                         
1617                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1618                         val1= texres->tr+texres->tg+texres->tb;
1619                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1620                         val2= texr.tr + texr.tg + texr.tb;
1621                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1622                         val3= texr.tr + texr.tg + texr.tb;
1623
1624                         /* don't switch x or y! */
1625                         texres->nor[0]= (val1-val2);
1626                         texres->nor[1]= (val1-val3);
1627                         
1628                         if(previbuf!=curibuf) {  /* interpolate */
1629                                 
1630                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1631                                 
1632                                 /* calc rgb */
1633                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1634                                 if(dx>=1.0f) {
1635                                         texres->ta= texr.ta; texres->tb= texr.tb;
1636                                         texres->tg= texr.tg; texres->tr= texr.tr;
1637                                 }
1638                                 else {
1639                                         dy= 1.0f-dx;
1640                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1641                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1642                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1643                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1644                                 }
1645                                 
1646                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1647                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1648                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1649                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1650                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1651                                 
1652                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1653                                 texres->nor[1]= (val1-val3);
1654                                 
1655                                 if(dx<1.0f) {
1656                                         dy= 1.0f-dx;
1657                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1658                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1659                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1660                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1661                                 }
1662                         }
1663                         texres->nor[0]*= bumpscale;
1664                         texres->nor[1]*= bumpscale;
1665                 }
1666                 else {
1667                         maxx= fx+minx;
1668                         minx= fx-minx;
1669                         maxy= fy+miny;
1670                         miny= fy-miny;
1671
1672                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1673
1674                         if(previbuf!=curibuf) {  /* interpolate */
1675                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1676                                 
1677                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1678                                 
1679                                 if(fx>=1.0) {
1680                                         texres->ta= texr.ta; texres->tb= texr.tb;
1681                                         texres->tg= texr.tg; texres->tr= texr.tr;
1682                                 } else {
1683                                         fy= 1.0f-fx;
1684                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1685                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1686                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1687                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1688                                 }
1689                         }
1690                 }
1691         }
1692         else {
1693                 const int intpol = tex->imaflag & TEX_INTERPOL;
1694                 if (intpol) {
1695                         /* sample 1 pixel minimum */
1696                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1697                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1698                 }
1699
1700                 if(texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1701                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1702                         val1= texres->tr+texres->tg+texres->tb;
1703                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1704                         val2= texr.tr + texr.tg + texr.tb;
1705                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1706                         val3= texr.tr + texr.tg + texr.tb;
1707
1708                         /* don't switch x or y! */
1709                         texres->nor[0]= (val1-val2);
1710                         texres->nor[1]= (val1-val3);
1711                 }
1712                 else
1713                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1714         }
1715         
1716         if(tex->imaflag & TEX_CALCALPHA) {
1717                 texres->ta= texres->tin= texres->ta*MAX3(texres->tr, texres->tg, texres->tb);
1718         }
1719         else texres->tin= texres->ta;
1720
1721         if(tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1722         
1723         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1724                 ibuf->rect-= (ibuf->x*ibuf->y);
1725         }
1726
1727         if(texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1728                 // qdn: normal from color
1729                 texres->nor[0] = 2.f*(texres->tr - 0.5f);
1730                 texres->nor[1] = 2.f*(0.5f - texres->tg);
1731                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1732         }
1733         
1734         /* de-premul, this is being premulled in shade_input_do_shade() */
1735         if(texres->ta!=1.0f && texres->ta>FLT_EPSILON) {
1736                 fx= 1.0f/texres->ta;
1737                 texres->tr*= fx;
1738                 texres->tg*= fx;
1739                 texres->tb*= fx;
1740         }
1741
1742         BRICONTRGB;
1743         
1744         return retval;
1745 }
1746
1747 void image_sample(Image *ima, float fx, float fy, float dx, float dy, float *result)
1748 {
1749         TexResult texres;
1750         ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL);
1751         
1752         if(ibuf==NULL) {
1753                 result[0]= result[1]= result[2]= result[3]= 0.0f;
1754                 return;
1755         }
1756         
1757         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1758                 ibuf->rect+= (ibuf->x*ibuf->y);
1759         
1760         boxsample(ibuf, fx, fy, fx+dx, fy+dy, &texres, 0, 1);
1761         result[0]= texres.tr;
1762         result[1]= texres.tg;
1763         result[2]= texres.tb;
1764         result[3]= texres.ta;
1765         
1766         if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1767                 ibuf->rect-= (ibuf->x*ibuf->y);
1768 }
1769
1770 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float *result)
1771 {
1772         TexResult texres;
1773         afdata_t AFD;
1774         
1775         if(ibuf==NULL) {
1776                 return;
1777         }
1778         
1779         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1780         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1781         //copy_v2_v2(AFD.dxt, dx);
1782         //copy_v2_v2(AFD.dyt, dy);
1783         
1784         AFD.intpol = 1;
1785         AFD.extflag = TXC_EXTD;
1786         
1787         memset(&texres, 0, sizeof(texres));
1788         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1789         
1790         
1791         result[0]= texres.tr;
1792         result[1]= texres.tg;
1793         result[2]= texres.tb;
1794         result[3]= texres.ta;
1795 }