From f3c774baa435a365d36a3eb358c1dd7dd0269682 Mon Sep 17 00:00:00 2001 From: Artem Pavlenko Date: Tue, 29 May 2012 15:09:33 +0100 Subject: [PATCH] + add grain-extract blending mode (gimp) --- deps/agg/include/agg_pixfmt_rgba.h | 70 +++++++++++++++++++++------- include/mapnik/image_compositing.hpp | 3 +- src/cairo_renderer.cpp | 1 + src/image_compositing.cpp | 1 + 4 files changed, 56 insertions(+), 19 deletions(-) diff --git a/deps/agg/include/agg_pixfmt_rgba.h b/deps/agg/include/agg_pixfmt_rgba.h index 92c0ea5c6..7d2ef4f0a 100644 --- a/deps/agg/include/agg_pixfmt_rgba.h +++ b/deps/agg/include/agg_pixfmt_rgba.h @@ -117,15 +117,6 @@ namespace agg const GammaLut& m_gamma; }; - - - - - - - - - //=============================================================blender_rgba template struct blender_rgba { @@ -1416,28 +1407,69 @@ namespace agg unsigned sa, unsigned cover) { - if(cover < 255) + if (cover < 255) { sr = (sr * cover + 255) >> 8; sg = (sg * cover + 255) >> 8; sb = (sb * cover + 255) >> 8; sa = (sa * cover + 255) >> 8; } - if (sa) + if (sa > 0) { calc_type da = p[Order::A]; - - p[Order::R] = (sr + p[Order::R] > 128) ? sr + p[Order::R]-128 : 0; - p[Order::G] = (sg + p[Order::G] > 128) ? sg + p[Order::G]-128 : 0; - p[Order::B] = (sb + p[Order::B] > 128) ? sb + p[Order::B]-128 : 0; + int dr = sr + p[Order::R] - 128; + int dg = sg + p[Order::G] - 128; + int db = sb + p[Order::B] - 128; + p[Order::R] = dr < 0 ? 0 : (dr > 255 ? 255 : dr); + p[Order::G] = dg < 0 ? 0 : (dg > 255 ? 255 : dg); + p[Order::B] = db < 0 ? 0 : (db > 255 ? 255 : db); p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); - if (p[Order::R] > 255) p[Order::R] = 255; - if (p[Order::G] > 255) p[Order::G] = 255; - if (p[Order::B] > 255) p[Order::B] = 255; } } }; + // grain extract (GIMP) + // E = I - M + 128 + + template + struct comp_op_rgba_grain_extract + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if (sa > 0) + { + calc_type da = p[Order::A]; + int dr = p[Order::R] - sr + 128; + int dg = p[Order::G] - sg + 128; + int db = p[Order::B] - sb + 128; + + p[Order::R] = dr < 0 ? 0 : (dr > 255 ? 255 : dr); + p[Order::G] = dg < 0 ? 0 : (dg > 255 ? 255 : dg); + p[Order::B] = db < 0 ? 0 : (db > 255 ? 255 : db); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; //======================================================comp_op_table_rgba @@ -1487,6 +1519,7 @@ namespace agg comp_op_rgba_invert ::blend_pix, comp_op_rgba_invert_rgb ::blend_pix, comp_op_rgba_grain_merge::blend_pix, + comp_op_rgba_grain_extract::blend_pix, 0 }; @@ -1523,6 +1556,7 @@ namespace agg comp_op_invert, //----comp_op_invert comp_op_invert_rgb, //----comp_op_invert_rgb comp_op_grain_merge, //----comp_op_grain_merge_rgb + comp_op_grain_extract, //----comp_op_grain_extract_rgb end_of_comp_op_e }; diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index 90f621f7b..09c9e0db1 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.hpp @@ -69,7 +69,8 @@ enum composite_mode_e contrast, invert, invert_rgb, - grain_merge + grain_merge, + grain_extract }; MAPNIK_DECL boost::optional comp_op_from_string(std::string const& name); diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 5b0b1caeb..15d23feee 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -383,6 +383,7 @@ public: case invert: case invert_rgb: case grain_merge: + case grain_extract: break; } } diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp index 680cfd4a1..fb2fc61f7 100644 --- a/src/image_compositing.cpp +++ b/src/image_compositing.cpp @@ -69,6 +69,7 @@ static const comp_op_lookup_type comp_lookup = boost::assign::list_of comp_op_from_string(std::string const& name)