Bunch of gcc 4.0 warning fixes.
[blender.git] / source / blender / render / intern / source / zblur.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. The Blender
10  * Foundation also sells licenses for use in proprietary software under
11  * the Blender License.  See http://www.blender.org/BL/ for information
12  * about this.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  *
23  * ***** END GPL/BL DUAL LICENSE BLOCK *****
24  */
25
26 /* 
27  * This file is largely based on the focal blur plugin by onk, 8.99
28  *
29  */
30
31 #include <math.h>
32 #include <string.h>
33 #include <limits.h>
34 #include <stdio.h>
35
36 #include "MEM_guardedalloc.h"
37
38 #include "DNA_camera_types.h"
39 #include "DNA_scene_types.h"
40
41 #include "BKE_global.h"
42 #include "BKE_utildefines.h"
43
44 #include "RE_callbacks.h"
45
46 #include "render.h"
47 #include "pixelblending.h"
48
49 #include "blendef.h"
50
51 //#include "BIF_gl.h"
52
53 /* -------------------------------------------------
54  * defines, protos */
55
56 typedef enum { I_GRAY, I_FLOAT, I_FLOAT4 } IMGTYPE;
57
58 typedef struct {
59         int x, y;
60         int size, el_size;
61         IMGTYPE type;
62         char *data;
63 } Image;
64
65 typedef struct {                        /* blur mask struct */
66         int size;
67         float fac;
68         float *val;
69 } Mask;
70
71 typedef Mask* Maskarray;
72
73 /* don't change these */
74 #define NMASKS_SHIFT 2                  
75 #define NMASKS 64
76
77
78 static Image *alloc_img(int x, int y, IMGTYPE type)
79 {
80         Image *ret;
81         int size, typesize;
82
83         switch (type) {
84         case I_GRAY:
85                 typesize = 1;
86                 break;
87         case I_FLOAT:
88                 typesize = sizeof(float);
89                 break;
90         case I_FLOAT4:
91                 typesize = 4 * sizeof(float);
92                 break;
93         default:
94                 return 0;
95         }
96
97         size = x * y;
98         
99         ret = (Image *) MEM_mallocN(sizeof(Image) + size*typesize, "zblur_img");
100         if (ret) {
101                 ret->x = x;
102                 ret->y = y;
103                 ret->size = size;
104                 ret->el_size = typesize;
105                 ret->type = type;
106                 ret->data = (char *) (ret + 1);
107                 size *= typesize;
108                 memset(ret->data, 0, size);
109         }
110
111         return ret;
112 }
113
114 static int free_img(Image *img)
115 {
116         MEM_freeN(img);
117         return 1;
118 }
119
120 /* 32 bits (int) rect to float buf */
121 static void recti2imgf(unsigned int *src, Image *dest, int x, int y)
122 {
123         char *from;
124         float *to;
125         int i, ix, iy;
126         
127         if(dest->type != I_FLOAT4) return;
128         
129         from = (char *) src;
130         to = (float *) dest->data;
131         
132         if (R.r.mode & R_FIELDS) {      /* double each scanline */
133                 for (iy=0; iy<y; iy++) {
134                         for (ix=0; ix<x; ix++) {
135                                 *to++ = ((float)from[0])/255.0;
136                                 *to++ = ((float)from[1])/255.0;
137                                 *to++ = ((float)from[2])/255.0;
138                                 *to++ = ((float)from[3])/255.0;
139                                 from += 4;
140                         }
141                         
142                         memcpy(to, to-4*sizeof(float)*x, 4*sizeof(float)*x);
143                         to+= 4*x;
144                         
145                         iy++;
146                 }
147         }
148         else {
149                 i = x * y;
150                 while(i--) {
151                         *to++ = ((float)from[0])/255.0;
152                         *to++ = ((float)from[1])/255.0;
153                         *to++ = ((float)from[2])/255.0;
154                         *to++ = ((float)from[3])/255.0;
155                         from += 4;
156                 }
157         }
158 }
159
160 /* float rect to float buf */
161 static void rectf2imgf(float *src, Image *dest, int x, int y)
162 {
163         float *from;
164         float *to;
165         int i, iy;
166         
167         if(dest->type != I_FLOAT4) return;
168
169         from = src;
170         to = (float *) dest->data;
171         
172         if (R.r.mode & R_FIELDS) {      /* double each scanline */
173                 for (iy=0; iy<y; iy++) {
174                         
175                         memcpy(to, from, 4*sizeof(float)*x);
176                         to+= 4*x;
177                         memcpy(to, from, 4*sizeof(float)*x);
178                         to+= 4*x;
179                         
180                         iy++;
181                         from += 4*x;
182                 }
183         }
184         else {
185                 i = y;
186                 while(i--) {
187                         memcpy(to, from, 4*sizeof(float)*x);
188                         from += 4*x;
189                         to += 4*x;
190                 }
191         }
192 }
193
194 /* floatbuf back to 32 bits rect */
195 static void imgf2recti(Image *src, unsigned int *dest)
196 {
197         float *from;
198         char *to;
199         int i, ix, iy;
200         
201         if(src->type != I_FLOAT4) return;
202         
203         from = (float *) src->data;
204         to = (char *) dest;
205         
206         if (R.r.mode & R_FIELDS) {
207                 for (iy=0; iy<src->y; iy++) {
208                         for (ix=0; ix<src->x; ix++) {
209                                 *to++ = (char)(from[0]*255.0);
210                                 *to++ = (char)(from[1]*255.0);
211                                 *to++ = (char)(from[2]*255.0);
212                                 *to++ = (char)(from[3]*255.0);
213                                 from += 4;
214                         }
215                         iy++;
216                         from+= 4*src->x;
217                 }       
218         }
219         else {
220                 i = src->x * src->y;
221                 while(i--) {
222                         *to++ = (char)(from[0]*255.0);
223                         *to++ = (char)(from[1]*255.0);
224                         *to++ = (char)(from[2]*255.0);
225                         *to++ = (char)(from[3]*255.0);
226                         from += 4;
227                 }
228         }
229 }
230
231 /* floatbuf back to float rect */
232 static void imgf2rectf(Image *src, float *dest)
233 {
234         float *from;
235         float *to;
236         int i, iy;
237         
238         if(src->type != I_FLOAT4) return;
239         
240         from = (float *) src->data;
241         to = dest;
242         
243         if (R.r.mode & R_FIELDS) {
244                 for (iy=0; iy<src->y; iy++) {
245                         
246                         memcpy(to, from, 4*sizeof(float)*src->x);
247                         
248                         iy++;
249                         to+= 4*src->x;
250                         from+= 8*src->x;
251                 }
252         }
253         else {
254                 i = src->x * src->y;
255                 memcpy(to, from, 4*sizeof(float)*i);
256         }
257 }
258
259
260 static void imgf_gamma(Image *src, float gamma)
261 {
262         float *to;
263         int i;
264         
265         if(gamma==1.0) return;
266         
267         i = 4 * src->x * src->y;
268         to= (float *) src->data;
269         while(i--) {
270                 *to = (float)pow(*to, gamma); 
271                 to++;
272         }
273 }
274
275 #if 0
276 /* create new image with alpha & color zero where mask is zero */
277 static Image *imgf_apply_mask(Image *src, Image *zmask)
278 {
279         Image *dest;
280         float *from, *to;
281         int i;
282         char *zptr;
283         
284         dest = alloc_img(src->x, src->y, I_FLOAT4);
285         
286         i= src->x * src->y;
287         from= (float *) src->data;
288         to= (float *) dest->data;
289         zptr= (char *)zmask->data;
290
291         while(i--) {
292                 if(*zptr) {
293                         to[0]= from[0];
294                         to[1]= from[1];
295                         to[2]= from[2];
296                         to[3]= from[3];
297                 }
298                 else {
299                         to[0]= to[1]= to[2]= to[3]= 0.0f;
300                 }
301                 zptr++;
302                 to+= 4;
303                 from+= 4;
304         }
305         
306         return dest;
307 }
308
309 static void imgf_alpha_over(Image *dest, Image *src)
310 {
311         float *from, *to;
312         int i;
313         
314         i= src->x * src->y;
315         from= (float *) src->data;
316         to= (float *) dest->data;
317         
318         while(i--) {
319                 addAlphaOverFloat(to, from);
320                 to+= 4;
321                 from+= 4;
322         }
323 }
324
325 #endif
326
327 /* --------------------------------------------------------------------- */
328 /* mask routines */
329
330 static Mask *alloc_mask(int size)
331 {
332         Mask *m;
333         int memsize;
334
335         memsize = (sizeof(Mask) + (2 * size +1) * (2 * size +1) * sizeof(float));
336
337         m = (Mask*) MEM_mallocN(memsize, "zblur_mask");
338         m->size = size;
339         m->val = (float *) (m + 1);
340
341         return m;
342 }
343
344 static void free_mask(Mask *m)
345 {
346         int memsize;
347
348         memsize = 2 * m->size + 1;
349         memsize *= memsize * sizeof(float);
350         memsize += sizeof(Mask);
351         
352         MEM_freeN(m);
353 }
354
355 /* normalize mask to 1 */
356
357 static void norm_mask(Mask *m)
358 {
359         float fac;
360         int size;
361         float *v;
362
363         fac = m->fac;
364         size = (2 * m->size +1)*(2 * m->size +1);
365
366         v = m->val;
367         while(size--) {
368                 *v++ *= fac;
369         }
370         m->fac = 1.0;
371 }
372
373 /* filters a grayvalue image with a gaussian IIR filter with blur radius "rad" 
374  * For large blurs, it's more efficient to call the routine several times
375  * instead of using big blur radii.
376  * The original image is changed */
377
378
379 static void gauss_blur(Image *img, float rad)
380 {
381         Image *new;
382         register float sum, val;
383         float gval;
384         float *gausstab, *v;
385         int r, n, m;
386         int x, y;
387         int i;
388         int step, bigstep;
389         char *src, *dest;
390
391         r = (1.5 * rad + 1.5);
392         n = 2 * r + 1;
393         
394         /* ugly : */
395         if ((img->x <= n) || (img->y <= n)) {
396                 return;
397         }
398         
399         gausstab = (float *) MEM_mallocN(n * sizeof(float), "zblur_gauss");
400         if (!gausstab) {
401                 return;
402         }
403         
404         sum = 0.0;
405         v = gausstab;
406         for (x = -r; x <= r; x++) {
407
408                 val = exp(-4*(float ) (x*x)/ (float) (r*r));
409                 sum += val;
410                 *v++ = val;
411         }
412
413         i = n;
414         v = gausstab;
415         while (i--) {
416                 *v++ /= sum;
417         }
418
419         new = alloc_img(img->x, img->y, I_GRAY);
420         if (!new) {
421                 return;
422         }
423
424         /* horizontal */
425
426         step = (n - 1);
427
428         for (y = 0; y < img->y; y++) {
429                 src = (char *)img->data + (y * img->x);
430                 dest = (char *)new->data + (y * img->x);
431
432                 for (x = r; x > 0 ; x--) {
433                         m = n - x;
434                         gval = 0.0;
435                         sum = 0.0;
436                         v = gausstab + x;
437                         for (i = 0; i < m; i++) {
438                                 val = *v++;
439                                 sum += val;
440                                 gval += val * (*src++);
441                         }
442                         *dest++ = gval / sum;
443                         src -= m;
444                 }
445
446                 for (x = 0; x <= (img->x - n); x++) {
447                         gval = 0.0;
448                         v = gausstab;
449
450                         for (i = 0; i < n; i++) {
451                                 val = *v++;
452                                 gval += val * (*src++);
453                         }
454                         *dest++ = gval;
455                         src -= step;
456                 }       
457
458                 for (x = 1; x <= r ; x++) {
459                         m = n - x;
460                         gval = 0.0;
461                         sum = 0.0;
462                         v = gausstab;
463                         for (i = 0; i < m; i++) {
464                                 val = *v++;
465                                 sum += val;
466                                 gval += val * (*src++);
467                         }
468                         *dest++ = gval / sum;
469                         src -= (m - 1);
470                 }
471         }
472
473         /* vertical */
474
475         step = img->x;
476         bigstep = (n - 1) * step;
477         for (x = 0; x < step  ; x++) {
478                 src = new->data + x;
479                 dest = img->data + x;
480
481                 for (y = r; y > 0; y--) {
482                         m = n - y;
483                         gval = 0.0;
484                         sum = 0.0;
485                         v = gausstab + y;
486                         for (i = 0; i < m; i++) {
487                                 val = *v++;
488                                 sum += val;
489                                 gval += val * src[0];
490                                 src += step;
491                         }
492                         dest[0] = gval / sum;
493                         src -= m * step;
494                         dest+= step;
495                 }
496                 for (y = 0; y <= (img->y - n); y++) {
497                         gval = 0.0;
498                         v = gausstab;
499                         for (i = 0; i < n; i++) {
500                                 val = *v++;
501                                 gval += val * src[0];
502                                 src += step;
503                         }
504                         dest[0] = gval;
505                         dest += step;
506                         src -= bigstep;
507                 }
508                 for (y = 1; y <= r ; y++) {
509                         m = n - y;
510                         gval = 0.0;
511                         sum = 0.0;
512                         v = gausstab;
513                         for (i = 0; i < m; i++) {
514                                 val = *v++;
515                                 sum += val;
516                                 gval += val * src[0];
517                                 src += step;
518                         }
519                         dest[0] = gval / sum;
520                         dest += step;
521                         src -= (m - 1) * step;
522                 }
523         }
524         MEM_freeN(gausstab);
525         free_img(new);
526 }
527
528 static float zigma(float x, float sigma, float sigma4)
529 {
530         //return 1.0/(1.0+pow(x, sigma));
531         
532         if(x < sigma) {
533                 x*= sigma;
534                 return 1.0/exp(x*x) - sigma4;
535         }
536         return 0.0;
537 }
538
539
540 static Mask *gauss_mask(float rad, float sigma)
541 {
542         Mask *m;
543         float sum, val, *v, fac, radsq= rad*rad;
544         float sigma4;
545         int r;
546         int ix, iy;
547         
548         r = (1.0 * rad + 1.0);
549         m = alloc_mask(r);
550         v = m->val;
551         sum = 0.0;
552         
553         sigma4= 1.0/exp(sigma*sigma*sigma*sigma);
554         
555         for (iy = -r; iy <= r; iy++) {
556                 for (ix = -r; ix <= r; ix++) {
557                         
558                         fac= ((float)(ix*ix + iy*iy))/(radsq);
559                         val = zigma(fac, sigma, sigma4);
560                         
561                         // val = exp(-(float) (ix*ix + iy*iy)/(rad * rad));
562                         sum += val;
563                         *v++ = val;
564                 }
565         }
566         
567         m->fac = 1.0 / sum;
568         
569         norm_mask(m);
570         return m;
571 }
572
573 /* generates #num masks with the maximal blur radius 'rad' 
574  * */
575 static Maskarray *init_masks(int num, float rad, float sigma)
576 {
577         int i;
578         float r, step;
579         Maskarray *maskarray;
580
581         maskarray = (Maskarray*) MEM_mallocN(num * sizeof (Maskarray), "zblur_masks");
582         step = rad / num;
583         r = 0.1;
584         for (i = 0; i < num; i++) {
585                 maskarray[i] = gauss_mask(r, sigma);
586                 r += step;
587         }
588         return maskarray;
589 }
590
591
592 /* ********************* Do the blur ******************************** */
593
594 static Image *zblur(Image *src, Image *zbuf, float radius, float sigma)
595 {
596         Image *dest;
597         Maskarray *mar;
598         Mask *m;
599         float *sptr, *dptr;
600         float *mval;                            /* mask value pointer */
601         float rval, gval, bval, aval;                   
602         float norm, fac;                        
603         int tmp;
604         int zval;
605         int size;
606         int row;
607         int mrow;
608         int x, y;
609         int i;
610         int sx, sy, ex, ey;
611         int mx, my;
612         char *zptr;
613
614         if(src->type != I_FLOAT4) return NULL;
615
616         dest = alloc_img(src->x, src->y, I_FLOAT4);
617         row = src->x * 4;
618
619         mar = init_masks(NMASKS, radius, sigma);
620
621         for (y = 0; y < src->y  ; y++) {
622                 for (x = 0; x < src->x; x++) {
623                         dptr = (float *) (dest->data + ((y * src->x + x) * src->el_size));
624                         zptr = zbuf->data + (y * src->x + x);
625                         zval = *zptr;
626                         sptr = (float *) (src->data + ((y *src->x + x )* src->el_size));
627
628                         m = mar[zval >> NMASKS_SHIFT];
629
630                         size = m->size;
631
632                         if(size==0 || zval==0) {
633                                 dptr[0] = sptr[0];
634                                 dptr[1] = sptr[1];
635                                 dptr[2] = sptr[2];
636                                 dptr[3] = sptr[3];
637                                 continue;
638                         }
639
640                         ex = src->x - x;
641                         ey = src->y - y;
642
643                         sx = (x < size) ? x : size;
644                         sy = (y < size) ? y : size;
645                         ex = (ex <= size) ? ex - 1: size;
646                         ey = (ey <= size) ? ey - 1: size;
647
648                         sptr -= sy *src->x * 4;
649                         zptr -= sy * src->x;
650                         mrow = (size << 1) + 1;
651                         mval = m->val + (size - sy) * mrow + size;
652
653                         norm = rval = gval = bval = aval= 0.0;
654         
655                         for (my = -sy; my <= ey; my++) {
656                                 for (mx = -sx; mx <= ex; mx++) {
657                                         if( zptr[mx] ) {
658                                                 tmp = 4 * mx;
659                                                 fac = mval[mx] * (float) zptr[mx] /255.0 ;
660                                                 
661                                                 norm += fac;
662                                                 rval += fac * sptr[tmp];
663                                                 gval += fac * sptr[tmp + 1];
664                                                 bval += fac * sptr[tmp + 2];
665                                                 aval += fac * sptr[tmp + 3];
666                                         }
667                                 }
668                                 mval += mrow;
669                                 sptr += row;
670                                 zptr += src->x;
671                         }
672
673                         dptr[0] = rval / norm;
674                         dptr[1] = gval / norm;
675                         dptr[2] = bval / norm;
676                         dptr[3] = aval / norm;
677                 }
678                 if(!(y % 4) && RE_local_test_break()) break;            
679         }
680         
681         for (i= 0; i < NMASKS; i++) {
682                 free_mask(mar[i]);
683         }
684         
685         MEM_freeN(mar);
686         
687         return dest;
688 }
689
690
691 /* this splits the z-buffer into 2 gray-images (background, foreground)
692 * which are used for the weighted blur */
693
694 static void zsplit(int *zptr, Image *fg, Image *bg, int zfocus, int zmax, int zmin, int x, int y)
695 {
696         char *p, *q;
697         int i, ix, iy;
698         float fdist;
699         float fgnorm, bgnorm;
700
701         p = fg->data;
702         q = bg->data;
703         bgnorm = 255.0 / ((float) zmax - (float) zfocus);
704         fgnorm = 255.0 / ((float) zfocus - (float) zmin);
705
706         if (R.r.mode & R_FIELDS) {
707                 for (iy=0; iy<y; iy++) {
708                         for (ix=0; ix<x; ix++) {
709                                 fdist = (float) (*zptr++);
710                                 if (fdist < zmin) fdist = zmin;
711                                         
712                                 fdist -= zfocus;
713                 
714                                 if (fdist < 0) {
715                                         *p = (char) (-fdist * fgnorm);
716                                         *q = 0;
717                                 }
718                                 else {
719                                         *q = (char) (fdist * bgnorm);
720                                         *p = 0;
721                                 }
722                                 p++, q++;                       
723                         }
724                         iy++;
725                         p+= x;
726                         q+= x;
727                 }
728         }
729         else {
730                 i = x * y;
731                 while(i--) {
732                         fdist = (float) (*zptr++);
733                         if (fdist < zmin) fdist = zmin;
734                                 
735                         fdist -= zfocus;
736         
737                         if (fdist < 0) {
738                                 *p = (char) (-fdist * fgnorm);
739                                 *q = 0;
740                         }
741                         else {
742                                 *q = (char) (fdist * bgnorm);
743                                 *p = 0;
744                         }
745                         p++, q++;
746                 }
747         }
748 }
749
750 void add_zblur(void)
751 {
752         Image *orig, *zfront, *work, *zback;
753         float zblurr;
754         int zfocus;
755         int x, y, zmin;
756         
757         if (R.rectz == NULL) return;
758         
759         x= R.rectx;
760         y= R.recty;
761
762         zblurr= (R.r.zblur*R.r.size)/100;
763         
764         if (R.r.mode & R_FIELDS) {
765                 y *= 2;
766                 zblurr *= 2;
767         } 
768
769         zmin= INT_MAX*( 2.0*R.r.zmin - 1.0);    // R.r.zmin ranges 0 - 1
770         zfocus = INT_MAX*( 2.0*R.r.focus - 1.0);
771         
772         if(zmin>zfocus) zmin= zfocus;
773         
774         zfront = alloc_img(x, y, I_GRAY);
775         zback = alloc_img(x, y, I_GRAY);
776         orig = alloc_img(x, y, I_FLOAT4);
777
778         if(R.rectftot) rectf2imgf(R.rectftot, orig, x, y);
779         else recti2imgf(R.rectot, orig, x, y);
780
781         imgf_gamma(orig, R.r.zgamma);   // pregamma correct if required
782         
783
784         /* split up z buffer into 2 gray images */
785         zsplit(R.rectz, zfront, zback, zfocus, INT_MAX, zmin, x, y);
786         
787 //      glDrawBuffer(GL_FRONT);
788 //      glRasterPos2i(0, 0);
789 //      glDrawPixels(x, y, GL_RED, GL_UNSIGNED_BYTE, zback->data);
790 //      glFlush();
791 //      glDrawBuffer(GL_BACK);
792         
793         gauss_blur(zback, 1.0);
794         gauss_blur(zfront, zblurr);
795         
796         /* blur back part */
797         work = zblur(orig, zback, zblurr, R.r.zsigma);
798         free_img(orig);
799         
800         /* blur front part */
801         orig = zblur(work, zfront, zblurr, R.r.zsigma);
802
803         imgf_gamma(orig, 1.0/R.r.zgamma);       // pregamma correct if required
804         
805         if(R.rectftot) imgf2rectf(orig, R.rectftot);
806         else imgf2recti(orig, R.rectot);
807         
808         free_img(work);
809         free_img(orig);
810         free_img(zfront); 
811         free_img(zback);
812
813         /* make new display rect */
814         if(R.rectftot) RE_floatbuffer_to_output();
815 }
816
817