summaryrefslogtreecommitdiffstats
path: root/src/display
diff options
context:
space:
mode:
authorNiko Kiirala <niko@kiirala.com>2007-07-26 11:38:36 +0000
committerkiirala <kiirala@users.sourceforge.net>2007-07-26 11:38:36 +0000
commit13fa505ea30c087ca93f18a64d2a9837cbfd06cf (patch)
tree4a799476b76020ac22ec2c8710b22675d571ed93 /src/display
parentSpinSlider: (diff)
downloadinkscape-13fa505ea30c087ca93f18a64d2a9837cbfd06cf.tar.gz
inkscape-13fa505ea30c087ca93f18a64d2a9837cbfd06cf.zip
Added support for feMerge filter priitive
(bzr r3308)
Diffstat (limited to 'src/display')
-rw-r--r--src/display/Makefile_insert2
-rw-r--r--src/display/nr-filter-merge.cpp140
-rw-r--r--src/display/nr-filter-merge.h51
-rw-r--r--src/display/nr-filter.cpp3
4 files changed, 195 insertions, 1 deletions
diff --git a/src/display/Makefile_insert b/src/display/Makefile_insert
index 624733a42..1713dc751 100644
--- a/src/display/Makefile_insert
+++ b/src/display/Makefile_insert
@@ -83,6 +83,8 @@ display_libspdisplay_a_SOURCES = \
display/nr-filter-getalpha.h \
display/nr-filter-image.cpp \
display/nr-filter-image.h \
+ display/nr-filter-merge.cpp \
+ display/nr-filter-merge.h \
display/nr-filter-offset.cpp \
display/nr-filter-offset.h \
display/nr-filter-primitive.cpp \
diff --git a/src/display/nr-filter-merge.cpp b/src/display/nr-filter-merge.cpp
new file mode 100644
index 000000000..8650fee8b
--- /dev/null
+++ b/src/display/nr-filter-merge.cpp
@@ -0,0 +1,140 @@
+/*
+ * feMerge filter effect renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <cmath>
+#include <vector>
+
+#include "isnan.h"
+#include "sp-femerge.h"
+#include "display/nr-filter-merge.h"
+#include "display/nr-filter-pixops.h"
+#include "display/nr-filter-slot.h"
+#include "display/nr-filter-utils.h"
+#include "libnr/nr-blit.h"
+#include "libnr/nr-pixblock.h"
+#include "libnr/nr-pixops.h"
+#include "libnr/nr-matrix.h"
+
+inline void
+composite_over(unsigned char *r, unsigned char const *a, unsigned char const *b)
+{
+ r[0] = a[0] + NR_NORMALIZE_21(b[0] * (255 - a[3]));
+ r[1] = a[1] + NR_NORMALIZE_21(b[1] * (255 - a[3]));
+ r[2] = a[2] + NR_NORMALIZE_21(b[2] * (255 - a[3]));
+ r[3] = a[3] + NR_NORMALIZE_21(b[3] * (255 - a[3]));
+}
+
+namespace NR {
+
+FilterMerge::FilterMerge() :
+ _input_image(1, NR_FILTER_SLOT_NOT_SET)
+{}
+
+FilterPrimitive * FilterMerge::create() {
+ return new FilterMerge();
+}
+
+FilterMerge::~FilterMerge()
+{}
+
+int FilterMerge::render(FilterSlot &slot, Matrix const &trans) {
+ NRPixBlock *in[_input_image.size()];
+ NRPixBlock *original_in[_input_image.size()];
+
+ for (unsigned int i = 0 ; i < _input_image.size() ; i++) {
+ in[i] = slot.get(_input_image[i]);
+ original_in[i] = in[i];
+ }
+
+ NRPixBlock *out;
+
+ // Bail out if either one of source images is missing
+ for (unsigned int i = 0 ; i < _input_image.size() ; i++) {
+ if (!in[i]) {
+ g_warning("Missing source image for feMerge (number=%d slot=%d)", i, _input_image[i]);
+ return 1;
+ }
+ }
+
+ out = new NRPixBlock;
+ NRRectL out_area = in[0]->area;
+ for (unsigned int i = 1 ; i < _input_image.size() ; i++) {
+ nr_rect_l_union(&out_area, &out_area, &in[i]->area);
+ }
+ nr_pixblock_setup_fast(out, NR_PIXBLOCK_MODE_R8G8B8A8P,
+ out_area.x0, out_area.y0, out_area.x1, out_area.y1,
+ true);
+
+ // Merge is defined for premultiplied RGBA values, thus convert them to
+ // that format before blending
+ for (unsigned int i = 0 ; i < _input_image.size() ; i++) {
+ if (in[i]->mode != NR_PIXBLOCK_MODE_R8G8B8A8P) {
+ in[i] = new NRPixBlock;
+ nr_pixblock_setup_fast(in[i], NR_PIXBLOCK_MODE_R8G8B8A8P,
+ original_in[i]->area.x0,
+ original_in[i]->area.y0,
+ original_in[i]->area.x1,
+ original_in[i]->area.y1,
+ false);
+ nr_blit_pixblock_pixblock(in[i], original_in[i]);
+ }
+ }
+
+ /* pixops_mix is defined in display/nr-filter-pixops.h
+ * It mixes the two input images with the function given as template
+ * and places the result in output image.
+ */
+ for (unsigned int i = 0 ; i < _input_image.size() ; i++) {
+ pixops_mix<composite_over>(*out, *in[i], *out);
+ }
+
+ for (unsigned int i = 0 ; i < _input_image.size() ; i++) {
+ if (in[i] != original_in[i]) {
+ nr_pixblock_release(in[i]);
+ delete in[i];
+ }
+ }
+
+ out->empty = FALSE;
+ slot.set(_output, out);
+
+ return 0;
+}
+
+void FilterMerge::set_input(int slot) {
+ _input_image[0] = slot;
+}
+
+void FilterMerge::set_input(int input, int slot) {
+ if (input < 0) return;
+
+ if (_input_image.size() > input) {
+ _input_image[input] = slot;
+ } else {
+ for (unsigned int i = _input_image.size() ; i < input ; i++) {
+ _input_image.push_back(NR_FILTER_SLOT_NOT_SET);
+ }
+ _input_image.push_back(slot);
+ }
+}
+
+} /* 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-merge.h b/src/display/nr-filter-merge.h
new file mode 100644
index 000000000..a88819c50
--- /dev/null
+++ b/src/display/nr-filter-merge.h
@@ -0,0 +1,51 @@
+#ifndef __NR_FILTER_MERGE_H__
+#define __NR_FILTER_MERGE_H__
+
+/*
+ * feMerge filter effect renderer
+ *
+ * Authors:
+ * Niko Kiirala <niko@kiirala.com>
+ *
+ * Copyright (C) 2007 authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <vector>
+
+#include "sp-femerge.h"
+#include "display/nr-filter-primitive.h"
+#include "display/nr-filter-slot.h"
+#include "libnr/nr-matrix.h"
+
+namespace NR {
+
+class FilterMerge : public FilterPrimitive {
+public:
+ FilterMerge();
+ static FilterPrimitive *create();
+ virtual ~FilterMerge();
+
+ virtual int render(FilterSlot &slot, Matrix const &trans);
+
+ virtual void set_input(int input);
+ virtual void set_input(int input, int slot);
+
+private:
+ std::vector<int> _input_image;
+};
+
+} /* namespace NR */
+
+#endif /* __NR_FILTER_MERGE_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 f09573eb4..95867363b 100644
--- a/src/display/nr-filter.cpp
+++ b/src/display/nr-filter.cpp
@@ -28,6 +28,7 @@
#include "display/nr-filter-displacement-map.h"
#include "display/nr-filter-gaussian.h"
#include "display/nr-filter-image.h"
+#include "display/nr-filter-merge.h"
#include "display/nr-filter-offset.h"
#include "display/nr-filter-specularlighting.h"
#include "display/nr-filter-turbulence.h"
@@ -326,7 +327,7 @@ void Filter::_create_constructor_table()
_constructor[NR_FILTER_FLOOD] = NULL;
_constructor[NR_FILTER_GAUSSIANBLUR] = &FilterGaussian::create;
_constructor[NR_FILTER_IMAGE] = &FilterImage::create;
- _constructor[NR_FILTER_MERGE] = NULL;
+ _constructor[NR_FILTER_MERGE] = &FilterMerge::create;
_constructor[NR_FILTER_MORPHOLOGY] = NULL;
_constructor[NR_FILTER_OFFSET] = &FilterOffset::create;
_constructor[NR_FILTER_SPECULARLIGHTING] = &FilterSpecularLighting::create;