diff options
| author | Niko Kiirala <niko@kiirala.com> | 2007-07-20 20:19:00 +0000 |
|---|---|---|
| committer | kiirala <kiirala@users.sourceforge.net> | 2007-07-20 20:19:00 +0000 |
| commit | 35a27d887d02724d1318071c2178c5dfcb381ee0 (patch) | |
| tree | 29db11c6259786662dfc5b8b1129a6b6b359aa8a /src/display | |
| parent | Patch from Jean-René Reinhard: support for feDiffuseLighting and (diff) | |
| download | inkscape-35a27d887d02724d1318071c2178c5dfcb381ee0.tar.gz inkscape-35a27d887d02724d1318071c2178c5dfcb381ee0.zip | |
Patch from Felipe Sanches: support for feConvolveMatrix filter primitive
(bzr r3270)
Diffstat (limited to 'src/display')
| -rw-r--r-- | src/display/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/display/nr-filter-convolve-matrix.cpp | 141 | ||||
| -rw-r--r-- | src/display/nr-filter-convolve-matrix.h | 60 | ||||
| -rw-r--r-- | src/display/nr-filter.cpp | 3 |
4 files changed, 205 insertions, 1 deletions
diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert index bc6fb3336..eaa2f584f 100644 --- a/src/display/Makefile_insert +++ b/src/display/Makefile_insert @@ -81,6 +81,8 @@ display_libspdisplay_a_SOURCES = \ display/nr-filter-specularlighting.h \ display/nr-filter-composite.h \ display/nr-filter-composite.cpp \ + display/nr-filter-convolve-matrix.cpp \ + display/nr-filter-convolve-matrix.h \ display/nr-filter-slot.cpp \ display/nr-filter-slot.h \ display/nr-filter-getalpha.cpp \ diff --git a/src/display/nr-filter-convolve-matrix.cpp b/src/display/nr-filter-convolve-matrix.cpp new file mode 100644 index 000000000..6bdb3306e --- /dev/null +++ b/src/display/nr-filter-convolve-matrix.cpp @@ -0,0 +1,141 @@ +/* + * feConvolveMatrix filter primitive renderer + * + * Authors: + * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * + * Copyright (C) 2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/nr-filter-convolve-matrix.h" +#include <vector> +namespace NR { + +FilterConvolveMatrix::FilterConvolveMatrix() +{} + +FilterPrimitive * FilterConvolveMatrix::create() { + return new FilterConvolveMatrix(); +} + +FilterConvolveMatrix::~FilterConvolveMatrix() +{} + +static bool inside_area(int px, int py, int w, int h){ + if (px<0) return false; + if (py<0) return false; + if (px>w) return false; + if (py>h) return false; + return true; +} + +int FilterConvolveMatrix::render(FilterSlot &slot, Matrix const &trans) { + NRPixBlock *in = slot.get(_input); + NRPixBlock *out = new NRPixBlock; + + nr_pixblock_setup_fast(out, in->mode, + in->area.x0, in->area.y0, in->area.x1, in->area.y1, + true); + + unsigned char *in_data = NR_PIXBLOCK_PX(in); + unsigned char *out_data = NR_PIXBLOCK_PX(out); + + double result_R, result_G, result_B, result_A; + int i, j, x, y; + int width = in->area.x1 - in->area.x0; + int height = in->area.y1 - in->area.y0; + + double div=0; + + if (divisor != 0){ + div = divisor; + } else { + for (i=0;i<orderX*orderY;i++){ + div += kernelMatrix[i]; + } + } + + for (x=0; x < width; x++){ + for (y=0; y < height; y++){ + result_R = 0; + result_G = 0; + result_B = 0; + result_A = 0; + for (i=0; i < orderY; i++){ + for (j=0; j < orderX; j++){ + if (inside_area(x - targetX + j, y - targetY + i, width, height)){ + result_R += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] ); + result_G += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+1] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] ); + result_B += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+2] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] ); + result_A += ( (double) in_data[4*( x - targetX + j + width*(y - targetY + i) )+3] * kernelMatrix[orderX-j-1 + orderX*(orderY-i-1)] ); + } + } + } + result_R = result_R / div + bias; + result_G = result_G / div + bias; + result_B = result_B / div + bias; + result_A = result_A / div + bias; + + result_R = (result_R > 0 ? result_R : 0); + result_G = (result_G > 0 ? result_G : 0); + result_B = (result_B > 0 ? result_B : 0); + result_A = (result_A > 0 ? result_A : 0); + + out_data[4*( x + width*y )] = (result_R < 255 ? (unsigned char)result_R : 255); + out_data[4*( x + width*y )+1] = (result_G < 255 ? (unsigned char)result_G : 255); + out_data[4*( x + width*y )+2] = (result_B < 255 ? (unsigned char)result_B : 255); + out_data[4*( x + width*y )+3] = (result_A < 255 ? (unsigned char)result_A : 255); + } + } + + out->empty = FALSE; + slot.set(_output, out); + return 0; +} + +void FilterConvolveMatrix::set_targetX(int coord) { + targetX = coord; +} + +void FilterConvolveMatrix::set_targetY(int coord) { + targetY = coord; +} + +void FilterConvolveMatrix::set_orderX(int coord) { + orderX = coord; +} + +void FilterConvolveMatrix::set_orderY(int coord) { + orderY = coord; +} + +void FilterConvolveMatrix::set_divisor(double d) { + divisor = d; +} + +void FilterConvolveMatrix::set_bias(double b) { + bias = b; +} + +void FilterConvolveMatrix::set_kernelMatrix(std::vector<gdouble> &km) { + kernelMatrix = km; +} + +void FilterConvolveMatrix::area_enlarge(NRRectL &area, Matrix const &trans) +{ +} + +} /* namespace NR */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/nr-filter-convolve-matrix.h b/src/display/nr-filter-convolve-matrix.h new file mode 100644 index 000000000..e5b72a71f --- /dev/null +++ b/src/display/nr-filter-convolve-matrix.h @@ -0,0 +1,60 @@ +#ifndef __NR_FILTER_CONVOLVE_MATRIX_H__ +#define __NR_FILTER_CONVOLVE_MATRIX_H__ + +/* + * feConvolveMatrix filter primitive renderer + * + * Authors: + * Felipe Corrêa da Silva Sanches <felipe.sanches@gmail.com> + * + * Copyright (C) 2007 authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "display/nr-filter-primitive.h" +#include "display/nr-filter-slot.h" +#include "libnr/nr-matrix.h" +#include "libnr/nr-rect-l.h" +#include <vector> + +namespace NR { + +class FilterConvolveMatrix : public FilterPrimitive { +public: + FilterConvolveMatrix(); + static FilterPrimitive *create(); + virtual ~FilterConvolveMatrix(); + + virtual int render(FilterSlot &slot, Matrix const &trans); + virtual void area_enlarge(NRRectL &area, Matrix const &trans); + + void set_targetY(int coord); + void set_targetX(int coord); + void set_orderY(int coord); + void set_orderX(int coord); + void set_kernelMatrix(std::vector<gdouble>& km); + void set_bias(double b); + void set_divisor(double d); + +private: + std::vector<gdouble> kernelMatrix; + int targetX, targetY; + int orderX, orderY; + gdouble divisor, bias; + int dx, dy; //kernelUnitLength +}; + +} /* namespace NR */ + +#endif /* __NR_FILTER_CONVOLVE_MATRIX_H__ */ +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 : diff --git a/src/display/nr-filter.cpp b/src/display/nr-filter.cpp index 8a22778a1..73a3df415 100644 --- a/src/display/nr-filter.cpp +++ b/src/display/nr-filter.cpp @@ -22,6 +22,7 @@ #include "display/pixblock-transform.h" #include "display/nr-filter-gaussian.h" +#include "display/nr-filter-convolve-matrix.h" #include "display/nr-filter-blend.h" #include "display/nr-filter-offset.h" #include "display/nr-filter-composite.h" @@ -314,7 +315,7 @@ void Filter::_create_constructor_table() _constructor[NR_FILTER_COLORMATRIX] = NULL; _constructor[NR_FILTER_COMPONENTTRANSFER] = NULL; _constructor[NR_FILTER_COMPOSITE] = &FilterComposite::create; - _constructor[NR_FILTER_CONVOLVEMATRIX] = NULL; + _constructor[NR_FILTER_CONVOLVEMATRIX] = &FilterConvolveMatrix::create; _constructor[NR_FILTER_DIFFUSELIGHTING] = &FilterDiffuseLighting::create; _constructor[NR_FILTER_DISPLACEMENTMAP] = NULL; _constructor[NR_FILTER_FLOOD] = NULL; |
