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