Implemented a new get_pixel method to go along with the set_pixel method in image_util. Ref #2633

This commit is contained in:
Blake Thompson 2015-01-16 22:15:33 -06:00
parent a002139e18
commit aa03cf4f7c
4 changed files with 111 additions and 4 deletions

View file

@ -130,12 +130,11 @@ void background(mapnik::image_32 & im, mapnik::color const& c)
mapnik::fill(im.data(), c);
}
unsigned get_pixel(mapnik::image_32 const& im, int x, int y)
uint32_t get_pixel(mapnik::image_32 const& im, int x, int y)
{
if (x < static_cast<int>(im.width()) && y < static_cast<int>(im.height()))
{
mapnik::image_data_rgba8 const & data = im.data();
return data(x,y);
return mapnik::get_pixel<mapnik::image_data_rgba8, uint32_t>(im.data(), x, y);
}
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
boost::python::throw_error_already_set();

View file

@ -38,7 +38,14 @@ 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"); }
pixel_type& operator() (std::size_t, std::size_t)
{
throw std::runtime_error("Can not set or get values for null image_data");
}
pixel_type const& operator() (std::size_t, std::size_t) const
{
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

@ -150,6 +150,9 @@ MAPNIK_DECL void composite_pixel(T & data, unsigned op, int x, int y, unsigned c
template <typename T1, typename T2>
MAPNIK_DECL void set_pixel(T1 & data, std::size_t x, std::size_t y, T2 const& val);
template <typename T1, typename T2>
MAPNIK_DECL T2 get_pixel(T1 const& data, std::size_t x, std::size_t y);
inline bool is_png(std::string const& filename)
{
return boost::algorithm::iends_with(filename,std::string(".png"));

View file

@ -1106,4 +1106,102 @@ MAPNIK_DECL void set_pixel<image_data_rgba8, int32_t> (image_data_rgba8 & data,
visitor(data);
}
namespace detail {
template <typename T1>
struct visitor_get_pixel
{
visitor_get_pixel(std::size_t x, std::size_t y)
: x_(x), y_(y) {}
template <typename T2>
T1 operator() (T2 const& data)
{
if (check_bounds(data, x_, y_))
{
return static_cast<T1>(data(x_, y_));
}
else
{
throw std::runtime_error("Out of range for dataset with get pixel");
}
}
private:
std::size_t x_;
std::size_t y_;
};
template<>
struct visitor_get_pixel<color>
{
visitor_get_pixel(std::size_t x, std::size_t y)
: x_(x), y_(y) {}
template <typename T2>
color operator() (T2 const& data)
{
if (check_bounds(data, x_, y_))
{
uint32_t val = static_cast<uint32_t>(data(x_, y_));
return color(static_cast<uint8_t>(val),
static_cast<uint8_t>((val >>= 8)),
static_cast<uint8_t>((val >>= 8)),
static_cast<uint8_t>((val >>= 8)));
}
else
{
throw std::runtime_error("Out of range for dataset with get pixel");
}
}
private:
std::size_t x_;
std::size_t y_;
};
} // end detail ns
// For all the generic data types.
template <typename T1, typename T2>
MAPNIK_DECL T2 get_pixel (T1 const& data, std::size_t x, std::size_t y)
{
return util::apply_visitor(detail::visitor_get_pixel<T2>(x, y), data);
}
template color get_pixel(image_data_any const&, std::size_t, std::size_t);
template uint32_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template int32_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template uint16_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template int16_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template uint8_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template int8_t get_pixel(image_data_any const&, std::size_t, std::size_t);
template float get_pixel(image_data_any const&, std::size_t, std::size_t);
template double get_pixel(image_data_any const&, std::size_t, std::size_t);
// Temporary remove these later!
template <>
MAPNIK_DECL color get_pixel<image_data_rgba8, color> (image_data_rgba8 const& data, std::size_t x, std::size_t y)
{
detail::visitor_get_pixel<color> visitor(x, y);
return visitor(data);
}
// Temporary remove these later!
template <>
MAPNIK_DECL uint32_t get_pixel<image_data_rgba8, uint32_t> (image_data_rgba8 const& data, std::size_t x, std::size_t y)
{
detail::visitor_get_pixel<uint32_t> visitor(x, y);
return visitor(data);
}
// Temporary remove these later!
template <>
MAPNIK_DECL int32_t get_pixel<image_data_rgba8, int32_t> (image_data_rgba8 const& data, std::size_t x, std::size_t y)
{
detail::visitor_get_pixel<int32_t> visitor(x, y);
return visitor(data);
}
} // end ns