Added a lot of premultiply_alpha functions to attempt to have proper premultiplication of data prior to compositing. There still seem to be some errors in the resulting images, but I am not quite sure what they are yet.
This commit is contained in:
parent
42c7d7ddf2
commit
202a0e8e5f
6 changed files with 32 additions and 11 deletions
|
@ -228,6 +228,8 @@ void demultiply(image_32 & im)
|
|||
|
||||
void composite(image_32 & dst, image_32 & src, mapnik::composite_mode_e mode, float opacity)
|
||||
{
|
||||
mapnik::premultiply_alpha(dst.data());
|
||||
mapnik::premultiply_alpha(src.data());
|
||||
mapnik::composite(dst.data(),src.data(),mode,opacity,0,0);
|
||||
}
|
||||
|
||||
|
|
|
@ -192,15 +192,22 @@ struct tag_setter
|
|||
throw ImageWriterException("Could not write TIFF - unknown image type provided");
|
||||
}
|
||||
|
||||
inline void operator() (image_data_rgba8 const&) const
|
||||
inline void operator() (image_data_rgba8 const& data) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 4);
|
||||
//uint16 extras[] = { EXTRASAMPLE_UNASSALPHA };
|
||||
uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
if (data.get_premultiplied())
|
||||
{
|
||||
uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16 extras[] = { EXTRASAMPLE_UNASSALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
}
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
|
|
|
@ -145,6 +145,8 @@ void agg_renderer<T0,T1>::setup(Map const &m)
|
|||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
premultiply_alpha(*bg_image);
|
||||
premultiply_alpha(pixmap_.data());
|
||||
composite(pixmap_.data(),*bg_image, m.background_image_comp_op(), m.background_image_opacity(), x*w, y*h);
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +169,7 @@ void agg_renderer<T0,T1>::start_map_processing(Map const& map)
|
|||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::end_map_processing(Map const& )
|
||||
{
|
||||
|
||||
agg::rendering_buffer buf(pixmap_.raw_data(),common_.width_,common_.height_, common_.width_ * 4);
|
||||
agg::pixfmt_rgba32_pre pixf(buf);
|
||||
pixf.demultiply();
|
||||
mapnik::demultiply_alpha(pixmap_.data());
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End map processing";
|
||||
}
|
||||
|
||||
|
@ -280,6 +279,8 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
|
|||
util::apply_visitor(visitor, filter_tag);
|
||||
}
|
||||
}
|
||||
mapnik::premultiply_alpha(pixmap_.data());
|
||||
mapnik::premultiply_alpha(current_buffer_->data());
|
||||
if (st.comp_op())
|
||||
{
|
||||
composite(pixmap_.data(), current_buffer_->data(),
|
||||
|
@ -373,6 +374,8 @@ void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
|||
{
|
||||
double cx = 0.5 * width;
|
||||
double cy = 0.5 * height;
|
||||
mapnik::premultiply_alpha(current_buffer_->data());
|
||||
mapnik::premultiply_alpha(**marker.get_bitmap_data());
|
||||
composite(current_buffer_->data(), **marker.get_bitmap_data(),
|
||||
comp_op, opacity,
|
||||
std::floor(pos.x - cx + .5),
|
||||
|
|
|
@ -54,6 +54,8 @@ void agg_renderer<T0,T1>::process(raster_symbolizer const& sym,
|
|||
sym, feature, prj_trans, common_,
|
||||
[&](image_data_rgba8 & target, composite_mode_e comp_op, double opacity,
|
||||
int start_x, int start_y) {
|
||||
premultiply_alpha(target);
|
||||
premultiply_alpha(current_buffer_->data());
|
||||
composite(current_buffer_->data(), target,
|
||||
comp_op, opacity, start_x, start_y);
|
||||
}
|
||||
|
|
|
@ -49,8 +49,7 @@ image_32::image_32(image_32 const& rhs)
|
|||
|
||||
image_32::image_32(image_data_rgba8 && data)
|
||||
: data_(std::move(data)),
|
||||
painted_(false),
|
||||
premultiplied_(false) {}
|
||||
painted_(false) {}
|
||||
|
||||
image_32::~image_32() {}
|
||||
|
||||
|
|
|
@ -166,7 +166,15 @@ MAPNIK_DECL void composite(image_data_rgba8 & dst, image_data_rgba8 const& src,
|
|||
pixfmt_type pixf(dst_buffer);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(mode));
|
||||
agg::pixfmt_alpha_blend_rgba<agg::blender_rgba32, const_rendering_buffer, agg::pixel32_type> pixf_mask(src_buffer);
|
||||
if (!src.get_premultiplied()) pixf_mask.premultiply();
|
||||
// DEBUGGING ONLY REMOVE
|
||||
if (!src.get_premultiplied())
|
||||
{
|
||||
throw std::runtime_error("SOURCE MUST BE PREMULTIPLIED FOR COMPOSITING!");
|
||||
}
|
||||
if (!dst.get_premultiplied())
|
||||
{
|
||||
throw std::runtime_error("DESTINATION MUST BE PREMULTIPLIED FOR COMPOSITING!");
|
||||
}
|
||||
renderer_type ren(pixf);
|
||||
ren.blend_from(pixf_mask,0,dx,dy,unsigned(255*opacity));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue