Added set_pixel to visitor pattern and moved it to image_util. Added exception throwing in composite only if debug flags are on.

Ref #2633
This commit is contained in:
Blake Thompson 2015-01-16 18:26:56 -06:00
parent 1470bea9cb
commit a002139e18
8 changed files with 115 additions and 32 deletions

View file

@ -144,7 +144,7 @@ unsigned get_pixel(mapnik::image_32 const& im, int x, int y)
void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c)
{
im.setPixel(x, y, c.rgba());
mapnik::set_pixel(im.data(), x, y, c);
}
std::shared_ptr<image_32> open_from_file(std::string const& filename)

View file

@ -89,22 +89,7 @@ public:
return image_view_rgba8(x,y,w,h,data_);
}
private:
inline bool checkBounds(int x, int y) const
{
return (x >= 0 && x < static_cast<int>(data_.width()) && y >= 0 && y < static_cast<int>(data_.height()));
}
public:
inline void setPixel(int x,int y,unsigned int rgba)
{
if (checkBounds(x,y))
{
data_(x,y)=rgba;
}
}
inline unsigned width() const
{
return data_.width();

View file

@ -38,6 +38,7 @@ struct image_data_null
bool get_premultiplied() const { return false; }
void set_premultiplied(bool) const {}
void set(pixel_type const&) { throw std::runtime_error("Can not set values for null image_data"); }
pixel_type& operator() (std::size_t, std::size_t) { throw std::runtime_error("Can not set or get values for null image_data"); }
};
using image_data_base = util::variant<image_data_null,

View file

@ -139,14 +139,17 @@ template <typename T>
MAPNIK_DECL void set_rectangle (T & dst, T const& src, int x = 0, int y = 0);
template <typename T>
MAPNIK_DECL bool check_bounds (T const& data, int x, int y)
MAPNIK_DECL bool check_bounds (T const& data, std::size_t x, std::size_t y)
{
return (x >= 0 && x < static_cast<int>(data.width()) && y >= 0 && y < static_cast<int>(data.height()));
return (x < static_cast<int>(data.width()) && y < static_cast<int>(data.height()));
}
template <typename T>
MAPNIK_DECL void composite_pixel(T & data, unsigned op, int x, int y, unsigned c, unsigned cover, double opacity );
template <typename T1, typename T2>
MAPNIK_DECL void set_pixel(T1 & data, std::size_t x, std::size_t y, T2 const& val);
inline bool is_png(std::string const& filename)
{
return boost::algorithm::iends_with(filename,std::string(".png"));

View file

@ -507,13 +507,13 @@ void agg_renderer<T0,T1>::draw_geo_extent(box2d<double> const& extent, mapnik::c
unsigned rgba = color.rgba();
for (double x=x0; x<x1; x++)
{
pixmap_.setPixel(x, y0, rgba);
pixmap_.setPixel(x, y1, rgba);
mapnik::set_pixel(pixmap_.data(), x, y0, rgba);
mapnik::set_pixel(pixmap_.data(), x, y1, rgba);
}
for (double y=y0; y<y1; y++)
{
pixmap_.setPixel(x0, y, rgba);
pixmap_.setPixel(x1, y, rgba);
mapnik::set_pixel(pixmap_.data(), x0, y, rgba);
mapnik::set_pixel(pixmap_.data(), x1, y, rgba);
}
}

View file

@ -26,6 +26,7 @@
#include <mapnik/graphics.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/label_collision_detector.hpp>
#include <mapnik/image_util.hpp>
namespace mapnik {
@ -38,13 +39,13 @@ void draw_rect(image_32 &pixmap, box2d<double> const& box)
unsigned color1 = 0xff0000ff;
for (int x=x0; x<x1; x++)
{
pixmap.setPixel(x, y0, color1);
pixmap.setPixel(x, y1, color1);
mapnik::set_pixel(pixmap.data(), x, y0, color1);
mapnik::set_pixel(pixmap.data(), x, y1, color1);
}
for (int y=y0; y<y1; y++)
{
pixmap.setPixel(x0, y, color1);
pixmap.setPixel(x1, y, color1);
mapnik::set_pixel(pixmap.data(), x0, y, color1);
mapnik::set_pixel(pixmap.data(), x1, y, color1);
}
}
@ -79,11 +80,11 @@ void agg_renderer<T0,T1>::process(debug_symbolizer const& sym,
if (cmd == SEG_CLOSE) continue;
prj_trans.backward(x,y,z);
common_.t_.forward(&x,&y);
pixmap_.setPixel(x,y,0xff0000ff);
pixmap_.setPixel(x-1,y-1,0xff0000ff);
pixmap_.setPixel(x+1,y+1,0xff0000ff);
pixmap_.setPixel(x-1,y+1,0xff0000ff);
pixmap_.setPixel(x+1,y-1,0xff0000ff);
mapnik::set_pixel(pixmap_.data(),x,y,0xff0000ff);
mapnik::set_pixel(pixmap_.data(),x-1,y-1,0xff0000ff);
mapnik::set_pixel(pixmap_.data(),x+1,y+1,0xff0000ff);
mapnik::set_pixel(pixmap_.data(),x-1,y+1,0xff0000ff);
mapnik::set_pixel(pixmap_.data(),x+1,y-1,0xff0000ff);
}
}
}

View file

@ -166,7 +166,7 @@ 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);
// DEBUGGING ONLY REMOVE
#ifdef MAPNIK_DEBUG
if (!src.get_premultiplied())
{
throw std::runtime_error("SOURCE MUST BE PREMULTIPLIED FOR COMPOSITING!");
@ -175,6 +175,7 @@ MAPNIK_DECL void composite(image_data_rgba8 & dst, image_data_rgba8 const& src,
{
throw std::runtime_error("DESTINATION MUST BE PREMULTIPLIED FOR COMPOSITING!");
}
#endif
renderer_type ren(pixf);
ren.blend_from(pixf_mask,0,dx,dy,unsigned(255*opacity));
}

View file

@ -1014,4 +1014,96 @@ MAPNIK_DECL void composite_pixel<image_data_rgba8>(image_data_rgba8 & data, unsi
visitor(data);
}
namespace detail {
template <typename T1>
struct visitor_set_pixel
{
visitor_set_pixel(std::size_t x, std::size_t y, T1 const& val)
: val_(val), x_(x), y_(y) {}
template <typename T2>
void operator() (T2 & data)
{
using pixel_type = typename T2::pixel_type;
pixel_type val = static_cast<pixel_type>(val_);
if (check_bounds(data, x_, y_))
{
data(x_, y_) = val;
}
}
private:
T1 const& val_;
std::size_t x_;
std::size_t y_;
};
template<>
struct visitor_set_pixel<color>
{
visitor_set_pixel(std::size_t x, std::size_t y, color const& val)
: val_(val), x_(x), y_(y) {}
template <typename T2>
void operator() (T2 & data)
{
using pixel_type = typename T2::pixel_type;
pixel_type val = static_cast<pixel_type>(val_.rgba());
if (check_bounds(data, x_, y_))
{
data(x_, y_) = val;
}
}
private:
color const& val_;
std::size_t x_;
std::size_t y_;
};
} // end detail ns
// For all the generic data types.
template <typename T1, typename T2>
MAPNIK_DECL void set_pixel (T1 & data, std::size_t x, std::size_t y, T2 const& val)
{
util::apply_visitor(detail::visitor_set_pixel<T2>(x, y, val), data);
}
template void set_pixel(image_data_any &, std::size_t, std::size_t, color const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, uint32_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, int32_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, uint16_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, int16_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, uint8_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, int8_t const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, float const&);
template void set_pixel(image_data_any &, std::size_t, std::size_t, double const&);
// Temporary remove these later!
template <>
MAPNIK_DECL void set_pixel<image_data_rgba8, color> (image_data_rgba8 & data, std::size_t x, std::size_t y, color const& val)
{
detail::visitor_set_pixel<color> visitor(x, y, val);
visitor(data);
}
// Temporary remove these later!
template <>
MAPNIK_DECL void set_pixel<image_data_rgba8, uint32_t> (image_data_rgba8 & data, std::size_t x, std::size_t y, uint32_t const& val)
{
detail::visitor_set_pixel<uint32_t> visitor(x, y, val);
visitor(data);
}
// Temporary remove these later!
template <>
MAPNIK_DECL void set_pixel<image_data_rgba8, int32_t> (image_data_rgba8 & data, std::size_t x, std::size_t y, int32_t const& val)
{
detail::visitor_set_pixel<int32_t> visitor(x, y, val);
visitor(data);
}
} // end ns