0663fb2244e8437643a84b66775c6ce4b9a90c20
[blender.git] / source / blender / blenkernel / intern / image.c
1 /*  image.c        
2  * 
3  * $Id$
4  *
5  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version. The Blender
11  * Foundation also sells licenses for use in proprietary software under
12  * the Blender License.  See http://www.blender.org/BL/ for information
13  * about this.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software Foundation,
22  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23  *
24  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
25  * All rights reserved.
26  *
27  * The Original Code is: all of this file.
28  *
29  * Contributor(s): none yet.
30  *
31  * ***** END GPL/BL DUAL LICENSE BLOCK *****
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <stdio.h>
39 #include <string.h>
40 #include <fcntl.h>
41 #include <math.h>
42 #ifndef WIN32 
43 #include <unistd.h>
44 #else
45 #include <io.h>
46 #endif
47
48 #include "MEM_guardedalloc.h"
49
50 #include "IMB_imbuf_types.h"
51 #include "IMB_imbuf.h"
52
53 #include "DNA_texture_types.h"
54 #include "DNA_image_types.h"
55 #include "DNA_packedFile_types.h"
56
57 #include "BLI_blenlib.h"
58
59 #include "BKE_bad_level_calls.h"
60 #include "BKE_utildefines.h"
61
62 #include "BKE_global.h"
63 #include "BKE_main.h"
64
65 #include "BKE_image.h"
66 #include "BKE_bmfont.h"
67 #include "BKE_screen.h"
68 #include "BKE_texture.h"
69 #include "BKE_packedFile.h"
70 #include "BKE_library.h"
71
72 void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2);
73 void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2);
74 float square_rctf(rctf *rf);
75 float clipx_rctf(rctf *rf, float x1, float x2);
76 float clipy_rctf(rctf *rf, float y1, float y2);
77 void boxsample(struct ImBuf *ibuf,
78                            float minx, float miny, float maxx, float maxy,
79                            float *rcol, float *gcol, float *bcol, float *acol);
80 void boxsampleclip(struct ImBuf *ibuf, rctf *rf, float *rcol,
81                                    float *gcol, float *bcol, float *acol);
82 void filtersample(struct ImBuf *ibuf,
83                                   float fx, float fy,
84                                   float *rcol, float *gcol, float *bcol, float *acol);
85
86         
87
88 /* If defined: check arguments on call */
89 /*  #define IMAGE_C_ARG_CHECK */
90
91 /* Communicate with texture channels. */
92 extern float Tin, Tr, Tg, Tb, Ta;
93
94 int Talpha;
95 int imaprepeat, imapextend;
96
97
98 /*
99  * 
100  *  Talpha==TRUE means: read alpha from image. This does not mean that Ta
101  *  should not be used, here info can be stored about outside edge of an image!
102  * 
103  */
104
105 void free_image_buffers(Image *ima)
106 {
107         int a;
108
109         if(ima->ibuf) {
110                 if (ima->ibuf->userdata) {
111                         MEM_freeN(ima->ibuf->userdata);
112                         ima->ibuf->userdata = 0;
113                 }
114                 IMB_freeImBuf(ima->ibuf);
115                 ima->ibuf= 0;
116         }
117         if(ima->anim) IMB_free_anim(ima->anim);
118         ima->anim= 0;
119         
120         for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
121                 if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
122                 ima->mipmap[a]= 0;
123         }
124         
125         free_realtime_image(ima);
126 }
127
128
129 void free_image(Image *ima)
130 {
131
132         free_image_buffers(ima);
133         if (ima->packedfile) {
134                 freePackedFile(ima->packedfile);
135                 ima->packedfile = NULL;
136         }
137 }
138
139
140 Image *add_image(char *name)
141 {
142         Image *ima;
143         int file, len;
144         char *libname, str[256], strtest[256];
145         
146         strcpy(str, name);
147         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
148         
149         file= open(str, O_BINARY|O_RDONLY);
150         if(file== -1) return 0;
151         close(file);
152         
153         /* first search an identical image */
154         ima= G.main->image.first;
155         while(ima) {
156                 strcpy(strtest, ima->name);
157                 BLI_convertstringcode(strtest, G.sce, G.scene->r.cfra);
158                 if( strcmp(strtest, str)==0 ) {
159                         if(ima->anim==0 || ima->id.us==0) {
160                                 strcpy(ima->name, name);        /* for stringcode */
161                                 ima->id.us++;
162                                 ima->ok= 1;
163                                 return ima;
164                         }
165                 }
166                 ima= ima->id.next;
167         }
168
169         len= strlen(name);
170         
171         while (len > 0 && name[len - 1] != '/' && name[len - 1] != '\\') len--;
172         libname= name+len;
173         
174         ima= alloc_libblock(&G.main->image, ID_IM, libname);
175         strcpy(ima->name, name);
176         ima->ok= 1;
177         
178         ima->xrep= ima->yrep= 1;
179         
180         return ima;
181 }
182
183 void free_unused_animimages()
184 {
185         Image *ima, *nima;
186
187         ima= G.main->image.first;
188         while(ima) {
189                 nima= ima->id.next;
190                 if(ima->id.us==0) {
191                         if(ima->flag & IMA_FROMANIM) free_libblock(&G.main->image, ima);
192                 }
193                 ima= nima;
194         }
195 }
196
197
198 /* *********** READ AND WRITE ************** */
199
200 void makepicstring(char *string, int frame)
201 {
202         short i,len;
203         char num[10], *extension;
204
205         if (string==0) return;
206
207         extension= "";
208
209         strcpy(string, G.scene->r.pic);
210         BLI_convertstringcode(string, G.sce, G.scene->r.cfra);
211
212                         len= strlen(string);
213                         
214         /* can also: sprintf(num, "%04d", frame); */
215
216         i=4-sprintf(num,"%d",frame);
217         for(;i>0;i--){
218                 string[len]='0';
219                 len++;
220         }
221         string[len]=0;
222         strcat(string,num);
223
224         if(G.scene->r.imtype== R_IRIS) {
225                 extension= ".rgb";
226         }
227         else if(G.scene->r.imtype==R_IRIZ) {
228                 extension= ".rgb";
229         }
230         else if(G.scene->r.imtype==R_PNG) {
231                 extension= ".png";
232         }
233         else if(G.scene->r.imtype==R_TARGA) {
234                 extension= ".tga";
235         }
236         else if(G.scene->r.imtype==R_RAWTGA) {
237                 extension= ".tga";
238         }
239         else if(G.scene->r.imtype==R_JPEG90) {
240                 extension= ".jpg";
241         }
242         else if(G.scene->r.imtype==R_BMP) {
243                 extension= ".bmp";
244         }
245         
246         if(G.scene->r.scemode & R_EXTENSION) strcat(string, extension);
247                 
248 }
249
250 /* ******** IMAGE WRAPPING INIT ************* */
251
252 void converttopremul(struct ImBuf *ibuf)
253 {
254         int x, y, val;
255         char *cp;
256         
257         if(ibuf==0) return;
258         if(ibuf->depth==24) {   /* put alpha at 255 */
259
260                 cp= (char *)(ibuf->rect);
261                 for(y=0; y<ibuf->y; y++) {
262                         for(x=0; x<ibuf->x; x++, cp+=4) {
263                                 cp[3]= 255;
264                         }
265                 }
266                 return;
267         }
268         
269         cp= (char *)(ibuf->rect);
270         for(y=0; y<ibuf->y; y++) {
271                 for(x=0; x<ibuf->x; x++, cp+=4) {
272                         if(cp[3]==0) {
273                                 cp[0]= cp[1]= cp[2]= 0;
274                         }
275                         else if(cp[3]!=255) {
276                                 val= cp[3];
277                                 cp[0]= (cp[0]*val)>>8;
278                                 cp[1]= (cp[1]*val)>>8;
279                                 cp[2]= (cp[2]*val)>>8;
280                         }
281                 }
282         }
283 }
284
285
286
287 void makemipmap(Image *ima)
288 {
289         struct ImBuf *ibuf;
290         int minsize, curmap=0;
291
292         ibuf= ima->ibuf;
293         minsize= MIN2(ibuf->x, ibuf->y);
294
295         while(minsize>3 && curmap<BLI_ARRAY_NELEMS(ima->mipmap)) {
296
297                 ibuf= IMB_dupImBuf(ibuf);
298                 IMB_filter(ibuf);
299                 ima->mipmap[curmap]= (struct ImBuf *)IMB_onehalf(ibuf);
300                 IMB_freeImBuf(ibuf);
301                 ibuf= ima->mipmap[curmap];
302                 
303                 curmap++;
304                 minsize= MIN2(ibuf->x, ibuf->y);
305         }
306 }
307
308 struct anim *openanim(char * name, int flags)
309 {
310         struct anim * anim;
311         struct ImBuf * ibuf;
312         
313         anim = IMB_open_anim(name, flags);
314         if (anim == 0) return(0);
315
316         
317         ibuf = IMB_anim_absolute(anim, 0);
318         if (ibuf == 0) {
319                 printf("anim_absolute 0 failed\n");
320                 IMB_free_anim(anim);
321                 return(0);
322         }
323         IMB_freeImBuf(ibuf);
324         
325         return(anim);
326 }
327
328 int calcimanr(int cfra, Tex *tex)
329 {
330         int imanr, len, a, fra, dur;
331
332         /* here (+fie_ima/2-1) makes sure that division happens correctly */
333         
334         if(tex->frames==0) return 1;
335         
336         cfra= cfra-tex->sfra+1;
337         
338         /* cyclic */
339         if(tex->len==0) len= (tex->fie_ima*tex->frames)/2;
340         else len= tex->len;
341         
342         if(tex->imaflag & TEX_ANIMCYCLIC) {
343                 cfra= ( (cfra) % len );
344                 if(cfra < 0) cfra+= len;
345                 if(cfra==0) cfra= len;
346         }
347         
348         if(cfra<1) cfra= 1;
349         else if(cfra>len) cfra= len;
350         
351         /* convert current frame to current field */
352         cfra= 2*(cfra);
353         if(R.flag & R_SEC_FIELD) cfra++;
354         
355         /* transform to images space */
356         imanr= (cfra+tex->fie_ima-2)/tex->fie_ima;
357         if(imanr>tex->frames) imanr= tex->frames;
358         imanr+= tex->offset;
359         
360         if(tex->imaflag & TEX_ANIMCYCLIC) {
361                 imanr= ( (imanr) % len );
362                 while(imanr < 0) imanr+= len;
363                 if(imanr==0) imanr= len;
364         }
365
366         /* are there images that last longer? */
367         for(a=0; a<4; a++) {
368                 if(tex->fradur[a][0]) {
369                         
370                         fra= tex->fradur[a][0];
371                         dur= tex->fradur[a][1]-1;
372                         
373                         while(dur>0 && imanr>fra) {
374                                 imanr--;
375                                 dur--;
376                         }
377                 }
378         }
379
380         return imanr;
381 }
382
383 void do_laseroptics_patch(ImBuf *ibuf)
384 {
385         char *rt;
386         float fac;
387         int a, val;
388         
389         rt= (char *)ibuf->rect;
390         a= ibuf->x*ibuf->y;
391
392         if(ibuf->flags & IB_fields) a+= a;
393
394         while(a--) {
395                 
396                 fac= (rt[1]+rt[2]+rt[3])/765.0f;
397                 val= (int)((255.0/0.8)*(fac-0.1));
398                 
399                 if(val<0) val= 0; else if(val>255) val= 255;
400                 
401                 rt[0]= rt[1]= rt[2]= rt[3]= val;
402                 
403                 rt+= 4;
404         }
405 }
406
407 void de_interlace_ng(struct ImBuf *ibuf)        /* neogeo fields */
408 {
409         struct ImBuf * tbuf1, * tbuf2;
410         
411         if (ibuf == 0) return;
412         if (ibuf->flags & IB_fields) return;
413         ibuf->flags |= IB_fields;
414         
415         if (ibuf->rect) {
416                 /* make copies */
417                 tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
418                 tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, (int)IB_rect, (unsigned char)0);
419                 
420                 ibuf->x *= 2;
421                 /* These rectop calls are broken!!! I added a trailing 0 arg... */
422                 IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
423                 IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0);
424         
425                 ibuf->x /= 2;
426                 IMB_rectop(ibuf, tbuf1, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
427                 IMB_rectop(ibuf, tbuf2, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0);
428                 
429                 IMB_freeImBuf(tbuf1);
430                 IMB_freeImBuf(tbuf2);
431         }
432         ibuf->y /= 2;
433 }
434
435 void de_interlace_st(struct ImBuf *ibuf)        /* standard fields */
436 {
437         struct ImBuf * tbuf1, * tbuf2;
438         
439         if (ibuf == 0) return;
440         if (ibuf->flags & IB_fields) return;
441         ibuf->flags |= IB_fields;
442         
443         if (ibuf->rect) {
444                 /* make copies */
445                 tbuf1 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
446                 tbuf2 = IMB_allocImBuf(ibuf->x, (short)(ibuf->y >> 1), (unsigned char)32, IB_rect, 0);
447                 
448                 ibuf->x *= 2;
449                 /* These are brolenm as well... */
450                 IMB_rectop(tbuf1, ibuf, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
451                 IMB_rectop(tbuf2, ibuf, 0, 0, tbuf2->x, 0, 32767, 32767, IMB_rectcpy, 0);
452         
453                 ibuf->x /= 2;
454                 IMB_rectop(ibuf, tbuf2, 0, 0, 0, 0, 32767, 32767, IMB_rectcpy, 0);
455                 IMB_rectop(ibuf, tbuf1, 0, tbuf2->y, 0, 0, 32767, 32767, IMB_rectcpy, 0);
456                 
457                 IMB_freeImBuf(tbuf1);
458                 IMB_freeImBuf(tbuf2);
459         }
460         ibuf->y /= 2;
461 }
462
463 /*
464 load_image handles reading the image from disk or from the packedfile.
465 */
466
467 void load_image(Image * ima, int flags, char *relabase, int framenum)
468 {
469         char name[FILE_MAXDIR + FILE_MAXFILE];
470
471         if (ima->ibuf == NULL) {
472
473                 // is there a PackedFile with this image ?;
474                 if (ima->packedfile) {
475                         ima->ibuf = IMB_ibImageFromMemory((int *) ima->packedfile->data, ima->packedfile->size, flags);
476                 } else {
477                         strcpy(name, ima->name);
478                         BLI_convertstringcode(name, relabase, framenum);
479
480                         ima->ibuf = IMB_loadiffname(name , flags);
481                 }
482                 // check if the image is a font image...
483                 // printf("Checking for font\n");
484
485                 if (ima->ibuf) {
486                         detectBitmapFont(ima->ibuf);
487                 }
488         }
489 }
490
491 void ima_ibuf_is_nul(Tex *tex)
492 {
493         void (*de_interlacefunc)(struct ImBuf *ibuf);
494         Image *ima;
495         int a, fra, dur;
496         char str[FILE_MAXDIR+FILE_MAXFILE], *cp;
497                 
498         ima= tex->ima;
499         if(ima==0) return;
500
501         waitcursor(1);
502                 
503         strcpy(str, ima->name);
504         BLI_convertstringcode(str, G.sce, G.scene->r.cfra);
505         
506         if(tex->imaflag & TEX_STD_FIELD) de_interlacefunc= de_interlace_st;
507         else de_interlacefunc= de_interlace_ng;
508
509         if(tex->imaflag & TEX_ANIM5) {
510         
511                 if(ima->anim==0) ima->anim = openanim(str, IB_cmap | IB_rect);
512                 if (ima->anim) {
513                         dur = IMB_anim_get_duration(ima->anim);
514                         
515                         ima->lastquality= R.osa;
516                         fra= ima->lastframe-1;
517
518                         if(fra<0) fra = 0;
519                         if(fra>(dur-1)) fra= dur-1;
520                         ima->ibuf = IMB_anim_absolute(ima->anim, fra);
521
522                         /* patch for textbutton with name ima (B_NAMEIMA) */
523                         if(ima->ibuf) {
524                                 strcpy(ima->ibuf->name, ima->name);
525                                 if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
526                         }
527                 }
528                 else error("Not an anim");
529
530         } else {
531                 // create a packedfile for this image when autopack is on
532                 // for performance (IMB_loadiffname uses mmap) we don't do this by default
533                 if ((ima->packedfile == NULL) && (G.fileflags & G_AUTOPACK)) {
534                         ima->packedfile = newPackedFile(str);
535                 }
536                 
537                 load_image(ima, IB_rect, G.sce, G.scene->r.cfra);
538
539                 if (tex->imaflag & TEX_FIELDS) de_interlacefunc(ima->ibuf);
540                 
541                 ima->lastquality= R.osa;
542         }
543         
544         if(ima->ibuf) {
545                 
546                 /* stringcodes also in ibuf. ibuf->name is used as 'undo' (buttons.c) */
547                 strcpy(ima->ibuf->name, ima->name);
548                 
549                 if(ima->ibuf->cmap) {
550                         
551                         if(tex->imaflag & TEX_ANIM5) {
552                         
553                                 if(tex->imaflag & TEX_MORKPATCH) {
554                                                 /**** PATCH TO SET COLOR 2 RIGHT (neogeo..) */
555                                         if(ima->ibuf->maxcol > 4) {
556                                                 cp= (char *)(ima->ibuf->cmap+2);
557                                                 cp[0]= 0x80;
558                                         }
559                                 }
560                         
561                                 IMB_applycmap(ima->ibuf);
562                                 IMB_convert_rgba_to_abgr(ima->ibuf->x*ima->ibuf->y, ima->ibuf->rect);
563                                 
564                         }
565                         
566                         converttopremul(ima->ibuf);
567                 }
568                 
569                 if(R.osa) {
570                         
571                         if(tex->imaflag & TEX_ANTISCALE) {
572                                 IMB_clever_double(ima->ibuf);
573                                 IMB_antialias(ima->ibuf);
574                         }
575                         else if(tex->imaflag & TEX_ANTIALI) IMB_antialias(ima->ibuf);
576                 }
577         }
578         
579         if(ima->ibuf==0) ima->ok= 0;
580         
581         for(a=0; a<BLI_ARRAY_NELEMS(ima->mipmap); a++) {
582                 if(ima->mipmap[a]) IMB_freeImBuf(ima->mipmap[a]);
583                 ima->mipmap[a]= 0;
584         }
585
586         if((R.flag & R_RENDERING)==0) waitcursor(0);
587         
588 }
589
590
591
592 /* *********** IMAGEWRAPPING ****************** */
593
594
595 int imagewrap(Tex *tex, float *texvec)
596 {
597         Image *ima;
598         struct ImBuf *ibuf;
599         float fx, fy, val1, val2, val3;
600         int ofs, x, y;
601         char *rect;
602
603         Tin= Ta= Tr= Tg= Tb= 0.0;
604         ima= tex->ima;
605         if(ima==0 || ima->ok== 0) {
606                 return 0;
607         }
608         
609         if(ima->ibuf==0) ima_ibuf_is_nul(tex);
610
611         if (ima->ok) {
612                 ibuf = ima->ibuf;
613
614                 if(tex->imaflag & TEX_IMAROT) {
615                         fy= texvec[0];
616                         fx= texvec[1];
617                 }
618                 else {
619                         fx= texvec[0];
620                         fy= texvec[1];
621                 }
622                 
623                 if(tex->extend == TEX_CHECKER) {
624                         int xs, ys;
625                         
626                         xs= (int)floor(fx);
627                         ys= (int)floor(fy);
628                         fx-= xs;
629                         fy-= ys;
630
631                         if( (tex->flag & TEX_CHECKER_ODD)==0) {
632                                 if((xs+ys) & 1);else return 0;
633                         }
634                         if( (tex->flag & TEX_CHECKER_EVEN)==0) {
635                                 if((xs+ys) & 1) return 0; 
636                         }
637                         /* scale around center, (0.5, 0.5) */
638                         if(tex->checkerdist<1.0) {
639                                 fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
640                                 fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
641                         }
642                 }
643
644                 x = (int)(fx*ibuf->x);
645                 y = (int)(fy*ibuf->y);
646
647                 if(tex->extend == TEX_CLIPCUBE) {
648                         if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y || texvec[2]<-1.0 || texvec[2]>1.0) {
649                                 return 0;
650                         }
651                 }
652                 else if( tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
653                         if(x<0 || y<0 || x>=ibuf->x || y>=ibuf->y) {
654                                 return 0;
655                         }
656                 }
657                 else {
658                         if(tex->extend==TEX_EXTEND) {
659                                 if(x>=ibuf->x) x = ibuf->x-1;
660                                 else if(x<0) x= 0;
661                         }
662                         else {
663                                 x= x % ibuf->x;
664                                 if(x<0) x+= ibuf->x;
665                         }
666                         if(tex->extend==TEX_EXTEND) {
667                                 if(y>=ibuf->y) y = ibuf->y-1;
668                                 else if(y<0) y= 0;
669                         }
670                         else {
671                                 y= y % ibuf->y;
672                                 if(y<0) y+= ibuf->y;
673                         }
674                 }
675                 
676                 /* warning, no return before setting back! */
677                 if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
678                         ibuf->rect+= (ibuf->x*ibuf->y);
679                 }
680
681                 ofs = y * ibuf->x + x;
682                 rect = (char *)( ibuf->rect+ ofs);
683
684                 if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
685                         ibuf->rect-= (ibuf->x*ibuf->y);
686                 }
687
688                 Talpha= 0;
689                 if(tex->imaflag & TEX_USEALPHA) {
690                         if(tex->imaflag & TEX_CALCALPHA);
691                         else Talpha= 1;
692                 }
693
694                 Tr = ((float)rect[0])/255.0f;
695                 Tg = ((float)rect[1])/255.0f;
696                 Tb = ((float)rect[2])/255.0f;
697                 
698                 if(tex->nor) {
699                         if(tex->imaflag & TEX_NORMALMAP) {
700                                 tex->nor[0]= 0.5-Tr;
701                                 tex->nor[1]= 0.5-Tg;
702                                 tex->nor[2]= -Tb;
703                         }
704                         else {
705                                 /* bump: take three samples */
706                                 val1= Tr+Tg+Tb;
707
708                                 if(x<ibuf->x-1) {
709                                         rect+=4;
710                                         val2= ((float)(rect[0]+rect[1]+rect[2]))/255.0f;
711                                         rect-=4;
712                                 }
713                                 else val2= val1;
714
715                                 if(y<ibuf->y-1) {
716                                         rect+= 4*ibuf->x;
717                                         val3= ((float)(rect[0]+rect[1]+rect[2]))/255.0f;
718                                 }
719                                 else val3= val1;
720
721                                 /* do not mix up x and y here! */
722                                 tex->nor[0]= (val1-val2);
723                                 tex->nor[1]= (val1-val3);
724                         }
725                 }
726
727                 BRICONRGB;
728
729                 if(Talpha) Ta= Tin= ((float)rect[3])/255.0f;
730                 else if(tex->imaflag & TEX_CALCALPHA) {
731                         Ta= Tin= MAX3(Tr, Tg, Tb);
732                 }
733                 else Ta= Tin= 1.0;
734                 
735                 if(tex->flag & TEX_NEGALPHA) Ta= 1.0f-Ta;
736
737         }
738
739         if(tex->nor) return 3;
740         else return 1;
741 }
742
743 void clipx_rctf_swap(rctf *stack, short *count, float x1, float x2)
744 /*  rctf *stack; */
745 /*  short *count; */
746 /*  float x1, x2; */
747 {
748         rctf *rf, *newrct;
749         short a;
750
751         a= *count;
752         rf= stack;
753         for(;a>0;a--) {
754                 if(rf->xmin<x1) {
755                         if(rf->xmax<x1) {
756                                 rf->xmin+= (x2-x1);
757                                 rf->xmax+= (x2-x1);
758                         }
759                         else {
760                                 if(rf->xmax>x2) rf->xmax= x2;
761                                 newrct= stack+ *count;
762                                 (*count)++;
763
764                                 newrct->xmax= x2;
765                                 newrct->xmin= rf->xmin+(x2-x1);
766                                 newrct->ymin= rf->ymin;
767                                 newrct->ymax= rf->ymax;
768                                 
769                                 if(newrct->xmin==newrct->xmax) (*count)--;
770                                 
771                                 rf->xmin= x1;
772                         }
773                 }
774                 else if(rf->xmax>x2) {
775                         if(rf->xmin>x2) {
776                                 rf->xmin-= (x2-x1);
777                                 rf->xmax-= (x2-x1);
778                         }
779                         else {
780                                 if(rf->xmin<x1) rf->xmin= x1;
781                                 newrct= stack+ *count;
782                                 (*count)++;
783
784                                 newrct->xmin= x1;
785                                 newrct->xmax= rf->xmax-(x2-x1);
786                                 newrct->ymin= rf->ymin;
787                                 newrct->ymax= rf->ymax;
788
789                                 if(newrct->xmin==newrct->xmax) (*count)--;
790
791                                 rf->xmax= x2;
792                         }
793                 }
794                 rf++;
795         }
796
797 }
798
799 void clipy_rctf_swap(rctf *stack, short *count, float y1, float y2)
800 /*  rctf *stack; */
801 /*  short *count; */
802 /*  float y1, y2; */
803 {
804         rctf *rf, *newrct;
805         short a;
806
807         a= *count;
808         rf= stack;
809         for(;a>0;a--) {
810                 if(rf->ymin<y1) {
811                         if(rf->ymax<y1) {
812                                 rf->ymin+= (y2-y1);
813                                 rf->ymax+= (y2-y1);
814                         }
815                         else {
816                                 if(rf->ymax>y2) rf->ymax= y2;
817                                 newrct= stack+ *count;
818                                 (*count)++;
819
820                                 newrct->ymax= y2;
821                                 newrct->ymin= rf->ymin+(y2-y1);
822                                 newrct->xmin= rf->xmin;
823                                 newrct->xmax= rf->xmax;
824
825                                 if(newrct->ymin==newrct->ymax) (*count)--;
826
827                                 rf->ymin= y1;
828                         }
829                 }
830                 else if(rf->ymax>y2) {
831                         if(rf->ymin>y2) {
832                                 rf->ymin-= (y2-y1);
833                                 rf->ymax-= (y2-y1);
834                         }
835                         else {
836                                 if(rf->ymin<y1) rf->ymin= y1;
837                                 newrct= stack+ *count;
838                                 (*count)++;
839
840                                 newrct->ymin= y1;
841                                 newrct->ymax= rf->ymax-(y2-y1);
842                                 newrct->xmin= rf->xmin;
843                                 newrct->xmax= rf->xmax;
844
845                                 if(newrct->ymin==newrct->ymax) (*count)--;
846
847                                 rf->ymax= y2;
848                         }
849                 }
850                 rf++;
851         }
852
853 }
854
855
856
857 float square_rctf(rctf *rf)
858 /*  rctf *rf; */
859 {
860         float x, y;
861
862         x= rf->xmax- rf->xmin;
863         y= rf->ymax- rf->ymin;
864         return (x*y);
865 }
866
867 float clipx_rctf(rctf *rf, float x1, float x2)
868 /*  rctf *rf; */
869 /*  float x1, x2; */
870 {
871         float size;
872
873         size= rf->xmax - rf->xmin;
874
875         if(rf->xmin<x1) {
876                 rf->xmin= x1;
877         }
878         if(rf->xmax>x2) {
879                 rf->xmax= x2;
880         }
881         if(rf->xmin > rf->xmax) {
882                 rf->xmin = rf->xmax;
883                 return 0.0;
884         }
885         else if(size!=0.0) {
886                 return (rf->xmax - rf->xmin)/size;
887         }
888         return 1.0;
889 }
890
891 float clipy_rctf(rctf *rf, float y1, float y2)
892 /*  rctf *rf; */
893 /*  float y1, y2; */
894 {
895         float size;
896
897         size= rf->ymax - rf->ymin;
898 /* PRINT(f, size); */
899         if(rf->ymin<y1) {
900                 rf->ymin= y1;
901         }
902         if(rf->ymax>y2) {
903                 rf->ymax= y2;
904         }
905 /* PRINT(f, size); */
906         if(rf->ymin > rf->ymax) {
907                 rf->ymin = rf->ymax;
908                 return 0.0;
909         }
910         else if(size!=0.0) {
911                 return (rf->ymax - rf->ymin)/size;
912         }
913         return 1.0;
914
915 }
916
917 void boxsampleclip(struct ImBuf *ibuf, rctf *rf, float *rcol,
918                                    float *gcol, float *bcol, float *acol)       /* return color 0.0-1.0 */
919 /*  struct ImBuf *ibuf; */
920 /*  rctf *rf; */
921 /*  float *rcol, *gcol, *bcol, *acol; */
922 {
923         /* sample box, is clipped already, and minx etc. have been set at ibuf size.
924        Enlarge with antialiased edges of the pixels */
925
926         float muly,mulx,div;
927         int ofs;
928         int x, y, startx, endx, starty, endy;
929         char *rect;
930
931         startx= (int)floor(rf->xmin);
932         endx= (int)floor(rf->xmax);
933         starty= (int)floor(rf->ymin);
934         endy= (int)floor(rf->ymax);
935
936         if(startx < 0) startx= 0;
937         if(starty < 0) starty= 0;
938         if(endx>=ibuf->x) endx= ibuf->x-1;
939         if(endy>=ibuf->y) endy= ibuf->y-1;
940
941         if(starty==endy && startx==endx) {
942
943                 ofs = starty*ibuf->x + startx;
944                 rect = (char *)(ibuf->rect +ofs);
945                 *rcol= ((float)rect[0])/255.0f;
946                 *gcol= ((float)rect[1])/255.0f;
947                 *bcol= ((float)rect[2])/255.0f;
948                         /* alpha is global, has been set in function imagewraposa() */
949                 if(Talpha) {
950                         *acol= ((float)rect[3])/255.0f;
951                 }
952         }
953         else {
954                 div= *rcol= *gcol= *bcol= *acol= 0.0;
955                 for(y=starty;y<=endy;y++) {
956                         ofs = y*ibuf->x +startx;
957                         rect = (char *)(ibuf->rect+ofs);
958
959                         muly= 1.0;
960
961                         if(starty==endy);
962                         else {
963                                 if(y==starty) muly= 1.0f-(rf->ymin - y);
964                                 if(y==endy) muly= (rf->ymax - y);
965                         }
966                         if(startx==endx) {
967                                 mulx= muly;
968                                 if(Talpha) *acol+= mulx*rect[3];
969                                 *rcol+= mulx*rect[0];
970                                 *gcol+= mulx*rect[1];
971                                 *bcol+= mulx*rect[2];
972                                 div+= mulx;
973                         }
974                         else {
975                                 for(x=startx;x<=endx;x++) {
976                                         mulx= muly;
977                                         if(x==startx) mulx*= 1.0f-(rf->xmin - x);
978                                         if(x==endx) mulx*= (rf->xmax - x);
979
980                                         if(mulx==1.0) {
981                                                 if(Talpha) *acol+= rect[3];
982                                                 *rcol+= rect[0];
983                                                 *gcol+= rect[1];
984                                                 *bcol+= rect[2];
985                                                 div+= 1.0;
986                                         }
987                                         else {
988                                                 if(Talpha) *acol+= mulx*rect[3];
989                                                 *rcol+= mulx*rect[0];
990                                                 *gcol+= mulx*rect[1];
991                                                 *bcol+= mulx*rect[2];
992                                                 div+= mulx;
993                                         }
994                                         rect+=4;
995                                 }
996                         }
997                 }
998                 if(div!=0.0) {
999                         div*= 255.0;
1000         
1001                         *bcol/= div;
1002                         *gcol/= div;
1003                         *rcol/= div;
1004                         
1005                         if(Talpha) *acol/= div;
1006                 }
1007                 else {
1008                         *rcol= *gcol= *bcol= *acol= 0.0;
1009                 }
1010         }
1011 }
1012
1013 void boxsample(struct ImBuf *ibuf,
1014                            float minx, float miny, float maxx, float maxy,
1015                            float *rcol, float *gcol, float *bcol, float *acol)  /* return color 0.0-1.0 */
1016 /*  struct ImBuf *ibuf; */
1017 /*  float minx, miny, maxx, maxy; */
1018 /*  float *rcol, *gcol, *bcol, *acol; */
1019 {
1020         /* Sample box, performs clip. minx etc are in range 0.0 - 1.0 .
1021      * Enlarge with antialiased edges of pixels.
1022      * If global variable 'imaprepeat' has been set, the
1023      *  clipped-away parts are sampled as well.
1024      */
1025         rctf *rf, stack[8];
1026         float opp, tot, r, g, b, a, alphaclip= 1.0;
1027         short count=1;
1028
1029         rf= stack;
1030         rf->xmin= minx*(ibuf->x);
1031         rf->xmax= maxx*(ibuf->x);
1032         rf->ymin= miny*(ibuf->y);
1033         rf->ymax= maxy*(ibuf->y);
1034
1035         if(imapextend);
1036         else if(imaprepeat) clipx_rctf_swap(stack, &count, 0.0, (float)(ibuf->x));
1037         else {
1038                 alphaclip= clipx_rctf(rf, 0.0, (float)(ibuf->x));
1039
1040                 if(alphaclip<=0.0) {
1041                         *rcol= *bcol= *gcol= *acol= 0.0;
1042                         return;
1043                 }
1044         }
1045
1046         if(imapextend);
1047         else if(imaprepeat) clipy_rctf_swap(stack, &count, 0.0, (float)(ibuf->y));
1048         else {
1049                 alphaclip*= clipy_rctf(rf, 0.0, (float)(ibuf->y));
1050
1051                 if(alphaclip<=0.0) {
1052                         *rcol= *bcol= *gcol= *acol= 0.0;
1053                         return;
1054                 }
1055         }
1056
1057         if(count>1) {
1058                 tot= *rcol= *bcol= *gcol= *acol= 0.0;
1059                 while(count--) {
1060                         boxsampleclip(ibuf, rf, &r, &g, &b, &a);
1061                         
1062                         opp= square_rctf(rf);
1063                         tot+= opp;
1064
1065                         *rcol+= opp*r;
1066                         *gcol+= opp*g;
1067                         *bcol+= opp*b;
1068                         if(Talpha) *acol+= opp*a;
1069                         rf++;
1070                 }
1071                 if(tot!= 0.0) {
1072                         *rcol/= tot;
1073                         *gcol/= tot;
1074                         *bcol/= tot;
1075                         if(Talpha) *acol/= tot;
1076                 }
1077         }
1078         else {
1079                 boxsampleclip(ibuf, rf, rcol, gcol, bcol, acol);
1080         }
1081
1082         if(Talpha==0) *acol= 1.0;
1083         
1084         if(alphaclip!=1.0) {
1085                 /* this is for laetr investigation, premul or not? */
1086                 /* *rcol*= alphaclip; */
1087                 /* *gcol*= alphaclip; */
1088                 /* *bcol*= alphaclip; */
1089                 *acol*= alphaclip;
1090         }
1091 }       
1092
1093 void filtersample(struct ImBuf *ibuf,
1094                                   float fx, float fy,
1095                                   float *rcol, float *gcol, float *bcol, float *acol)
1096         /* return color 0.0-1.0 */
1097 /*  struct ImBuf *ibuf; */                                                                              /* fx en fy tussen 0.0 en 1.0 */
1098 /*  float fx, fy; */
1099 /*  float *rcol, *gcol, *bcol, *acol; */
1100 {
1101         /* with weighted filter 3x3
1102      * left or right collumn is always 0
1103      * upper or lower row is awlays 0
1104      */
1105
1106         int fac, fac1, fac2, fracx, fracy, filt[4];
1107         int ix, iy, x4;
1108         unsigned int r=0, g=0, b=0, a=0;
1109         char *rowcol, *rfilt[4];
1110
1111         ix= (int)( 256.0*fx );
1112         fracx= (ix & 255);
1113         ix= (ix>>8);
1114         iy= (int)( 256.0*fy );
1115         fracy= (iy & 255);
1116         iy= (iy>>8);
1117         
1118         if(ix>=ibuf->x) ix= ibuf->x-1;
1119         if(iy>=ibuf->y) iy= ibuf->y-1;
1120         
1121         rowcol= (char *)(ibuf->rect+ iy*ibuf->x +ix);
1122
1123         rfilt[0]= rfilt[1]= rfilt[2]= rfilt[3]= rowcol;
1124         x4= 4*ibuf->x;
1125
1126         if(fracx<128) {
1127                 if(ix>0) { 
1128                         rfilt[0]-= 4; 
1129                         rfilt[2]-=4; 
1130                 }
1131                 else if(imaprepeat) { 
1132                         rfilt[0]+= x4-4; 
1133                         rfilt[2]+= x4-4; 
1134                 }
1135
1136                 if(fracy<128) {
1137                         /* case left-under */
1138                         fac1= 128+fracy;
1139                         fac2= 128-fracy;
1140
1141                         if(iy>0) { 
1142                                 rfilt[3]-= x4; 
1143                                 rfilt[2]-= x4; 
1144                         }
1145                         else if(imaprepeat) {
1146                                 fac= x4*(ibuf->y-1) ;
1147                                 rfilt[3]+= fac; 
1148                                 rfilt[2]+= fac;
1149                         }
1150                 }
1151                 else {
1152                         /* case left-upper */
1153                         fac2= 384-fracy;
1154                         fac1= fracy-128;
1155
1156                         if(iy<ibuf->y-1) { 
1157                                 rfilt[1]+= x4; 
1158                                 rfilt[0]+= x4; 
1159                         }
1160                         else if(imaprepeat) {
1161                                 fac= x4*(ibuf->y-1) ;
1162                                 rfilt[1]-= fac; 
1163                                 rfilt[0]-= fac;
1164                         }
1165                 }
1166
1167                 filt[1]=filt[3]= 128+ fracx;
1168                 filt[0]=filt[2]= 128- fracx;
1169                 filt[0]*= fac1; 
1170                 filt[1]*= fac1;
1171                 filt[2]*= fac2; 
1172                 filt[3]*= fac2;
1173         }
1174         else {
1175                 if(fracy<128) {
1176                         /* case right-under */
1177                         fac1= 128+fracy;
1178                         fac2= 128-fracy;
1179
1180                         if(iy>0) { 
1181                                 rfilt[3]-= x4; 
1182                                 rfilt[2]-= x4; 
1183                         }
1184                         else if(imaprepeat) {
1185                                 fac= x4*(ibuf->y-1) ;
1186                                 rfilt[3]+= fac; 
1187                                 rfilt[2]+= fac;
1188                         }
1189                 }
1190                 else {
1191                         /* case right-upper */
1192                         fac2= 384-fracy;
1193                         fac1= fracy-128;
1194
1195                         if(iy<ibuf->y-1) { 
1196                                 rfilt[1]+= x4; 
1197                                 rfilt[0]+= x4; 
1198                         }
1199                         else if(imaprepeat) {
1200                                 fac= x4*(ibuf->y-1) ;
1201                                 rfilt[1]-= fac; 
1202                                 rfilt[0]-= fac;
1203                         }
1204                 }
1205                 filt[0]=filt[2]= 384-fracx;
1206                 filt[1]=filt[3]= fracx-128;
1207                 filt[0]*= fac1; 
1208                 filt[1]*= fac1;
1209                 filt[2]*= fac2; 
1210                 filt[3]*= fac2;
1211
1212                 if(ix<ibuf->x-1) { 
1213                         rfilt[1]+= 4; 
1214                         rfilt[3]+=4; 
1215                 }
1216                 else if(imaprepeat) { 
1217                         rfilt[1]-= x4-4; 
1218                         rfilt[3]-= x4-4; 
1219                 }
1220         }
1221
1222         for(fac=3; fac>=0; fac--) {
1223                 rowcol= rfilt[fac];
1224                 r+= filt[fac]*rowcol[0];
1225                 g+= filt[fac]*rowcol[1];
1226                 b+= filt[fac]*rowcol[2];
1227                 if(Talpha) a+= filt[fac]*rowcol[3];             /* alpha is global */
1228         }
1229         *rcol= ((float)r)/16777216.0f;
1230         *gcol= ((float)g)/16777216.0f;
1231         *bcol= ((float)b)/16777216.0f;
1232         if(Talpha) *acol= ((float)a)/16777216.0f;
1233         
1234 }
1235
1236
1237 int imagewraposa(Tex *tex, float *texvec, float *dxt, float *dyt)
1238 {
1239         struct Image *ima;
1240         struct ImBuf *ibuf, *previbuf;
1241         float fx, fy, minx, maxx, miny, maxy, dx, dy, fac1, fac2, fac3, fac4;
1242         float maxd, pixsize, val1, val2, val3;
1243         int curmap;
1244
1245 #ifdef IMAGE_C_ARG_CHECK
1246         if (!tex) {
1247                 printf("imagewraposa: null pointer to texture\n");
1248         }
1249 #endif
1250         
1251         ima= tex->ima;
1252 #ifdef IMAGE_C_ARG_CHECK
1253         if (!ima) {
1254                 printf("imagewraposa: null pointer to image\n");
1255         }
1256 #endif
1257
1258         Tin= Ta= Tr= Tg= Tb= 0.0;
1259
1260         if(ima==0 || ima->ok== 0) {
1261                 return 0;
1262         }
1263         
1264         if(ima->ibuf==0) ima_ibuf_is_nul(tex);
1265
1266         if (ima->ok) {
1267         
1268                 if(tex->imaflag & TEX_MIPMAP) {
1269                         if(ima->mipmap[0]==0) makemipmap(ima);
1270                 }
1271         
1272                 ibuf = ima->ibuf;
1273                 
1274                 Talpha= 0;
1275                 if(tex->imaflag & TEX_USEALPHA) {
1276                         if(tex->imaflag & TEX_CALCALPHA);
1277                         else Talpha= 1;
1278                 }
1279                 
1280                 if(tex->imaflag & TEX_IMAROT) {
1281                         fy= texvec[0];
1282                         fx= texvec[1];
1283                 }
1284                 else {
1285                         fx= texvec[0];
1286                         fy= texvec[1];
1287                 }
1288                 
1289                 if(ibuf->flags & IB_fields) {
1290                         if(R.r.mode & R_FIELDS) {                       /* field render */
1291                                 if(R.flag & R_SEC_FIELD) {              /* correction for 2nd field */
1292                                         /* fac1= 0.5/( (float)ibuf->y ); */
1293                                         /* fy-= fac1; */
1294                                 }
1295                                 else {                          /* first field */
1296                                         fac1= 0.5f/( (float)ibuf->y );
1297                                         fy+= fac1;
1298                                 }
1299                         }
1300                 }
1301                 
1302                 /* pixel coordinates */
1303
1304                 minx= MIN3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1305                 maxx= MAX3(dxt[0],dyt[0],dxt[0]+dyt[0] );
1306                 miny= MIN3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1307                 maxy= MAX3(dxt[1],dyt[1],dxt[1]+dyt[1] );
1308
1309                 /* tex_sharper has been removed */
1310
1311                 minx= tex->filtersize*(maxx-minx)/2.0f;
1312                 miny= tex->filtersize*(maxy-miny)/2.0f;
1313                 
1314                 if(tex->imaflag & TEX_IMAROT) SWAP(float, minx, miny);
1315                 
1316                 if(minx>0.25) minx= 0.25;
1317                 else if(minx<0.00001f) minx= 0.00001f;  /* side faces of unit-cube */
1318                 if(miny>0.25) miny= 0.25;
1319                 else if(miny<0.00001f) miny= 0.00001f;
1320
1321                 
1322                 /* repeat and clip */
1323                 
1324                 /* watch it: imaprepeat is global value (see boxsample) */
1325                 imaprepeat= (tex->extend==TEX_REPEAT);
1326                 imapextend= (tex->extend==TEX_EXTEND);
1327
1328                 if(tex->extend == TEX_CHECKER) {
1329                         int xs, ys, xs1, ys1, xs2, ys2, boundary;
1330                         
1331                         xs= (int)floor(fx);
1332                         ys= (int)floor(fy);
1333                         
1334                         // both checkers available, no boundary exceptions, checkerdist will eat aliasing
1335                         if( (tex->flag & TEX_CHECKER_ODD) && (tex->flag & TEX_CHECKER_EVEN) ) {
1336                                 fx-= xs;
1337                                 fy-= ys;
1338                         }
1339                         else {
1340                                 
1341                                 xs1= (int)floor(fx-minx);
1342                                 ys1= (int)floor(fy-miny);
1343                                 xs2= (int)floor(fx+minx);
1344                                 ys2= (int)floor(fy+miny);
1345                                 boundary= (xs1!=xs2) || (ys1!=ys2);
1346         
1347                                 if(boundary==0) {
1348                                         if( (tex->flag & TEX_CHECKER_ODD)==0) {
1349                                                 if((xs+ys) & 1); 
1350                                                 else return 0;
1351                                         }
1352                                         if( (tex->flag & TEX_CHECKER_EVEN)==0) {
1353                                                 if((xs+ys) & 1) return 0;
1354                                         }
1355                                         fx-= xs;
1356                                         fy-= ys;
1357                                 }
1358                                 else {
1359                                         if(tex->flag & TEX_CHECKER_ODD) {
1360                                                 if((xs1+ys) & 1) fx-= xs2;
1361                                                 else fx-= xs1;
1362                                                 
1363                                                 if((ys1+xs) & 1) fy-= ys2;
1364                                                 else fy-= ys1;
1365                                         }
1366                                         if(tex->flag & TEX_CHECKER_EVEN) {
1367                                                 if((xs1+ys) & 1) fx-= xs1;
1368                                                 else fx-= xs2;
1369                                                 
1370                                                 if((ys1+xs) & 1) fy-= ys1;
1371                                                 else fy-= ys2;
1372                                         }
1373                                 }
1374                         }
1375
1376                         /* scale around center, (0.5, 0.5) */
1377                         if(tex->checkerdist<1.0) {
1378                                 fx= (fx-0.5)/(1.0-tex->checkerdist) +0.5;
1379                                 fy= (fy-0.5)/(1.0-tex->checkerdist) +0.5;
1380                                 minx/= (1.0-tex->checkerdist);
1381                                 miny/= (1.0-tex->checkerdist);
1382                         }
1383                 }
1384
1385                 if(tex->extend == TEX_CLIPCUBE) {
1386                         if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0 || texvec[2]<-1.0 || texvec[2]>1.0) {
1387                                 return 0;
1388                         }
1389                 }
1390                 else if(tex->extend==TEX_CLIP || tex->extend==TEX_CHECKER) {
1391                         if(fx+minx<0.0 || fy+miny<0.0 || fx-minx>1.0 || fy-miny>1.0) {
1392                                 return 0;
1393                         }
1394                 }
1395                 else {
1396                         if(tex->extend==TEX_EXTEND) {
1397                                 if(fx>1.0) fx = 1.0;
1398                                 else if(fx<0.0) fx= 0.0;
1399                         }
1400                         else {
1401                                 if(fx>1.0) fx -= (int)(fx);
1402                                 else if(fx<0.0) fx+= 1-(int)(fx);
1403                         }
1404                         
1405                         if(tex->extend==TEX_EXTEND) {
1406                                 if(fy>1.0) fy = 1.0;
1407                                 else if(fy<0.0) fy= 0.0;
1408                         }
1409                         else {
1410                                 if(fy>1.0) fy -= (int)(fy);
1411                                 else if(fy<0.0) fy+= 1-(int)(fy);
1412                         }
1413                 }
1414         
1415                 /* warning no return! */
1416                 if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1417                         ibuf->rect+= (ibuf->x*ibuf->y);
1418                 }
1419
1420                 /* choice:  */
1421                 if(tex->imaflag & TEX_MIPMAP) {
1422                         
1423                         dx= minx;
1424                         dy= miny;
1425                         maxd= MAX2(dx, dy);
1426                         if(maxd>0.5) maxd= 0.5;
1427
1428                         pixsize = 1.0f/ (float) MIN2(ibuf->x, ibuf->y);
1429                         
1430                         curmap= 0;
1431                         previbuf= ibuf;
1432                         while(curmap<BLI_ARRAY_NELEMS(ima->mipmap) && ima->mipmap[curmap]) {
1433                                 if(maxd < pixsize) break;
1434                                 previbuf= ibuf;
1435                                 ibuf= ima->mipmap[curmap];
1436                                 pixsize= 1.0f / (float)MIN2(ibuf->x, ibuf->y); /* this used to be 1.0 */                
1437                                 curmap++;
1438                         }
1439                         
1440                         if(previbuf!=ibuf || (tex->imaflag & TEX_INTERPOL)) {
1441                                 /* sample at least 1 pixel */
1442                                 if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x;
1443                                 if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y;
1444                         }
1445                         
1446                         if(tex->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1447                                 /* a bit extra filter */
1448                                 minx*= 1.35f;
1449                                 miny*= 1.35f;
1450                                 
1451                                 boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta);
1452                                 val1= Tr+Tg+Tb;
1453                                 boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4);
1454                                 val2= fac1+fac2+fac3;
1455                                 boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4);
1456                                 val3= fac1+fac2+fac3;
1457         
1458                                 if(previbuf!=ibuf) {  /* interpolate */
1459                                         
1460                                         boxsample(previbuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &fac1, &fac2, &fac3, &fac4);
1461                                         
1462                                         /* calc rgb */
1463                                         dx= 2.0f*(pixsize-maxd)/pixsize;
1464                                         if(dx>=1.0f) {
1465                                                 Ta= fac4; Tb= fac3;
1466                                                 Tg= fac2; Tr= fac1;
1467                                         }
1468                                         else {
1469                                                 dy= 1.0f-dx;
1470                                                 Tb= dy*Tb+ dx*fac3;
1471                                                 Tg= dy*Tg+ dx*fac2;
1472                                                 Tr= dy*Tr+ dx*fac1;
1473                                                 if(Talpha) Ta= dy*Ta+ dx*fac4;
1474                                         }
1475                                         
1476                                         val1= dy*val1+ dx*(fac1+fac2+fac3);
1477                                         boxsample(previbuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4);
1478                                         val2= dy*val2+ dx*(fac1+fac2+fac3);
1479                                         boxsample(previbuf, fx-2.0f*minx, fy-miny, fx+minx, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4);
1480                                         val3= dy*val3+ dx*(fac1+fac2+fac3);
1481                                 }
1482
1483                                 /* don't switch x or y! */
1484                                 tex->nor[0]= (val1-val2);
1485                                 tex->nor[1]= (val1-val3);
1486                         }
1487                         else {
1488                                 maxx= fx+minx;
1489                                 minx= fx-minx;
1490                                 maxy= fy+miny;
1491                                 miny= fy-miny;
1492         
1493                                 boxsample(ibuf, minx, miny, maxx, maxy, &Tr, &Tg, &Tb, &Ta);
1494         
1495                                 if(previbuf!=ibuf) {  /* interpolate */
1496                                         boxsample(previbuf, minx, miny, maxx, maxy, &fac1, &fac2, &fac3, &fac4);
1497                                         
1498                                         fx= 2.0f*(pixsize-maxd)/pixsize;
1499                                         
1500                                         if(fx>=1.0) {
1501                                                 Ta= fac4; Tb= fac3;
1502                                                 Tg= fac2; Tr= fac1;
1503                                         } else {
1504                                                 fy= 1.0f-fx;
1505                                                 Tb= fy*Tb+ fx*fac3;
1506                                                 Tg= fy*Tg+ fx*fac2;
1507                                                 Tr= fy*Tr+ fx*fac1;
1508                                                 if(Talpha) Ta= fy*Ta+ fx*fac4;
1509                                         }
1510                                 }
1511                         }
1512                 }
1513                 else {
1514                         if((tex->imaflag & TEX_INTERPOL)) {
1515                                 /* sample 1 pixel minimum */
1516                                 if (minx < 0.5f / ima->ibuf->x) minx = 0.5f / ima->ibuf->x;
1517                                 if (miny < 0.5f / ima->ibuf->y) miny = 0.5f / ima->ibuf->y;
1518                         }
1519
1520                         if(tex->nor && (tex->imaflag & TEX_NORMALMAP)==0) {
1521                                 
1522                                 /* a bit extra filter */
1523                                 minx*= 1.35f;
1524                                 miny*= 1.35f;
1525                                 
1526                                 boxsample(ibuf, fx-2.0f*minx, fy-2.0f*miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta);
1527                                 val1= Tr+Tg+Tb;
1528
1529                                 boxsample(ibuf, fx-minx, fy-2.0f*miny, fx+2.0f*minx, fy+miny, &fac1, &fac2, &fac3, &fac4);
1530                                 val2= fac1+fac2+fac3;
1531                                 
1532                                 boxsample(ibuf, fx-2.0f*minx, fy-miny, fx+miny, fy+2.0f*miny, &fac1, &fac2, &fac3, &fac4);
1533                                 val3= fac1+fac2+fac3;
1534
1535                                 /* don't switch x or y! */
1536                                 tex->nor[0]= (val1-val2);
1537                                 tex->nor[1]= (val1-val3);
1538                         }
1539                         else {
1540                                 boxsample(ibuf, fx-minx, fy-miny, fx+minx, fy+miny, &Tr, &Tg, &Tb, &Ta);
1541                         }
1542                 }
1543                 
1544                 BRICONRGB;
1545                 
1546                 if(tex->imaflag & TEX_CALCALPHA) {
1547                         Ta= Tin= Ta*MAX3(Tr, Tg, Tb);
1548                 }
1549                 else Tin= Ta;
1550                 if(tex->flag & TEX_NEGALPHA) Ta= 1.0f-Ta;
1551                 
1552                 if( (R.flag & R_SEC_FIELD) && (ibuf->flags & IB_fields) ) {
1553                         ibuf->rect-= (ibuf->x*ibuf->y);
1554                 }
1555
1556                 if(tex->nor && (tex->imaflag & TEX_NORMALMAP)) {
1557                         tex->nor[0]= 0.5-Tr;
1558                         tex->nor[1]= 0.5-Tg;
1559                         tex->nor[2]= -Tb;
1560                 }
1561         }
1562         else {
1563                 Tin= 0.0f;
1564                 return 0;
1565         }
1566         
1567         if(tex->nor) return 3;
1568         else return 1;
1569 }
1570