From 4d402c5ef14402ff0e6727f51f87539e567133dd Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Fri, 4 Mar 2016 10:58:12 +0000 Subject: [PATCH 1/4] raster scaling: fix accessing out of bounds pixels --- include/mapnik/span_image_filter.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index 972558ccf..8559394fa 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -81,7 +81,7 @@ public: int src_x = x >> agg::image_subpixel_shift; int src_y = y >> agg::image_subpixel_shift; - const value_type* pix = reinterpret_cast(base_type::source().span(src_x, src_y, 0)); + const value_type* pix = reinterpret_cast(base_type::source().span(src_x, src_y, 1)); if (nodata_value_ && *nodata_value_ == *pix) { span->v = *nodata_value_; From 1054e1bddb2aa4fe3d740a9c2e22fcef62c8481c Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Fri, 4 Mar 2016 15:13:55 +0000 Subject: [PATCH 2/4] raster scaling: check for division by zero --- include/mapnik/span_image_filter.hpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index 8559394fa..ccb4c2ba3 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -131,19 +131,27 @@ public: fg_ptr = reinterpret_cast(base_type::source().next_y()); } - fg /= total_weight; - if (fg < std::numeric_limits::min()) + if (total_weight == 0) { - span->v = std::numeric_limits::min(); - } - else if (fg > std::numeric_limits::max()) - { - span->v = std::numeric_limits::max(); + span->v = *nodata_value_; } else { - span->v = static_cast(fg); + fg /= total_weight; + if (fg < std::numeric_limits::min()) + { + span->v = std::numeric_limits::min(); + } + else if (fg > std::numeric_limits::max()) + { + span->v = std::numeric_limits::max(); + } + else + { + span->v = static_cast(fg); + } } + span->a = base_mask; ++span; From f1f65664cd9962b27a292a9b010e4e0667846f11 Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Fri, 4 Mar 2016 15:14:01 +0000 Subject: [PATCH 3/4] raster scaling: a bit of optimization --- include/mapnik/span_image_filter.hpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index ccb4c2ba3..0b6fc2dec 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -79,16 +79,19 @@ public: { base_type::interpolator().coordinates(&x, &y); - int src_x = x >> agg::image_subpixel_shift; - int src_y = y >> agg::image_subpixel_shift; - const value_type* pix = reinterpret_cast(base_type::source().span(src_x, src_y, 1)); - if (nodata_value_ && *nodata_value_ == *pix) + if (nodata_value_) { - span->v = *nodata_value_; - span->a = base_mask; - ++span; - ++base_type::interpolator(); - continue; + int src_x = x >> agg::image_subpixel_shift; + int src_y = y >> agg::image_subpixel_shift; + const value_type* pix = reinterpret_cast(base_type::source().span(src_x, src_y, 1)); + if (*nodata_value_ == *pix) + { + span->v = *nodata_value_; + span->a = base_mask; + ++span; + ++base_type::interpolator(); + continue; + } } x += base_type::filter_dx_int() - radius_x; From d4ac105eca8e3aa6fd2363922a5bede503bab782 Mon Sep 17 00:00:00 2001 From: Jiri Drbalek Date: Fri, 4 Mar 2016 16:59:12 +0000 Subject: [PATCH 4/4] raster scaling: use mapnik::safe_cast, fixes clipping negative floats --- include/mapnik/span_image_filter.hpp | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/include/mapnik/span_image_filter.hpp b/include/mapnik/span_image_filter.hpp index 0b6fc2dec..31217690e 100644 --- a/include/mapnik/span_image_filter.hpp +++ b/include/mapnik/span_image_filter.hpp @@ -30,6 +30,8 @@ #include +#include + namespace mapnik { @@ -140,19 +142,7 @@ public: } else { - fg /= total_weight; - if (fg < std::numeric_limits::min()) - { - span->v = std::numeric_limits::min(); - } - else if (fg > std::numeric_limits::max()) - { - span->v = std::numeric_limits::max(); - } - else - { - span->v = static_cast(fg); - } + span->v = safe_cast(fg / total_weight); } span->a = base_mask;