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