De-duplicate EWA filter code between renderer and compositor
[blender-staging.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 "IMB_imbuf_types.h"
42 #include "IMB_imbuf.h"
43
44 #include "DNA_image_types.h"
45 #include "DNA_scene_types.h"
46 #include "DNA_texture_types.h"
47
48 #include "BLI_math.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_threads.h"
51 #include "BLI_utildefines.h"
52
53 #include "BKE_main.h"
54 #include "BKE_image.h"
55
56 #include "RE_render_ext.h"
57
58 #include "renderpipeline.h"
59 #include "render_types.h"
60 #include "texture.h"
61
62 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
63 /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
64 /* only to be used here in this file, it's for speed */
65 extern struct Render R;
66 /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
67
68 static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend);
69
70 /* *********** IMAGEWRAPPING ****************** */
71
72
73 /* x and y have to be checked for image size */
74 static void ibuf_get_color(float col[4], struct ImBuf *ibuf, int x, int y)
75 {
76         int ofs = y * ibuf->x + x;
77         
78         if (ibuf->rect_float) {
79                 if (ibuf->channels==4) {
80                         const float *fp= ibuf->rect_float + 4*ofs;
81                         copy_v4_v4(col, fp);
82                 }
83                 else if (ibuf->channels==3) {
84                         const float *fp= ibuf->rect_float + 3*ofs;
85                         copy_v3_v3(col, fp);
86                         col[3]= 1.0f;
87                 }
88                 else {
89                         const float *fp= ibuf->rect_float + ofs;
90                         col[0]= col[1]= col[2]= col[3]= *fp;
91                 }
92         }
93         else {
94                 const char *rect = (char *)( ibuf->rect+ ofs);
95
96                 col[0] = ((float)rect[0])*(1.0f/255.0f);
97                 col[1] = ((float)rect[1])*(1.0f/255.0f);
98                 col[2] = ((float)rect[2])*(1.0f/255.0f);
99                 col[3] = ((float)rect[3])*(1.0f/255.0f);
100
101                 /* bytes are internally straight, however render pipeline seems to expect premul */
102                 col[0] *= col[3];
103                 col[1] *= col[3];
104                 col[2] *= col[3];
105         }
106 }
107
108 int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResult *texres, struct ImagePool *pool)
109 {
110         float fx, fy, val1, val2, val3;
111         int x, y, retval;
112         int xi, yi; /* original values */
113
114         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
115         
116         /* we need to set retval OK, otherwise texture code generates normals itself... */
117         retval= texres->nor ? 3 : 1;
118         
119         /* quick tests */
120         if (ibuf==NULL && ima==NULL)
121                 return retval;
122         if (ima) {
123                 
124                 /* hack for icon render */
125                 if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
126                         return retval;
127
128                 ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
129
130                 ima->flag|= IMA_USED_FOR_RENDER;
131         }
132         if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
133                 if (ima)
134                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
135                 return retval;
136         }
137         
138         /* setup mapping */
139         if (tex->imaflag & TEX_IMAROT) {
140                 fy= texvec[0];
141                 fx= texvec[1];
142         }
143         else {
144                 fx= texvec[0];
145                 fy= texvec[1];
146         }
147         
148         if (tex->extend == TEX_CHECKER) {
149                 int xs, ys;
150                 
151                 xs= (int)floor(fx);
152                 ys= (int)floor(fy);
153                 fx-= xs;
154                 fy-= ys;
155
156                 if ( (tex->flag & TEX_CHECKER_ODD) == 0) {
157                         if ((xs + ys) & 1) {
158                                 /* pass */
159                         }
160                         else {
161                                 if (ima)
162                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
163                                 return retval;
164                         }
165                 }
166                 if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
167                         if ((xs+ys) & 1) {
168                                 if (ima)
169                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
170                                 return retval;
171                         }
172                 }
173                 /* scale around center, (0.5, 0.5) */
174                 if (tex->checkerdist<1.0f) {
175                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
176                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
177                 }
178         }
179
180         x= xi= (int)floorf(fx*ibuf->x);
181         y= yi= (int)floorf(fy*ibuf->y);
182
183         if (tex->extend == TEX_CLIPCUBE) {
184                 if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0f || texvec[2]>1.0f) {
185                         if (ima)
186                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
187                         return retval;
188                 }
189         }
190         else if ( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
191                 if (x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
192                         if (ima)
193                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
194                         return retval;
195                 }
196         }
197         else {
198                 if (tex->extend==TEX_EXTEND) {
199                         if (x>=ibuf->x) x = ibuf->x-1;
200                         else if (x<0) x= 0;
201                 }
202                 else {
203                         x= x % ibuf->x;
204                         if (x<0) x+= ibuf->x;
205                 }
206                 if (tex->extend==TEX_EXTEND) {
207                         if (y>=ibuf->y) y = ibuf->y-1;
208                         else if (y<0) y= 0;
209                 }
210                 else {
211                         y= y % ibuf->y;
212                         if (y<0) y+= ibuf->y;
213                 }
214         }
215         
216         /* warning, no return before setting back! */
217         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
218                 ibuf->rect+= (ibuf->x*ibuf->y);
219         }
220
221         /* keep this before interpolation [#29761] */
222         if (ima) {
223                 if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
224                         if ((tex->imaflag & TEX_CALCALPHA) == 0) {
225                                 texres->talpha = true;
226                         }
227                 }
228         }
229
230         /* interpolate */
231         if (tex->imaflag & TEX_INTERPOL) {
232                 float filterx, filtery;
233                 filterx = (0.5f * tex->filtersize) / ibuf->x;
234                 filtery = (0.5f * tex->filtersize) / ibuf->y;
235
236                 /* important that this value is wrapped [#27782]
237                  * this applies the modifications made by the checks above,
238                  * back to the floating point values */
239                 fx -= (float)(xi - x) / (float)ibuf->x;
240                 fy -= (float)(yi - y) / (float)ibuf->y;
241
242                 boxsample(ibuf, fx-filterx, fy-filtery, fx+filterx, fy+filtery, texres, (tex->extend==TEX_REPEAT), (tex->extend==TEX_EXTEND));
243         }
244         else { /* no filtering */
245                 ibuf_get_color(&texres->tr, ibuf, x, y);
246         }
247         
248         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
249                 ibuf->rect-= (ibuf->x*ibuf->y);
250         }
251
252         if (texres->nor) {
253                 if (tex->imaflag & TEX_NORMALMAP) {
254                         /* qdn: normal from color
255                          * The invert of the red channel is to make
256                          * the normal map compliant with the outside world.
257                          * It needs to be done because in Blender
258                          * the normal used in the renderer points inward. It is generated
259                          * this way in calc_vertexnormals(). Should this ever change
260                          * this negate must be removed. */
261                         texres->nor[0] = -2.f*(texres->tr - 0.5f);
262                         texres->nor[1] = 2.f*(texres->tg - 0.5f);
263                         texres->nor[2] = 2.f*(texres->tb - 0.5f);
264                 }
265                 else {
266                         /* bump: take three samples */
267                         val1= texres->tr+texres->tg+texres->tb;
268
269                         if (x<ibuf->x-1) {
270                                 float col[4];
271                                 ibuf_get_color(col, ibuf, x+1, y);
272                                 val2= (col[0]+col[1]+col[2]);
273                         }
274                         else {
275                                 val2= val1;
276                         }
277
278                         if (y<ibuf->y-1) {
279                                 float col[4];
280                                 ibuf_get_color(col, ibuf, x, y+1);
281                                 val3 = (col[0]+col[1]+col[2]);
282                         }
283                         else {
284                                 val3 = val1;
285                         }
286
287                         /* do not mix up x and y here! */
288                         texres->nor[0]= (val1-val2);
289                         texres->nor[1]= (val1-val3);
290                 }
291         }
292
293         if (texres->talpha) {
294                 texres->tin = texres->ta;
295         }
296         else if (tex->imaflag & TEX_CALCALPHA) {
297                 texres->ta = texres->tin = max_fff(texres->tr, texres->tg, texres->tb);
298         }
299         else {
300                 texres->ta = texres->tin = 1.0;
301         }
302         
303         if (tex->flag & TEX_NEGALPHA) {
304                 texres->ta = 1.0f - texres->ta;
305         }
306
307         /* de-premul, this is being premulled in shade_input_do_shade()
308          * do not de-premul for generated alpha, it is already in straight */
309         if (texres->ta!=1.0f && texres->ta>1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
310                 fx= 1.0f/texres->ta;
311                 texres->tr*= fx;
312                 texres->tg*= fx;
313                 texres->tb*= fx;
314         }
315
316         if (ima)
317                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
318
319         BRICONTRGB;
320         
321         return retval;
322 }
323
324 static void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
325 {
326         rctf *rf, *newrct;
327         short a;
328
329         a= *count;
330         rf= stack;
331         for (;a>0;a--) {
332                 if (rf->xmin<x1) {
333                         if (rf->xmax<x1) {
334                                 rf->xmin+= (x2-x1);
335                                 rf->xmax+= (x2-x1);
336                         }
337                         else {
338                                 if (rf->xmax>x2) rf->xmax = x2;
339                                 newrct= stack+ *count;
340                                 (*count)++;
341
342                                 newrct->xmax = x2;
343                                 newrct->xmin = rf->xmin+(x2-x1);
344                                 newrct->ymin = rf->ymin;
345                                 newrct->ymax = rf->ymax;
346                                 
347                                 if (newrct->xmin ==newrct->xmax) (*count)--;
348                                 
349                                 rf->xmin = x1;
350                         }
351                 }
352                 else if (rf->xmax>x2) {
353                         if (rf->xmin>x2) {
354                                 rf->xmin-= (x2-x1);
355                                 rf->xmax-= (x2-x1);
356                         }
357                         else {
358                                 if (rf->xmin<x1) rf->xmin = x1;
359                                 newrct= stack+ *count;
360                                 (*count)++;
361
362                                 newrct->xmin = x1;
363                                 newrct->xmax = rf->xmax-(x2-x1);
364                                 newrct->ymin = rf->ymin;
365                                 newrct->ymax = rf->ymax;
366
367                                 if (newrct->xmin ==newrct->xmax) (*count)--;
368
369                                 rf->xmax = x2;
370                         }
371                 }
372                 rf++;
373         }
374
375 }
376
377 static void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2)
378 {
379         rctf *rf, *newrct;
380         short a;
381
382         a= *count;
383         rf= stack;
384         for (;a>0;a--) {
385                 if (rf->ymin<y1) {
386                         if (rf->ymax<y1) {
387                                 rf->ymin+= (y2-y1);
388                                 rf->ymax+= (y2-y1);
389                         }
390                         else {
391                                 if (rf->ymax>y2) rf->ymax = y2;
392                                 newrct= stack+ *count;
393                                 (*count)++;
394
395                                 newrct->ymax = y2;
396                                 newrct->ymin = rf->ymin+(y2-y1);
397                                 newrct->xmin = rf->xmin;
398                                 newrct->xmax = rf->xmax;
399
400                                 if (newrct->ymin==newrct->ymax) (*count)--;
401
402                                 rf->ymin = y1;
403                         }
404                 }
405                 else if (rf->ymax>y2) {
406                         if (rf->ymin>y2) {
407                                 rf->ymin-= (y2-y1);
408                                 rf->ymax-= (y2-y1);
409                         }
410                         else {
411                                 if (rf->ymin<y1) rf->ymin = y1;
412                                 newrct= stack+ *count;
413                                 (*count)++;
414
415                                 newrct->ymin = y1;
416                                 newrct->ymax = rf->ymax-(y2-y1);
417                                 newrct->xmin = rf->xmin;
418                                 newrct->xmax = rf->xmax;
419
420                                 if (newrct->ymin==newrct->ymax) (*count)--;
421
422                                 rf->ymax = y2;
423                         }
424                 }
425                 rf++;
426         }
427 }
428
429 static float square_rctf(rctf *rf)
430 {
431         float x, y;
432
433         x = BLI_rctf_size_x(rf);
434         y = BLI_rctf_size_y(rf);
435         return x * y;
436 }
437
438 static float clipx_rctf(rctf *rf, float x1, float x2)
439 {
440         float size;
441
442         size = BLI_rctf_size_x(rf);
443
444         if (rf->xmin<x1) {
445                 rf->xmin = x1;
446         }
447         if (rf->xmax>x2) {
448                 rf->xmax = x2;
449         }
450         if (rf->xmin > rf->xmax) {
451                 rf->xmin = rf->xmax;
452                 return 0.0;
453         }
454         else if (size != 0.0f) {
455                 return BLI_rctf_size_x(rf) / size;
456         }
457         return 1.0;
458 }
459
460 static float clipy_rctf(rctf *rf, float y1, float y2)
461 {
462         float size;
463
464         size = BLI_rctf_size_y(rf);
465
466         if (rf->ymin<y1) {
467                 rf->ymin = y1;
468         }
469         if (rf->ymax>y2) {
470                 rf->ymax = y2;
471         }
472
473         if (rf->ymin > rf->ymax) {
474                 rf->ymin = rf->ymax;
475                 return 0.0;
476         }
477         else if (size != 0.0f) {
478                 return BLI_rctf_size_y(rf) / size;
479         }
480         return 1.0;
481
482 }
483
484 static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres)
485 {
486         /* sample box, is clipped already, and minx etc. have been set at ibuf size.
487          * Enlarge with antialiased edges of the pixels */
488
489         float muly, mulx, div, col[4];
490         int x, y, startx, endx, starty, endy;
491
492         startx= (int)floor(rf->xmin);
493         endx= (int)floor(rf->xmax);
494         starty= (int)floor(rf->ymin);
495         endy= (int)floor(rf->ymax);
496
497         if (startx < 0) startx= 0;
498         if (starty < 0) starty= 0;
499         if (endx>=ibuf->x) endx= ibuf->x-1;
500         if (endy>=ibuf->y) endy= ibuf->y-1;
501
502         if (starty==endy && startx==endx) {
503                 ibuf_get_color(&texres->tr, ibuf, startx, starty);
504         }
505         else {
506                 div= texres->tr= texres->tg= texres->tb= texres->ta= 0.0;
507                 for (y=starty; y<=endy; y++) {
508                         
509                         muly= 1.0;
510
511                         if (starty==endy) {
512                                 /* pass */
513                         }
514                         else {
515                                 if (y==starty) muly= 1.0f-(rf->ymin - y);
516                                 if (y==endy) muly= (rf->ymax - y);
517                         }
518                         
519                         if (startx==endx) {
520                                 mulx= muly;
521                                 
522                                 ibuf_get_color(col, ibuf, startx, y);
523
524                                 texres->ta+= mulx*col[3];
525                                 texres->tr+= mulx*col[0];
526                                 texres->tg+= mulx*col[1];
527                                 texres->tb+= mulx*col[2];
528                                 div+= mulx;
529                         }
530                         else {
531                                 for (x=startx; x<=endx; x++) {
532                                         mulx= muly;
533                                         if (x==startx) mulx*= 1.0f-(rf->xmin - x);
534                                         if (x==endx) mulx*= (rf->xmax - x);
535
536                                         ibuf_get_color(col, ibuf, x, y);
537                                         
538                                         if (mulx==1.0f) {
539                                                 texres->ta+= col[3];
540                                                 texres->tr+= col[0];
541                                                 texres->tg+= col[1];
542                                                 texres->tb+= col[2];
543                                                 div+= 1.0f;
544                                         }
545                                         else {
546                                                 texres->ta+= mulx*col[3];
547                                                 texres->tr+= mulx*col[0];
548                                                 texres->tg+= mulx*col[1];
549                                                 texres->tb+= mulx*col[2];
550                                                 div+= mulx;
551                                         }
552                                 }
553                         }
554                 }
555
556                 if (div!=0.0f) {
557                         div= 1.0f/div;
558                         texres->tb*= div;
559                         texres->tg*= div;
560                         texres->tr*= div;
561                         texres->ta*= div;
562                 }
563                 else {
564                         texres->tr= texres->tg= texres->tb= texres->ta= 0.0f;
565                 }
566         }
567 }
568
569 static void boxsample(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, TexResult *texres, const short imaprepeat, const short imapextend)
570 {
571         /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 .
572          * Enlarge with antialiased edges of pixels.
573          * If variable 'imaprepeat' has been set, the
574          * clipped-away parts are sampled as well.
575          */
576         /* note: actually minx etc isn't in the proper range... this due to filter size and offset vectors for bump */
577         /* note: talpha must be initialized */
578         /* note: even when 'imaprepeat' is set, this can only repeat once in any direction.
579          * the point which min/max is derived from is assumed to be wrapped */
580         TexResult texr;
581         rctf *rf, stack[8];
582         float opp, tot, alphaclip= 1.0;
583         short count=1;
584
585         rf= stack;
586         rf->xmin = minx*(ibuf->x);
587         rf->xmax = maxx*(ibuf->x);
588         rf->ymin = miny*(ibuf->y);
589         rf->ymax = maxy*(ibuf->y);
590
591         texr.talpha= texres->talpha;    /* is read by boxsample_clip */
592         
593         if (imapextend) {
594                 CLAMP(rf->xmin, 0.0f, ibuf->x-1);
595                 CLAMP(rf->xmax, 0.0f, ibuf->x-1);
596         }
597         else if (imaprepeat)
598                 clipx_rctf_swap(stack, &count, 0.0, (float)(ibuf->x));
599         else {
600                 alphaclip= clipx_rctf(rf, 0.0, (float)(ibuf->x));
601
602                 if (alphaclip<=0.0f) {
603                         texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
604                         return;
605                 }
606         }
607
608         if (imapextend) {
609                 CLAMP(rf->ymin, 0.0f, ibuf->y-1);
610                 CLAMP(rf->ymax, 0.0f, ibuf->y-1);
611         }
612         else if (imaprepeat)
613                 clipy_rctf_swap(stack, &count, 0.0, (float)(ibuf->y));
614         else {
615                 alphaclip*= clipy_rctf(rf, 0.0, (float)(ibuf->y));
616
617                 if (alphaclip<=0.0f) {
618                         texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
619                         return;
620                 }
621         }
622
623         if (count>1) {
624                 tot= texres->tr= texres->tb= texres->tg= texres->ta= 0.0;
625                 while (count--) {
626                         boxsampleclip(ibuf, rf, &texr);
627                         
628                         opp= square_rctf(rf);
629                         tot+= opp;
630
631                         texres->tr+= opp*texr.tr;
632                         texres->tg+= opp*texr.tg;
633                         texres->tb+= opp*texr.tb;
634                         if (texres->talpha) texres->ta+= opp*texr.ta;
635                         rf++;
636                 }
637                 if (tot!= 0.0f) {
638                         texres->tr/= tot;
639                         texres->tg/= tot;
640                         texres->tb/= tot;
641                         if (texres->talpha) texres->ta/= tot;
642                 }
643         }
644         else
645                 boxsampleclip(ibuf, rf, texres);
646
647         if (texres->talpha==0) texres->ta= 1.0;
648         
649         if (alphaclip!=1.0f) {
650                 /* premul it all */
651                 texres->tr*= alphaclip;
652                 texres->tg*= alphaclip;
653                 texres->tb*= alphaclip;
654                 texres->ta*= alphaclip;
655         }
656 }       
657
658 /*-----------------------------------------------------------------------------------------------------------------
659  * from here, some functions only used for the new filtering */
660
661 /* anisotropic filters, data struct used instead of long line of (possibly unused) func args */
662 typedef struct afdata_t {
663         float dxt[2], dyt[2];
664         int intpol, extflag;
665         /* feline only */
666         float majrad, minrad, theta;
667         int iProbes;
668         float dusc, dvsc;
669 } afdata_t;
670
671 /* this only used here to make it easier to pass extend flags as single int */
672 enum {TXC_XMIR = 1, TXC_YMIR, TXC_REPT, TXC_EXTD};
673
674 /* similar to ibuf_get_color() but clips/wraps coords according to repeat/extend flags
675  * returns true if out of range in clipmode */
676 static int ibuf_get_color_clip(float col[4], ImBuf *ibuf, int x, int y, int extflag)
677 {
678         int clip = 0;
679         switch (extflag) {
680                 case TXC_XMIR:  /* y rep */
681                         x %= 2*ibuf->x;
682                         x += x < 0 ? 2*ibuf->x : 0;
683                         x = x >= ibuf->x ? 2*ibuf->x - x - 1 : x;
684                         y %= ibuf->y;
685                         y += y < 0 ? ibuf->y : 0;
686                         break;
687                 case TXC_YMIR:  /* x rep */
688                         x %= ibuf->x;
689                         x += x < 0 ? ibuf->x : 0;
690                         y %= 2*ibuf->y;
691                         y += y < 0 ? 2*ibuf->y : 0;
692                         y = y >= ibuf->y ? 2*ibuf->y - y - 1 : y;
693                         break;
694                 case TXC_EXTD:
695                         x = (x < 0) ? 0 : ((x >= ibuf->x) ? (ibuf->x - 1) : x);
696                         y = (y < 0) ? 0 : ((y >= ibuf->y) ? (ibuf->y - 1) : y);
697                         break;
698                 case TXC_REPT:
699                         x %= ibuf->x;
700                         x += (x < 0) ? ibuf->x : 0;
701                         y %= ibuf->y;
702                         y += (y < 0) ? ibuf->y : 0;
703                         break;
704                 default:
705                 {       /* as extend, if clipped, set alpha to 0.0 */
706                         if (x < 0) { x = 0;  } /* TXF alpha: clip = 1; } */
707                         if (x >= ibuf->x) { x = ibuf->x - 1; } /* TXF alpha:  clip = 1; } */
708                         if (y < 0) { y = 0; } /* TXF alpha:  clip = 1; } */
709                         if (y >= ibuf->y) { y = ibuf->y - 1; } /* TXF alpha:  clip = 1; } */
710                 }
711         }
712
713         if (ibuf->rect_float) {
714                 const float* fp = ibuf->rect_float + (x + y*ibuf->x)*ibuf->channels;
715                 if (ibuf->channels == 1)
716                         col[0] = col[1] = col[2] = col[3] = *fp;
717                 else {
718                         col[0] = fp[0];
719                         col[1] = fp[1];
720                         col[2] = fp[2];
721                         col[3] = clip ? 0.f : (ibuf->channels == 4 ? fp[3] : 1.f);
722                 }
723         }
724         else {
725                 const char *rect = (char *)(ibuf->rect + x + y*ibuf->x);
726                 float inv_alpha_fac = (1.0f / 255.0f) * rect[3] * (1.0f / 255.0f);
727                 col[0] = rect[0] * inv_alpha_fac;
728                 col[1] = rect[1] * inv_alpha_fac;
729                 col[2] = rect[2] * inv_alpha_fac;
730                 col[3] = clip ? 0.f : rect[3]*(1.f/255.f);
731         }
732         return clip;
733 }
734
735 /* as above + bilerp */
736 static int ibuf_get_color_clip_bilerp(float col[4], ImBuf *ibuf, float u, float v, int intpol, int extflag)
737 {
738         if (intpol) {
739                 float c00[4], c01[4], c10[4], c11[4];
740                 const float ufl = floorf(u -= 0.5f), vfl = floorf(v -= 0.5f);
741                 const float uf = u - ufl, vf = v - vfl;
742                 const float w00=(1.f-uf)*(1.f-vf), w10=uf*(1.f-vf), w01=(1.f-uf)*vf, w11=uf*vf;
743                 const int x1 = (int)ufl, y1 = (int)vfl, x2 = x1 + 1, y2 = y1 + 1;
744                 int clip = ibuf_get_color_clip(c00, ibuf, x1, y1, extflag);
745                 clip |= ibuf_get_color_clip(c10, ibuf, x2, y1, extflag);
746                 clip |= ibuf_get_color_clip(c01, ibuf, x1, y2, extflag);
747                 clip |= ibuf_get_color_clip(c11, ibuf, x2, y2, extflag);
748                 col[0] = w00*c00[0] + w10*c10[0] + w01*c01[0] + w11*c11[0];
749                 col[1] = w00*c00[1] + w10*c10[1] + w01*c01[1] + w11*c11[1];
750                 col[2] = w00*c00[2] + w10*c10[2] + w01*c01[2] + w11*c11[2];
751                 col[3] = clip ? 0.f : w00*c00[3] + w10*c10[3] + w01*c01[3] + w11*c11[3];
752                 return clip;
753         }
754         return ibuf_get_color_clip(col, ibuf, (int)u, (int)v, extflag);
755 }
756
757 static void area_sample(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD)
758 {
759         int xs, ys, clip = 0;
760         float tc[4], xsd, ysd, cw = 0.f;
761         const float ux = ibuf->x*AFD->dxt[0], uy = ibuf->y*AFD->dxt[1];
762         const float vx = ibuf->x*AFD->dyt[0], vy = ibuf->y*AFD->dyt[1];
763         int xsam = (int)(0.5f*sqrtf(ux*ux + uy*uy) + 0.5f);
764         int ysam = (int)(0.5f*sqrtf(vx*vx + vy*vy) + 0.5f);
765         const int minsam = AFD->intpol ? 2 : 4;
766         xsam = CLAMPIS(xsam, minsam, ibuf->x*2);
767         ysam = CLAMPIS(ysam, minsam, ibuf->y*2);
768         xsd = 1.f / xsam;
769         ysd = 1.f / ysam;
770         texr->tr = texr->tg = texr->tb = texr->ta = 0.f;
771         for (ys=0; ys<ysam; ++ys) {
772                 for (xs=0; xs<xsam; ++xs) {
773                         const float su = (xs + ((ys & 1) + 0.5f)*0.5f)*xsd - 0.5f;
774                         const float sv = (ys + ((xs & 1) + 0.5f)*0.5f)*ysd - 0.5f;
775                         const float pu = fx + su*AFD->dxt[0] + sv*AFD->dyt[0];
776                         const float pv = fy + su*AFD->dxt[1] + sv*AFD->dyt[1];
777                         const int out = ibuf_get_color_clip_bilerp(tc, ibuf, pu*ibuf->x, pv*ibuf->y, AFD->intpol, AFD->extflag);
778                         clip |= out;
779                         cw += out ? 0.f : 1.f;
780                         texr->tr += tc[0];
781                         texr->tg += tc[1];
782                         texr->tb += tc[2];
783                         texr->ta += texr->talpha ? tc[3] : 0.f;
784                 }
785         }
786         xsd *= ysd;
787         texr->tr *= xsd;
788         texr->tg *= xsd;
789         texr->tb *= xsd;
790         /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
791         texr->ta = texr->talpha ? texr->ta*xsd : (clip ? cw*xsd : 1.f);
792 }
793
794 /* test if a float value is 'nan'
795  * there is a C99 function for this: isnan(), but blender seems to use C90 (according to gcc warns),
796  * and may not be supported by other compilers either */
797 /* TODO(sergey): Consider using isnan(), it's used in the other areas. */
798 #ifndef ISNAN
799 #  define ISNAN(x) ((x) != (x))
800 #endif
801
802 typedef struct ReadEWAData {
803         ImBuf *ibuf;
804         afdata_t *AFD;
805 } ReadEWAData;
806
807 static void ewa_read_pixel_cb(void *userdata, int x, int y, float result[4])
808 {
809         ReadEWAData *data = (ReadEWAData *) userdata;
810         ibuf_get_color_clip(result, data->ibuf, x, y, data->AFD->extflag);
811 }
812
813 static void ewa_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD)
814 {
815         ReadEWAData data;
816         float uv[2] = {fx, fy};
817         data.ibuf = ibuf;
818         data.AFD = AFD;
819         BLI_ewa_filter(ibuf->x, ibuf->y,
820                        AFD->intpol != 0,
821                        texr->talpha,
822                        uv, AFD->dxt, AFD->dyt,
823                        ewa_read_pixel_cb,
824                        &data,
825                        &texr->tr);
826
827 }
828
829 static void feline_eval(TexResult *texr, ImBuf *ibuf, float fx, float fy, afdata_t *AFD)
830 {
831         const int maxn = AFD->iProbes - 1;
832         const float ll = ((AFD->majrad == AFD->minrad) ? 2.f*AFD->majrad : 2.f*(AFD->majrad - AFD->minrad)) / (maxn ? (float)maxn : 1.f);
833         float du = maxn ? cosf(AFD->theta)*ll : 0.f;
834         float dv = maxn ? sinf(AFD->theta)*ll : 0.f;
835         /* const float D = -0.5f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad); */
836         const float D = (EWA_MAXIDX + 1)*0.25f*(du*du + dv*dv) / (AFD->majrad*AFD->majrad);
837         float d; /* TXF alpha: cw = 0.f; */
838         int n; /* TXF alpha: clip = 0; */
839         /* have to use same scaling for du/dv here as for Ux/Vx/Uy/Vy (*after* D calc.) */
840         du *= AFD->dusc;
841         dv *= AFD->dvsc;
842         d = texr->tr = texr->tb = texr->tg = texr->ta = 0.f;
843         for (n=-maxn; n<=maxn; n+=2) {
844                 float tc[4];
845                 const float hn = n*0.5f;
846                 const float u = fx + hn*du, v = fy + hn*dv;
847                 /*const float wt = expf(n*n*D);
848                  * can use ewa table here too */
849                 const float wt = EWA_WTS[(int)(n*n*D)];
850                 /*const int out =*/ ibuf_get_color_clip_bilerp(tc, ibuf, ibuf->x*u, ibuf->y*v, AFD->intpol, AFD->extflag);
851                 /* TXF alpha: clip |= out;
852                  * TXF alpha: cw += out ? 0.f : wt; */
853                 texr->tr += tc[0]*wt;
854                 texr->tg += tc[1]*wt;
855                 texr->tb += tc[2]*wt;
856                 texr->ta += texr->talpha ? tc[3]*wt : 0.f;
857                 d += wt;
858         }
859
860         d = 1.f/d;
861         texr->tr *= d;
862         texr->tg *= d;
863         texr->tb *= d;
864         /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
865         texr->ta = texr->talpha ? texr->ta*d : 1.f; // TXF alpha: (clip ? cw*d : 1.f);
866 }
867 #undef EWA_MAXIDX
868
869 static void alpha_clip_aniso(ImBuf *ibuf, float minx, float miny, float maxx, float maxy, int extflag, TexResult *texres)
870 {
871         float alphaclip;
872         rctf rf;
873
874         /* TXF apha: we're doing the same alphaclip here as boxsample, but i'm doubting
875          * if this is actually correct for the all the filtering algorithms .. */
876
877         if (!(extflag == TXC_REPT || extflag == TXC_EXTD)) {
878                 rf.xmin = minx*(ibuf->x);
879                 rf.xmax = maxx*(ibuf->x);
880                 rf.ymin = miny*(ibuf->y);
881                 rf.ymax = maxy*(ibuf->y);
882
883                 alphaclip  = clipx_rctf(&rf, 0.0, (float)(ibuf->x));
884                 alphaclip *= clipy_rctf(&rf, 0.0, (float)(ibuf->y));
885                 alphaclip  = max_ff(alphaclip, 0.0f);
886
887                 if (alphaclip!=1.0f) {
888                         /* premul it all */
889                         texres->tr*= alphaclip;
890                         texres->tg*= alphaclip;
891                         texres->tb*= alphaclip;
892                         texres->ta*= alphaclip;
893                 }
894         }
895 }
896
897 static void image_mipmap_test(Tex *tex, ImBuf *ibuf)
898 {
899         if (tex->imaflag & TEX_MIPMAP) {
900                 if ((ibuf->flags & IB_fields) == 0) {
901                         
902                         if (ibuf->mipmap[0] && (ibuf->userflags & IB_MIPMAP_INVALID)) {
903                                 BLI_lock_thread(LOCK_IMAGE);
904                                 if (ibuf->userflags & IB_MIPMAP_INVALID) {
905                                         IMB_remakemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
906                                         ibuf->userflags &= ~IB_MIPMAP_INVALID;
907                                 }
908                                 BLI_unlock_thread(LOCK_IMAGE);
909                         }
910                         if (ibuf->mipmap[0] == NULL) {
911                                 BLI_lock_thread(LOCK_IMAGE);
912                                 if (ibuf->mipmap[0] == NULL) 
913                                         IMB_makemipmap(ibuf, tex->imaflag & TEX_GAUSS_MIP);
914                                 BLI_unlock_thread(LOCK_IMAGE);
915                         }
916                         /* if no mipmap could be made, fall back on non-mipmap render */
917                         if (ibuf->mipmap[0] == NULL) {
918                                 tex->imaflag &= ~TEX_MIPMAP;
919                         }
920                 }
921         }
922         
923 }
924
925 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)
926 {
927         TexResult texr;
928         float fx, fy, minx, maxx, miny, maxy;
929         float maxd, val1, val2, val3;
930         int curmap, retval, intpol, extflag = 0;
931         afdata_t AFD;
932
933         void (*filterfunc)(TexResult*, ImBuf*, float, float, afdata_t*);
934         switch (tex->texfilter) {
935                 case TXF_EWA:
936                         filterfunc = ewa_eval;
937                         break;
938                 case TXF_FELINE:
939                         filterfunc = feline_eval;
940                         break;
941                 case TXF_AREA:
942                 default:
943                         filterfunc = area_sample;
944         }
945
946         texres->tin = texres->ta = texres->tr = texres->tg = texres->tb = 0.f;
947
948         /* we need to set retval OK, otherwise texture code generates normals itself... */
949         retval = texres->nor ? 3 : 1;
950
951         /* quick tests */
952         if (ibuf==NULL && ima==NULL) return retval;
953
954         if (ima) {      /* hack for icon render */
955                 if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima)) {
956                         return retval;
957                 }
958                 ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
959         }
960
961         if ((ibuf == NULL) || ((ibuf->rect == NULL) && (ibuf->rect_float == NULL))) {
962                 if (ima)
963                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
964                 return retval;
965         }
966
967         if (ima) {
968                 ima->flag |= IMA_USED_FOR_RENDER;
969         }
970
971         /* mipmap test */
972         image_mipmap_test(tex, ibuf);
973         
974         if (ima) {
975                 if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
976                         if ((tex->imaflag & TEX_CALCALPHA) == 0) {
977                                 texres->talpha = 1;
978                         }
979                 }
980         }
981         texr.talpha = texres->talpha;
982
983         if (tex->imaflag & TEX_IMAROT) {
984                 fy = texvec[0];
985                 fx = texvec[1];
986         }
987         else {
988                 fx = texvec[0];
989                 fy = texvec[1];
990         }
991
992         if (ibuf->flags & IB_fields) {
993                 if (R.r.mode & R_FIELDS) {                      /* field render */
994                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
995                                 /* fac1= 0.5/( (float)ibuf->y ); */
996                                 /* fy-= fac1; */
997                         }
998                         else    /* first field */
999                                 fy += 0.5f/( (float)ibuf->y );
1000                 }
1001         }
1002
1003         /* pixel coordinates */
1004         minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1005         maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1006         miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1007         maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1008
1009         /* tex_sharper has been removed */
1010         minx = (maxx - minx)*0.5f;
1011         miny = (maxy - miny)*0.5f;
1012
1013         if (tex->imaflag & TEX_FILTER_MIN) {
1014                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1015                 const float addval = (0.5f * tex->filtersize) / (float)MIN2(ibuf->x, ibuf->y);
1016                 if (addval > minx) minx = addval;
1017                 if (addval > miny) miny = addval;
1018         }
1019         else if (tex->filtersize != 1.f) {
1020                 minx *= tex->filtersize;
1021                 miny *= tex->filtersize;
1022                 dxt[0] *= tex->filtersize;
1023                 dxt[1] *= tex->filtersize;
1024                 dyt[0] *= tex->filtersize;
1025                 dyt[1] *= tex->filtersize;
1026         }
1027
1028         if (tex->imaflag & TEX_IMAROT) {
1029                 float t;
1030                 SWAP(float, minx, miny);
1031                 /* must rotate dxt/dyt 90 deg
1032                  * yet another blender problem is that swapping X/Y axes (or any tex proj switches) should do something similar,
1033                  * but it doesn't, it only swaps coords, so filter area will be incorrect in those cases. */
1034                 t = dxt[0];
1035                 dxt[0] = dxt[1];
1036                 dxt[1] = -t;
1037                 t = dyt[0];
1038                 dyt[0] = dyt[1];
1039                 dyt[1] = -t;
1040         }
1041
1042         /* side faces of unit-cube */
1043         minx = (minx > 0.25f) ? 0.25f : ((minx < 1e-5f) ? 1e-5f : minx);
1044         miny = (miny > 0.25f) ? 0.25f : ((miny < 1e-5f) ? 1e-5f : miny);
1045
1046         /* repeat and clip */
1047
1048         if (tex->extend == TEX_REPEAT) {
1049                 if ((tex->flag & (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR)) == (TEX_REPEAT_XMIR | TEX_REPEAT_YMIR))
1050                         extflag = TXC_EXTD;
1051                 else if (tex->flag & TEX_REPEAT_XMIR)
1052                         extflag = TXC_XMIR;
1053                 else if (tex->flag & TEX_REPEAT_YMIR)
1054                         extflag = TXC_YMIR;
1055                 else
1056                         extflag = TXC_REPT;
1057         }
1058         else if (tex->extend == TEX_EXTEND)
1059                 extflag = TXC_EXTD;
1060
1061         if (tex->extend == TEX_CHECKER) {
1062                 int xs = (int)floorf(fx), ys = (int)floorf(fy);
1063                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1064                 if ((tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN)) {
1065                         fx -= xs;
1066                         fy -= ys;
1067                 }
1068                 else {
1069                         int xs1 = (int)floorf(fx - minx);
1070                         int ys1 = (int)floorf(fy - miny);
1071                         int xs2 = (int)floorf(fx + minx);
1072                         int ys2 = (int)floorf(fy + miny);
1073                         if ((xs1 != xs2) || (ys1 != ys2)) {
1074                                 if (tex->flag & TEX_CHECKER_ODD) {
1075                                         fx -= ((xs1 + ys) & 1) ? xs2 : xs1;
1076                                         fy -= ((ys1 + xs) & 1) ? ys2 : ys1;
1077                                 }
1078                                 if (tex->flag & TEX_CHECKER_EVEN) {
1079                                         fx -= ((xs1 + ys) & 1) ? xs1 : xs2;
1080                                         fy -= ((ys1 + xs) & 1) ? ys1 : ys2;
1081                                 }
1082                         }
1083                         else {
1084                                 if ((tex->flag & TEX_CHECKER_ODD) == 0 && ((xs + ys) & 1) == 0) {
1085                                         if (ima)
1086                                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1087                                         return retval;
1088                                 }
1089                                 if ((tex->flag & TEX_CHECKER_EVEN) == 0 && (xs + ys) & 1) {
1090                                         if (ima)
1091                                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1092                                         return retval;
1093                                 }
1094                                 fx -= xs;
1095                                 fy -= ys;
1096                         }
1097                 }
1098                 /* scale around center, (0.5, 0.5) */
1099                 if (tex->checkerdist < 1.f) {
1100                         const float omcd = 1.f / (1.f - tex->checkerdist);
1101                         fx = (fx - 0.5f)*omcd + 0.5f;
1102                         fy = (fy - 0.5f)*omcd + 0.5f;
1103                         minx *= omcd;
1104                         miny *= omcd;
1105                 }
1106         }
1107
1108         if (tex->extend == TEX_CLIPCUBE) {
1109                 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) {
1110                         if (ima)
1111                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1112                         return retval;
1113                 }
1114         }
1115         else if (tex->extend == TEX_CLIP || tex->extend == TEX_CHECKER) {
1116                 if ((fx + minx) < 0.f || (fy + miny) < 0.f || (fx - minx) > 1.f || (fy - miny) > 1.f) {
1117                         if (ima)
1118                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1119                         return retval;
1120                 }
1121         }
1122         else {
1123                 if (tex->extend == TEX_EXTEND) {
1124                         fx = (fx > 1.f) ? 1.f : ((fx < 0.f) ? 0.f : fx);
1125                         fy = (fy > 1.f) ? 1.f : ((fy < 0.f) ? 0.f : fy);
1126                 }
1127                 else {
1128                         fx -= floorf(fx);
1129                         fy -= floorf(fy);
1130                 }
1131         }
1132
1133         intpol = tex->imaflag & TEX_INTERPOL;
1134
1135         /* warning no return! */
1136         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1137                 ibuf->rect += ibuf->x*ibuf->y;
1138
1139         /* struct common data */
1140         copy_v2_v2(AFD.dxt, dxt);
1141         copy_v2_v2(AFD.dyt, dyt);
1142         AFD.intpol = intpol;
1143         AFD.extflag = extflag;
1144
1145         /* brecht: added stupid clamping here, large dx/dy can give very large
1146          * filter sizes which take ages to render, it may be better to do this
1147          * more intelligently later in the code .. probably it's not noticeable */
1148         if (AFD.dxt[0]*AFD.dxt[0] + AFD.dxt[1]*AFD.dxt[1] > 2.0f*2.0f)
1149                 mul_v2_fl(AFD.dxt, 2.0f/len_v2(AFD.dxt));
1150         if (AFD.dyt[0]*AFD.dyt[0] + AFD.dyt[1]*AFD.dyt[1] > 2.0f*2.0f)
1151                 mul_v2_fl(AFD.dyt, 2.0f/len_v2(AFD.dyt));
1152
1153         /* choice: */
1154         if (tex->imaflag & TEX_MIPMAP) {
1155                 ImBuf *previbuf, *curibuf;
1156                 float levf;
1157                 int maxlev;
1158                 ImBuf *mipmaps[IB_MIPMAP_LEVELS + 1];
1159
1160                 /* modify ellipse minor axis if too eccentric, use for area sampling as well
1161                  * scaling dxt/dyt as done in pbrt is not the same
1162                  * (as in ewa_eval(), scale by sqrt(ibuf->x) to maximize precision) */
1163                 const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1164                 const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1165                 const float A = Vx*Vx + Vy*Vy;
1166                 const float B = -2.f*(Ux*Vx + Uy*Vy);
1167                 const float C = Ux*Ux + Uy*Uy;
1168                 const float F = A*C - B*B*0.25f;
1169                 float a, b, th, ecc;
1170                 BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1171                 if (tex->texfilter == TXF_FELINE) {
1172                         float fProbes;
1173                         a *= ff;
1174                         b *= ff;
1175                         a = max_ff(a, 1.0f);
1176                         b = max_ff(b, 1.0f);
1177                         fProbes = 2.f*(a / b) - 1.f;
1178                         AFD.iProbes = iroundf(fProbes);
1179                         AFD.iProbes = MIN2(AFD.iProbes, tex->afmax);
1180                         if (AFD.iProbes < fProbes)
1181                                 b = 2.f*a / (float)(AFD.iProbes + 1);
1182                         AFD.majrad = a/ff;
1183                         AFD.minrad = b/ff;
1184                         AFD.theta = th;
1185                         AFD.dusc = 1.f/ff;
1186                         AFD.dvsc = ff / (float)ibuf->y;
1187                 }
1188                 else {  /* EWA & area */
1189                         if (ecc > (float)tex->afmax) b = a / (float)tex->afmax;
1190                         b *= ff;
1191                 }
1192                 maxd = max_ff(b, 1e-8f);
1193                 levf = ((float)M_LOG2E) * logf(maxd);
1194
1195                 curmap = 0;
1196                 maxlev = 1;
1197                 mipmaps[0] = ibuf;
1198                 while (curmap < IB_MIPMAP_LEVELS) {
1199                         mipmaps[curmap + 1] = ibuf->mipmap[curmap];
1200                         if (ibuf->mipmap[curmap]) maxlev++;
1201                         curmap++;
1202                 }
1203
1204                 /* mipmap level */
1205                 if (levf < 0.f) {  /* original image only */
1206                         previbuf = curibuf = mipmaps[0];
1207                         levf = 0.f;
1208                 }
1209                 else if (levf >= maxlev - 1) {
1210                         previbuf = curibuf = mipmaps[maxlev - 1];
1211                         levf = 0.f;
1212                         if (tex->texfilter == TXF_FELINE) AFD.iProbes = 1;
1213                 }
1214                 else {
1215                         const int lev = ISNAN(levf) ? 0 : (int)levf;
1216                         curibuf = mipmaps[lev];
1217                         previbuf = mipmaps[lev + 1];
1218                         levf -= floorf(levf);
1219                 }
1220
1221                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1222
1223                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1224                         /* color & normal */
1225                         filterfunc(texres, curibuf, fx, fy, &AFD);
1226                         val1 = texres->tr + texres->tg + texres->tb;
1227                         filterfunc(&texr, curibuf, fx + dxt[0], fy + dxt[1], &AFD);
1228                         val2 = texr.tr + texr.tg + texr.tb;
1229                         filterfunc(&texr, curibuf, fx + dyt[0], fy + dyt[1], &AFD);
1230                         val3 = texr.tr + texr.tg + texr.tb;
1231                         /* don't switch x or y! */
1232                         texres->nor[0] = val1 - val2;
1233                         texres->nor[1] = val1 - val3;
1234                         if (previbuf != curibuf) {  /* interpolate */
1235                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1236                                 /* rgb */
1237                                 texres->tr += levf*(texr.tr - texres->tr);
1238                                 texres->tg += levf*(texr.tg - texres->tg);
1239                                 texres->tb += levf*(texr.tb - texres->tb);
1240                                 texres->ta += levf*(texr.ta - texres->ta);
1241                                 /* normal */
1242                                 val1 += levf*((texr.tr + texr.tg + texr.tb) - val1);
1243                                 filterfunc(&texr, previbuf, fx + dxt[0], fy + dxt[1], &AFD);
1244                                 val2 += levf*((texr.tr + texr.tg + texr.tb) - val2);
1245                                 filterfunc(&texr, previbuf, fx + dyt[0], fy + dyt[1], &AFD);
1246                                 val3 += levf*((texr.tr + texr.tg + texr.tb) - val3);
1247                                 texres->nor[0] = val1 - val2;  /* vals have been interpolated above! */
1248                                 texres->nor[1] = val1 - val3;
1249                         }
1250                 }
1251                 else {  /* color */
1252                         filterfunc(texres, curibuf, fx, fy, &AFD);
1253                         if (previbuf != curibuf) {  /* interpolate */
1254                                 filterfunc(&texr, previbuf, fx, fy, &AFD);
1255                                 texres->tr += levf*(texr.tr - texres->tr);
1256                                 texres->tg += levf*(texr.tg - texres->tg);
1257                                 texres->tb += levf*(texr.tb - texres->tb);
1258                                 texres->ta += levf*(texr.ta - texres->ta);
1259                         }
1260
1261                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1262                 }
1263         }
1264         else {  /* no mipmap */
1265                 /* filter functions take care of interpolation themselves, no need to modify dxt/dyt here */
1266                 if (tex->texfilter == TXF_FELINE) {
1267                         const float ff = sqrtf(ibuf->x), q = ibuf->y/ff;
1268                         const float Ux = dxt[0]*ff, Vx = dxt[1]*q, Uy = dyt[0]*ff, Vy = dyt[1]*q;
1269                         const float A = Vx*Vx + Vy*Vy;
1270                         const float B = -2.f*(Ux*Vx + Uy*Vy);
1271                         const float C = Ux*Ux + Uy*Uy;
1272                         const float F = A*C - B*B*0.25f;
1273                         float a, b, th, ecc, fProbes;
1274                         BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
1275                         a *= ff;
1276                         b *= ff;
1277                         a = max_ff(a, 1.0f);
1278                         b = max_ff(b, 1.0f);
1279                         fProbes = 2.f*(a / b) - 1.f;
1280                         /* no limit to number of Probes here */
1281                         AFD.iProbes = iroundf(fProbes);
1282                         if (AFD.iProbes < fProbes) b = 2.f*a / (float)(AFD.iProbes + 1);
1283                         AFD.majrad = a/ff;
1284                         AFD.minrad = b/ff;
1285                         AFD.theta = th;
1286                         AFD.dusc = 1.f/ff;
1287                         AFD.dvsc = ff / (float)ibuf->y;
1288                 }
1289                 if (texres->nor && ((tex->imaflag & TEX_NORMALMAP) == 0)) {
1290                         /* color & normal */
1291                         filterfunc(texres, ibuf, fx, fy, &AFD);
1292                         val1 = texres->tr + texres->tg + texres->tb;
1293                         filterfunc(&texr, ibuf, fx + dxt[0], fy + dxt[1], &AFD);
1294                         val2 = texr.tr + texr.tg + texr.tb;
1295                         filterfunc(&texr, ibuf, fx + dyt[0], fy + dyt[1], &AFD);
1296                         val3 = texr.tr + texr.tg + texr.tb;
1297                         /* don't switch x or y! */
1298                         texres->nor[0] = val1 - val2;
1299                         texres->nor[1] = val1 - val3;
1300                 }
1301                 else {
1302                         filterfunc(texres, ibuf, fx, fy, &AFD);
1303                         alpha_clip_aniso(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, extflag, texres);
1304                 }
1305         }
1306
1307         if (tex->imaflag & TEX_CALCALPHA)
1308                 texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
1309         else
1310                 texres->tin = texres->ta;
1311         if (tex->flag & TEX_NEGALPHA) texres->ta = 1.f - texres->ta;
1312         
1313         if ((R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields))
1314                 ibuf->rect -= ibuf->x*ibuf->y;
1315
1316         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {    /* normal from color */
1317                 /* The invert of the red channel is to make
1318                  * the normal map compliant with the outside world.
1319                  * It needs to be done because in Blender
1320                  * the normal used in the renderer points inward. It is generated
1321                  * this way in calc_vertexnormals(). Should this ever change
1322                  * this negate must be removed. */
1323                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1324                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1325                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1326         }
1327
1328         /* de-premul, this is being premulled in shade_input_do_shade()
1329          * TXF: this currently does not (yet?) work properly, destroys edge AA in clip/checker mode, so for now commented out
1330          * also disabled in imagewraposa() to be able to compare results with blender's default texture filtering */
1331
1332         /* brecht: tried to fix this, see "TXF alpha" comments */
1333
1334         /* do not de-premul for generated alpha, it is already in straight */
1335         if (texres->ta!=1.0f && texres->ta>1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
1336                 fx = 1.f/texres->ta;
1337                 texres->tr *= fx;
1338                 texres->tg *= fx;
1339                 texres->tb *= fx;
1340         }
1341
1342         if (ima)
1343                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1344
1345         BRICONTRGB;
1346         
1347         return retval;
1348 }
1349
1350
1351 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)
1352 {
1353         TexResult texr;
1354         float fx, fy, minx, maxx, miny, maxy, dx, dy, dxt[2], dyt[2];
1355         float maxd, pixsize, val1, val2, val3;
1356         int curmap, retval, imaprepeat, imapextend;
1357
1358         /* TXF: since dxt/dyt might be modified here and since they might be needed after imagewraposa() call,
1359          * make a local copy here so that original vecs remain untouched */
1360         copy_v2_v2(dxt, DXT);
1361         copy_v2_v2(dyt, DYT);
1362
1363         /* anisotropic filtering */
1364         if (tex->texfilter != TXF_BOX)
1365                 return imagewraposa_aniso(tex, ima, ibuf, texvec, dxt, dyt, texres, pool);
1366
1367         texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f;
1368         
1369         /* we need to set retval OK, otherwise texture code generates normals itself... */
1370         retval = texres->nor ? 3 : 1;
1371         
1372         /* quick tests */
1373         if (ibuf==NULL && ima==NULL)
1374                 return retval;
1375         if (ima) {
1376
1377                 /* hack for icon render */
1378                 if ((R.r.scemode & R_NO_IMAGE_LOAD) && !BKE_image_has_loaded_ibuf(ima))
1379                         return retval;
1380                 
1381                 ibuf = BKE_image_pool_acquire_ibuf(ima, &tex->iuser, pool);
1382
1383                 ima->flag|= IMA_USED_FOR_RENDER;
1384         }
1385         if (ibuf==NULL || (ibuf->rect==NULL && ibuf->rect_float==NULL)) {
1386                 if (ima)
1387                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1388                 return retval;
1389         }
1390         
1391         /* mipmap test */
1392         image_mipmap_test(tex, ibuf);
1393
1394         if (ima) {
1395                 if ((tex->imaflag & TEX_USEALPHA) && (ima->flag & IMA_IGNORE_ALPHA) == 0) {
1396                         if ((tex->imaflag & TEX_CALCALPHA) == 0) {
1397                                 texres->talpha = true;
1398                         }
1399                 }
1400         }
1401         
1402         texr.talpha= texres->talpha;
1403         
1404         if (tex->imaflag & TEX_IMAROT) {
1405                 fy= texvec[0];
1406                 fx= texvec[1];
1407         }
1408         else {
1409                 fx= texvec[0];
1410                 fy= texvec[1];
1411         }
1412         
1413         if (ibuf->flags & IB_fields) {
1414                 if (R.r.mode & R_FIELDS) {                      /* field render */
1415                         if (R.flag & R_SEC_FIELD) {             /* correction for 2nd field */
1416                                 /* fac1= 0.5/( (float)ibuf->y ); */
1417                                 /* fy-= fac1; */
1418                         }
1419                         else {                          /* first field */
1420                                 fy+= 0.5f/( (float)ibuf->y );
1421                         }
1422                 }
1423         }
1424         
1425         /* pixel coordinates */
1426
1427         minx = min_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1428         maxx = max_fff(dxt[0], dyt[0], dxt[0] + dyt[0]);
1429         miny = min_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1430         maxy = max_fff(dxt[1], dyt[1], dxt[1] + dyt[1]);
1431
1432         /* tex_sharper has been removed */
1433         minx= (maxx-minx)/2.0f;
1434         miny= (maxy-miny)/2.0f;
1435         
1436         if (tex->imaflag & TEX_FILTER_MIN) {
1437                 /* make sure the filtersize is minimal in pixels (normal, ref map can have miniature pixel dx/dy) */
1438                 float addval= (0.5f * tex->filtersize) / (float) MIN2(ibuf->x, ibuf->y);
1439
1440                 if (addval > minx)
1441                         minx= addval;
1442                 if (addval > miny)
1443                         miny= addval;
1444         }
1445         else if (tex->filtersize!=1.0f) {
1446                 minx*= tex->filtersize;
1447                 miny*= tex->filtersize;
1448                 
1449                 dxt[0]*= tex->filtersize;
1450                 dxt[1]*= tex->filtersize;
1451                 dyt[0]*= tex->filtersize;
1452                 dyt[1]*= tex->filtersize;
1453         }
1454
1455         if (tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1456         
1457         if (minx>0.25f) minx= 0.25f;
1458         else if (minx<0.00001f) minx= 0.00001f; /* side faces of unit-cube */
1459         if (miny>0.25f) miny= 0.25f;
1460         else if (miny<0.00001f) miny= 0.00001f;
1461
1462         
1463         /* repeat and clip */
1464         imaprepeat= (tex->extend==TEX_REPEAT);
1465         imapextend= (tex->extend==TEX_EXTEND);
1466
1467         if (tex->extend == TEX_REPEAT) {
1468                 if (tex->flag & (TEX_REPEAT_XMIR|TEX_REPEAT_YMIR)) {
1469                         imaprepeat= 0;
1470                         imapextend= 1;
1471                 }
1472         }
1473
1474         if (tex->extend == TEX_CHECKER) {
1475                 int xs, ys, xs1, ys1, xs2, ys2, boundary;
1476                 
1477                 xs= (int)floor(fx);
1478                 ys= (int)floor(fy);
1479                 
1480                 /* both checkers available, no boundary exceptions, checkerdist will eat aliasing */
1481                 if ( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1482                         fx-= xs;
1483                         fy-= ys;
1484                 }
1485                 else {
1486                         
1487                         xs1= (int)floor(fx-minx);
1488                         ys1= (int)floor(fy-miny);
1489                         xs2= (int)floor(fx+minx);
1490                         ys2= (int)floor(fy+miny);
1491                         boundary= (xs1!=xs2) || (ys1!=ys2);
1492
1493                         if (boundary==0) {
1494                                 if ( (tex->flag & TEX_CHECKER_ODD)==0) {
1495                                         if ((xs + ys) & 1) {
1496                                                 /* pass */
1497                                         }
1498                                         else {
1499                                                 if (ima)
1500                                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1501                                                 return retval;
1502                                         }
1503                                 }
1504                                 if ( (tex->flag & TEX_CHECKER_EVEN)==0) {
1505                                         if ((xs + ys) & 1) {
1506                                                 if (ima)
1507                                                         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1508                                                 return retval;
1509                                         }
1510                                 }
1511                                 fx-= xs;
1512                                 fy-= ys;
1513                         }
1514                         else {
1515                                 if (tex->flag & TEX_CHECKER_ODD) {
1516                                         if ((xs1+ys) & 1) fx-= xs2;
1517                                         else fx-= xs1;
1518                                         
1519                                         if ((ys1+xs) & 1) fy-= ys2;
1520                                         else fy-= ys1;
1521                                 }
1522                                 if (tex->flag & TEX_CHECKER_EVEN) {
1523                                         if ((xs1+ys) & 1) fx-= xs1;
1524                                         else fx-= xs2;
1525                                         
1526                                         if ((ys1+xs) & 1) fy-= ys1;
1527                                         else fy-= ys2;
1528                                 }
1529                         }
1530                 }
1531
1532                 /* scale around center, (0.5, 0.5) */
1533                 if (tex->checkerdist<1.0f) {
1534                         fx= (fx-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1535                         fy= (fy-0.5f)/(1.0f-tex->checkerdist) +0.5f;
1536                         minx/= (1.0f-tex->checkerdist);
1537                         miny/= (1.0f-tex->checkerdist);
1538                 }
1539         }
1540
1541         if (tex->extend == TEX_CLIPCUBE) {
1542                 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) {
1543                         if (ima)
1544                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1545                         return retval;
1546                 }
1547         }
1548         else if (tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1549                 if (fx+minx<0.0f || fy+miny<0.0f || fx-minx>1.0f || fy-miny>1.0f) {
1550                         if (ima)
1551                                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1552                         return retval;
1553                 }
1554         }
1555         else {
1556                 if (imapextend) {
1557                         if (fx>1.0f) fx = 1.0f;
1558                         else if (fx<0.0f) fx= 0.0f;
1559                 }
1560                 else {
1561                         if (fx>1.0f) fx -= (int)(fx);
1562                         else if (fx<0.0f) fx+= 1-(int)(fx);
1563                 }
1564                 
1565                 if (imapextend) {
1566                         if (fy>1.0f) fy = 1.0f;
1567                         else if (fy<0.0f) fy= 0.0f;
1568                 }
1569                 else {
1570                         if (fy>1.0f) fy -= (int)(fy);
1571                         else if (fy<0.0f) fy+= 1-(int)(fy);
1572                 }
1573         }
1574
1575         /* warning no return! */
1576         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1577                 ibuf->rect+= (ibuf->x*ibuf->y);
1578         }
1579
1580         /* choice:  */
1581         if (tex->imaflag & TEX_MIPMAP) {
1582                 ImBuf *previbuf, *curibuf;
1583                 float bumpscale;
1584                 
1585                 dx = minx;
1586                 dy = miny;
1587                 maxd = max_ff(dx, dy);
1588                 if (maxd > 0.5f) maxd = 0.5f;
1589
1590                 pixsize = 1.0f / (float) MIN2(ibuf->x, ibuf->y);
1591                 
1592                 bumpscale= pixsize/maxd;
1593                 if (bumpscale>1.0f) bumpscale= 1.0f;
1594                 else bumpscale*=bumpscale;
1595                 
1596                 curmap= 0;
1597                 previbuf= curibuf= ibuf;
1598                 while (curmap<IB_MIPMAP_LEVELS && ibuf->mipmap[curmap]) {
1599                         if (maxd < pixsize) break;
1600                         previbuf= curibuf;
1601                         curibuf= ibuf->mipmap[curmap];
1602                         pixsize= 1.0f / (float)MIN2(curibuf->x, curibuf->y);
1603                         curmap++;
1604                 }
1605
1606                 if (previbuf!=curibuf || (tex->imaflag & TEX_INTERPOL)) {
1607                         /* sample at least 1 pixel */
1608                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1609                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1610                 }
1611                 
1612                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1613                         /* a bit extra filter */
1614                         //minx*= 1.35f;
1615                         //miny*= 1.35f;
1616                         
1617                         boxsample(curibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1618                         val1= texres->tr+texres->tg+texres->tb;
1619                         boxsample(curibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1620                         val2= texr.tr + texr.tg + texr.tb;
1621                         boxsample(curibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1622                         val3= texr.tr + texr.tg + texr.tb;
1623
1624                         /* don't switch x or y! */
1625                         texres->nor[0]= (val1-val2);
1626                         texres->nor[1]= (val1-val3);
1627                         
1628                         if (previbuf!=curibuf) {  /* interpolate */
1629                                 
1630                                 boxsample(previbuf, fx-minx, fy-miny, fx+minx, fy+miny, &texr, imaprepeat, imapextend);
1631                                 
1632                                 /* calc rgb */
1633                                 dx= 2.0f*(pixsize-maxd)/pixsize;
1634                                 if (dx>=1.0f) {
1635                                         texres->ta= texr.ta; texres->tb= texr.tb;
1636                                         texres->tg= texr.tg; texres->tr= texr.tr;
1637                                 }
1638                                 else {
1639                                         dy= 1.0f-dx;
1640                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1641                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1642                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1643                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1644                                 }
1645                                 
1646                                 val1= dy*val1+ dx*(texr.tr + texr.tg + texr.tb);
1647                                 boxsample(previbuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1648                                 val2= dy*val2+ dx*(texr.tr + texr.tg + texr.tb);
1649                                 boxsample(previbuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1650                                 val3= dy*val3+ dx*(texr.tr + texr.tg + texr.tb);
1651                                 
1652                                 texres->nor[0]= (val1-val2);    /* vals have been interpolated above! */
1653                                 texres->nor[1]= (val1-val3);
1654                                 
1655                                 if (dx<1.0f) {
1656                                         dy= 1.0f-dx;
1657                                         texres->tb= dy*texres->tb+ dx*texr.tb;
1658                                         texres->tg= dy*texres->tg+ dx*texr.tg;
1659                                         texres->tr= dy*texres->tr+ dx*texr.tr;
1660                                         texres->ta= dy*texres->ta+ dx*texr.ta;
1661                                 }
1662                         }
1663                         texres->nor[0]*= bumpscale;
1664                         texres->nor[1]*= bumpscale;
1665                 }
1666                 else {
1667                         maxx= fx+minx;
1668                         minx= fx-minx;
1669                         maxy= fy+miny;
1670                         miny= fy-miny;
1671
1672                         boxsample(curibuf, minx, miny, maxx, maxy, texres, imaprepeat, imapextend);
1673
1674                         if (previbuf!=curibuf) {  /* interpolate */
1675                                 boxsample(previbuf, minx, miny, maxx, maxy, &texr, imaprepeat, imapextend);
1676                                 
1677                                 fx= 2.0f*(pixsize-maxd)/pixsize;
1678                                 
1679                                 if (fx>=1.0f) {
1680                                         texres->ta= texr.ta; texres->tb= texr.tb;
1681                                         texres->tg= texr.tg; texres->tr= texr.tr;
1682                                 }
1683                                 else {
1684                                         fy= 1.0f-fx;
1685                                         texres->tb= fy*texres->tb+ fx*texr.tb;
1686                                         texres->tg= fy*texres->tg+ fx*texr.tg;
1687                                         texres->tr= fy*texres->tr+ fx*texr.tr;
1688                                         texres->ta= fy*texres->ta+ fx*texr.ta;
1689                                 }
1690                         }
1691                 }
1692         }
1693         else {
1694                 const int intpol = tex->imaflag & TEX_INTERPOL;
1695                 if (intpol) {
1696                         /* sample 1 pixel minimum */
1697                         if (minx < 0.5f / ibuf->x) minx = 0.5f / ibuf->x;
1698                         if (miny < 0.5f / ibuf->y) miny = 0.5f / ibuf->y;
1699                 }
1700
1701                 if (texres->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1702                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1703                         val1= texres->tr+texres->tg+texres->tb;
1704                         boxsample(ibuf, fx-minx+dxt[0], fy-miny+dxt[1], fx+minx+dxt[0], fy+miny+dxt[1], &texr, imaprepeat, imapextend);
1705                         val2= texr.tr + texr.tg + texr.tb;
1706                         boxsample(ibuf, fx-minx+dyt[0], fy-miny+dyt[1], fx+minx+dyt[0], fy+miny+dyt[1], &texr, imaprepeat, imapextend);
1707                         val3= texr.tr + texr.tg + texr.tb;
1708
1709                         /* don't switch x or y! */
1710                         texres->nor[0]= (val1-val2);
1711                         texres->nor[1]= (val1-val3);
1712                 }
1713                 else
1714                         boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, texres, imaprepeat, imapextend);
1715         }
1716         
1717         if (tex->imaflag & TEX_CALCALPHA) {
1718                 texres->ta = texres->tin = texres->ta * max_fff(texres->tr, texres->tg, texres->tb);
1719         }
1720         else {
1721                 texres->tin = texres->ta;
1722         }
1723
1724         if (tex->flag & TEX_NEGALPHA) texres->ta= 1.0f-texres->ta;
1725         
1726         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1727                 ibuf->rect-= (ibuf->x*ibuf->y);
1728         }
1729
1730         if (texres->nor && (tex->imaflag & TEX_NORMALMAP)) {
1731                 /* qdn: normal from color
1732                  * The invert of the red channel is to make
1733                  * the normal map compliant with the outside world.
1734                  * It needs to be done because in Blender
1735                  * the normal used in the renderer points inward. It is generated
1736                  * this way in calc_vertexnormals(). Should this ever change
1737                  * this negate must be removed. */
1738                 texres->nor[0] = -2.f*(texres->tr - 0.5f);
1739                 texres->nor[1] = 2.f*(texres->tg - 0.5f);
1740                 texres->nor[2] = 2.f*(texres->tb - 0.5f);
1741         }
1742
1743         /* de-premul, this is being premulled in shade_input_do_shade() */
1744         /* do not de-premul for generated alpha, it is already in straight */
1745         if (texres->ta!=1.0f && texres->ta>1e-4f && !(tex->imaflag & TEX_CALCALPHA)) {
1746                 mul_v3_fl(&texres->tr, 1.0f / texres->ta);
1747         }
1748
1749         if (ima)
1750                 BKE_image_pool_release_ibuf(ima, ibuf, pool);
1751
1752         BRICONTRGB;
1753         
1754         return retval;
1755 }
1756
1757 void image_sample(Image *ima, float fx, float fy, float dx, float dy, float result[4], struct ImagePool *pool)
1758 {
1759         TexResult texres;
1760         ImBuf *ibuf = BKE_image_pool_acquire_ibuf(ima, NULL, pool);
1761         
1762         if (UNLIKELY(ibuf == NULL)) {
1763                 zero_v4(result);
1764                 return;
1765         }
1766         
1767         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1768                 ibuf->rect+= (ibuf->x*ibuf->y);
1769
1770         texres.talpha = true; /* boxsample expects to be initialized */
1771         boxsample(ibuf, fx, fy, fx + dx, fy + dy, &texres, 0, 1);
1772         copy_v4_v4(result, &texres.tr);
1773         
1774         if ( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) )
1775                 ibuf->rect-= (ibuf->x*ibuf->y);
1776
1777         ima->flag|= IMA_USED_FOR_RENDER;
1778
1779         BKE_image_pool_release_ibuf(ima, ibuf, pool);
1780 }
1781
1782 void ibuf_sample(ImBuf *ibuf, float fx, float fy, float dx, float dy, float result[4])
1783 {
1784         TexResult texres = {0};
1785         afdata_t AFD;
1786
1787         AFD.dxt[0] = dx; AFD.dxt[1] = dx;
1788         AFD.dyt[0] = dy; AFD.dyt[1] = dy;
1789         //copy_v2_v2(AFD.dxt, dx);
1790         //copy_v2_v2(AFD.dyt, dy);
1791         
1792         AFD.intpol = 1;
1793         AFD.extflag = TXC_EXTD;
1794
1795         ewa_eval(&texres, ibuf, fx, fy, &AFD);
1796         
1797         copy_v4_v4(result, &texres.tr);
1798 }