image_data : re-factor (ref #2491)
* factor out raw image data alloc/dealloc into separate detail::buffer * remove shallow ctor * remove no-op dtor from image_data
This commit is contained in:
parent
5e2a53bac9
commit
f7649c27b0
1 changed files with 61 additions and 43 deletions
|
@ -25,74 +25,100 @@
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/global.hpp>
|
#include <mapnik/global.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct buffer
|
||||||
{
|
{
|
||||||
|
explicit buffer(std::size_t size)
|
||||||
|
: size_(size),
|
||||||
|
data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
|
||||||
|
{}
|
||||||
|
|
||||||
|
buffer(buffer && rhs) noexcept = default;
|
||||||
|
buffer(buffer const& rhs)
|
||||||
|
: size_(rhs.size_),
|
||||||
|
data_(rhs.data_)
|
||||||
|
{
|
||||||
|
if (data_) std::copy(rhs.data_, rhs.data_ + rhs.size_, data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator!() const { return (data_ == nullptr)? false : true; }
|
||||||
|
~buffer()
|
||||||
|
{
|
||||||
|
::operator delete(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned char* data() { return data_; }
|
||||||
|
inline unsigned char const* data() const { return data_; }
|
||||||
|
inline std::size_t size() const { return size_; }
|
||||||
|
std::size_t size_;
|
||||||
|
unsigned char* data_;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class image_data
|
class image_data
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using pixel_type = T;
|
using pixel_type = T;
|
||||||
|
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
||||||
|
|
||||||
image_data(std::size_t width, std::size_t height, bool initialize = true)
|
image_data(std::size_t width, std::size_t height, bool initialize = true)
|
||||||
: width_(width),
|
: width_(width),
|
||||||
height_(height),
|
height_(height),
|
||||||
pData_((width!=0 && height!=0) ? static_cast<T*>(::operator new(sizeof(T) * width_ * height_)):0),
|
buffer_(width_ * height_ * pixel_size),
|
||||||
|
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
|
||||||
owns_data_(true)
|
owns_data_(true)
|
||||||
{
|
{
|
||||||
if (pData_ && initialize) std::fill(pData_, pData_ + width_ * height_, 0);
|
if (pData_ && initialize) std::fill(pData_, pData_ + width_ * height_, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
image_data(std::size_t width, std::size_t height, T * data)
|
image_data(image_data<pixel_type> const& rhs)
|
||||||
: width_(width),
|
|
||||||
height_(height),
|
|
||||||
owns_data_(false),
|
|
||||||
pData_(data) {}
|
|
||||||
|
|
||||||
image_data(image_data<T> const& rhs)
|
|
||||||
: width_(rhs.width_),
|
: width_(rhs.width_),
|
||||||
height_(rhs.height_),
|
height_(rhs.height_),
|
||||||
pData_((rhs.width_!=0 && rhs.height_!=0) ?
|
buffer_(rhs.buffer_),
|
||||||
static_cast<T*>(::operator new(sizeof(T) * rhs.width_ * rhs.height_)) : 0),
|
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
|
||||||
owns_data_(true)
|
owns_data_(true) {}
|
||||||
{
|
|
||||||
if (pData_) std::copy(rhs.pData_, rhs.pData_ + rhs.width_* rhs.height_, pData_);
|
|
||||||
}
|
|
||||||
|
|
||||||
image_data(image_data<T> && rhs) noexcept
|
image_data(image_data<pixel_type> && rhs) noexcept
|
||||||
: width_(rhs.width_),
|
: width_(rhs.width_),
|
||||||
height_(rhs.height_),
|
height_(rhs.height_),
|
||||||
pData_(rhs.pData_)
|
buffer_(std::move(rhs.buffer_)),
|
||||||
|
pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
|
||||||
{
|
{
|
||||||
rhs.width_ = 0;
|
rhs.width_ = 0;
|
||||||
rhs.height_ = 0;
|
rhs.height_ = 0;
|
||||||
rhs.pData_ = nullptr;
|
rhs.pData_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
image_data<T>& operator=(image_data<T> rhs)
|
image_data<pixel_type>& operator=(image_data<pixel_type> rhs)
|
||||||
{
|
{
|
||||||
swap(rhs);
|
swap(rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(image_data<T> & rhs)
|
void swap(image_data<pixel_type> & rhs)
|
||||||
{
|
{
|
||||||
std::swap(width_, rhs.width_);
|
std::swap(width_, rhs.width_);
|
||||||
std::swap(height_, rhs.height_);
|
std::swap(height_, rhs.height_);
|
||||||
std::swap(pData_, rhs.pData_);
|
std::swap(buffer_, rhs.buffer_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T& operator() (std::size_t i, std::size_t j)
|
inline pixel_type& operator() (std::size_t i, std::size_t j)
|
||||||
{
|
{
|
||||||
assert(i<width_ && j<height_);
|
assert(i<width_ && j<height_);
|
||||||
return pData_[j * width_ + i];
|
return pData_[j * width_ + i];
|
||||||
}
|
}
|
||||||
inline const T& operator() (std::size_t i,std::size_t j) const
|
inline const pixel_type& operator() (std::size_t i, std::size_t j) const
|
||||||
{
|
{
|
||||||
assert(i < width_ && j < height_);
|
assert(i < width_ && j < height_);
|
||||||
return pData_[j * width_ + i];
|
return pData_[j * width_ + i];
|
||||||
|
@ -105,64 +131,56 @@ public:
|
||||||
{
|
{
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
inline void set(T const& t)
|
inline void set(pixel_type const& t)
|
||||||
{
|
{
|
||||||
std::fill(pData_, pData_ + width_ * height_, t);
|
std::fill(pData_, pData_ + width_ * height_, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const T* getData() const
|
inline const pixel_type* getData() const
|
||||||
{
|
{
|
||||||
return pData_;
|
return pData_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T* getData()
|
inline pixel_type* getData()
|
||||||
{
|
{
|
||||||
return pData_;
|
return pData_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const unsigned char* getBytes() const
|
inline const unsigned char* getBytes() const
|
||||||
{
|
{
|
||||||
return reinterpret_cast<unsigned char*>(pData_);
|
return buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned char* getBytes()
|
inline unsigned char* getBytes()
|
||||||
{
|
{
|
||||||
return reinterpret_cast<unsigned char*>(pData_);
|
return buffer_.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const T* getRow(unsigned row) const
|
inline const pixel_type* getRow(unsigned row) const
|
||||||
{
|
{
|
||||||
return pData_ + row * width_;
|
return pData_ + row * width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T* getRow(unsigned row)
|
inline pixel_type* getRow(unsigned row)
|
||||||
{
|
{
|
||||||
return pData_ + row * width_;
|
return pData_ + row * width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setRow(std::size_t row, T const* buf, std::size_t size)
|
inline void setRow(std::size_t row, pixel_type const* buf, std::size_t size)
|
||||||
{
|
{
|
||||||
assert(row < height_);
|
assert(row < height_);
|
||||||
assert(size <= width_);
|
assert(size <= width_);
|
||||||
std::copy(buf, buf + size, pData_ + row * width_);
|
std::copy(buf, buf + size, pData_ + row * width_);
|
||||||
}
|
}
|
||||||
inline void setRow(std::size_t row, std::size_t x0, std::size_t x1, T const* buf)
|
inline void setRow(std::size_t row, std::size_t x0, std::size_t x1, pixel_type const* buf)
|
||||||
{
|
{
|
||||||
std::copy(buf, buf + (x1 - x0), pData_ + row * width_);
|
std::copy(buf, buf + (x1 - x0), pData_ + row * width_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline ~image_data()
|
|
||||||
{
|
|
||||||
if (owns_data_)
|
|
||||||
{
|
|
||||||
::operator delete(pData_),pData_=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::size_t width_;
|
std::size_t width_;
|
||||||
std::size_t height_;
|
std::size_t height_;
|
||||||
T *pData_;
|
detail::buffer buffer_;
|
||||||
|
pixel_type *pData_;
|
||||||
bool owns_data_;
|
bool owns_data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue