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