re-enable zero allocation image interface - refs #3069

This commit is contained in:
Dane Springmeyer 2015-09-14 16:45:58 -07:00
parent 0532df7b6e
commit b2d08ea4ea
4 changed files with 37 additions and 4 deletions

View file

@ -34,6 +34,7 @@ namespace detail {
struct MAPNIK_DECL buffer struct MAPNIK_DECL buffer
{ {
explicit buffer(std::size_t size); explicit buffer(std::size_t size);
explicit buffer(unsigned char* data, std::size_t size);
buffer(buffer && rhs) noexcept; buffer(buffer && rhs) noexcept;
buffer(buffer const& rhs); buffer(buffer const& rhs);
~buffer(); ~buffer();
@ -51,6 +52,7 @@ struct MAPNIK_DECL buffer
private: private:
std::size_t size_; std::size_t size_;
unsigned char* data_; unsigned char* data_;
bool owns_;
}; };
@ -93,6 +95,11 @@ public:
bool initialize = true, bool initialize = true,
bool premultiplied = false, bool premultiplied = false,
bool painted = false); bool painted = false);
image(int width,
int height,
detail::buffer && buf,
bool premultiplied = false,
bool painted = false);
image(image<T> const& rhs); image(image<T> const& rhs);
image(image<T> && rhs) noexcept; image(image<T> && rhs) noexcept;
image<T>& operator=(image<T> rhs); image<T>& operator=(image<T> rhs);

View file

@ -77,6 +77,16 @@ image<T>::image()
painted_(false) painted_(false)
{} {}
template <typename T>
image<T>::image(int width, int height, detail::buffer && buf, bool premultiplied, bool painted)
: dimensions_(width, height),
buffer_(std::move(buf)),
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
offset_(0.0),
scaling_(1.0),
premultiplied_alpha_(premultiplied),
painted_(painted) {}
template <typename T> template <typename T>
image<T>::image(int width, int height, bool initialize, bool premultiplied, bool painted) image<T>::image(int width, int height, bool initialize, bool premultiplied, bool painted)
: dimensions_(width, height), : dimensions_(width, height),

View file

@ -36,27 +36,37 @@ namespace detail
// BUFFER // BUFFER
buffer::buffer(std::size_t size) buffer::buffer(std::size_t size)
: size_(size), : size_(size),
data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr)) data_(static_cast<unsigned char*>(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 buffer::buffer(buffer && rhs) noexcept
: size_(std::move(rhs.size_)), : size_(std::move(rhs.size_)),
data_(std::move(rhs.data_)) data_(std::move(rhs.data_)),
owns_(std::move(rhs.owns_))
{ {
rhs.size_ = 0; rhs.size_ = 0;
rhs.data_ = nullptr; rhs.data_ = nullptr;
rhs.owns_ = true;
} }
buffer::buffer(buffer const& rhs) buffer::buffer(buffer const& rhs)
: size_(rhs.size_), : size_(rhs.size_),
data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr)) data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr)),
owns_(rhs.owns_)
{ {
if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_); if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
} }
buffer::~buffer() buffer::~buffer()
{ {
::operator delete(data_); if (owns_) ::operator delete(data_);
} }
buffer& buffer::operator=(buffer rhs) buffer& buffer::operator=(buffer rhs)
@ -69,6 +79,7 @@ void buffer::swap(buffer & rhs)
{ {
std::swap(size_, rhs.size_); std::swap(size_, rhs.size_);
std::swap(data_, rhs.data_); std::swap(data_, rhs.data_);
std::swap(owns_, rhs.owns_);
} }
unsigned char* buffer::data() unsigned char* buffer::data()

View file

@ -21,6 +21,11 @@ SECTION("readers") {
boost::optional<std::string> type; boost::optional<std::string> type;
try 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) #if defined(HAVE_JPEG)
should_throw = "./test/data/images/blank.jpg"; should_throw = "./test/data/images/blank.jpg";
REQUIRE( mapnik::util::exists( should_throw ) ); REQUIRE( mapnik::util::exists( should_throw ) );