~ubuntu-branches/debian/squeeze/inkscape/squeeze

« back to all changes in this revision

Viewing changes to src/display/nr-filter-colormatrix.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-09-09 23:29:02 UTC
  • mfrom: (1.1.7 upstream)
  • Revision ID: james.westby@ubuntu.com-20080909232902-c50iujhk1w79u8e7
Tags: 0.46-2.1
* Non-maintainer upload.
* Add upstream patch fixing a crash in the open dialog
  in the zh_CN.utf8 locale. Closes: #487623.
  Thanks to Luca Bruno for the patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * feColorMatrix filter primitive renderer
 
3
 *
 
4
 * Authors:
 
5
 *   Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com>
 
6
 *
 
7
 * Copyright (C) 2007 authors
 
8
 *
 
9
 * Released under GNU GPL, read the file 'COPYING' for more information
 
10
 */
 
11
 
 
12
#include "display/nr-filter-colormatrix.h"
 
13
#include "display/nr-filter-units.h"
 
14
#include "display/nr-filter-utils.h"
 
15
#include "libnr/nr-blit.h"
 
16
#include <math.h>
 
17
 
 
18
namespace NR {
 
19
 
 
20
FilterColorMatrix::FilterColorMatrix()
 
21
{
 
22
}
 
23
 
 
24
FilterPrimitive * FilterColorMatrix::create() {
 
25
    return new FilterColorMatrix();
 
26
}
 
27
 
 
28
FilterColorMatrix::~FilterColorMatrix()
 
29
{}
 
30
 
 
31
int FilterColorMatrix::render(FilterSlot &slot, FilterUnits const &/*units*/) {
 
32
    NRPixBlock *in = slot.get(_input);
 
33
    if (!in) {
 
34
        g_warning("Missing source image for feColorMatrix (in=%d)", _input);
 
35
        return 1;
 
36
    }
 
37
 
 
38
    NRPixBlock *out = new NRPixBlock;
 
39
 
 
40
    nr_pixblock_setup_fast(out, NR_PIXBLOCK_MODE_R8G8B8A8N,
 
41
                           in->area.x0, in->area.y0, in->area.x1, in->area.y1,
 
42
                           true);
 
43
 
 
44
    // this primitive is defined for non-premultiplied RGBA values,
 
45
    // thus convert them to that format
 
46
    if (in->mode != NR_PIXBLOCK_MODE_R8G8B8A8N) {
 
47
        NRPixBlock *original_in = in;
 
48
        in = new NRPixBlock;
 
49
        nr_pixblock_setup_fast(in, NR_PIXBLOCK_MODE_R8G8B8A8N,
 
50
                               original_in->area.x0, original_in->area.y0,
 
51
                               original_in->area.x1, original_in->area.y1,
 
52
                               false);
 
53
        nr_blit_pixblock_pixblock(in, original_in);
 
54
    }
 
55
 
 
56
    unsigned char *in_data = NR_PIXBLOCK_PX(in);
 
57
    unsigned char *out_data = NR_PIXBLOCK_PX(out);
 
58
    unsigned char r,g,b,a;
 
59
    int x,y,x0,y0,x1,y1,i;
 
60
    double a00,a01,a02,a10,a11,a12,a20,a21,a22, coshue, sinhue;
 
61
    x0=in->area.x0;
 
62
    y0=in->area.y0;
 
63
    x1=in->area.x1;
 
64
    y1=in->area.y1;
 
65
 
 
66
    switch(type){
 
67
        case COLORMATRIX_MATRIX:
 
68
            if (values.size()!=20) {
 
69
                g_warning("ColorMatrix: values parameter error. Wrong size: %i.", static_cast<int>(values.size()));
 
70
                return -1;
 
71
            }
 
72
            for (x=x0;x<x1;x++){
 
73
                for (y=y0;y<y1;y++){
 
74
                    i = ((x-x0) + (x1-x0)*(y-y0))*4;
 
75
                    r = in_data[i];
 
76
                    g = in_data[i+1];
 
77
                    b = in_data[i+2];
 
78
                    a = in_data[i+3];
 
79
                    out_data[i] = CLAMP_D_TO_U8( r*values[0] + g*values[1] + b*values[2] + a*values[3] + 255*values[4] );
 
80
                    out_data[i+1] = CLAMP_D_TO_U8( r*values[5] + g*values[6] + b*values[7] + a*values[8] + 255*values[9] );
 
81
                    out_data[i+2] = CLAMP_D_TO_U8( r*values[10] + g*values[11] + b*values[12] + a*values[13] + 255*values[14] );
 
82
                    out_data[i+3] = CLAMP_D_TO_U8( r*values[15] + g*values[16] + b*values[17] + a*values[18] + 255*values[19] );
 
83
                }
 
84
            }
 
85
            break;
 
86
        case COLORMATRIX_SATURATE:
 
87
            for (x=x0;x<x1;x++){
 
88
                for (y=y0;y<y1;y++){
 
89
                    i = ((x-x0) + (x1-x0)*(y-y0))*4;
 
90
                    r = in_data[i];
 
91
                    g = in_data[i+1];
 
92
                    b = in_data[i+2];
 
93
                    a = in_data[i+3];
 
94
                    out_data[i] = CLAMP_D_TO_U8( r*(0.213+0.787*value) + g*(0.715-0.715*value) + b*(0.072-0.072*value) );
 
95
                    out_data[i+1] = CLAMP_D_TO_U8( r*(0.213-0.213*value) + g*(0.715+0.285*value) + b*(0.072-0.072*value) );
 
96
                    out_data[i+2] = CLAMP_D_TO_U8( r*(0.213-0.213*value) + g*(0.715-0.715*value) + b*(0.072+0.928*value) );
 
97
                    out_data[i+3] = a;
 
98
                }
 
99
            }
 
100
            break;
 
101
        case COLORMATRIX_HUEROTATE:
 
102
            coshue = cos(value * M_PI/180.0);
 
103
            sinhue = sin(value * M_PI/180.0);
 
104
            a00 = 0.213 + coshue*( 0.787) + sinhue*(-0.213);
 
105
            a01 = 0.715 + coshue*(-0.715) + sinhue*(-0.715);
 
106
            a02 = 0.072 + coshue*(-0.072) + sinhue*( 0.928);
 
107
            a10 = 0.213 + coshue*(-0.213) + sinhue*( 0.143);
 
108
            a11 = 0.715 + coshue*( 0.285) + sinhue*( 0.140);
 
109
            a12 = 0.072 + coshue*(-0.072) + sinhue*(-0.283);
 
110
            a20 = 0.213 + coshue*(-0.213) + sinhue*(-0.787);
 
111
            a21 = 0.715 + coshue*(-0.715) + sinhue*( 0.715);
 
112
            a22 = 0.072 + coshue*( 0.928) + sinhue*( 0.072);
 
113
 
 
114
            for (x=x0;x<x1;x++){
 
115
                for (y=y0;y<y1;y++){
 
116
                    i = ((x-x0) + (x1-x0)*(y-y0))*4;
 
117
                    r = in_data[i];
 
118
                    g = in_data[i+1];
 
119
                    b = in_data[i+2];
 
120
                    a = in_data[i+3];
 
121
 
 
122
                    out_data[i] = CLAMP_D_TO_U8( r*a00 + g*a01 + b*a02 );
 
123
                    out_data[i+1] = CLAMP_D_TO_U8( r*a10 + g*a11 + b*a12 );
 
124
                    out_data[i+2] = CLAMP_D_TO_U8( r*a20 + g*a21 + b*a22 );
 
125
                    out_data[i+3] = a;
 
126
                }
 
127
            }
 
128
            break;
 
129
        case COLORMATRIX_LUMINANCETOALPHA:
 
130
            for (x=x0;x<x1;x++){
 
131
                for (y=y0;y<y1;y++){
 
132
                    i = ((x-x0) + (x1-x0)*(y-y0))*4;
 
133
                    r = in_data[i];
 
134
                    g = in_data[i+1];
 
135
                    b = in_data[i+2];
 
136
                    out_data[i] = 0;
 
137
                    out_data[i+1] = 0;
 
138
                    out_data[i+2] = 0;
 
139
                    out_data[i+3] = CLAMP_D_TO_U8( r*0.2125 + g*0.7154 + b*0.0721);
 
140
                }
 
141
            }
 
142
            break;
 
143
        case COLORMATRIX_ENDTYPE:
 
144
            break;
 
145
    }
 
146
    out->empty = FALSE;
 
147
    slot.set(_output, out);
 
148
    return 0;
 
149
}
 
150
 
 
151
void FilterColorMatrix::area_enlarge(NRRectL &/*area*/, Matrix const &/*trans*/)
 
152
{
 
153
}
 
154
 
 
155
void FilterColorMatrix::set_type(FilterColorMatrixType t){
 
156
        type = t;
 
157
}
 
158
 
 
159
void FilterColorMatrix::set_value(gdouble v){
 
160
        value = v;
 
161
}
 
162
 
 
163
void FilterColorMatrix::set_values(std::vector<gdouble> &v){
 
164
        values = v;
 
165
}
 
166
 
 
167
} /* namespace NR */
 
168
 
 
169
/*
 
170
  Local Variables:
 
171
  mode:c++
 
172
  c-file-style:"stroustrup"
 
173
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
 
174
  indent-tabs-mode:nil
 
175
  fill-column:99
 
176
  End:
 
177
*/
 
178
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :