Code

6cc6dd7b8f713651ce5253b3190859a579bf5ac5
[inkscape.git] / src / display / nr-filter-morphology.cpp
1 /*
2  * feMorphology 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-morphology.h"
13 namespace NR {
15 FilterMorphology::FilterMorphology()
16 {
17 }
19 FilterPrimitive * FilterMorphology::create() {
20     return new FilterMorphology();
21 }
23 FilterMorphology::~FilterMorphology()
24 {}
26 int FilterMorphology::render(FilterSlot &slot, Matrix const &trans) {
27     NRPixBlock *in = slot.get(_input);
28     NRPixBlock *out = new NRPixBlock;
30     int x0=in->area.x0;
31     int y0=in->area.y0;
32     int x1=in->area.x1;
33     int y1=in->area.y1;            
34     int w=x1-x0, h=y1-y0;
35     int x,y,i,j;
36     int rmax,gmax,bmax,amax;
37     int rmin,gmin,bmin,amin;
38     
39     nr_pixblock_setup_fast(out, in->mode, x0, y0, x1, y1, true);
41     unsigned char *in_data = NR_PIXBLOCK_PX(in);
42     unsigned char *out_data = NR_PIXBLOCK_PX(out);
44     for(x=xradius; x<w-xradius; x++){
45         for(y=yradius; y<h-yradius; y++){
46             rmin=rmax=in_data[4*(x + w*y)];
47             gmin=gmax=in_data[4*(x + w*y)+1];
48             bmin=bmax=in_data[4*(x + w*y)+2];
49             amin=amax=in_data[4*(x + w*y)+3];
50             for(i=x-xradius;i<x+xradius;i++){
51                 for(j=y-yradius;j<y+yradius;j++){
52                     if(in_data[4*(i + w*j)]>rmax) rmax = in_data[4*(i + w*j)];
53                     if(in_data[4*(i + w*j)+1]>gmax) gmax = in_data[4*(i + w*j)+1];
54                     if(in_data[4*(i + w*j)+2]>bmax) bmax = in_data[4*(i + w*j)+2];
55                     if(in_data[4*(i + w*j)+3]>amax) amax = in_data[4*(i + w*j)+3];
56                                                             
57                     if(in_data[4*(i + w*j)]<rmin) rmin = in_data[4*(i + w*j)];
58                     if(in_data[4*(i + w*j)+1]<gmin) gmin = in_data[4*(i + w*j)+1];
59                     if(in_data[4*(i + w*j)+2]<bmin) bmin = in_data[4*(i + w*j)+2];
60                     if(in_data[4*(i + w*j)+3]<amin) amin = in_data[4*(i + w*j)+3];                    
61                 }
62             }
63             if (Operator==MORPHOLOGY_OPERATOR_DILATE){
64                 out_data[4*(x + w*y)]=rmax;
65                 out_data[4*(x + w*y)+1]=gmax;
66                 out_data[4*(x + w*y)+2]=bmax;
67                 out_data[4*(x + w*y)+3]=amax;
68             } else {
69                 out_data[4*(x + w*y)]=rmin;
70                 out_data[4*(x + w*y)+1]=gmin;
71                 out_data[4*(x + w*y)+2]=bmin;
72                 out_data[4*(x + w*y)+3]=amin;
73             }
74         }
75     }
76    
77     out->empty = FALSE;
78     slot.set(_output, out);
79     return 0;
80 }
82 void FilterMorphology::area_enlarge(NRRectL &area, Matrix const &trans)
83 {
84     area.x0-=xradius;
85     area.x1+=xradius;
86     area.y0-=yradius;
87     area.y1+=yradius;            
88 }
90 void FilterMorphology::set_operator(FilterMorphologyOperator &o){
91     Operator = o;
92 }
94 void FilterMorphology::set_xradius(int x){
95     xradius = x;
96 }
98 void FilterMorphology::set_yradius(int y){
99     yradius = y;
102 FilterTraits FilterMorphology::get_input_traits() {
103     return TRAIT_PARALLER;
106 } /* namespace NR */
108 /*
109   Local Variables:
110   mode:c++
111   c-file-style:"stroustrup"
112   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
113   indent-tabs-mode:nil
114   fill-column:99
115   End:
116 */
117 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :