initial image_data_any implentation (work-in-progress)

This commit is contained in:
artemp 2014-11-26 12:22:36 +01:00
parent 33c1d21b7f
commit bf9c99e3d3
7 changed files with 122 additions and 28 deletions

View File

@ -41,7 +41,14 @@ struct buffer
data_(static_cast<unsigned char*>(size_ != 0 ? ::operator new(size_) : nullptr))
{}
buffer(buffer && rhs) noexcept = default;
buffer(buffer && rhs) noexcept
: size_(std::move(rhs.size_)),
data_(std::move(rhs.data_))
{
rhs.size_ = 0;
rhs.data_ = nullptr;
}
buffer(buffer const& rhs)
: size_(rhs.size_),
data_(rhs.data_)
@ -184,6 +191,7 @@ private:
using image_data_32 = image_data<std::uint32_t>;
using image_data_8 = image_data<byte> ;
using image_data_float32 = image_data<float>;
}
#endif // MAPNIK_IMAGE_DATA_HPP

View File

@ -27,26 +27,99 @@
#include <mapnik/box2d.hpp>
#include <mapnik/image_data.hpp>
#include <mapnik/noncopyable.hpp>
#include <mapnik/util/variant.hpp>
// boost
#include <boost/optional.hpp>
namespace mapnik {
using image_data_base = util::variant<image_data_32, image_data_8, image_data_float32>;
namespace detail {
struct get_bytes_visitor : util::static_visitor<unsigned char*>
{
template <typename T>
unsigned char* operator()(T & data)
{
return data.getBytes();
}
};
struct get_bytes_visitor_const : util::static_visitor<unsigned char const*>
{
template <typename T>
unsigned char const* operator()(T const& data) const
{
return data.getBytes();
}
};
struct get_width_visitor : util::static_visitor<std::size_t>
{
template <typename T>
std::size_t operator()(T const& data) const
{
return data.width();
}
};
struct get_height_visitor : util::static_visitor<std::size_t>
{
template <typename T>
std::size_t operator()(T const& data) const
{
return data.height();
}
};
} // namespace detail
struct image_data_any : image_data_base
{
template <typename T>
image_data_any(T && data) noexcept
: image_data_base(std::move(data)) {}
unsigned char const* getBytes() const
{
return util::apply_visitor(detail::get_bytes_visitor_const(),*this);
}
unsigned char* getBytes()
{
return util::apply_visitor(detail::get_bytes_visitor(),*this);
}
std::size_t width() const
{
return util::apply_visitor(detail::get_width_visitor(),*this);
}
std::size_t height() const
{
return util::apply_visitor(detail::get_height_visitor(),*this);
}
};
class raster : private mapnik::noncopyable
{
public:
box2d<double> ext_;
image_data_32 data_;
image_data_any data_;
double filter_factor_;
bool premultiplied_alpha_;
boost::optional<double> nodata_;
template <typename ImageData>
raster(box2d<double> const& ext,
unsigned width,
unsigned height,
ImageData && data,
double filter_factor,
bool premultiplied_alpha = false)
: ext_(ext),
data_(width,height),
data_(std::move(data)),
filter_factor_(filter_factor),
premultiplied_alpha_(premultiplied_alpha) {}

View File

@ -86,7 +86,8 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
{
double offset_x = ext.minx() - start_x;
double offset_y = ext.miny() - start_y;
raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
image_data_32 data(raster_width, raster_height);
raster target(target_ext, data, source->get_filter_factor());
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
reproject_and_scale_raster(target,
*source,
@ -95,7 +96,10 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
offset_y,
mesh_size,
scaling_method);
composite(target.data_, comp_op, opacity, start_x, start_y);
if (target.data_.is<image_data_32>())
{
composite(util::get<image_data_32>(target.data_), comp_op, opacity, start_x, start_y);
}
}
else
{
@ -107,20 +111,27 @@ void render_raster_symbolizer(raster_symbolizer const &sym,
(std::abs(start_x) <= eps) &&
(std::abs(start_y) <= eps) )
{
composite(source->data_, comp_op, opacity, start_x, start_y);
if (source->data_.is<image_data_32>())
{
composite(util::get<image_data_32>(source->data_), comp_op, opacity, start_x, start_y);
}
}
else
{
raster target(target_ext, raster_width, raster_height, source->get_filter_factor());
scale_image_agg<image_data_32>(target.data_,
source->data_,
scaling_method,
image_ratio_x,
image_ratio_y,
0.0,
0.0,
source->get_filter_factor());
composite(target.data_, comp_op, opacity, start_x, start_y);
if (source->data_.is<image_data_32>())
{
image_data_32 data(raster_width, raster_height);
raster target(target_ext, data, source->get_filter_factor());
scale_image_agg<image_data_32>(util::get<image_data_32>(target.data_),
util::get<image_data_32>(source->data_),
scaling_method,
image_ratio_x,
image_ratio_y,
0.0,
0.0,
source->get_filter_factor());
composite(util::get<image_data_32>(target.data_), comp_op, opacity, start_x, start_y);
}
}
}
}

View File

@ -199,9 +199,10 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
if (im_width > 0 && im_height > 0)
{
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, im_width, im_height, filter_factor);
mapnik::image_data_32 data(im_width, im_height);
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, data, filter_factor);
feature->set_raster(raster);
mapnik::image_data_32 & image = raster->data_;
mapnik::image_data_32 & image = mapnik::util::get<mapnik::image_data_32>(raster->data_);
image.set(0xffffffff);
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Image Size=(" << im_width << "," << im_height << ")";

View File

@ -28,6 +28,7 @@
#include <mapnik/image_reader.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/feature_factory.hpp>
#include <mapnik/util/variant.hpp>
// boost
#pragma GCC diagnostic push
@ -113,9 +114,9 @@ feature_ptr raster_featureset<LookupPolicy>::next()
rem.maxx() + x_off + width,
rem.maxy() + y_off + height);
intersect = t.backward(feature_raster_extent);
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, width, height, 1.0);
reader->read(x_off, y_off, raster->data_);
image_data_32 data(width,height);
reader->read(x_off, y_off, data);
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, data, 1.0);
raster->premultiplied_alpha_ = reader->premultiplied_alpha();
feature->set_raster(raster);
}

View File

@ -124,14 +124,14 @@ bool raster_colorizer::add_stop(colorizer_stop const& stop)
void raster_colorizer::colorize(raster_ptr const& raster, feature_impl const& f) const
{
unsigned *imageData = raster->data_.getData();
unsigned* imageData = reinterpret_cast<unsigned*>(raster->data_.getBytes());
int len = raster->data_.width() * raster->data_.height();
boost::optional<double> const& nodata = raster->nodata();
for (int i=0; i<len; ++i)
{
// the GDAL plugin reads single bands as floats
float value = *reinterpret_cast<float *> (&imageData[i]);
float value = *reinterpret_cast<float*> (&imageData[i]);
if (nodata && (std::fabs(value - *nodata) < epsilon_))
{
imageData[i] = 0;

View File

@ -83,7 +83,7 @@ void reproject_and_scale_raster(raster & target, raster const& source,
agg::rasterizer_scanline_aa<> rasterizer;
agg::scanline_bin scanline;
agg::rendering_buffer buf((unsigned char*)target.data_.getData(),
agg::rendering_buffer buf(target.data_.getBytes(),
target.data_.width(),
target.data_.height(),
target.data_.width()*4);
@ -91,7 +91,7 @@ void reproject_and_scale_raster(raster & target, raster const& source,
renderer_base rb(pixf);
rasterizer.clip_box(0, 0, target.data_.width(), target.data_.height());
agg::rendering_buffer buf_tile(
(unsigned char*)source.data_.getData(),
const_cast<unsigned char*>(source.data_.getBytes()),
source.data_.width(),
source.data_.height(),
source.data_.width() * 4);