add mapnik.Image.premultiplied() to query status of pixel premultiplication

This commit is contained in:
Dane Springmeyer 2013-07-02 16:01:23 -04:00
parent 80d9171bd1
commit c011524b67
5 changed files with 27 additions and 3 deletions

View file

@ -6,6 +6,10 @@ Developers: Please commit along with changes.
For a complete change history, see the git log. For a complete change history, see the git log.
## Future
- Added `premultiplied` property on mapnik::image_32 / mapnik.Image to enable knowledge of premultiplied status of image buffer.
## 2.2.0 ## 2.2.0
Released June 3rd, 2013 Released June 3rd, 2013

View file

@ -272,6 +272,7 @@ void export_image()
arg("mode")=mapnik::src_over, arg("mode")=mapnik::src_over,
arg("opacity")=1.0f arg("opacity")=1.0f
)) ))
.def("premultiplied",&image_32::premultiplied)
.def("premultiply",&image_32::premultiply) .def("premultiply",&image_32::premultiply)
.def("demultiply",&image_32::demultiply) .def("demultiply",&image_32::demultiply)
.def("set_pixel",&set_pixel) .def("set_pixel",&set_pixel)

View file

@ -54,6 +54,7 @@ private:
boost::optional<color> background_; boost::optional<color> background_;
image_data_32 data_; image_data_32 data_;
bool painted_; bool painted_;
bool premultiplied_;
public: public:
image_32(int width,int height); image_32(int width,int height);
image_32(image_32 const& rhs); image_32(image_32 const& rhs);
@ -72,6 +73,11 @@ public:
return painted_; return painted_;
} }
bool premultiplied() const
{
return premultiplied_;
}
inline void clear() inline void clear()
{ {
std::memset(data_.getData(),0,sizeof(mapnik::image_data_32::pixel_type)*data_.width()*data_.height()); std::memset(data_.getData(),0,sizeof(mapnik::image_data_32::pixel_type)*data_.width()*data_.height());

View file

@ -45,19 +45,22 @@ image_32::image_32(int width,int height)
:width_(width), :width_(width),
height_(height), height_(height),
data_(width,height), data_(width,height),
painted_(false) {} painted_(false),
premultiplied_(false) {}
image_32::image_32(const image_32& rhs) image_32::image_32(const image_32& rhs)
:width_(rhs.width_), :width_(rhs.width_),
height_(rhs.height_), height_(rhs.height_),
data_(rhs.data_), data_(rhs.data_),
painted_(rhs.painted_) {} painted_(rhs.painted_),
premultiplied_(rhs.premultiplied_) {}
#ifdef HAVE_CAIRO #ifdef HAVE_CAIRO
image_32::image_32(cairo_surface_ptr const& surface) image_32::image_32(cairo_surface_ptr const& surface)
:width_(cairo_image_surface_get_width(&*surface)), :width_(cairo_image_surface_get_width(&*surface)),
height_(cairo_image_surface_get_height(&*surface)), height_(cairo_image_surface_get_height(&*surface)),
data_(width_, height_) data_(width_, height_),
premultiplied_(false)
{ {
painted_ = true; painted_ = true;
if ( cairo_image_surface_get_format(&*surface) != CAIRO_FORMAT_ARGB32) if ( cairo_image_surface_get_format(&*surface) != CAIRO_FORMAT_ARGB32)
@ -193,6 +196,7 @@ void image_32::premultiply()
agg::rendering_buffer buffer(data_.getBytes(),width_,height_,width_ * 4); agg::rendering_buffer buffer(data_.getBytes(),width_,height_,width_ * 4);
agg::pixfmt_rgba32 pixf(buffer); agg::pixfmt_rgba32 pixf(buffer);
pixf.premultiply(); pixf.premultiply();
premultiplied_ = true;
} }
void image_32::demultiply() void image_32::demultiply()
@ -200,6 +204,7 @@ void image_32::demultiply()
agg::rendering_buffer buffer(data_.getBytes(),width_,height_,width_ * 4); agg::rendering_buffer buffer(data_.getBytes(),width_,height_,width_ * 4);
agg::pixfmt_rgba32 pixf(buffer); agg::pixfmt_rgba32 pixf(buffer);
pixf.demultiply(); pixf.demultiply();
premultiplied_ = false;
} }
void image_32::composite_pixel(unsigned op, int x,int y, unsigned c, unsigned cover, double opacity) void image_32::composite_pixel(unsigned op, int x,int y, unsigned c, unsigned cover, double opacity)

View file

@ -12,6 +12,14 @@ def setup():
# from another directory we need to chdir() # from another directory we need to chdir()
os.chdir(execution_path('.')) os.chdir(execution_path('.'))
def test_image_premultiply():
im = mapnik.Image(256,256)
eq_(im.premultiplied(),False)
im.premultiply()
eq_(im.premultiplied(),True)
im.demultiply()
eq_(im.premultiplied(),False)
@raises(RuntimeError) @raises(RuntimeError)
def test_negative_image_dimensions(): def test_negative_image_dimensions():
im = mapnik.Image(-40,40) im = mapnik.Image(-40,40)