[mapnik] 04/13: Imported Upstream version 3.0.3+ds
Sebastiaan Couwenberg
sebastic at moszumanska.debian.org
Tue Aug 25 19:37:34 UTC 2015
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch master
in repository mapnik.
commit a8ab0b32ef54af82d31028caed5c2e034263d735
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Tue Aug 25 20:14:51 2015 +0200
Imported Upstream version 3.0.3+ds
---
CHANGELOG.md | 21 ++
SConstruct | 4 +
include/mapnik/geometry.hpp | 8 +-
include/mapnik/geometry_adapters.hpp | 7 +-
include/mapnik/geometry_fusion_adapted.hpp | 5 +-
include/mapnik/image_filter.hpp | 205 ++++++++++-
include/mapnik/image_filter_grammar_impl.hpp | 6 +
include/mapnik/image_filter_types.hpp | 48 ++-
include/mapnik/image_util_jpeg.hpp | 4 +-
include/mapnik/json/geometry_generator_grammar.hpp | 2 +-
include/mapnik/svg/svg_converter.hpp | 4 +-
include/mapnik/text/placement_finder.hpp | 2 +-
include/mapnik/util/singleton.hpp | 2 +
include/mapnik/util/spirit_transform_attribute.hpp | 9 +-
include/mapnik/version.hpp | 4 +-
plugins/input/ogr/ogr_featureset.cpp | 8 +-
plugins/input/ogr/ogr_index_featureset.cpp | 8 +-
src/agg/agg_renderer.cpp | 15 +-
src/agg/process_dot_symbolizer.cpp | 4 +-
src/image_util_jpeg.cpp | 31 +-
src/load_map.cpp | 2 +-
src/save_map.cpp | 1 -
src/text/placement_finder.cpp | 9 +-
test/unit/datasource/ogr.cpp | 58 ++++
test/unit/imaging/image_filter.cpp | 377 +++++++++++++++++++++
test/unit/imaging/image_io_test.cpp | 14 +
26 files changed, 804 insertions(+), 54 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8facec3..789b725 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,27 @@ Developers: Please commit along with changes.
For a complete change history, see the git log.
+## Future
+
+Released: YYYY XX, 2015
+
+(Packaged from xxxx)
+
+## 3.0.3
+
+Released: August 12, 2015
+
+(Packaged from 3d262c7)
+
+#### Summary
+
+- Fixed an issue with fields over size of int32 in OGR plugin (https://github.com/mapnik/node-mapnik/issues/499)
+- Added 3 new image-filters to simulate types of colorblindness (`color-blind-protanope`,`color-blind-deuteranope`,`color-blind-tritanope`)
+- Fix so that null text boxes have no bounding boxes when attempting placement ( 162f82cba5b0fb984c425586c6a4b354917abc47 )
+- Patch to add legacy method for setting JPEG quality in images ( #3024 )
+- Added `filter_image` method which can modify an image in place or return a new image that is filtered.
+- Added missing typedef's in mapnik::geometry to allow experiementing with different containers
+
## 3.0.2
Released: July 31, 2015
diff --git a/SConstruct b/SConstruct
index 359801d..b1c7f30 100644
--- a/SConstruct
+++ b/SConstruct
@@ -301,6 +301,7 @@ opts.AddVariables(
('HOST', 'Set the target host for cross compiling', ''),
('CONFIG', "The path to the python file in which to save user configuration options. Currently : '%s'" % SCONS_LOCAL_CONFIG,SCONS_LOCAL_CONFIG),
BoolVariable('USE_CONFIG', "Use SCons user '%s' file (will also write variables after successful configuration)", 'True'),
+ BoolVariable('NO_ATEXIT', 'Will prevent Singletons from being deleted atexit of main thread', 'False'),
# http://www.scons.org/wiki/GoFastButton
# http://stackoverflow.com/questions/1318863/how-to-optimize-an-scons-script
BoolVariable('FAST', "Make SCons faster at the cost of less precise dependency tracking", 'False'),
@@ -1706,6 +1707,9 @@ if not preconfigured:
if env['THREADING'] == 'multi':
env.Append(CPPDEFINES = '-DMAPNIK_THREADSAFE')
+ if env['NO_ATEXIT']:
+ env.Append(CPPDEFINES = '-DMAPNIK_NO_ATEXIT')
+
# Mac OSX (Darwin) special settings
if env['PLATFORM'] == 'Darwin':
pthread = ''
diff --git a/include/mapnik/geometry.hpp b/include/mapnik/geometry.hpp
index 970f8dd..3766ebf 100644
--- a/include/mapnik/geometry.hpp
+++ b/include/mapnik/geometry.hpp
@@ -29,6 +29,8 @@
#include <type_traits>
#include <cstddef>
+
+
namespace mapnik { namespace geometry {
template <typename T>
@@ -91,10 +93,14 @@ struct linear_ring : line_string<T>
};
template <typename T>
+using rings_container = std::vector<linear_ring<T>>;
+
+template <typename T, template <typename> class InteriorRings = rings_container>
struct polygon
{
linear_ring<T> exterior_ring;
- std::vector<linear_ring<T>> interior_rings;
+ using rings_container = InteriorRings<T>;
+ rings_container interior_rings;
polygon() = default;
inline void set_exterior_ring(linear_ring<T> && ring)
diff --git a/include/mapnik/geometry_adapters.hpp b/include/mapnik/geometry_adapters.hpp
index 0c7a657..3f08c2b 100644
--- a/include/mapnik/geometry_adapters.hpp
+++ b/include/mapnik/geometry_adapters.hpp
@@ -47,7 +47,6 @@
#include <mapnik/box2d.hpp>
#include <cstdint>
-#include <vector>
// register point
BOOST_GEOMETRY_REGISTER_POINT_2D (mapnik::geometry::point<double>, double, boost::geometry::cs::cartesian, x, y)
@@ -180,13 +179,13 @@ struct ring_mutable_type<mapnik::geometry::polygon<CoordinateType> >
template <typename CoordinateType>
struct interior_const_type<mapnik::geometry::polygon<CoordinateType> >
{
- using type = typename std::vector<mapnik::geometry::linear_ring<CoordinateType> > const&;
+ using type = typename mapnik::geometry::polygon<CoordinateType>::rings_container const&;
};
template <typename CoordinateType>
struct interior_mutable_type<mapnik::geometry::polygon<CoordinateType> >
{
- using type = typename std::vector<mapnik::geometry::linear_ring<CoordinateType> >&;
+ using type = typename mapnik::geometry::polygon<CoordinateType>::rings_container&;
};
// exterior
@@ -207,7 +206,7 @@ struct exterior_ring<mapnik::geometry::polygon<CoordinateType> >
template <typename CoordinateType>
struct interior_rings<mapnik::geometry::polygon<CoordinateType> >
{
- using holes_type = std::vector<mapnik::geometry::linear_ring<CoordinateType> >;
+ using holes_type = typename mapnik::geometry::polygon<CoordinateType>::rings_container;
static holes_type& get(mapnik::geometry::polygon<CoordinateType> & p)
{
return p.interior_rings;
diff --git a/include/mapnik/geometry_fusion_adapted.hpp b/include/mapnik/geometry_fusion_adapted.hpp
index 6889de6..e3bdd7e 100644
--- a/include/mapnik/geometry_fusion_adapted.hpp
+++ b/include/mapnik/geometry_fusion_adapted.hpp
@@ -26,7 +26,6 @@
#include <mapnik/geometry.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
-#include <vector>
BOOST_FUSION_ADAPT_STRUCT(
mapnik::geometry::point<double>,
@@ -43,11 +42,11 @@ BOOST_FUSION_ADAPT_STRUCT(
BOOST_FUSION_ADAPT_STRUCT(
mapnik::geometry::polygon<double>,
(mapnik::geometry::linear_ring<double> const&, exterior_ring)
- (std::vector<mapnik::geometry::linear_ring<double> > const& , interior_rings))
+ (mapnik::geometry::polygon<double>::rings_container const& , interior_rings))
BOOST_FUSION_ADAPT_STRUCT(
mapnik::geometry::polygon<std::int64_t>,
(mapnik::geometry::linear_ring<std::int64_t> const&, exterior_ring)
- (std::vector<mapnik::geometry::linear_ring<std::int64_t> > const& , interior_rings))
+ (mapnik::geometry::polygon<std::int64_t>::rings_container const& , interior_rings))
#endif // MAPNIK_GEOMETRY_FUSION_ADAPTED_HPP
diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp
index 8301ade..d6ed0cd 100644
--- a/include/mapnik/image_filter.hpp
+++ b/include/mapnik/image_filter.hpp
@@ -26,6 +26,7 @@
//mapnik
#include <mapnik/image_filter_types.hpp>
+#include <mapnik/image_util.hpp>
#include <mapnik/util/hsl.hpp>
// boost GIL
@@ -394,17 +395,15 @@ void apply_convolution_3x3(Src const& src_view, Dst & dst_view, Filter const& fi
template <typename Src, typename Filter>
void apply_filter(Src & src, Filter const& filter)
{
- {
- demultiply_alpha(src);
- double_buffer<Src> tb(src);
- apply_convolution_3x3(tb.src_view, tb.dst_view, filter);
- } // ensure ~double_buffer() is called before premultiplying
- premultiply_alpha(src);
+ demultiply_alpha(src);
+ double_buffer<Src> tb(src);
+ apply_convolution_3x3(tb.src_view, tb.dst_view, filter);
}
template <typename Src>
void apply_filter(Src & src, agg_stack_blur const& op)
{
+ premultiply_alpha(src);
agg::rendering_buffer buf(src.bytes(),src.width(),src.height(), src.row_size());
agg::pixfmt_rgba32_pre pixf(buf);
agg::stack_blur_rgba32(pixf,op.rx,op.ry);
@@ -427,6 +426,7 @@ template <typename Src>
void apply_filter(Src & src, color_to_alpha const& op)
{
using namespace boost::gil;
+ bool premultiplied = src.get_premultiplied();
rgba8_view_t src_view = rgba8_view(src);
double cr = static_cast<double>(op.color.red())/255.0;
double cg = static_cast<double>(op.color.green())/255.0;
@@ -450,7 +450,7 @@ void apply_filter(Src & src, color_to_alpha const& op)
r = g = b = 0;
continue;
}
- else
+ else if (premultiplied)
{
sr /= sa;
sg /= sa;
@@ -479,6 +479,8 @@ void apply_filter(Src & src, color_to_alpha const& op)
}
}
}
+ // set as premultiplied
+ set_premultiplied_alpha(src, true);
}
template <typename Src>
@@ -509,6 +511,8 @@ void apply_filter(Src & src, colorize_alpha const& op)
}
}
}
+ // set as premultiplied
+ set_premultiplied_alpha(src, true);
}
else if (size > 1)
{
@@ -584,6 +588,8 @@ void apply_filter(Src & src, colorize_alpha const& op)
}
}
}
+ // set as premultiplied
+ set_premultiplied_alpha(src, true);
}
}
@@ -597,6 +603,7 @@ void apply_filter(Src & src, scale_hsla const& transform)
// should be run to avoid overhead of temp buffer
if (tinting || set_alpha)
{
+ bool premultiplied = src.get_premultiplied();
rgba8_view_t src_view = rgba8_view(src);
for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
{
@@ -617,12 +624,13 @@ void apply_filter(Src & src, scale_hsla const& transform)
r = g = b = 0;
continue;
}
- else
+ else if (premultiplied)
{
r2 /= a2;
g2 /= a2;
b2 /= a2;
}
+
if (set_alpha)
{
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
@@ -671,12 +679,154 @@ void apply_filter(Src & src, scale_hsla const& transform)
if (b>a) b=a;
}
}
+ // set as premultiplied
+ set_premultiplied_alpha(src, true);
+ }
+}
+
+template <typename Src, typename ColorBlindFilter>
+void color_blind_filter(Src & src, ColorBlindFilter const& op)
+{
+ using namespace boost::gil;
+ rgba8_view_t src_view = rgba8_view(src);
+ bool premultiplied = src.get_premultiplied();
+
+ for (std::ptrdiff_t y = 0; y < src_view.height(); ++y)
+ {
+ rgba8_view_t::x_iterator src_it = src_view.row_begin(static_cast<long>(y));
+ for (std::ptrdiff_t x = 0; x < src_view.width(); ++x)
+ {
+ // formula taken from boost/gil/color_convert.hpp:rgb_to_luminance
+ uint8_t & r = get_color(src_it[x], red_t());
+ uint8_t & g = get_color(src_it[x], green_t());
+ uint8_t & b = get_color(src_it[x], blue_t());
+ uint8_t & a = get_color(src_it[x], alpha_t());
+ double dr = static_cast<double>(r)/255.0;
+ double dg = static_cast<double>(g)/255.0;
+ double db = static_cast<double>(b)/255.0;
+ double da = static_cast<double>(a)/255.0;
+ // demultiply
+ if (da <= 0.0)
+ {
+ r = g = b = 0;
+ continue;
+ }
+ else if (premultiplied)
+ {
+ dr /= da;
+ dg /= da;
+ db /= da;
+ }
+ // Convert source color into XYZ color space
+ double pow_r = std::pow(dr, 2.2);
+ double pow_g = std::pow(dg, 2.2);
+ double pow_b = std::pow(db, 2.2);
+ double X = (0.412424 * pow_r) + (0.357579 * pow_g) + (0.180464 * pow_b);
+ double Y = (0.212656 * pow_r) + (0.715158 * pow_g) + (0.0721856 * pow_b);
+ double Z = (0.0193324 * pow_r) + (0.119193 * pow_g) + (0.950444 * pow_b);
+ // Convert XYZ into xyY Chromacity Coordinates (xy) and Luminance (Y)
+ double chroma_x = X / (X + Y + Z);
+ double chroma_y = Y / (X + Y + Z);
+ // Generate the "Confusion Line" between the source color and the Confusion Point
+ double m_div = chroma_x - op.x;
+ if (std::abs(m_div) < (std::numeric_limits<double>::epsilon())) continue;
+ double m = (chroma_y - op.y) / (chroma_x - op.x); // slope of Confusion Line
+ double yint = chroma_y - chroma_x * m; // y-intercept of confusion line (x-intercept = 0.0)
+ // How far the xy coords deviate from the simulation
+ double m_div2 = m - op.m;
+ if (std::abs(m_div2) < (std::numeric_limits<double>::epsilon())) continue;
+ double deviate_x = (op.yint - yint) / (m - op.m);
+ double deviate_y = (m * deviate_x) + yint;
+ if (std::abs(deviate_y) < (std::numeric_limits<double>::epsilon()))
+ {
+ deviate_y = std::numeric_limits<double>::epsilon() * 2.0;
+ }
+ // Compute the simulated color's XYZ coords
+ X = deviate_x * Y / deviate_y;
+ Z = (1.0 - (deviate_x + deviate_y)) * Y / deviate_y;
+ // Neutral grey calculated from luminance (in D65)
+ double neutral_X = 0.312713 * Y / 0.329016;
+ double neutral_Z = 0.358271 * Y / 0.329016;
+ // Difference between simulated color and neutral grey
+ double diff_X = neutral_X - X;
+ double diff_Z = neutral_Z - Z;
+ double diff_r = diff_X * 3.24071 + diff_Z * -0.498571; // XYZ->RGB (sRGB:D65)
+ double diff_g = diff_X * -0.969258 + diff_Z * 0.0415557;
+ double diff_b = diff_X * 0.0556352 + diff_Z * 1.05707;
+ if (std::abs(diff_r) < (std::numeric_limits<double>::epsilon()))
+ {
+ diff_r = std::numeric_limits<double>::epsilon() * 2.0;
+ }
+ if (std::abs(diff_g) < (std::numeric_limits<double>::epsilon()))
+ {
+ diff_g = std::numeric_limits<double>::epsilon() * 2.0;
+ }
+ if (std::abs(diff_b) < (std::numeric_limits<double>::epsilon()))
+ {
+ diff_b = std::numeric_limits<double>::epsilon() * 2.0;
+ }
+ // Convert to RGB color space
+ dr = X * 3.24071 + Y * -1.53726 + Z * -0.498571; // XYZ->RGB (sRGB:D65)
+ dg = X * -0.969258 + Y * 1.87599 + Z * 0.0415557;
+ db = X * 0.0556352 + Y * -0.203996 + Z * 1.05707;
+ // Compensate simulated color towards a neutral fit in RGB space
+ double fit_r = ((dr < 0.0 ? 0.0 : 1.0) - dr) / diff_r;
+ double fit_g = ((dg < 0.0 ? 0.0 : 1.0) - dg) / diff_g;
+ double fit_b = ((db < 0.0 ? 0.0 : 1.0) - db) / diff_b;
+ double adjust = std::max( (fit_r > 1.0 || fit_r < 0.0) ? 0.0 : fit_r,
+ (fit_g > 1.0 || fit_g < 0.0) ? 0.0 : fit_g
+ );
+ adjust = std::max((fit_b > 1.0 || fit_b < 0.0) ? 0.0 : fit_b, adjust);
+ // Shift proportional to the greatest shift
+ dr = dr + (adjust * diff_r);
+ dg = dg + (adjust * diff_g);
+ db = db + (adjust * diff_b);
+ // Apply gamma correction
+ dr = std::pow(dr, 1.0 / 2.2);
+ dg = std::pow(dg, 1.0 / 2.2);
+ db = std::pow(db, 1.0 / 2.2);
+ // premultiply
+ dr *= da;
+ dg *= da;
+ db *= da;
+ // Clamp values
+ if(dr < 0.0) dr = 0.0;
+ if(dr > 1.0) dr = 1.0;
+ if(dg < 0.0) dg = 0.0;
+ if(dg > 1.0) dg = 1.0;
+ if(db < 0.0) db = 0.0;
+ if(db > 1.0) db = 1.0;
+ r = static_cast<uint8_t>(dr * 255.0);
+ g = static_cast<uint8_t>(dg * 255.0);
+ b = static_cast<uint8_t>(db * 255.0);
+ }
}
+ // set as premultiplied
+ set_premultiplied_alpha(src, true);
+}
+
+template <typename Src>
+void apply_filter(Src & src, color_blind_protanope const& op)
+{
+ color_blind_filter(src, op);
+}
+
+template <typename Src>
+void apply_filter(Src & src, color_blind_deuteranope const& op)
+{
+ color_blind_filter(src, op);
+}
+
+template <typename Src>
+void apply_filter(Src & src, color_blind_tritanope const& op)
+{
+ color_blind_filter(src, op);
}
template <typename Src>
void apply_filter(Src & src, gray const& /*op*/)
{
+ premultiply_alpha(src);
using namespace boost::gil;
rgba8_view_t src_view = rgba8_view(src);
@@ -727,6 +877,7 @@ void x_gradient_impl(Src const& src_view, Dst const& dst_view)
template <typename Src>
void apply_filter(Src & src, x_gradient const& /*op*/)
{
+ premultiply_alpha(src);
double_buffer<Src> tb(src);
x_gradient_impl(tb.src_view, tb.dst_view);
}
@@ -734,6 +885,7 @@ void apply_filter(Src & src, x_gradient const& /*op*/)
template <typename Src>
void apply_filter(Src & src, y_gradient const& /*op*/)
{
+ premultiply_alpha(src);
double_buffer<Src> tb(src);
x_gradient_impl(rotated90ccw_view(tb.src_view),
rotated90ccw_view(tb.dst_view));
@@ -742,6 +894,7 @@ void apply_filter(Src & src, y_gradient const& /*op*/)
template <typename Src>
void apply_filter(Src & src, invert const& /*op*/)
{
+ premultiply_alpha(src);
using namespace boost::gil;
rgba8_view_t src_view = rgba8_view(src);
@@ -794,6 +947,40 @@ struct filter_radius_visitor
}
};
-}}
+template<typename Src>
+void filter_image(Src & src, std::string const& filter)
+{
+ std::vector<filter_type> filter_vector;
+ if(!parse_image_filters(filter, filter_vector))
+ {
+ throw std::runtime_error("Failed to parse filter argument in filter_image: '" + filter + "'");
+ }
+ filter_visitor<Src> visitor(src);
+ for (filter_type const& filter_tag : filter_vector)
+ {
+ util::apply_visitor(visitor, filter_tag);
+ }
+}
+
+template<typename Src>
+Src filter_image(Src const& src, std::string const& filter)
+{
+ std::vector<filter_type> filter_vector;
+ if(!parse_image_filters(filter, filter_vector))
+ {
+ throw std::runtime_error("Failed to parse filter argument in filter_image: '" + filter + "'");
+ }
+ Src new_src(src);
+ filter_visitor<Src> visitor(new_src);
+ for (filter_type const& filter_tag : filter_vector)
+ {
+ util::apply_visitor(visitor, filter_tag);
+ }
+ return new_src;
+}
+
+} // End Namespace Filter
+
+} // End Namespace Mapnik
#endif // MAPNIK_IMAGE_FILTER_HPP
diff --git a/include/mapnik/image_filter_grammar_impl.hpp b/include/mapnik/image_filter_grammar_impl.hpp
index a9f11d8..e41f63e 100644
--- a/include/mapnik/image_filter_grammar_impl.hpp
+++ b/include/mapnik/image_filter_grammar_impl.hpp
@@ -80,6 +80,12 @@ image_filter_grammar<Iterator,ContType>::image_filter_grammar()
|
lit("invert") >> no_args [push_back(_val,construct<mapnik::filter::invert>())]
|
+ lit("color-blind-protanope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_protanope>())]
+ |
+ lit("color-blind-deuteranope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_deuteranope>())]
+ |
+ lit("color-blind-tritanope") >> no_args [push_back(_val,construct<mapnik::filter::color_blind_tritanope>())]
+ |
agg_blur_filter(_val)
|
scale_hsla_filter(_val)
diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp
index 5d61d1d..67e03da 100644
--- a/include/mapnik/image_filter_types.hpp
+++ b/include/mapnik/image_filter_types.hpp
@@ -55,6 +55,31 @@ struct x_gradient : image_filter_base {};
struct y_gradient : image_filter_base {};
struct invert : image_filter_base {};
+// http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf
+struct color_blind_protanope : image_filter_base
+{
+ const double x = 0.7465;
+ const double y = 0.2535;
+ const double m = 1.273463;
+ const double yint = -0.073894;
+};
+
+struct color_blind_deuteranope : image_filter_base
+{
+ const double x = 1.4;
+ const double y = -0.4;
+ const double m = 0.968437;
+ const double yint = 0.003331;
+};
+
+struct color_blind_tritanope : image_filter_base
+{
+ const double x = 0.1748;
+ const double y = 0.0;
+ const double m = 0.062921;
+ const double yint = 0.292119;
+};
+
struct agg_stack_blur : image_filter_base
{
agg_stack_blur(unsigned rx_, unsigned ry_)
@@ -169,7 +194,10 @@ using filter_type = util::variant<filter::blur,
filter::invert,
filter::scale_hsla,
filter::colorize_alpha,
- filter::color_to_alpha>;
+ filter::color_to_alpha,
+ filter::color_blind_protanope,
+ filter::color_blind_deuteranope,
+ filter::color_blind_tritanope>;
inline std::ostream& operator<< (std::ostream& os, blur)
{
@@ -247,6 +275,24 @@ inline std::ostream& operator<< (std::ostream& os, invert)
return os;
}
+inline std::ostream& operator<< (std::ostream& os, color_blind_protanope)
+{
+ os << "color-blind-protanope";
+ return os;
+}
+
+inline std::ostream& operator<< (std::ostream& os, color_blind_deuteranope)
+{
+ os << "color-blind-deuteranope";
+ return os;
+}
+
+inline std::ostream& operator<< (std::ostream& os, color_blind_tritanope)
+{
+ os << "color-blind-tritanope";
+ return os;
+}
+
inline std::ostream& operator<< (std::ostream& os, colorize_alpha const& filter)
{
os << "colorize-alpha(";
diff --git a/include/mapnik/image_util_jpeg.hpp b/include/mapnik/image_util_jpeg.hpp
index b4d2648..b8b213a 100644
--- a/include/mapnik/image_util_jpeg.hpp
+++ b/include/mapnik/image_util_jpeg.hpp
@@ -28,7 +28,9 @@
#include <iostream>
namespace mapnik {
-
+namespace detail {
+MAPNIK_DECL int parse_jpeg_quality(std::string const& params);
+}
struct jpeg_saver
{
jpeg_saver(std::ostream &, std::string const&);
diff --git a/include/mapnik/json/geometry_generator_grammar.hpp b/include/mapnik/json/geometry_generator_grammar.hpp
index 01b6318..1095d32 100644
--- a/include/mapnik/json/geometry_generator_grammar.hpp
+++ b/include/mapnik/json/geometry_generator_grammar.hpp
@@ -104,7 +104,7 @@ struct geometry_generator_grammar :
karma::rule<OutputIterator, geometry::geometry<double> const&()> polygon;
karma::rule<OutputIterator, geometry::polygon<double> const&()> polygon_coord;
karma::rule<OutputIterator, geometry::linear_ring<double> const&()> exterior_ring_coord;
- karma::rule<OutputIterator, std::vector<geometry::linear_ring<double> > const&()> interior_ring_coord;
+ karma::rule<OutputIterator, geometry::polygon<double>::rings_container const&()> interior_ring_coord;
karma::rule<OutputIterator, geometry::geometry<double> const& ()> multi_point;
karma::rule<OutputIterator, geometry::multi_point<double> const& ()> multi_point_coord;
karma::rule<OutputIterator, geometry::geometry<double> const& ()> multi_linestring;
diff --git a/include/mapnik/svg/svg_converter.hpp b/include/mapnik/svg/svg_converter.hpp
index 0066a1f..27fee31 100644
--- a/include/mapnik/svg/svg_converter.hpp
+++ b/include/mapnik/svg/svg_converter.hpp
@@ -320,12 +320,12 @@ public:
svg_height_ = h;
}
- double width()
+ double width() const
{
return svg_width_;
}
- double height()
+ double height() const
{
return svg_height_;
}
diff --git a/include/mapnik/text/placement_finder.hpp b/include/mapnik/text/placement_finder.hpp
index 0460b2c..8bb63a7 100644
--- a/include/mapnik/text/placement_finder.hpp
+++ b/include/mapnik/text/placement_finder.hpp
@@ -74,7 +74,7 @@ private:
// Checks for collision.
bool collision(box2d<double> const& box, const value_unicode_string &repeat_key, bool line_placement) const;
// Adds marker to glyph_positions and to collision detector. Returns false if there is a collision.
- bool add_marker(glyph_positions_ptr & glyphs, pixel_position const& pos) const;
+ bool add_marker(glyph_positions_ptr & glyphs, pixel_position const& pos, std::vector<box2d<double>> & bboxes) const;
// Maps upright==auto, left-only and right-only to left,right to simplify processing.
// angle = angle of at start of line (to estimate best option for upright==auto)
text_upright_e simplify_upright(text_upright_e upright, double angle) const;
diff --git a/include/mapnik/util/singleton.hpp b/include/mapnik/util/singleton.hpp
index 2c40406..e77b25b 100644
--- a/include/mapnik/util/singleton.hpp
+++ b/include/mapnik/util/singleton.hpp
@@ -119,8 +119,10 @@ template <typename T,
{
tmp = CreatePolicy<T>::create();
pInstance_.store(tmp, std::memory_order_release);
+#ifndef MAPNIK_NO_ATEXIT
// register destruction
std::atexit(&DestroySingleton);
+#endif
}
}
}
diff --git a/include/mapnik/util/spirit_transform_attribute.hpp b/include/mapnik/util/spirit_transform_attribute.hpp
index e924fd8..f7fb1ca 100644
--- a/include/mapnik/util/spirit_transform_attribute.hpp
+++ b/include/mapnik/util/spirit_transform_attribute.hpp
@@ -26,7 +26,6 @@
#include <mapnik/geometry.hpp>
#include <mapnik/util/variant.hpp>
-#include <vector>
#include <cstdint>
// boost
@@ -76,9 +75,9 @@ namespace boost { namespace spirit { namespace traits {
template <>
struct transform_attribute<mapnik::geometry::polygon<double> const,
- std::vector<mapnik::geometry::linear_ring<double> > const&, karma::domain>
+ mapnik::geometry::polygon<double>::rings_container const&, karma::domain>
{
- using type = std::vector<mapnik::geometry::linear_ring<double> > const&;
+ using type = mapnik::geometry::polygon<double>::rings_container const&;
static type pre(mapnik::geometry::polygon<double> const& poly)
{
return poly.interior_rings;
@@ -164,9 +163,9 @@ namespace boost { namespace spirit { namespace traits {
template <>
struct transform_attribute<mapnik::geometry::polygon<std::int64_t> const,
- std::vector<mapnik::geometry::linear_ring<std::int64_t> > const&, karma::domain>
+ mapnik::geometry::polygon<std::int64_t>::rings_container const&, karma::domain>
{
- using type = std::vector<mapnik::geometry::linear_ring<std::int64_t> > const&;
+ using type = mapnik::geometry::polygon<std::int64_t>::rings_container const&;
static type pre(mapnik::geometry::polygon<std::int64_t> const& poly)
{
return poly.interior_rings;
diff --git a/include/mapnik/version.hpp b/include/mapnik/version.hpp
index 9e511c1..9b16040 100644
--- a/include/mapnik/version.hpp
+++ b/include/mapnik/version.hpp
@@ -27,9 +27,9 @@
#define MAPNIK_MAJOR_VERSION 3
#define MAPNIK_MINOR_VERSION 0
-#define MAPNIK_PATCH_VERSION 2
+#define MAPNIK_PATCH_VERSION 3
-// translates to 300001
+// translates to 300003
#define MAPNIK_VERSION (MAPNIK_MAJOR_VERSION*100000) + (MAPNIK_MINOR_VERSION*100) + (MAPNIK_PATCH_VERSION)
#ifndef MAPNIK_STRINGIFY
diff --git a/plugins/input/ogr/ogr_featureset.cpp b/plugins/input/ogr/ogr_featureset.cpp
index 3d46fcf..267ebc0 100644
--- a/plugins/input/ogr/ogr_featureset.cpp
+++ b/plugins/input/ogr/ogr_featureset.cpp
@@ -125,13 +125,17 @@ feature_ptr ogr_featureset::next()
switch (type_oid)
{
case OFTInteger:
+ {
+ feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger(i));
+ break;
+ }
#if GDAL_VERSION_MAJOR >= 2
case OFTInteger64:
-#endif
{
- feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger(i));
+ feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger64(i));
break;
}
+#endif
case OFTReal:
{
diff --git a/plugins/input/ogr/ogr_index_featureset.cpp b/plugins/input/ogr/ogr_index_featureset.cpp
index c59ef29..9338f95 100644
--- a/plugins/input/ogr/ogr_index_featureset.cpp
+++ b/plugins/input/ogr/ogr_index_featureset.cpp
@@ -148,13 +148,17 @@ feature_ptr ogr_index_featureset<filterT>::next()
switch (type_oid)
{
case OFTInteger:
+ {
+ feature->put<mapnik::value_integer>(fld_name,poFeature->GetFieldAsInteger (i));
+ break;
+ }
#if GDAL_VERSION_MAJOR >= 2
case OFTInteger64:
-#endif
{
- feature->put<mapnik::value_integer>(fld_name,poFeature->GetFieldAsInteger (i));
+ feature->put<mapnik::value_integer>( fld_name, poFeature->GetFieldAsInteger64(i));
break;
}
+#endif
case OFTReal:
{
diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp
index 56e1710..74e3c93 100644
--- a/src/agg/agg_renderer.cpp
+++ b/src/agg/agg_renderer.cpp
@@ -197,7 +197,7 @@ void agg_renderer<T0,T1>::start_map_processing(Map const& map)
}
template <typename T0, typename T1>
-void agg_renderer<T0,T1>::end_map_processing(Map const& )
+void agg_renderer<T0,T1>::end_map_processing(Map const& map)
{
mapnik::demultiply_alpha(pixmap_);
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End map processing";
@@ -309,6 +309,7 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
{
util::apply_visitor(visitor, filter_tag);
}
+ mapnik::premultiply_alpha(*current_buffer_);
}
if (st.comp_op())
{
@@ -325,11 +326,15 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
-common_.t_.offset());
}
}
- // apply any 'direct' image filters
- mapnik::filter::filter_visitor<buffer_type> visitor(pixmap_);
- for (mapnik::filter::filter_type const& filter_tag : st.direct_image_filters())
+ if (st.direct_image_filters().size() > 0)
{
- util::apply_visitor(visitor, filter_tag);
+ // apply any 'direct' image filters
+ mapnik::filter::filter_visitor<buffer_type> visitor(pixmap_);
+ for (mapnik::filter::filter_type const& filter_tag : st.direct_image_filters())
+ {
+ util::apply_visitor(visitor, filter_tag);
+ }
+ mapnik::premultiply_alpha(pixmap_);
}
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End processing style";
}
diff --git a/src/agg/process_dot_symbolizer.cpp b/src/agg/process_dot_symbolizer.cpp
index 322bfea..cc37586 100644
--- a/src/agg/process_dot_symbolizer.cpp
+++ b/src/agg/process_dot_symbolizer.cpp
@@ -106,8 +106,8 @@ void agg_renderer<T0,T1>::process(dot_symbolizer const& sym,
{
width = height = get<double>(sym, keys::height, feature, common_.vars_, 0.0);
}
- double rx = width/2.0;
- double ry = height/2.0;
+ double rx = width/2.0 * common_.scale_factor_;
+ double ry = height/2.0 * common_.scale_factor_;
double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0);
color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128));
ras_ptr->reset();
diff --git a/src/image_util_jpeg.cpp b/src/image_util_jpeg.cpp
index 22d6ed4..8966eb2 100644
--- a/src/image_util_jpeg.cpp
+++ b/src/image_util_jpeg.cpp
@@ -38,22 +38,29 @@
namespace mapnik
{
-jpeg_saver::jpeg_saver(std::ostream & stream, std::string const& t):
- stream_(stream), t_(t) {}
+jpeg_saver::jpeg_saver(std::ostream & stream, std::string const& t)
+ : stream_(stream), t_(t) {}
-template <typename T>
-void process_rgba8_jpeg(T const& image, std::string const& type, std::ostream & stream)
+namespace detail {
+
+MAPNIK_DECL int parse_jpeg_quality(std::string const& params)
{
-#if defined(HAVE_JPEG)
int quality = 85;
- if (type != "jpeg")
+ if (params != "jpeg")
{
- for (auto const& kv : parse_image_options(type))
+ for (auto const& kv : parse_image_options(params))
{
auto const& key = kv.first;
auto const& val = kv.second;
if ( key == "jpeg" ) continue;
+ else if ( key.size() > 4 && key.substr(0,4) == "jpeg")
+ {
+ if (!mapnik::util::string2int(key.substr(4), quality))
+ {
+ throw image_writer_exception("invalid jpeg quality: '" + key.substr(4) + "'");
+ }
+ }
else if ( key == "quality")
{
if (val && ! (*val).empty())
@@ -66,6 +73,16 @@ void process_rgba8_jpeg(T const& image, std::string const& type, std::ostream &
}
}
}
+ return quality;
+}
+
+}
+
+template <typename T>
+void process_rgba8_jpeg(T const& image, std::string const& type, std::ostream & stream)
+{
+#if defined(HAVE_JPEG)
+ int quality = detail::parse_jpeg_quality(type);
save_as_jpeg(stream, quality, image);
#else
throw image_writer_exception("jpeg output is not enabled in your build of Mapnik");
diff --git a/src/load_map.cpp b/src/load_map.cpp
index 44d1276..6e15ba2 100644
--- a/src/load_map.cpp
+++ b/src/load_map.cpp
@@ -196,7 +196,7 @@ void map_parser::parse_map(Map & map, xml_node const& node, std::string const& b
{
map.set_background(*bgcolor);
}
-
+
optional<std::string> image_filename = map_node.get_opt_attr<std::string>("background-image");
if (image_filename)
{
diff --git a/src/save_map.cpp b/src/save_map.cpp
index d757f9e..7ba9757 100644
--- a/src/save_map.cpp
+++ b/src/save_map.cpp
@@ -624,7 +624,6 @@ void serialize_map(ptree & pt, Map const& map, bool explicit_defaults)
set_attr(map_node, "background-image-opacity", opacity);
}
-
int buffer_size = map.buffer_size();
if ( buffer_size || explicit_defaults)
{
diff --git a/src/text/placement_finder.cpp b/src/text/placement_finder.cpp
index 53dda7d..086501e 100644
--- a/src/text/placement_finder.cpp
+++ b/src/text/placement_finder.cpp
@@ -143,7 +143,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
/* For point placements it is faster to just check the bounding box. */
if (collision(bbox, layouts_.text(), false)) return false;
- if (layout.num_lines()) bboxes.push_back(std::move(bbox));
+ if (layout.glyphs_count()) bboxes.push_back(std::move(bbox));
pixel_position layout_offset = layout_center - glyphs->get_base_point();
layout_offset.y = -layout_offset.y;
@@ -178,7 +178,7 @@ bool placement_finder::find_point_placement(pixel_position const& pos)
}
// add_marker first checks for collision and then updates the detector.
- if (has_marker_ && !add_marker(glyphs, pos)) return false;
+ if (has_marker_ && !add_marker(glyphs, pos, bboxes)) return false;
box2d<double> label_box;
bool first = true;
@@ -418,14 +418,15 @@ void placement_finder::set_marker(marker_info_ptr m, box2d<double> box, bool mar
}
-bool placement_finder::add_marker(glyph_positions_ptr & glyphs, pixel_position const& pos) const
+bool placement_finder::add_marker(glyph_positions_ptr & glyphs, pixel_position const& pos, std::vector<box2d<double>> & bboxes) const
{
pixel_position real_pos = (marker_unlocked_ ? pos : glyphs->get_base_point()) + marker_displacement_;
box2d<double> bbox = marker_box_;
bbox.move(real_pos.x, real_pos.y);
- glyphs->set_marker(marker_, real_pos);
if (collision(bbox, layouts_.text(), false)) return false;
detector_.insert(bbox);
+ bboxes.push_back(std::move(bbox));
+ glyphs->set_marker(marker_, real_pos);
return true;
}
diff --git a/test/unit/datasource/ogr.cpp b/test/unit/datasource/ogr.cpp
new file mode 100644
index 0000000..3dddb85
--- /dev/null
+++ b/test/unit/datasource/ogr.cpp
@@ -0,0 +1,58 @@
+/*****************************************************************************
+ *
+ * This file is part of Mapnik (c++ mapping toolkit)
+ *
+ * Copyright (C) 2015 Artem Pavlenko
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ *****************************************************************************/
+
+#include "catch.hpp"
+
+#include <mapnik/map.hpp>
+#include <mapnik/load_map.hpp>
+#include <mapnik/agg_renderer.hpp>
+#include <mapnik/image.hpp>
+#include <mapnik/image_reader.hpp>
+#include <mapnik/image_util.hpp>
+#include <mapnik/font_engine_freetype.hpp>
+#include <mapnik/util/fs.hpp>
+
+TEST_CASE("ogr") {
+
+ std::string geojson_plugin("./plugins/input/ogr.input");
+ if (mapnik::util::exists(geojson_plugin))
+ {
+ SECTION("ogr point feature")
+ {
+ mapnik::Map m(256,256);
+ mapnik::load_map(m, "./test/data/good_maps/point_json.xml");
+ std::string fontdir("fonts/");
+ REQUIRE( m.register_fonts(fontdir , true ) );
+ m.zoom_all();
+ mapnik::image_rgba8 im(256,256);
+ mapnik::agg_renderer<mapnik::image_rgba8> ren(m, im);
+ ren.apply();
+ //mapnik::save_to_file(im, "./test/data/images/point_json.png");
+ std::string filename("./test/data/images/point_json.png");
+ std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(filename,"png"));
+ mapnik::image_any data = reader->read(0, 0, reader->width(), reader->height());
+ mapnik::image_rgba8 expected = mapnik::util::get<mapnik::image_rgba8>(data);
+ REQUIRE(mapnik::compare(expected, im) == 0);
+ }
+
+ }
+}
diff --git a/test/unit/imaging/image_filter.cpp b/test/unit/imaging/image_filter.cpp
new file mode 100644
index 0000000..f07836d
--- /dev/null
+++ b/test/unit/imaging/image_filter.cpp
@@ -0,0 +1,377 @@
+#include "catch.hpp"
+
+// mapnik
+#include <mapnik/value.hpp>
+#include <mapnik/image_any.hpp>
+#include <mapnik/color.hpp>
+#include <mapnik/image_filter.hpp>
+#include <mapnik/image_util.hpp>
+
+TEST_CASE("image filter") {
+
+SECTION("test bad filter input") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ REQUIRE_THROWS( mapnik::filter::filter_image(im, "foo,asdfasdf()"); );
+ REQUIRE_THROWS( mapnik::filter::filter_image(im, "colorize-alpha("); );
+ REQUIRE_THROWS( mapnik::filter::filter_image(im, "color-to-alpha(blue"); );
+ REQUIRE_THROWS( mapnik::filter::filter_image(im, "color-to-alpha(,blue)"); );
+ REQUIRE_THROWS( mapnik::filter::filter_image(im, "colorize-alpha()"); );
+
+ REQUIRE_THROWS(
+ mapnik::image_rgba8 const& im2 = im;
+ mapnik::image_rgba8 new_im = mapnik::filter::filter_image(im2, "foo");
+ );
+
+ CHECK(im(0,0) == 0xffff0000);
+ CHECK(im(0,1) == 0xffff0000);
+ CHECK(im(0,2) == 0xffff0000);
+ CHECK(im(1,0) == 0xffff0000);
+ CHECK(im(1,1) == 0xff0000ff);
+ CHECK(im(1,2) == 0xffff0000);
+ CHECK(im(2,0) == 0xffff0000);
+ CHECK(im(2,1) == 0xffff0000);
+ CHECK(im(2,2) == 0xffff0000);
+
+} // END SECTION
+
+SECTION("test blur") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "blur");
+
+ CHECK(im(0,0) == 0xffc60038);
+ CHECK(im(0,1) == 0xffe2001c);
+ CHECK(im(0,2) == 0xffc60038);
+ CHECK(im(1,0) == 0xffc60038);
+ CHECK(im(1,1) == 0xffe2001c);
+ CHECK(im(1,2) == 0xffc60038);
+ CHECK(im(2,0) == 0xffc60038);
+ CHECK(im(2,1) == 0xffe2001c);
+ CHECK(im(2,2) == 0xffc60038);
+
+} // END SECTION
+
+SECTION("test blur constant") {
+
+ mapnik::image_rgba8 im_orig(3,3);
+ mapnik::fill(im_orig,mapnik::color("blue"));
+ mapnik::set_pixel(im_orig, 1, 1, mapnik::color("red"));
+
+ mapnik::image_rgba8 const& im_new = im_orig;
+ mapnik::image_rgba8 im = mapnik::filter::filter_image(im_new, "blur");
+
+ CHECK(im(0,0) == 0xffc60038);
+ CHECK(im(0,1) == 0xffe2001c);
+ CHECK(im(0,2) == 0xffc60038);
+ CHECK(im(1,0) == 0xffc60038);
+ CHECK(im(1,1) == 0xffe2001c);
+ CHECK(im(1,2) == 0xffc60038);
+ CHECK(im(2,0) == 0xffc60038);
+ CHECK(im(2,1) == 0xffe2001c);
+ CHECK(im(2,2) == 0xffc60038);
+
+} // END SECTION
+
+SECTION("test gray") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "gray");
+
+ CHECK(im(0,0) == 0xff1c1c1c);
+ CHECK(im(0,1) == 0xff1c1c1c);
+ CHECK(im(0,2) == 0xff1c1c1c);
+ CHECK(im(1,0) == 0xff1c1c1c);
+ CHECK(im(1,1) == 0xff4c4c4c);
+ CHECK(im(1,2) == 0xff1c1c1c);
+ CHECK(im(2,0) == 0xff1c1c1c);
+ CHECK(im(2,1) == 0xff1c1c1c);
+ CHECK(im(2,2) == 0xff1c1c1c);
+
+} // END SECTION
+
+SECTION("test agg stack blur") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "agg-stack-blur(1,1)");
+
+ CHECK(im(0,0) == 0xffef000f);
+ CHECK(im(0,1) == 0xffdf001f);
+ CHECK(im(0,2) == 0xffef000f);
+ CHECK(im(1,0) == 0xffdf001f);
+ CHECK(im(1,1) == 0xffbf003f);
+ CHECK(im(1,2) == 0xffdf001f);
+ CHECK(im(2,0) == 0xffef000f);
+ CHECK(im(2,1) == 0xffdf001f);
+ CHECK(im(2,2) == 0xffef000f);
+
+} // END SECTION
+
+SECTION("test scale-hsla") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ // Should throw because a value is greater then 1.0
+ REQUIRE_THROWS(mapnik::filter::filter_image(im, "scale-hsla(0.0,1.5,0.0,1.0,0.0,0.5,0.0,0.5)"););
+
+ mapnik::filter::filter_image(im, "scale-hsla(0.0,0.5,0.0,1.0,0.0,0.5,0.0,0.5)");
+
+ CHECK(im(0,0) == 0x80004000);
+ CHECK(im(0,1) == 0x80004000);
+ CHECK(im(0,2) == 0x80004000);
+ CHECK(im(1,0) == 0x80004000);
+ CHECK(im(1,1) == 0x80000040);
+ CHECK(im(1,2) == 0x80004000);
+ CHECK(im(2,0) == 0x80004000);
+ CHECK(im(2,1) == 0x80004000);
+ CHECK(im(2,2) == 0x80004000);
+
+} // END SECTION
+
+SECTION("test emboss") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("white"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("orange"));
+
+ mapnik::filter::filter_image(im, "emboss");
+
+ CHECK(im(0,0) == 0xff004bff);
+ CHECK(im(0,1) == 0xff00a5ff);
+ CHECK(im(0,2) == 0xff004bff);
+ CHECK(im(1,0) == 0xffffffff);
+ CHECK(im(1,1) == 0xff00a5ff);
+ CHECK(im(1,2) == 0xffffffff);
+ CHECK(im(2,0) == 0xffffffff);
+ CHECK(im(2,1) == 0xffffffff);
+ CHECK(im(2,2) == 0xffffffff);
+
+} // END SECTION
+
+SECTION("test sharpen") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "sharpen");
+
+ CHECK(im(0,0) == 0xffff0000);
+ CHECK(im(0,1) == 0xffff0000);
+ CHECK(im(0,2) == 0xffff0000);
+ CHECK(im(1,0) == 0xffff0000);
+ CHECK(im(1,1) == 0xff00ffff);
+ CHECK(im(1,2) == 0xffff0000);
+ CHECK(im(2,0) == 0xffff0000);
+ CHECK(im(2,1) == 0xffff0000);
+ CHECK(im(2,2) == 0xffff0000);
+
+} // END SECTION
+
+SECTION("test edge detect") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "edge-detect");
+
+ CHECK(im(0,0) == 0xff000000);
+ CHECK(im(0,1) == 0xff008080);
+ CHECK(im(0,2) == 0xff000000);
+ CHECK(im(1,0) == 0xff00ffff);
+ CHECK(im(1,1) == 0xffff0000);
+ CHECK(im(1,2) == 0xff00ffff);
+ CHECK(im(2,0) == 0xff000000);
+ CHECK(im(2,1) == 0xff008080);
+ CHECK(im(2,2) == 0xff000000);
+
+} // END SECTION
+
+SECTION("test sobel") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "sobel");
+
+ CHECK(im(0,0) == 0xfffeffff);
+ CHECK(im(0,1) == 0xfffeffff);
+ CHECK(im(0,2) == 0xfffeffff);
+ CHECK(im(1,0) == 0xff000000);
+ CHECK(im(1,1) == 0xff000000);
+ CHECK(im(1,2) == 0xff000000);
+ CHECK(im(2,0) == 0xfffeffff);
+ CHECK(im(2,1) == 0xfffeffff);
+ CHECK(im(2,2) == 0xfffeffff);
+
+} // END SECTION
+
+SECTION("test x-gradient") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "x-gradient");
+
+ CHECK(im(0,0) == 0xff808080);
+ CHECK(im(0,1) == 0xffbf4040);
+ CHECK(im(0,2) == 0xff808080);
+ CHECK(im(1,0) == 0xff808080);
+ CHECK(im(1,1) == 0xff808080);
+ CHECK(im(1,2) == 0xff808080);
+ CHECK(im(2,0) == 0xff808080);
+ CHECK(im(2,1) == 0xff41c0c0);
+ CHECK(im(2,2) == 0xff808080);
+
+} // END SECTION
+
+SECTION("test y-gradient") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "y-gradient");
+
+ CHECK(im(0,0) == 0xff808080);
+ CHECK(im(0,1) == 0xff808080);
+ CHECK(im(0,2) == 0xff808080);
+ CHECK(im(1,0) == 0xffbf4040);
+ CHECK(im(1,1) == 0xff808080);
+ CHECK(im(1,2) == 0xff41c0c0);
+ CHECK(im(2,0) == 0xff808080);
+ CHECK(im(2,1) == 0xff808080);
+ CHECK(im(2,2) == 0xff808080);
+
+} // END SECTION
+
+SECTION("test invert") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "invert");
+
+ CHECK(im(0,0) == 0xff00ffff);
+ CHECK(im(0,1) == 0xff00ffff);
+ CHECK(im(0,2) == 0xff00ffff);
+ CHECK(im(1,0) == 0xff00ffff);
+ CHECK(im(1,1) == 0xff7f7f7f);
+ CHECK(im(1,2) == 0xff00ffff);
+ CHECK(im(2,0) == 0xff00ffff);
+ CHECK(im(2,1) == 0xff00ffff);
+ CHECK(im(2,2) == 0xff00ffff);
+
+} // END SECTION
+
+SECTION("test colorize-alpha - one color") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "colorize-alpha(blue)");
+
+ CHECK(im(0,0) == 0xffff0000);
+ CHECK(im(0,1) == 0xffff0000);
+ CHECK(im(0,2) == 0xffff0000);
+ CHECK(im(1,0) == 0xffff0000);
+ CHECK(im(1,1) == 0xffff0000);
+ CHECK(im(1,2) == 0xffff0000);
+ CHECK(im(2,0) == 0xffff0000);
+ CHECK(im(2,1) == 0xffff0000);
+ CHECK(im(2,2) == 0xffff0000);
+
+} // END SECTION
+
+SECTION("test colorize-alpha - two color") {
+
+ mapnik::image_rgba8 im(3,3);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("gray"));
+
+ mapnik::filter::filter_image(im, "colorize-alpha(green,blue)");
+
+ CHECK(im(0,0) == 0xfffc0000);
+ CHECK(im(0,1) == 0xfffc0000);
+ CHECK(im(0,2) == 0xfffc0000);
+ CHECK(im(1,0) == 0xfffc0000);
+ CHECK(im(1,1) == 0xfffc0000);
+ CHECK(im(1,2) == 0xfffc0000);
+ CHECK(im(2,0) == 0xfffc0000);
+ CHECK(im(2,1) == 0xfffc0000);
+ CHECK(im(2,2) == 0xfffc0000);
+
+} // END SECTION
+
+SECTION("test color-blind-protanope") {
+
+ mapnik::image_rgba8 im(2,2);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 0, 1, mapnik::color("green"));
+ mapnik::set_pixel(im, 1, 0, mapnik::color("yellow"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "color-blind-protanope");
+
+ CHECK(im(0,0) == 0xff9a4a00);
+ CHECK(im(0,1) == 0xff006e7c);
+ CHECK(im(1,0) == 0xffd9f6ff);
+ CHECK(im(1,1) == 0xff1d7e8e);
+
+} // END SECTION
+
+SECTION("test color-blind-deuteranope") {
+
+ mapnik::image_rgba8 im(2,2);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 0, 1, mapnik::color("green"));
+ mapnik::set_pixel(im, 1, 0, mapnik::color("yellow"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "color-blind-deuteranope");
+
+ CHECK(im(0,0) == 0xff824f00);
+ CHECK(im(0,1) == 0xff1c688b);
+ CHECK(im(1,0) == 0xffe9f5ff);
+ CHECK(im(1,1) == 0xff0077a0);
+
+} // END SECTION
+
+SECTION("test color-blind-tritanope") {
+
+ mapnik::image_rgba8 im(2,2);
+ mapnik::fill(im,mapnik::color("blue"));
+ mapnik::set_pixel(im, 0, 1, mapnik::color("green"));
+ mapnik::set_pixel(im, 1, 0, mapnik::color("yellow"));
+ mapnik::set_pixel(im, 1, 1, mapnik::color("red"));
+
+ mapnik::filter::filter_image(im, "color-blind-tritanope");
+
+ CHECK(im(0,0) == 0xff595500);
+ CHECK(im(0,1) == 0xff80763a);
+ CHECK(im(1,0) == 0xfff8f3ff);
+ CHECK(im(1,1) == 0xff0017fd);
+
+} // END SECTION
+
+} // END TEST CASE
+
diff --git a/test/unit/imaging/image_io_test.cpp b/test/unit/imaging/image_io_test.cpp
index d0a984d..6daeca8 100644
--- a/test/unit/imaging/image_io_test.cpp
+++ b/test/unit/imaging/image_io_test.cpp
@@ -4,6 +4,7 @@
#include <mapnik/image.hpp>
#include <mapnik/image_reader.hpp>
#include <mapnik/image_util.hpp>
+#include <mapnik/image_util_jpeg.hpp>
#include <mapnik/util/fs.hpp>
#include <vector>
#include <algorithm>
@@ -41,6 +42,7 @@ SECTION("readers") {
{
REQUIRE( std::string(ex.what()) == std::string("JPEG Reader: libjpeg could not read image: Not a JPEG file: starts with 0x89 0x50") );
}
+
#endif
REQUIRE_THROWS(mapnik::image_rgba8 im(-10,-10)); // should throw rather than overflow
@@ -95,5 +97,17 @@ SECTION("readers") {
} // END SECTION
+SECTION("writers options")
+{
+#if defined(HAVE_JPEG)
+ // test we can parse both jpegXX and quality=XX options
+ REQUIRE_THROWS(mapnik::detail::parse_jpeg_quality("jpegXX"));
+ REQUIRE_THROWS(mapnik::detail::parse_jpeg_quality("jpeg:quality=XX"));
+ int q0 = mapnik::detail::parse_jpeg_quality("jpeg50");
+ int q1 = mapnik::detail::parse_jpeg_quality("jpeg:quality=50");
+ REQUIRE(q0 == q1);
+#endif
+
+} // END SECTION
} // END TEST_CASE
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/mapnik.git
More information about the Pkg-grass-devel
mailing list