Merge remote-tracking branch 'origin/master' into geometry-refactor

This commit is contained in:
artemp 2016-06-27 08:51:55 +01:00
commit 9dd00b28dc
7 changed files with 137 additions and 69 deletions

View file

@ -0,0 +1,87 @@
/*****************************************************************************
*
* 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>
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)
{
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

View file

@ -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)
{

View file

@ -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();
}

View file

@ -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,15 @@ 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 (!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 +238,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();
}

View file

@ -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

View file

@ -42,7 +42,7 @@ if [ -d "test/data" ]; then
if [ -d "test/data-visual/styles" ]; then
run_substep "Running visual tests..."
if [ -z "$JOBS" ]; then
if [ -z "${JOBS:-}" ]; then
JOBS=1
fi
if [[ -f ./test/visual/run ]]; then

View file

@ -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()));