~ubuntu-branches/ubuntu/gutsy/blender/gutsy-security

« back to all changes in this revision

Viewing changes to source/blender/render/intern/source/zblur.c

  • Committer: Bazaar Package Importer
  • Author(s): Florian Ernst
  • Date: 2005-11-06 12:40:03 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20051106124003-3pgs7tcg5rox96xg
Tags: 2.37a-1.1
* Non-maintainer upload.
* Split out parts of 01_SConstruct_debian.dpatch again: root_build_dir
  really needs to get adjusted before the clean target runs - closes: #333958,
  see #288882 for reference

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * $Id: zblur.c,v 1.5 2005/06/04 16:22:50 lukep Exp $
 
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