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