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