webp_reader : implement reading from file
This commit is contained in:
parent
b8637a900e
commit
1b90879d12
1 changed files with 104 additions and 15 deletions
|
@ -34,14 +34,63 @@ extern "C"
|
||||||
#include <boost/iostreams/device/file.hpp>
|
#include <boost/iostreams/device/file.hpp>
|
||||||
#include <boost/iostreams/device/array.hpp>
|
#include <boost/iostreams/device/array.hpp>
|
||||||
#include <boost/iostreams/stream.hpp>
|
#include <boost/iostreams/stream.hpp>
|
||||||
|
// stl
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct external_buffer_policy
|
||||||
|
{
|
||||||
|
external_buffer_policy( uint8_t const* data, std::size_t size)
|
||||||
|
: data_(data),
|
||||||
|
size_(size) {}
|
||||||
|
|
||||||
|
uint8_t const* data() const
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t const* data_;
|
||||||
|
std::size_t size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct internal_buffer_policy
|
||||||
|
{
|
||||||
|
internal_buffer_policy(std::size_t size)
|
||||||
|
: data_((size!=0) ? static_cast<uint8_t*>(::operator new(sizeof(uint8_t) * size)) : 0),
|
||||||
|
size_(size)
|
||||||
|
{}
|
||||||
|
|
||||||
|
uint8_t * data() const
|
||||||
|
{
|
||||||
|
return data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t size() const
|
||||||
|
{
|
||||||
|
return size_;
|
||||||
|
}
|
||||||
|
|
||||||
|
~internal_buffer_policy()
|
||||||
|
{
|
||||||
|
::operator delete(data_), data_=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t * data_;
|
||||||
|
std::size_t size_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
class webp_reader : public image_reader
|
class webp_reader : public image_reader
|
||||||
{
|
{
|
||||||
|
typedef T buffer_policy_type;
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct config_guard
|
struct config_guard
|
||||||
{
|
{
|
||||||
config_guard(WebPDecoderConfig & config)
|
config_guard(WebPDecoderConfig & config)
|
||||||
|
@ -53,13 +102,13 @@ private:
|
||||||
}
|
}
|
||||||
WebPDecoderConfig & config_;
|
WebPDecoderConfig & config_;
|
||||||
};
|
};
|
||||||
|
std::unique_ptr<buffer_policy_type> buffer_;
|
||||||
uint8_t const* data_;
|
|
||||||
size_t size_;
|
size_t size_;
|
||||||
unsigned width_;
|
unsigned width_;
|
||||||
unsigned height_;
|
unsigned height_;
|
||||||
public:
|
public:
|
||||||
explicit webp_reader(char const* data, std::size_t size);
|
explicit webp_reader(char const* data, std::size_t size);
|
||||||
|
explicit webp_reader(std::string const& filename);
|
||||||
~webp_reader();
|
~webp_reader();
|
||||||
unsigned width() const;
|
unsigned width() const;
|
||||||
unsigned height() const;
|
unsigned height() const;
|
||||||
|
@ -73,33 +122,70 @@ namespace
|
||||||
{
|
{
|
||||||
image_reader* create_webp_reader(char const * data, std::size_t size)
|
image_reader* create_webp_reader(char const * data, std::size_t size)
|
||||||
{
|
{
|
||||||
return new webp_reader(data, size);
|
return new webp_reader<external_buffer_policy>(data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
image_reader* create_webp_reader2(std::string const& filename)
|
||||||
|
{
|
||||||
|
return new webp_reader<internal_buffer_policy>(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool registered = register_image_reader("webp", create_webp_reader);
|
const bool registered = register_image_reader("webp", create_webp_reader);
|
||||||
|
const bool registered2 = register_image_reader("webp", create_webp_reader2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ctor
|
// ctor
|
||||||
webp_reader::webp_reader(char const* data, std::size_t size)
|
template <typename T>
|
||||||
: data_(reinterpret_cast<uint8_t const*>(data)),
|
webp_reader<T>::webp_reader(char const* data, std::size_t size)
|
||||||
size_(size),
|
: buffer_(new buffer_policy_type(reinterpret_cast<uint8_t const*>(data), size)),
|
||||||
width_(0),
|
width_(0),
|
||||||
height_(0)
|
height_(0)
|
||||||
{
|
{
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
webp_reader<T>::webp_reader(std::string const& filename)
|
||||||
|
: buffer_(0),
|
||||||
|
size_(0),
|
||||||
|
width_(0),
|
||||||
|
height_(0)
|
||||||
|
{
|
||||||
|
std::ifstream file(filename.c_str(), std::ios::binary);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
throw image_reader_exception("WEBP: Can't read file:" + filename);
|
||||||
|
}
|
||||||
|
std::streampos beg = file.tellg();
|
||||||
|
file.seekg (0, std::ios::end);
|
||||||
|
std::streampos end = file.tellg();
|
||||||
|
std::size_t file_size = end - beg;
|
||||||
|
file.seekg (0, std::ios::beg);
|
||||||
|
std::unique_ptr<buffer_policy_type> buffer(new buffer_policy_type(file_size));
|
||||||
|
file.read(reinterpret_cast<char*>(buffer->data()), buffer->size());
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
throw image_reader_exception("WEBP: Failed to read:" + filename);
|
||||||
|
}
|
||||||
|
buffer_ = std::move(buffer);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// dtor
|
// dtor
|
||||||
webp_reader::~webp_reader()
|
template <typename T>
|
||||||
|
webp_reader<T>::~webp_reader()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
|
||||||
void webp_reader::init()
|
template <typename T>
|
||||||
|
void webp_reader<T>::init()
|
||||||
{
|
{
|
||||||
int width, height;
|
int width, height;
|
||||||
if (!WebPGetInfo(data_, size_, &width, &height))
|
if (!WebPGetInfo(buffer_->data(), buffer_->size(), &width, &height))
|
||||||
{
|
{
|
||||||
throw image_reader_exception("WEBP reader: WebPGetInfo failed");
|
throw image_reader_exception("WEBP reader: WebPGetInfo failed");
|
||||||
}
|
}
|
||||||
|
@ -107,17 +193,20 @@ void webp_reader::init()
|
||||||
height_ = height;
|
height_ = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned webp_reader::width() const
|
template <typename T>
|
||||||
|
unsigned webp_reader<T>::width() const
|
||||||
{
|
{
|
||||||
return width_;
|
return width_;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned webp_reader::height() const
|
template <typename T>
|
||||||
|
unsigned webp_reader<T>::height() const
|
||||||
{
|
{
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void webp_reader::read(unsigned x0, unsigned y0,image_data_32& image)
|
template <typename T>
|
||||||
|
void webp_reader<T>::read(unsigned x0, unsigned y0,image_data_32& image)
|
||||||
{
|
{
|
||||||
WebPDecoderConfig config;
|
WebPDecoderConfig config;
|
||||||
config_guard guard(config);
|
config_guard guard(config);
|
||||||
|
@ -132,7 +221,7 @@ void webp_reader::read(unsigned x0, unsigned y0,image_data_32& image)
|
||||||
config.options.crop_width = std::min(width_ - x0, image.width());
|
config.options.crop_width = std::min(width_ - x0, image.width());
|
||||||
config.options.crop_height = std::min(height_ - y0, image.height());
|
config.options.crop_height = std::min(height_ - y0, image.height());
|
||||||
|
|
||||||
if (WebPGetFeatures(data_, size_, &config.input) != VP8_STATUS_OK)
|
if (WebPGetFeatures(buffer_->data(), buffer_->size(), &config.input) != VP8_STATUS_OK)
|
||||||
{
|
{
|
||||||
throw image_reader_exception("WEBP reader: WebPGetFeatures failed");
|
throw image_reader_exception("WEBP reader: WebPGetFeatures failed");
|
||||||
}
|
}
|
||||||
|
@ -142,7 +231,7 @@ void webp_reader::read(unsigned x0, unsigned y0,image_data_32& image)
|
||||||
config.output.u.RGBA.stride = 4 * image.width();
|
config.output.u.RGBA.stride = 4 * image.width();
|
||||||
config.output.u.RGBA.size = image.width() * image.height() * 4;
|
config.output.u.RGBA.size = image.width() * image.height() * 4;
|
||||||
config.output.is_external_memory = 1;
|
config.output.is_external_memory = 1;
|
||||||
if (WebPDecode(data_, size_, &config) != VP8_STATUS_OK)
|
if (WebPDecode(buffer_->data(), buffer_->size(), &config) != VP8_STATUS_OK)
|
||||||
{
|
{
|
||||||
throw image_reader_exception("WEBP reader: WebPDecode failed");
|
throw image_reader_exception("WEBP reader: WebPDecode failed");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue