From bf9c99e3d30bebcca7be7bc43665e5a697ef6fda Mon Sep 17 00:00:00 2001 From: artemp Date: Wed, 26 Nov 2014 12:22:36 +0100 Subject: [PATCH] initial image_data_any implentation (work-in-progress) --- include/mapnik/image_data.hpp | 10 ++- include/mapnik/raster.hpp | 83 +++++++++++++++++-- .../process_raster_symbolizer.hpp | 37 ++++++--- plugins/input/gdal/gdal_featureset.cpp | 5 +- plugins/input/raster/raster_featureset.cpp | 7 +- src/raster_colorizer.cpp | 4 +- src/warp.cpp | 4 +- 7 files changed, 122 insertions(+), 28 deletions(-) diff --git a/include/mapnik/image_data.hpp b/include/mapnik/image_data.hpp index 23f53394b..78b4acccb 100644 --- a/include/mapnik/image_data.hpp +++ b/include/mapnik/image_data.hpp @@ -41,7 +41,14 @@ struct buffer data_(static_cast(size_ != 0 ? ::operator new(size_) : nullptr)) {} - buffer(buffer && rhs) noexcept = default; + buffer(buffer && rhs) noexcept + : size_(std::move(rhs.size_)), + data_(std::move(rhs.data_)) + { + rhs.size_ = 0; + rhs.data_ = nullptr; + } + buffer(buffer const& rhs) : size_(rhs.size_), data_(rhs.data_) @@ -184,6 +191,7 @@ private: using image_data_32 = image_data; using image_data_8 = image_data ; +using image_data_float32 = image_data; } #endif // MAPNIK_IMAGE_DATA_HPP diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp index 2c97c3be8..791052de5 100644 --- a/include/mapnik/raster.hpp +++ b/include/mapnik/raster.hpp @@ -27,26 +27,99 @@ #include #include #include - +#include // boost #include namespace mapnik { + +using image_data_base = util::variant; + +namespace detail { + +struct get_bytes_visitor : util::static_visitor +{ + template + unsigned char* operator()(T & data) + { + return data.getBytes(); + } +}; + +struct get_bytes_visitor_const : util::static_visitor +{ + template + unsigned char const* operator()(T const& data) const + { + return data.getBytes(); + } +}; + +struct get_width_visitor : util::static_visitor +{ + template + std::size_t operator()(T const& data) const + { + return data.width(); + } +}; + +struct get_height_visitor : util::static_visitor +{ + template + std::size_t operator()(T const& data) const + { + return data.height(); + } +}; + + +} // namespace detail + +struct image_data_any : image_data_base +{ + template + image_data_any(T && data) noexcept + : image_data_base(std::move(data)) {} + + unsigned char const* getBytes() const + { + return util::apply_visitor(detail::get_bytes_visitor_const(),*this); + } + + unsigned char* getBytes() + { + return util::apply_visitor(detail::get_bytes_visitor(),*this); + } + + std::size_t width() const + { + return util::apply_visitor(detail::get_width_visitor(),*this); + } + + std::size_t height() const + { + return util::apply_visitor(detail::get_height_visitor(),*this); + } +}; + + class raster : private mapnik::noncopyable { public: box2d ext_; - image_data_32 data_; + image_data_any data_; double filter_factor_; bool premultiplied_alpha_; boost::optional nodata_; + + template raster(box2d const& ext, - unsigned width, - unsigned height, + ImageData && data, double filter_factor, bool premultiplied_alpha = false) : ext_(ext), - data_(width,height), + data_(std::move(data)), filter_factor_(filter_factor), premultiplied_alpha_(premultiplied_alpha) {} diff --git a/include/mapnik/renderer_common/process_raster_symbolizer.hpp b/include/mapnik/renderer_common/process_raster_symbolizer.hpp index f6a645edc..90ac8997c 100644 --- a/include/mapnik/renderer_common/process_raster_symbolizer.hpp +++ b/include/mapnik/renderer_common/process_raster_symbolizer.hpp @@ -86,7 +86,8 @@ void render_raster_symbolizer(raster_symbolizer const &sym, { double offset_x = ext.minx() - start_x; double offset_y = ext.miny() - start_y; - raster target(target_ext, raster_width, raster_height, source->get_filter_factor()); + image_data_32 data(raster_width, raster_height); + raster target(target_ext, data, source->get_filter_factor()); unsigned mesh_size = static_cast(get(sym,keys::mesh_size,feature, common.vars_, 16)); reproject_and_scale_raster(target, *source, @@ -95,7 +96,10 @@ void render_raster_symbolizer(raster_symbolizer const &sym, offset_y, mesh_size, scaling_method); - composite(target.data_, comp_op, opacity, start_x, start_y); + if (target.data_.is()) + { + composite(util::get(target.data_), comp_op, opacity, start_x, start_y); + } } else { @@ -107,20 +111,27 @@ void render_raster_symbolizer(raster_symbolizer const &sym, (std::abs(start_x) <= eps) && (std::abs(start_y) <= eps) ) { - composite(source->data_, comp_op, opacity, start_x, start_y); + if (source->data_.is()) + { + composite(util::get(source->data_), comp_op, opacity, start_x, start_y); + } } else { - raster target(target_ext, raster_width, raster_height, source->get_filter_factor()); - scale_image_agg(target.data_, - source->data_, - scaling_method, - image_ratio_x, - image_ratio_y, - 0.0, - 0.0, - source->get_filter_factor()); - composite(target.data_, comp_op, opacity, start_x, start_y); + if (source->data_.is()) + { + image_data_32 data(raster_width, raster_height); + raster target(target_ext, data, source->get_filter_factor()); + scale_image_agg(util::get(target.data_), + util::get(source->data_), + scaling_method, + image_ratio_x, + image_ratio_y, + 0.0, + 0.0, + source->get_filter_factor()); + composite(util::get(target.data_), comp_op, opacity, start_x, start_y); + } } } } diff --git a/plugins/input/gdal/gdal_featureset.cpp b/plugins/input/gdal/gdal_featureset.cpp index 5ec6cd526..4af9c525d 100644 --- a/plugins/input/gdal/gdal_featureset.cpp +++ b/plugins/input/gdal/gdal_featureset.cpp @@ -199,9 +199,10 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q) if (im_width > 0 && im_height > 0) { - mapnik::raster_ptr raster = std::make_shared(intersect, im_width, im_height, filter_factor); + mapnik::image_data_32 data(im_width, im_height); + mapnik::raster_ptr raster = std::make_shared(intersect, data, filter_factor); feature->set_raster(raster); - mapnik::image_data_32 & image = raster->data_; + mapnik::image_data_32 & image = mapnik::util::get(raster->data_); image.set(0xffffffff); MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")"; diff --git a/plugins/input/raster/raster_featureset.cpp b/plugins/input/raster/raster_featureset.cpp index e5ab501d8..d0f9cfb3d 100644 --- a/plugins/input/raster/raster_featureset.cpp +++ b/plugins/input/raster/raster_featureset.cpp @@ -28,6 +28,7 @@ #include #include #include +#include // boost #pragma GCC diagnostic push @@ -113,9 +114,9 @@ feature_ptr raster_featureset::next() rem.maxx() + x_off + width, rem.maxy() + y_off + height); intersect = t.backward(feature_raster_extent); - - mapnik::raster_ptr raster = std::make_shared(intersect, width, height, 1.0); - reader->read(x_off, y_off, raster->data_); + image_data_32 data(width,height); + reader->read(x_off, y_off, data); + mapnik::raster_ptr raster = std::make_shared(intersect, data, 1.0); raster->premultiplied_alpha_ = reader->premultiplied_alpha(); feature->set_raster(raster); } diff --git a/src/raster_colorizer.cpp b/src/raster_colorizer.cpp index 3a1785b41..3cf0b0850 100644 --- a/src/raster_colorizer.cpp +++ b/src/raster_colorizer.cpp @@ -124,14 +124,14 @@ bool raster_colorizer::add_stop(colorizer_stop const& stop) void raster_colorizer::colorize(raster_ptr const& raster, feature_impl const& f) const { - unsigned *imageData = raster->data_.getData(); + unsigned* imageData = reinterpret_cast(raster->data_.getBytes()); int len = raster->data_.width() * raster->data_.height(); boost::optional const& nodata = raster->nodata(); for (int i=0; i (&imageData[i]); + float value = *reinterpret_cast (&imageData[i]); if (nodata && (std::fabs(value - *nodata) < epsilon_)) { imageData[i] = 0; diff --git a/src/warp.cpp b/src/warp.cpp index 06e2adf62..eaf93c93d 100644 --- a/src/warp.cpp +++ b/src/warp.cpp @@ -83,7 +83,7 @@ void reproject_and_scale_raster(raster & target, raster const& source, agg::rasterizer_scanline_aa<> rasterizer; agg::scanline_bin scanline; - agg::rendering_buffer buf((unsigned char*)target.data_.getData(), + agg::rendering_buffer buf(target.data_.getBytes(), target.data_.width(), target.data_.height(), target.data_.width()*4); @@ -91,7 +91,7 @@ void reproject_and_scale_raster(raster & target, raster const& source, renderer_base rb(pixf); rasterizer.clip_box(0, 0, target.data_.width(), target.data_.height()); agg::rendering_buffer buf_tile( - (unsigned char*)source.data_.getData(), + const_cast(source.data_.getBytes()), source.data_.width(), source.data_.height(), source.data_.width() * 4);