~ubuntu-branches/ubuntu/saucy/blender/saucy-proposed

« back to all changes in this revision

Viewing changes to source/blender/compositor/operations/COM_GlareGhostOperation.cpp

  • Committer: Package Import Robot
  • Author(s): Jeremy Bicha
  • Date: 2013-03-06 12:08:47 UTC
  • mfrom: (1.5.1) (14.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20130306120847-frjfaryb2zrotwcg
Tags: 2.66a-1ubuntu1
* Resynchronize with Debian (LP: #1076930, #1089256, #1052743, #999024,
  #1122888, #1147084)
* debian/control:
  - Lower build-depends on libavcodec-dev since we're not
    doing the libav9 transition in Ubuntu yet

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2011, Blender Foundation.
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software Foundation,
 
16
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 *
 
18
 * Contributor:
 
19
 *              Jeroen Bakker
 
20
 *              Monique Dewanchand
 
21
 */
 
22
 
 
23
#include "COM_GlareGhostOperation.h"
 
24
#include "BLI_math.h"
 
25
#include "COM_FastGaussianBlurOperation.h"
 
26
 
 
27
static float smoothMask(float x, float y)
 
28
{
 
29
        float t;
 
30
        x = 2.0f * x - 1.0f;
 
31
        y = 2.0f * y - 1.0f;
 
32
        if ((t = 1.0f - sqrtf(x * x + y * y)) > 0.0f) {
 
33
                return t;
 
34
        }
 
35
        else {
 
36
                return 0.0f;
 
37
        }
 
38
}
 
39
 
 
40
void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, NodeGlare *settings)
 
41
{
 
42
        const int qt = 1 << settings->quality;
 
43
        const float s1 = 4.f / (float)qt, s2 = 2.f * s1;
 
44
        int x, y, n, p, np;
 
45
        fRGB c, tc, cm[64];
 
46
        float sc, isc, u, v, sm, s, t, ofs, scalef[64];
 
47
        const float cmo = 1.f - settings->colmod;
 
48
 
 
49
        MemoryBuffer *gbuf = inputTile->duplicate();
 
50
        MemoryBuffer *tbuf1 = inputTile->duplicate();
 
51
 
 
52
        bool breaked = false;
 
53
 
 
54
        FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 0, 3);
 
55
        if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 1, 3);
 
56
        if (isBreaked()) breaked = true;
 
57
        if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf1, s1, 2, 3);
 
58
 
 
59
        MemoryBuffer *tbuf2 = tbuf1->duplicate();
 
60
 
 
61
        if (isBreaked()) breaked = true;
 
62
        if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 0, 3);
 
63
        if (isBreaked()) breaked = true;
 
64
        if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 1, 3);
 
65
        if (isBreaked()) breaked = true;
 
66
        if (!breaked) FastGaussianBlurOperation::IIR_gauss(tbuf2, s2, 2, 3);
 
67
 
 
68
        if (settings->iter & 1) ofs = 0.5f; else ofs = 0.f;
 
69
        for (x = 0; x < (settings->iter * 4); x++) {
 
70
                y = x & 3;
 
71
                cm[x][0] = cm[x][1] = cm[x][2] = 1;
 
72
                if (y == 1) fRGB_rgbmult(cm[x], 1.f, cmo, cmo);
 
73
                if (y == 2) fRGB_rgbmult(cm[x], cmo, cmo, 1.f);
 
74
                if (y == 3) fRGB_rgbmult(cm[x], cmo, 1.f, cmo);
 
75
                scalef[x] = 2.1f * (1.f - (x + ofs) / (float)(settings->iter * 4));
 
76
                if (x & 1) scalef[x] = -0.99f / scalef[x];
 
77
        }
 
78
 
 
79
        sc = 2.13;
 
80
        isc = -0.97;
 
81
        for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
 
82
                v = ((float)y + 0.5f) / (float)gbuf->getHeight();
 
83
                for (x = 0; x < gbuf->getWidth(); x++) {
 
84
                        u = ((float)x + 0.5f) / (float)gbuf->getWidth();
 
85
                        s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f;
 
86
                        tbuf1->readCubic(c, s * gbuf->getWidth(), t * gbuf->getHeight());
 
87
                        sm = smoothMask(s, t);
 
88
                        mul_v3_fl(c, sm);
 
89
                        s = (u - 0.5f) * isc + 0.5f, t = (v - 0.5f) * isc + 0.5f;
 
90
                        tbuf2->readCubic(tc, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
 
91
                        sm = smoothMask(s, t);
 
92
                        madd_v3_v3fl(c, tc, sm);
 
93
 
 
94
                        gbuf->writePixel(x, y, c);
 
95
                }
 
96
                if (isBreaked()) breaked = true;
 
97
 
 
98
        }
 
99
 
 
100
        memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
 
101
        for (n = 1; n < settings->iter && (!breaked); n++) {
 
102
                for (y = 0; y < gbuf->getHeight() && (!breaked); y++) {
 
103
                        v = ((float)y + 0.5f) / (float)gbuf->getHeight();
 
104
                        for (x = 0; x < gbuf->getWidth(); x++) {
 
105
                                u = ((float)x + 0.5f) / (float)gbuf->getWidth();
 
106
                                tc[0] = tc[1] = tc[2] = 0.f;
 
107
                                for (p = 0; p < 4; p++) {
 
108
                                        np = (n << 2) + p;
 
109
                                        s = (u - 0.5f) * scalef[np] + 0.5f;
 
110
                                        t = (v - 0.5f) * scalef[np] + 0.5f;
 
111
                                        gbuf->readCubic(c, s * gbuf->getWidth() - 0.5f, t * gbuf->getHeight() - 0.5f);
 
112
                                        mul_v3_v3(c, cm[np]);
 
113
                                        sm = smoothMask(s, t) * 0.25f;
 
114
                                        madd_v3_v3fl(tc, c, sm);
 
115
                                }
 
116
                                tbuf1->addPixel(x, y, tc);
 
117
                        }
 
118
                        if (isBreaked()) breaked = true;
 
119
                }
 
120
                memcpy(gbuf->getBuffer(), tbuf1->getBuffer(), tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
 
121
        }
 
122
        memcpy(data, gbuf->getBuffer(), gbuf->getWidth() * gbuf->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float));
 
123
 
 
124
        delete gbuf;
 
125
        delete tbuf1;
 
126
        delete tbuf2;
 
127
}