Image cache rewrite to using generic movie cache
[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 ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
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 ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima)) {
1098                         return retval;
1099                 }
1100                 ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
1101         }
1102
1103         if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) {
1104                 if (ima)
1105                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1106                 return retval;
1107         }
1108
1109         if (ima) {
1110                 ima->flag |= IMA_USED_FOR_RENDER;
1111         }
1112
1113         /* mipmap test */
1114         image_mipmap_test(tex, ibuf);
1115         
1116         if (ima) {
1117                 if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
1118                         if ((tex->imaflag & TEX_CALCALPHA) == 0) {
1119                                 texres->talpha = 1;
1120                         }
1121                 }
1122         }
1123         texr.talpha = texres->talpha;
1124
1125         if (tex->imaflag & TEX_IMAROT) {
1126                 fy = texvec[0];
1127                 fx = texvec[1];
1128         }
1129         else {
1130                 fx = texvec[0];
1131                 fy = texvec[1];
1132         }
1133
1134         if (ibuf->flags & IB_fields) {
1135                 if (R.r.mode & R_FIELDS) {                      /* field render */
1136                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1137                                 /* fac1= 0.5/( (float)ibuf->y ); */
1138                                 /* fy-= fac1; */
1139                         }
1140                         else    /* first field */
1141                                 fy += 0.5f/( (float)ibuf->y );
1142                 }
1143         }
1144
1145         /* pixel coordinates */
1146         minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1147         maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1148         miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1149         maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1150
1151         /* tex_sharper has been removed */
1152         minx = (maxx - minx)*0.5f;
1153         miny = (maxy - miny)*0.5f;
1154
1155         if (tex->imaflag & TEX_FILTER_MIN) {
1156                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1157                 const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1158                 if (addval > minx) minx = addval;
1159                 if (addval > miny) miny = addval;
1160         }
1161         else if (tex->filtersize != 1.f) {
1162                 minx *= tex->filtersize;
1163                 miny *= tex->filtersize;
1164                 dxt[0] *= tex->filtersize;
1165                 dxt[1] *= tex->filtersize;
1166                 dyt[0] *= tex->filtersize;
1167                 dyt[1] *= tex->filtersize;
1168         }
1169
1170         if (tex->imaflag & TEX_IMAROT) {
1171                 float t;
1172                 SWAP(float, minx, miny);
1173                 /* must rotate dxt/dyt 90 deg
1174                  * yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1175                  * but it doesn't, it only swaps coords, so filter area will be incorrect in those cases. */
1176                 t = dxt[0];
1177                 dxt[0] = dxt[1];
1178                 dxt[1] = -t;
1179                 t = dyt[0];
1180                 dyt[0] = dyt[1];
1181                 dyt[1] = -t;
1182         }
1183
1184         /* side faces of unit-cube */
1185         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1186         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1187
1188         /* repeat and clip */
1189
1190         if (tex->extend == TEX_REPEAT) {
1191                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1192                         extflag = TXC_EXTD;
1193                 else if (tex->flag & TEX_REPEAT_XMIR)
1194                         extflag = TXC_XMIR;
1195                 else if (tex->flag & TEX_REPEAT_YMIR)
1196                         extflag = TXC_YMIR;
1197                 else
1198                         extflag = TXC_REPT;
1199         }
1200         else if (tex->extend == TEX_EXTEND)
1201                 extflag = TXC_EXTD;
1202
1203         if (tex->extend == TEX_CHECKER) {
1204                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1205                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1206                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1207                         fx -= xs;
1208                         fy -= ys;
1209                 }
1210                 else {
1211                         int xs1 = (int)floorf(fx - minx);
1212                         int ys1 = (int)floorf(fy - miny);
1213                         int xs2 = (int)floorf(fx + minx);
1214                         int ys2 = (int)floorf(fy + miny);
1215                         if ((xs1 != xs2) || (ys1 != ys2)) {
1216                                 if (tex->flag & TEX_CHECKER_ODD) {
1217                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1218                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1219                                 }
1220                                 if (tex->flag & TEX_CHECKER_EVEN) {
1221                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1222                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1223                                 }
1224                         }
1225                         else {
1226                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) {
1227                                         if (ima)
1228                                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1229                                         return retval;
1230                                 }
1231                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) {
1232                                         if (ima)
1233                                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1234                                         return retval;
1235                                 }
1236                                 fx -= xs;
1237                                 fy -= ys;
1238                         }
1239                 }
1240                 /* scale around center, (0.5, 0.5) */
1241                 if (tex->checkerdist < 1.f) {
1242                         const float omcd = 1.f / (1.f - tex->checkerdist);
1243                         fx = (fx - 0.5f)*omcd + 0.5f;
1244                         fy = (fy - 0.5f)*omcd + 0.5f;
1245                         minx *= omcd;
1246                         miny *= omcd;
1247                 }
1248         }
1249
1250         if (tex->extend == TEX_CLIPCUBE) {
1251                 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) {
1252                         if (ima)
1253                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1254                         return retval;
1255                 }
1256         }
1257         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1258                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) {
1259                         if (ima)
1260                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1261                         return retval;
1262                 }
1263         }
1264         else {
1265                 if (tex->extend == TEX_EXTEND) {
1266                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1267                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1268                 }
1269                 else {
1270                         fx -= floorf(fx);
1271                         fy -= floorf(fy);
1272                 }
1273         }
1274
1275         intpol = tex->imaflag & TEX_INTERPOL;
1276
1277         /* warning no return! */
1278         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1279                 ibuf->rect += ibuf->x*ibuf->y;
1280
1281         /* struct common data */
1282         copy_v2_v2(AFD.dxt, dxt);
1283         copy_v2_v2(AFD.dyt, dyt);
1284         AFD.intpol = intpol;
1285         AFD.extflag = extflag;
1286
1287         /* brecht: added stupid clamping here, large dx/dy can give very large
1288          * filter sizes which take ages to render, it may be better to do this
1289          * more intelligently later in the code .. probably it's not noticeable */
1290         if (AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f)
1291                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1292         if (AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1293                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1294
1295         /* choice: */
1296         if (tex->imaflag & TEX_MIPMAP) {
1297                 ImBuf *previbuf, *curibuf;
1298                 float levf;
1299                 int maxlev;
1300                 ImBuf *mipmaps[IB_MIPMAP_LEVELS + 1];
1301
1302                 /* modify ellipse minor axis if too eccentric, use for area sampling as well
1303                  * scaling dxt/dyt as done in pbrt is not the same
1304                  * (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision) */
1305                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1306                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1307                 const float A = Vx*Vx + Vy*Vy;
1308                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1309                 const float C = Ux*Ux + Uy*Uy;
1310                 const float F = A*C - B*B*0.25f;
1311                 float a, b, th, ecc;
1312                 imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1313                 if (tex->texfilter == TXF_FELINE) {
1314                         float fProbes;
1315                         a *= ff;
1316                         b *= ff;
1317                         a = max_ff(a, 1.0f);
1318                         b = max_ff(b, 1.0f);
1319                         fProbes = 2.f*(a / b) - 1.f;
1320                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1321                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1322                         if (AFD.iProbes < fProbes)
1323                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1324                         AFD.majrad = a/ff;
1325                         AFD.minrad = b/ff;
1326                         AFD.theta = th;
1327                         AFD.dusc = 1.f/ff;
1328                         AFD.dvsc = ff / (float)ibuf->y;
1329                 }
1330                 else {  /* EWA & area */
1331                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1332                         b *= ff;
1333                 }
1334                 maxd = max_ff(b, 1e-8f);
1335                 levf = ((float)M_LOG2E) * logf(maxd);
1336
1337                 curmap = 0;
1338                 maxlev = 1;
1339                 mipmaps[0] = ibuf;
1340                 while (curmap < IB_MIPMAP_LEVELS) {
1341                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1342                         if (ibuf->mipmap[curmap]) maxlev++;
1343                         curmap++;
1344                 }
1345
1346                 /* mipmap level */
1347                 if (levf < 0.f) {  /* original image only */
1348                         previbuf = curibuf = mipmaps[0];
1349                         levf = 0.f;
1350                 }
1351                 else if (levf >= maxlev - 1) {
1352                         previbuf = curibuf = mipmaps[maxlev - 1];
1353                         levf = 0.f;
1354                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1355                 }
1356                 else {
1357                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1358                         curibuf = mipmaps[lev];
1359                         previbuf = mipmaps[lev + 1];
1360                         levf -= floorf(levf);
1361                 }
1362
1363                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1364
1365                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1366                         /* color & normal */
1367                         filterfunc(texres, curibuf, fx, fy, &AFD);
1368                         val1 = texres->tr + texres->tg + texres->tb;
1369                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1370                         val2 = texr.tr + texr.tg + texr.tb;
1371                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1372                         val3 = texr.tr + texr.tg + texr.tb;
1373                         /* don't switch x or y! */
1374                         texres->nor[0] = val1 - val2;
1375                         texres->nor[1] = val1 - val3;
1376                         if (previbuf != curibuf) {  /* interpolate */
1377                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1378                                 /* rgb */
1379                                 texres->tr += levf*(texr.tr - texres->tr);
1380                                 texres->tg += levf*(texr.tg - texres->tg);
1381                                 texres->tb += levf*(texr.tb - texres->tb);
1382                                 texres->ta += levf*(texr.ta - texres->ta);
1383                                 /* normal */
1384                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1385                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1386                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1387                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1388                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1389                                 texres->nor[0] = val1 - val2;  /* vals have been interpolated above! */
1390                                 texres->nor[1] = val1 - val3;
1391                         }
1392                 }
1393                 else {  /* color */
1394                         filterfunc(texres, curibuf, fx, fy, &AFD);
1395                         if (previbuf != curibuf) {  /* interpolate */
1396                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1397                                 texres->tr += levf*(texr.tr - texres->tr);
1398                                 texres->tg += levf*(texr.tg - texres->tg);
1399                                 texres->tb += levf*(texr.tb - texres->tb);
1400                                 texres->ta += levf*(texr.ta - texres->ta);
1401                         }
1402
1403                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1404                 }
1405         }
1406         else {  /* no mipmap */
1407                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1408                 if (tex->texfilter == TXF_FELINE) {
1409                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1410                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1411                         const float A = Vx*Vx + Vy*Vy;
1412                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1413                         const float C = Ux*Ux + Uy*Uy;
1414                         const float F = A*C - B*B*0.25f;
1415                         float a, b, th, ecc, fProbes;
1416                         imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1417                         a *= ff;
1418                         b *= ff;
1419                         a = max_ff(a, 1.0f);
1420                         b = max_ff(b, 1.0f);
1421                         fProbes = 2.f*(a / b) - 1.f;
1422                         /* no limit to number of Probes here */
1423                         AFD.iProbes = (int)floorf(fProbes + 0.5f);
1424                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1425                         AFD.majrad = a/ff;
1426                         AFD.minrad = b/ff;
1427                         AFD.theta = th;
1428                         AFD.dusc = 1.f/ff;
1429                         AFD.dvsc = ff / (float)ibuf->y;
1430                 }
1431                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1432                         /* color & normal */
1433                         filterfunc(texres, ibuf, fx, fy, &AFD);
1434                         val1 = texres->tr + texres->tg + texres->tb;
1435                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1436                         val2 = texr.tr + texr.tg + texr.tb;
1437                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1438                         val3 = texr.tr + texr.tg + texr.tb;
1439                         /* don't switch x or y! */
1440                         texres->nor[0] = val1 - val2;
1441                         texres->nor[1] = val1 - val3;
1442                 }
1443                 else {
1444                         filterfunc(texres, ibuf, fx, fy, &AFD);
1445                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1446                 }
1447         }
1448
1449         if (tex->imaflag & TEX_CALCALPHA)
1450                 texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
1451         else
1452                 texres->tin = texres->ta;
1453         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1454         
1455         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1456                 ibuf->rect -= ibuf->x*ibuf->y;
1457
1458         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    /* normal from color */
1459                 /* The invert of the red channel is to make
1460                  * the normal map compliant with the outside world.
1461                  * It needs to be done because in Blender
1462                  * the normal used in the renderer points inward. It is generated
1463                  * this way in calc_vertexnormals(). Should this ever change
1464                  * this negate must be removed. */
1465                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1466                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1467                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1468         }
1469
1470         /* de-premul, this is being premulled in shade_input_do_shade()
1471          * TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1472          * also disabled in imagewraposa() to be able to compare results with blender's default texture filtering */
1473
1474         /* brecht: tried to fix this, see "TXF alpha" comments */
1475
1476         /* do not de-premul for generated alpha, it is already in straight */
1477         if (texres->ta!=1.0f && texres->ta>1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
1478                 fx = 1.f/texres->ta;
1479                 texres->tr *= fx;
1480                 texres->tg *= fx;
1481                 texres->tb *= fx;
1482         }
1483
1484         if (ima)
1485                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1486
1487         BRICONTRGB;
1488         
1489         return retval;
1490 }
1491
1492
1493 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)
1494 {
1495         TexResult texr;
1496         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
1497         float maxd, pixsize, val1, val2, val3;
1498         int curmap, retval, imaprepeat, imapextend;
1499
1500         /* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1501          * make a local copy here so that original vecs remain untouched */
1502         copy_v2_v2(dxt, DXT);
1503         copy_v2_v2(dyt, DYT);
1504
1505         /* anisotropic filtering */
1506         if (tex->texfilter != TXF_BOX)
1507                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool);
1508
1509         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1510         
1511         /* we need to set retval OK, otherwise texture code generates normals itself... */
1512         retval = texres->nor ? 3 : 1;
1513         
1514         /* quick tests */
1515         if (ibuf==NULL && ima==NULL)
1516                 return retval;
1517         if (ima) {
1518
1519                 /* hack for icon render */
1520                 if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
1521                         return retval;
1522                 
1523                 ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
1524
1525                 ima->flag|= IMA_USED_FOR_RENDER;
1526         }
1527         if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
1528                 if (ima)
1529                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1530                 return retval;
1531         }
1532         
1533         /* mipmap test */
1534         image_mipmap_test(tex, ibuf);
1535
1536         if (ima) {
1537                 if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
1538                         if ((tex->imaflag & TEX_CALCALPHA) == 0) {
1539                                 texres->talpha = TRUE;
1540                         }
1541                 }
1542         }
1543         
1544         texr.talpha= texres->talpha;
1545         
1546         if (tex->imaflag & TEX_IMAROT) {
1547                 fy= texvec[0];
1548                 fx= texvec[1];
1549         }
1550         else {
1551                 fx= texvec[0];
1552                 fy= texvec[1];
1553         }
1554         
1555         if (ibuf->flags & IB_fields) {
1556                 if (R.r.mode & R_FIELDS) {                      /* field render */
1557                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1558                                 /* fac1= 0.5/( (float)ibuf->y ); */
1559                                 /* fy-= fac1; */
1560                         }
1561                         else {                          /* first field */
1562                                 fy+= 0.5f/( (float)ibuf->y );
1563                         }
1564                 }
1565         }
1566         
1567         /* pixel coordinates */
1568
1569         minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1570         maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1571         miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1572         maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1573
1574         /* tex_sharper has been removed */
1575         minx= (maxx-minx)/2.0f;
1576         miny= (maxy-miny)/2.0f;
1577         
1578         if (tex->imaflag & TEX_FILTER_MIN) {
1579                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1580                 float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1581
1582                 if (addval > minx)
1583                         minx= addval;
1584                 if (addval > miny)
1585                         miny= addval;
1586         }
1587         else if (tex->filtersize!=1.0f) {
1588                 minx*= tex->filtersize;
1589                 miny*= tex->filtersize;
1590                 
1591                 dxt[0]*= tex->filtersize;
1592                 dxt[1]*= tex->filtersize;
1593                 dyt[0]*= tex->filtersize;
1594                 dyt[1]*= tex->filtersize;
1595         }
1596
1597         if (tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1598         
1599         if (minx>0.25f) minx= 0.25f;
1600         else if (minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
1601         if (miny>0.25f) miny= 0.25f;
1602         else if (miny<0.00001f) miny= 0.00001f;
1603
1604         
1605         /* repeat and clip */
1606         imaprepeat= (tex->extend==TEX_REPEAT);
1607         imapextend= (tex->extend==TEX_EXTEND);
1608
1609         if (tex->extend == TEX_REPEAT) {
1610                 if (tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1611                         imaprepeat= 0;
1612                         imapextend= 1;
1613                 }
1614         }
1615
1616         if (tex->extend == TEX_CHECKER) {
1617                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1618                 
1619                 xs= (int)floor(fx);
1620                 ys= (int)floor(fy);
1621                 
1622                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1623                 if ( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1624                         fx-= xs;
1625                         fy-= ys;
1626                 }
1627                 else {
1628                         
1629                         xs1= (int)floor(fx-minx);
1630                         ys1= (int)floor(fy-miny);
1631                         xs2= (int)floor(fx+minx);
1632                         ys2= (int)floor(fy+miny);
1633                         boundary= (xs1!=xs2) || (ys1!=ys2);
1634
1635                         if (boundary==0) {
1636                                 if ( (tex->flag & TEX_CHECKER_ODD)==0) {
1637                                         if ((xs + ys) & 1) {
1638                                                 /* pass */
1639                                         }
1640                                         else {
1641                                                 if (ima)
1642                                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1643                                                 return retval;
1644                                         }
1645                                 }
1646                                 if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
1647                                         if ((xs + ys) & 1) {
1648                                                 if (ima)
1649                                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1650                                                 return retval;
1651                                         }
1652                                 }
1653                                 fx-= xs;
1654                                 fy-= ys;
1655                         }
1656                         else {
1657                                 if (tex->flag & TEX_CHECKER_ODD) {
1658                                         if ((xs1+ys) & 1) fx-= xs2;
1659                                         else fx-= xs1;
1660                                         
1661                                         if ((ys1+xs) & 1) fy-= ys2;
1662                                         else fy-= ys1;
1663                                 }
1664                                 if (tex->flag & TEX_CHECKER_EVEN) {
1665                                         if ((xs1+ys) & 1) fx-= xs1;
1666                                         else fx-= xs2;
1667                                         
1668                                         if ((ys1+xs) & 1) fy-= ys1;
1669                                         else fy-= ys2;
1670                                 }
1671                         }
1672                 }
1673
1674                 /* scale around center, (0.5, 0.5) */
1675                 if (tex->checkerdist<1.0f) {
1676                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1677                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1678                         minx/= (1.0f-tex->checkerdist);
1679                         miny/= (1.0f-tex->checkerdist);
1680                 }
1681         }
1682
1683         if (tex->extend == TEX_CLIPCUBE) {
1684                 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) {
1685                         if (ima)
1686                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1687                         return retval;
1688                 }
1689         }
1690         else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1691                 if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
1692                         if (ima)
1693                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1694                         return retval;
1695                 }
1696         }
1697         else {
1698                 if (imapextend) {
1699                         if (fx>1.0f) fx = 1.0f;
1700                         else if (fx<0.0f) fx= 0.0f;
1701                 }
1702                 else {
1703                         if (fx>1.0f) fx -= (int)(fx);
1704                         else if (fx<0.0f) fx+= 1-(int)(fx);
1705                 }
1706                 
1707                 if (imapextend) {
1708                         if (fy>1.0f) fy = 1.0f;
1709                         else if (fy<0.0f) fy= 0.0f;
1710                 }
1711                 else {
1712                         if (fy>1.0f) fy -= (int)(fy);
1713                         else if (fy<0.0f) fy+= 1-(int)(fy);
1714                 }
1715         }
1716
1717         /* warning no return! */
1718         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1719                 ibuf->rect+= (ibuf->x*ibuf->y);
1720         }
1721
1722         /* choice:  */
1723         if (tex->imaflag & TEX_MIPMAP) {
1724                 ImBuf *previbuf, *curibuf;
1725                 float bumpscale;
1726                 
1727                 dx = minx;
1728                 dy = miny;
1729                 maxd = max_ff(dx, dy);
1730                 if (maxd > 0.5f) maxd = 0.5f;
1731
1732                 pixsize = 1.0f / (float) MIN2(ibuf->x, ibuf->y);
1733                 
1734                 bumpscale= pixsize/maxd;
1735                 if (bumpscale>1.0f) bumpscale= 1.0f;
1736                 else bumpscale*=bumpscale;
1737                 
1738                 curmap= 0;
1739                 previbuf= curibuf= ibuf;
1740                 while (curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1741                         if (maxd < pixsize) break;
1742                         previbuf= curibuf;
1743                         curibuf= ibuf->mipmap[curmap];
1744                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1745                         curmap++;
1746                 }
1747
1748                 if (previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1749                         /* sample at least 1 pixel */
1750                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1751                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1752                 }
1753                 
1754                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1755                         /* a bit extra filter */
1756                         //minx*= 1.35f;
1757                         //miny*= 1.35f;
1758                         
1759                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1760                         val1= texres->tr+texres->tg+texres->tb;
1761                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1762                         val2= texr.tr + texr.tg + texr.tb;
1763                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1764                         val3= texr.tr + texr.tg + texr.tb;
1765
1766                         /* don't switch x or y! */
1767                         texres->nor[0]= (val1-val2);
1768                         texres->nor[1]= (val1-val3);
1769                         
1770                         if (previbuf!=curibuf) {  /* interpolate */
1771                                 
1772                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1773                                 
1774                                 /* calc rgb */
1775                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1776                                 if (dx>=1.0f) {
1777                                         texres->ta= texr.ta; texres->tb= texr.tb;
1778                                         texres->tg= texr.tg; texres->tr= texr.tr;
1779                                 }
1780                                 else {
1781                                         dy= 1.0f-dx;
1782                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1783                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1784                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1785                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1786                                 }
1787                                 
1788                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1789                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1790                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1791                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1792                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1793                                 
1794                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1795                                 texres->nor[1]= (val1-val3);
1796                                 
1797                                 if (dx<1.0f) {
1798                                         dy= 1.0f-dx;
1799                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1800                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1801                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1802                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1803                                 }
1804                         }
1805                         texres->nor[0]*= bumpscale;
1806                         texres->nor[1]*= bumpscale;
1807                 }
1808                 else {
1809                         maxx= fx+minx;
1810                         minx= fx-minx;
1811                         maxy= fy+miny;
1812                         miny= fy-miny;
1813
1814                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1815
1816                         if (previbuf!=curibuf) {  /* interpolate */
1817                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1818                                 
1819                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1820                                 
1821                                 if (fx>=1.0f) {
1822                                         texres->ta= texr.ta; texres->tb= texr.tb;
1823                                         texres->tg= texr.tg; texres->tr= texr.tr;
1824                                 }
1825                                 else {
1826                                         fy= 1.0f-fx;
1827                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1828                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1829                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1830                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1831                                 }
1832                         }
1833                 }
1834         }
1835         else {
1836                 const int intpol = tex->imaflag & TEX_INTERPOL;
1837                 if (intpol) {
1838                         /* sample 1 pixel minimum */
1839                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1840                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1841                 }
1842
1843                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1844                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1845                         val1= texres->tr+texres->tg+texres->tb;
1846                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1847                         val2= texr.tr + texr.tg + texr.tb;
1848                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1849                         val3= texr.tr + texr.tg + texr.tb;
1850
1851                         /* don't switch x or y! */
1852                         texres->nor[0]= (val1-val2);
1853                         texres->nor[1]= (val1-val3);
1854                 }
1855                 else
1856                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1857         }
1858         
1859         if (tex->imaflag & TEX_CALCALPHA) {
1860                 texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
1861         }
1862         else {
1863                 texres->tin = texres->ta;
1864         }
1865
1866         if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1867         
1868         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1869                 ibuf->rect-= (ibuf->x*ibuf->y);
1870         }
1871
1872         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1873                 /* qdn: normal from color
1874                  * The invert of the red channel is to make
1875                  * the normal map compliant with the outside world.
1876                  * It needs to be done because in Blender
1877                  * the normal used in the renderer points inward. It is generated
1878                  * this way in calc_vertexnormals(). Should this ever change
1879                  * this negate must be removed. */
1880                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1881                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1882                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1883         }
1884
1885         /* de-premul, this is being premulled in shade_input_do_shade() */
1886         /* do not de-premul for generated alpha, it is already in straight */
1887         if (texres->ta!=1.0f && texres->ta>1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
1888                 mul_v3_fl(&texres->tr, 1.0f / texres->ta);
1889         }
1890
1891         if (ima)
1892                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1893
1894         BRICONTRGB;
1895         
1896         return retval;
1897 }
1898
1899 void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool)
1900 {
1901         TexResult texres;
1902         ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool);
1903         
1904         if (UNLIKELY(ibuf == NULL)) {
1905                 zero_v4(result);
1906                 return;
1907         }
1908         
1909         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1910                 ibuf->rect+= (ibuf->x*ibuf->y);
1911
1912         texres.talpha = TRUE; /* boxsample expects to be initialized */
1913         boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
1914         copy_v4_v4(result, &texres.tr);
1915         
1916         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1917                 ibuf->rect-= (ibuf->x*ibuf->y);
1918
1919         ima->flag|= IMA_USED_FOR_RENDER;
1920
1921         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1922 }
1923
1924 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
1925 {
1926         TexResult texres = {0};
1927         afdata_t AFD;
1928
1929         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1930         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1931         //copy_v2_v2(AFD.dxt, dx);
1932         //copy_v2_v2(AFD.dyt, dy);
1933         
1934         AFD.intpol = 1;
1935         AFD.extflag = TXC_EXTD;
1936
1937         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1938         
1939         copy_v4_v4(result, &texres.tr);
1940 }