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