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