diff --git a/src/tiff_reader.cpp b/src/tiff_reader.cpp index ec9d3ca9b..b07004865 100644 --- a/src/tiff_reader.cpp +++ b/src/tiff_reader.cpp @@ -29,6 +29,15 @@ extern "C" #include } +#if defined(MAPNIK_MEMORY_MAPPED_FILE) +#pragma GCC diagnostic push +#include +#include +#include +#pragma GCC diagnostic pop +#include +#endif + // stl #include #include @@ -95,21 +104,37 @@ static int tiff_map_proc(thandle_t, tdata_t* , toff_t*) } +namespace detail { + + +template +struct tiff_io_traits +{ + using input_stream_type = std::istream; +}; + +template <> +struct tiff_io_traits +{ + using input_stream_type = boost::interprocess::ibufferstream; +}; +} + template class tiff_reader : public image_reader { using tiff_ptr = std::shared_ptr; using source_type = T; - using input_stream = std::istream; + using input_stream = typename detail::tiff_io_traits::input_stream_type; +#if defined(MAPNIK_MEMORY_MAPPED_FILE) + mapnik::mapped_region_ptr mapped_region_; +#endif struct tiff_closer { void operator() (TIFF * tif) { - if (tif != 0) - { - TIFFClose(tif); - } + if (tif != 0) TIFFClose(tif); } }; @@ -183,7 +208,8 @@ namespace image_reader* create_tiff_reader(std::string const& filename) { - return new tiff_reader(filename); + //return new tiff_reader(filename); + return new tiff_reader(filename); } image_reader* create_tiff_reader2(char const * data, std::size_t size) @@ -199,7 +225,7 @@ const bool registered2 = register_image_reader("tiff", create_tiff_reader2); template tiff_reader::tiff_reader(std::string const& filename) : source_(), - stream_(&source_), + stream_(),//&source_), tif_(nullptr), read_method_(generic), rows_per_strip_(0), @@ -216,9 +242,25 @@ tiff_reader::tiff_reader(std::string const& filename) has_alpha_(false), is_tiled_(false) { - source_.open(filename, std::ios_base::in | std::ios_base::binary); - if (!stream_) throw image_reader_exception("TIFF reader: cannot open file "+ filename); - init(); + +#if defined(MAPNIK_MEMORY_MAPPED_FILE) + boost::optional memory = + mapnik::mapped_memory_cache::instance().find(filename,true); + + if (memory) + { + mapped_region_ = *memory; + stream_.buffer(static_cast(mapped_region_->get_address()),mapped_region_->get_size()); + } + else + { + throw image_reader_exception("could not create file mapping for " + filename); + } +#else + source_.open(filename, std::ios_base::in | std::ios_base::binary); +#endif + if (!stream_) throw image_reader_exception("TIFF reader: cannot open file " + filename); + init(); } template diff --git a/test/unit/imaging/tiff_io.cpp b/test/unit/imaging/tiff_io.cpp index 2c5380092..a92b0e322 100644 --- a/test/unit/imaging/tiff_io.cpp +++ b/test/unit/imaging/tiff_io.cpp @@ -11,11 +11,11 @@ #include #include #include - +#include #include "../../../src/tiff_reader.cpp" #define TIFF_ASSERT(filename) \ - mapnik::tiff_reader tiff_reader(filename); \ + mapnik::tiff_reader tiff_reader(filename); \ REQUIRE( tiff_reader.width() == 256 ); \ REQUIRE( tiff_reader.height() == 256 ); \ REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); \ @@ -141,7 +141,7 @@ void test_tiff_reader(std::string const& pattern) if (boost::iends_with(path,".tif") && boost::istarts_with(mapnik::util::basename(path), pattern)) { - mapnik::tiff_reader tiff_reader(path); + mapnik::tiff_reader< boost::interprocess::ibufferstream> tiff_reader(path); auto width = tiff_reader.width(); auto height = tiff_reader.height(); { @@ -180,7 +180,7 @@ TEST_CASE("tiff io") SECTION("scan rgb8 striped") { std::string filename("./test/data/tiff/scan_512x512_rgb8_striped.tif"); - mapnik::tiff_reader tiff_reader(filename); + mapnik::tiff_reader< boost::interprocess::ibufferstream> tiff_reader(filename); REQUIRE( tiff_reader.width() == 512 ); REQUIRE( tiff_reader.height() == 512 ); REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG ); @@ -210,7 +210,7 @@ TEST_CASE("tiff io") SECTION("scan rgb8 tiled") { std::string filename("./test/data/tiff/scan_512x512_rgb8_tiled.tif"); - mapnik::tiff_reader tiff_reader(filename); + mapnik::tiff_reader< boost::interprocess::ibufferstream> tiff_reader(filename); REQUIRE( tiff_reader.width() == 512 ); REQUIRE( tiff_reader.height() == 512 ); REQUIRE( tiff_reader.planar_config() == PLANARCONFIG_CONTIG );