Code

revert jasper's way overzealous fix in png-write.cpp rev 13700; new fix in item_rende...
[inkscape.git] / src / display / nr-filter-colormatrix.cpp
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  */
12 #include "display/nr-filter-colormatrix.h"
13 #include "display/nr-filter-utils.h"
14 #include<math.h>
16 namespace NR {
18 FilterColorMatrix::FilterColorMatrix()
19 {
20 }
22 FilterPrimitive * FilterColorMatrix::create() {
23     return new FilterColorMatrix();
24 }
26 FilterColorMatrix::~FilterColorMatrix()
27 {}
29 int FilterColorMatrix::render(FilterSlot &slot, Matrix const &trans) {
30     NRPixBlock *in = slot.get(_input);
31     NRPixBlock *out = new NRPixBlock;
33     nr_pixblock_setup_fast(out, in->mode,
34                            in->area.x0, in->area.y0, in->area.x1, in->area.y1,
35                            true);
37     unsigned char *in_data = NR_PIXBLOCK_PX(in);
38     unsigned char *out_data = NR_PIXBLOCK_PX(out);
39     unsigned char r,g,b,a;
40     int x,y,x0,y0,x1,y1,i;
41     double a00,a01,a02,a10,a11,a12,a20,a21,a22, coshue, sinhue;
42     x0=in->area.x0;
43     y0=in->area.y0;
44     x1=in->area.x1;
45     y1=in->area.y1;    
47     switch(type){
48         case COLORMATRIX_MATRIX:
49             if (values.size()!=20) {
50                 g_warning("ColorMatrix: values parameter error. Wrong size.");
51                 return -1;
52             }
53             for (x=x0;x<x1;x++){
54                 for (y=y0;y<y1;y++){
55                     i = ((x-x0) + (x1-x0)*(y-y0))*4;
56                     r = in_data[i];
57                     g = in_data[i+1];
58                     b = in_data[i+2];
59                     a = in_data[i+3];
60                     out_data[i] = CLAMP_D_TO_U8( r*values[0] + g*values[1] + b*values[2] + a*values[3] + values[4] );
61                     out_data[i+1] = CLAMP_D_TO_U8( r*values[5] + g*values[6] + b*values[7] + a*values[8] + values[9] );
62                     out_data[i+2] = CLAMP_D_TO_U8( r*values[10] + g*values[11] + b*values[12] + a*values[13] + values[14] );
63                     out_data[i+3] = CLAMP_D_TO_U8( r*values[15] + g*values[16] + b*values[17] + a*values[18] + values[19] );
64                 }
65             }
66             break;
67         case COLORMATRIX_SATURATE:
68             for (x=x0;x<x1;x++){
69                 for (y=y0;y<y1;y++){
70                     i = ((x-x0) + (x1-x0)*(y-y0))*4;
71                     r = in_data[i];
72                     g = in_data[i+1];
73                     b = in_data[i+2];
74                     a = in_data[i+3];
75                     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) );
76                     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) );
77                     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) );
78                     out_data[i+3] = a;
79                 }
80             }
81             break;
82         case COLORMATRIX_HUEROTATE:
83             coshue = cos(value);
84             sinhue = sin(value);
85             a00 = 0.213 + coshue*( 0.787) + sinhue*(-0.213);
86             a01 = 0.715 + coshue*(-0.715) + sinhue*(-0.715);
87             a02 = 0.072 + coshue*(-0.072) + sinhue*( 0.928);
88             a10 = 0.213 + coshue*(-0.213) + sinhue*( 0.143);
89             a11 = 0.715 + coshue*( 0.285) + sinhue*( 0.140);
90             a12 = 0.072 + coshue*(-0.072) + sinhue*(-0.283);
91             a20 = 0.213 + coshue*(-0.213) + sinhue*(-0.787);
92             a21 = 0.715 + coshue*(-0.715) + sinhue*( 0.715);
93             a22 = 0.072 + coshue*( 0.928) + sinhue*( 0.072);
94                                     
95             for (x=x0;x<x1;x++){
96                 for (y=y0;y<y1;y++){
97                     i = ((x-x0) + (x1-x0)*(y-y0))*4;
98                     r = in_data[i];
99                     g = in_data[i+1];
100                     b = in_data[i+2];
101                     a = in_data[i+3];
102                     
103                     out_data[i] = CLAMP_D_TO_U8( r*a00 + g*a01 + b*a02 );
104                     out_data[i+1] = CLAMP_D_TO_U8( r*a10 + g*a11 + b*a12 );
105                     out_data[i+2] = CLAMP_D_TO_U8( r*a20 + g*a21 + b*a22 );
106                     out_data[i+3] = a;
107                 }
108             }
109             break;
110         case COLORMATRIX_LUMINANCETOALPHA:
111             for (x=x0;x<x1;x++){
112                 for (y=y0;y<y1;y++){
113                     i = ((x-x0) + (x1-x0)*(y-y0))*4;
114                     r = in_data[i];
115                     g = in_data[i+1];
116                     b = in_data[i+2];
117                     out_data[i] = 0;
118                     out_data[i+1] = 0;
119                     out_data[i+2] = 0;
120                     out_data[i+3] = CLAMP_D_TO_U8( r*0.2125 + g*0.7154 + b*0.0721);
121                 }
122             }
123             break;
124         case COLORMATRIX_ENDTYPE:
125             break;
126     }
127     out->empty = FALSE;
128     slot.set(_output, out);
129     return 0;
132 void FilterColorMatrix::area_enlarge(NRRectL &area, Matrix const &trans)
136 void FilterColorMatrix::set_type(FilterColorMatrixType t){
137         type = t;
140 void FilterColorMatrix::set_value(gdouble v){
141         value = v;
144 void FilterColorMatrix::set_values(std::vector<gdouble> &v){
145         values = v;
148 } /* namespace NR */
150 /*
151   Local Variables:
152   mode:c++
153   c-file-style:"stroustrup"
154   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
155   indent-tabs-mode:nil
156   fill-column:99
157   End:
158 */
159 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :