implement custom char_array_bufrer
and remove boost::iostreams dependency
This commit is contained in:
parent
b17dae8381
commit
2e8c0d36c2
6 changed files with 139 additions and 68 deletions
89
include/mapnik/util/char_array_buffer.hpp
Normal file
89
include/mapnik/util/char_array_buffer.hpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2016 Artem Pavlenko
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
|
||||
#define MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
|
||||
|
||||
#include <streambuf>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
// ref https://artofcode.wordpress.com/2010/12/12/deriving-from-stdstreambuf/
|
||||
|
||||
class char_array_buffer : public std::streambuf
|
||||
{
|
||||
public:
|
||||
char_array_buffer(char const* data, std::size_t size)
|
||||
: begin_(data), end_(data + size), current_(data) {}
|
||||
|
||||
private:
|
||||
int_type underflow()
|
||||
{
|
||||
if (current_ == end_)
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
return traits_type::to_int_type(*current_);
|
||||
}
|
||||
|
||||
int_type uflow()
|
||||
{
|
||||
if (current_ == end_)
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
return traits_type::to_int_type(*current_++);
|
||||
}
|
||||
|
||||
int_type pbackfail(int_type ch)
|
||||
{
|
||||
std::cerr << "pbackfail" << std::endl;
|
||||
if (current_ == begin_ || (ch != traits_type::eof() && ch != current_[-1]))
|
||||
{
|
||||
return traits_type::eof();
|
||||
}
|
||||
return traits_type::to_int_type(*--current_);
|
||||
}
|
||||
|
||||
std::streamsize showmanyc()
|
||||
{
|
||||
return end_ - current_;
|
||||
}
|
||||
|
||||
pos_type seekoff(off_type off, std::ios_base::seekdir dir,
|
||||
std::ios_base::openmode which = std::ios_base::in | std::ios_base::out )
|
||||
{
|
||||
if (dir == std::ios_base::beg) current_ = std::min(begin_ + off, end_);
|
||||
else if (dir == std::ios_base::cur) current_ = std::min(current_ + off, end_);
|
||||
else current_ = std::max(end_ - off, begin_); // dir == std::ios_base::end
|
||||
return pos_type(off_type(current_ - begin_));
|
||||
}
|
||||
char const * const begin_;
|
||||
char const * const end_;
|
||||
char const * current_;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
|
||||
#endif // MAPNIK_UTIL_CHAR_ARRAY_BUFFER_HPP
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/image_reader.hpp>
|
||||
#include <mapnik/util/char_array_buffer.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
// jpeg
|
||||
|
@ -30,16 +31,10 @@ extern "C"
|
|||
#include <jpeglib.h>
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/iostreams/device/file.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// std
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -49,7 +44,7 @@ class jpeg_reader : public image_reader
|
|||
{
|
||||
public:
|
||||
using source_type = T;
|
||||
using input_stream = boost::iostreams::stream<source_type>;
|
||||
using input_stream = std::iostream;
|
||||
const static unsigned BUF_SIZE = 4096;
|
||||
private:
|
||||
struct jpeg_stream_wrapper
|
||||
|
@ -77,7 +72,7 @@ private:
|
|||
unsigned width_;
|
||||
unsigned height_;
|
||||
public:
|
||||
explicit jpeg_reader(std::string const& file_name);
|
||||
explicit jpeg_reader(std::string const& filename);
|
||||
explicit jpeg_reader(char const* data, size_t size);
|
||||
~jpeg_reader();
|
||||
unsigned width() const final;
|
||||
|
@ -99,14 +94,14 @@ private:
|
|||
|
||||
namespace
|
||||
{
|
||||
image_reader* create_jpeg_reader(std::string const& file)
|
||||
image_reader* create_jpeg_reader(std::string const& filename)
|
||||
{
|
||||
return new jpeg_reader<boost::iostreams::file_source>(file);
|
||||
return new jpeg_reader<std::filebuf>(filename);
|
||||
}
|
||||
|
||||
image_reader* create_jpeg_reader2(char const* data, size_t size)
|
||||
{
|
||||
return new jpeg_reader<boost::iostreams::array_source>(data, size);
|
||||
return new jpeg_reader<mapnik::util::char_array_buffer>(data, size);
|
||||
}
|
||||
|
||||
const bool registered = register_image_reader("jpeg",create_jpeg_reader);
|
||||
|
@ -115,20 +110,21 @@ const bool registered2 = register_image_reader("jpeg",create_jpeg_reader2);
|
|||
|
||||
// ctors
|
||||
template <typename T>
|
||||
jpeg_reader<T>::jpeg_reader(std::string const& file_name)
|
||||
: source_(file_name,std::ios_base::in | std::ios_base::binary),
|
||||
stream_(source_),
|
||||
jpeg_reader<T>::jpeg_reader(std::string const& filename)
|
||||
: source_(),
|
||||
stream_(&source_),
|
||||
width_(0),
|
||||
height_(0)
|
||||
{
|
||||
if (!stream_) throw image_reader_exception("cannot open image file "+ file_name);
|
||||
source_.open(filename, std::ios_base::in | std::ios_base::binary);
|
||||
if (!stream_) throw image_reader_exception("cannot open image file "+ filename);
|
||||
init();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
jpeg_reader<T>::jpeg_reader(char const* data, size_t size)
|
||||
: source_(data, size),
|
||||
stream_(source_),
|
||||
stream_(&source_),
|
||||
width_(0),
|
||||
height_(0)
|
||||
{
|
||||
|
|
|
@ -23,22 +23,17 @@
|
|||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
#include <mapnik/util/char_array_buffer.hpp>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <png.h>
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/iostreams/device/file.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
@ -47,7 +42,7 @@ template <typename T>
|
|||
class png_reader : public image_reader
|
||||
{
|
||||
using source_type = T;
|
||||
using input_stream = boost::iostreams::stream<source_type>;
|
||||
using input_stream = std::istream;
|
||||
|
||||
struct png_struct_guard
|
||||
{
|
||||
|
@ -73,7 +68,7 @@ private:
|
|||
int color_type_;
|
||||
bool has_alpha_;
|
||||
public:
|
||||
explicit png_reader(std::string const& file_name);
|
||||
explicit png_reader(std::string const& filename);
|
||||
png_reader(char const* data, std::size_t size);
|
||||
~png_reader();
|
||||
unsigned width() const final;
|
||||
|
@ -90,14 +85,14 @@ private:
|
|||
namespace
|
||||
{
|
||||
|
||||
image_reader* create_png_reader(std::string const& file)
|
||||
image_reader* create_png_reader(std::string const& filename)
|
||||
{
|
||||
return new png_reader<boost::iostreams::file_source>(file);
|
||||
return new png_reader<std::filebuf>(filename);
|
||||
}
|
||||
|
||||
image_reader* create_png_reader2(char const * data, std::size_t size)
|
||||
{
|
||||
return new png_reader<boost::iostreams::array_source>(data, size);
|
||||
return new png_reader<mapnik::util::char_array_buffer>(data, size);
|
||||
}
|
||||
|
||||
const bool registered = register_image_reader("png",create_png_reader);
|
||||
|
@ -128,31 +123,30 @@ void png_reader<T>::png_read_data(png_structp png_ptr, png_bytep data, png_size_
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
png_reader<T>::png_reader(std::string const& file_name)
|
||||
: source_(file_name,std::ios_base::in | std::ios_base::binary),
|
||||
stream_(source_),
|
||||
png_reader<T>::png_reader(std::string const& filename)
|
||||
: source_(),
|
||||
stream_(&source_),
|
||||
width_(0),
|
||||
height_(0),
|
||||
bit_depth_(0),
|
||||
color_type_(0),
|
||||
has_alpha_(false)
|
||||
{
|
||||
if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'");
|
||||
if (!stream_) throw image_reader_exception("PNG reader: cannot open file '"+ file_name + "'");
|
||||
source_.open(filename, std::ios_base::in | std::ios_base::binary);
|
||||
if (!source_.is_open()) throw image_reader_exception("PNG reader: cannot open file '"+ filename + "'");
|
||||
init();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
png_reader<T>::png_reader(char const* data, std::size_t size)
|
||||
: source_(data,size),
|
||||
stream_(source_),
|
||||
stream_(&source_),
|
||||
width_(0),
|
||||
height_(0),
|
||||
bit_depth_(0),
|
||||
color_type_(0),
|
||||
has_alpha_(false)
|
||||
{
|
||||
|
||||
if (!stream_) throw image_reader_exception("PNG reader: cannot open image stream");
|
||||
init();
|
||||
}
|
||||
|
|
|
@ -23,21 +23,15 @@
|
|||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
|
||||
#include <mapnik/util/char_array_buffer.hpp>
|
||||
extern "C"
|
||||
{
|
||||
#include <tiffio.h>
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/iostreams/device/file.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <memory>
|
||||
#include <fstream>
|
||||
|
||||
namespace mapnik { namespace impl {
|
||||
|
||||
|
@ -106,7 +100,7 @@ class tiff_reader : public image_reader
|
|||
{
|
||||
using tiff_ptr = std::shared_ptr<TIFF>;
|
||||
using source_type = T;
|
||||
using input_stream = boost::iostreams::stream<source_type>;
|
||||
using input_stream = std::istream;
|
||||
|
||||
struct tiff_closer
|
||||
{
|
||||
|
@ -145,7 +139,7 @@ public:
|
|||
stripped,
|
||||
tiled
|
||||
};
|
||||
explicit tiff_reader(std::string const& file_name);
|
||||
explicit tiff_reader(std::string const& filename);
|
||||
tiff_reader(char const* data, std::size_t size);
|
||||
virtual ~tiff_reader();
|
||||
unsigned width() const final;
|
||||
|
@ -183,14 +177,14 @@ private:
|
|||
namespace
|
||||
{
|
||||
|
||||
image_reader* create_tiff_reader(std::string const& file)
|
||||
image_reader* create_tiff_reader(std::string const& filename)
|
||||
{
|
||||
return new tiff_reader<boost::iostreams::file_source>(file);
|
||||
return new tiff_reader<std::filebuf>(filename);
|
||||
}
|
||||
|
||||
image_reader* create_tiff_reader2(char const * data, std::size_t size)
|
||||
{
|
||||
return new tiff_reader<boost::iostreams::array_source>(data, size);
|
||||
return new tiff_reader<mapnik::util::char_array_buffer>(data, size);
|
||||
}
|
||||
|
||||
const bool registered = register_image_reader("tiff",create_tiff_reader);
|
||||
|
@ -199,9 +193,9 @@ const bool registered2 = register_image_reader("tiff", create_tiff_reader2);
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
tiff_reader<T>::tiff_reader(std::string const& file_name)
|
||||
: source_(file_name, std::ios_base::in | std::ios_base::binary),
|
||||
stream_(source_),
|
||||
tiff_reader<T>::tiff_reader(std::string const& filename)
|
||||
: source_(),
|
||||
stream_(&source_),
|
||||
tif_(nullptr),
|
||||
read_method_(generic),
|
||||
rows_per_strip_(0),
|
||||
|
@ -218,14 +212,16 @@ tiff_reader<T>::tiff_reader(std::string const& file_name)
|
|||
has_alpha_(false),
|
||||
is_tiled_(false)
|
||||
{
|
||||
if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ file_name);
|
||||
source_.open(filename, std::ios_base::in | std::ios_base::binary);
|
||||
if (!source_.is_open()) throw image_reader_exception("TIFF reader: cannot open file "+ filename);
|
||||
if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ filename);
|
||||
init();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
|
||||
: source_(data, size),
|
||||
stream_(source_),
|
||||
stream_(&source_),
|
||||
tif_(nullptr),
|
||||
read_method_(generic),
|
||||
rows_per_strip_(0),
|
||||
|
@ -243,8 +239,6 @@ tiff_reader<T>::tiff_reader(char const* data, std::size_t size)
|
|||
is_tiled_(false)
|
||||
{
|
||||
if (!stream_) throw image_reader_exception("TIFF reader: cannot open image stream ");
|
||||
stream_.rdbuf()->pubsetbuf(0, 0);
|
||||
stream_.seekg(0, std::ios::beg);
|
||||
init();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,9 +33,6 @@ extern "C"
|
|||
#include <webp/decode.h>
|
||||
}
|
||||
|
||||
#include <boost/iostreams/device/file.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
// disabled on windows due to https://github.com/mapnik/mapnik/issues/2838
|
||||
// TODO - get to the bottom of why including `tiff_reader.cpp` breaks windows
|
||||
// or re-write image_readers to allow `#include tiff_reader.hpp`
|
||||
|
@ -12,7 +11,7 @@
|
|||
#include "../../../src/tiff_reader.cpp"
|
||||
|
||||
#define TIFF_ASSERT(filename) \
|
||||
mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename); \
|
||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename); \
|
||||
REQUIRE( tiff_reader.width() == 256 ); \
|
||||
REQUIRE( tiff_reader.height() == 256 ); \
|
||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); \
|
||||
|
@ -20,7 +19,7 @@
|
|||
REQUIRE( reader->width() == 256 ); \
|
||||
REQUIRE( reader->height() == 256 ); \
|
||||
mapnik::util::file file(filename); \
|
||||
mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size()); \
|
||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size()); \
|
||||
REQUIRE( tiff_reader2.width() == 256 ); \
|
||||
REQUIRE( tiff_reader2.height() == 256 ); \
|
||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size())); \
|
||||
|
@ -57,11 +56,13 @@
|
|||
REQUIRE( subimage.width() == 1 ); \
|
||||
REQUIRE( subimage.height() == 1 ); \
|
||||
|
||||
TEST_CASE("tiff io") {
|
||||
TEST_CASE("tiff io")
|
||||
{
|
||||
|
||||
SECTION("scan rgb8 striped") {
|
||||
SECTION("scan rgb8 striped")
|
||||
{
|
||||
std::string filename("./test/data/tiff/scan_512x512_rgb8_striped.tif");
|
||||
mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename);
|
||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
||||
REQUIRE( tiff_reader.width() == 512 );
|
||||
REQUIRE( tiff_reader.height() == 512 );
|
||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
||||
|
@ -76,7 +77,7 @@ SECTION("scan rgb8 striped") {
|
|||
REQUIRE( reader->width() == 512 );
|
||||
REQUIRE( reader->height() == 512 );
|
||||
mapnik::util::file file(filename);
|
||||
mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size());
|
||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
||||
REQUIRE( tiff_reader2.width() == 512 );
|
||||
REQUIRE( tiff_reader2.height() == 512 );
|
||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
||||
|
@ -91,7 +92,7 @@ SECTION("scan rgb8 striped") {
|
|||
|
||||
SECTION("scan rgb8 tiled") {
|
||||
std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif");
|
||||
mapnik::tiff_reader<boost::iostreams::file_source> tiff_reader(filename);
|
||||
mapnik::tiff_reader<std::filebuf> tiff_reader(filename);
|
||||
REQUIRE( tiff_reader.width() == 512 );
|
||||
REQUIRE( tiff_reader.height() == 512 );
|
||||
REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );
|
||||
|
@ -106,7 +107,7 @@ SECTION("scan rgb8 tiled") {
|
|||
REQUIRE( reader->width() == 512 );
|
||||
REQUIRE( reader->height() == 512 );
|
||||
mapnik::util::file file(filename);
|
||||
mapnik::tiff_reader<boost::iostreams::array_source> tiff_reader2(file.data().get(),file.size());
|
||||
mapnik::tiff_reader<mapnik::util::char_array_buffer> tiff_reader2(file.data().get(),file.size());
|
||||
REQUIRE( tiff_reader2.width() == 512 );
|
||||
REQUIRE( tiff_reader2.height() == 512 );
|
||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(file.data().get(),file.size()));
|
||||
|
|
Loading…
Reference in a new issue