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