From b2d08ea4eaf77fb334b2c09b9b56bdd71d3dd0ce Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Mon, 14 Sep 2015 16:45:58 -0700 Subject: [PATCH] re-enable zero allocation image interface - refs #3069 --- include/mapnik/image.hpp | 7 +++++++ include/mapnik/image_impl.hpp | 10 ++++++++++ src/image.cpp | 19 +++++++++++++++---- test/unit/imaging/image_io_test.cpp | 5 +++++ 4 files changed, 37 insertions(+), 4 deletions(-) diff --git a/include/mapnik/image.hpp b/include/mapnik/image.hpp index ec8b1f88a..bea771449 100644 --- a/include/mapnik/image.hpp +++ b/include/mapnik/image.hpp @@ -34,6 +34,7 @@ namespace detail { struct MAPNIK_DECL buffer { explicit buffer(std::size_t size); + explicit buffer(unsigned char* data, std::size_t size); buffer(buffer && rhs) noexcept; buffer(buffer const& rhs); ~buffer(); @@ -51,6 +52,7 @@ struct MAPNIK_DECL buffer private: std::size_t size_; unsigned char* data_; + bool owns_; }; @@ -93,6 +95,11 @@ public: bool initialize = true, bool premultiplied = false, bool painted = false); + image(int width, + int height, + detail::buffer && buf, + bool premultiplied = false, + bool painted = false); image(image const& rhs); image(image && rhs) noexcept; image& operator=(image rhs); diff --git a/include/mapnik/image_impl.hpp b/include/mapnik/image_impl.hpp index 5a84f9e85..94b753c1c 100644 --- a/include/mapnik/image_impl.hpp +++ b/include/mapnik/image_impl.hpp @@ -77,6 +77,16 @@ image::image() painted_(false) {} +template +image::image(int width, int height, detail::buffer && buf, bool premultiplied, bool painted) + : dimensions_(width, height), + buffer_(std::move(buf)), + pData_(reinterpret_cast(buffer_.data())), + offset_(0.0), + scaling_(1.0), + premultiplied_alpha_(premultiplied), + painted_(painted) {} + template image::image(int width, int height, bool initialize, bool premultiplied, bool painted) : dimensions_(width, height), diff --git a/src/image.cpp b/src/image.cpp index caa0a8fc1..006ce3191 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -36,27 +36,37 @@ namespace detail // BUFFER buffer::buffer(std::size_t size) : size_(size), - data_(static_cast(size_ != 0 ? ::operator new(size_) : nullptr)) + data_(static_cast(size_ != 0 ? ::operator new(size_) : nullptr)), + owns_(true) +{} + +buffer::buffer(unsigned char* data, std::size_t size) + : size_(size), + data_(data), + owns_(false) {} buffer::buffer(buffer && rhs) noexcept : size_(std::move(rhs.size_)), - data_(std::move(rhs.data_)) + data_(std::move(rhs.data_)), + owns_(std::move(rhs.owns_)) { rhs.size_ = 0; rhs.data_ = nullptr; + rhs.owns_ = true; } buffer::buffer(buffer const& rhs) : size_(rhs.size_), - data_(static_cast(size_ != 0 ? ::operator new(size_) : nullptr)) + data_(static_cast(size_ != 0 ? ::operator new(size_) : nullptr)), + owns_(rhs.owns_) { if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_); } buffer::~buffer() { - ::operator delete(data_); + if (owns_) ::operator delete(data_); } buffer& buffer::operator=(buffer rhs) @@ -69,6 +79,7 @@ void buffer::swap(buffer & rhs) { std::swap(size_, rhs.size_); std::swap(data_, rhs.data_); + std::swap(owns_, rhs.owns_); } unsigned char* buffer::data() diff --git a/test/unit/imaging/image_io_test.cpp b/test/unit/imaging/image_io_test.cpp index 6daeca899..881179865 100644 --- a/test/unit/imaging/image_io_test.cpp +++ b/test/unit/imaging/image_io_test.cpp @@ -21,6 +21,11 @@ SECTION("readers") { boost::optional type; try { + mapnik::image_rgba8 im_og; + auto im_size = mapnik::image_rgba8::pixel_size * im_og.width() * im_og.height(); + mapnik::detail::buffer buf(im_og.bytes(),im_size); + mapnik::image_rgba8 im2(im_og.width(),im_og.height(),std::move(buf)); + CHECK( im2.bytes() == im_og.bytes() ); #if defined(HAVE_JPEG) should_throw = "./test/data/images/blank.jpg"; REQUIRE( mapnik::util::exists( should_throw ) );