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