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