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