diff --git a/.gitignore b/.gitignore index bbf225e80..a7653de61 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ *.os *.so *.a +*.swp *.dylib plugins/input/*.input plugins/input/templates/*.input diff --git a/bindings/python/mapnik_image.cpp b/bindings/python/mapnik_image.cpp index 5d674be72..92e023970 100644 --- a/bindings/python/mapnik_image.cpp +++ b/bindings/python/mapnik_image.cpp @@ -83,7 +83,7 @@ PyObject* tostring2(image_32 const & im, std::string const& format) (s.data(),s.size()); } -PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba_palette const& pal) +PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba_palette_ptr const& pal) { std::string s = save_to_string(im, format, pal); return @@ -106,7 +106,7 @@ void save_to_file2(mapnik::image_32 const& im, std::string const& filename, std: save_to_file(im,filename,type); } -void save_to_file3(mapnik::image_32 const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette const& pal) +void save_to_file3(mapnik::image_32 const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette_ptr const& pal) { save_to_file(im,filename,type,pal); } diff --git a/bindings/python/mapnik_image_view.cpp b/bindings/python/mapnik_image_view.cpp index e08129f7f..bcd890385 100644 --- a/bindings/python/mapnik_image_view.cpp +++ b/bindings/python/mapnik_image_view.cpp @@ -77,7 +77,7 @@ PyObject* view_tostring2(image_view const & view, std::string (s.data(),s.size()); } -PyObject* view_tostring3(image_view const & view, std::string const& format, mapnik::rgba_palette const& pal) +PyObject* view_tostring3(image_view const & view, std::string const& format, mapnik::rgba_palette_ptr const& pal) { std::string s = save_to_string(view, format, pal); return @@ -126,7 +126,7 @@ void save_view2(image_view const& view, void save_view3(image_view const& view, std::string const& filename, std::string const& type, - mapnik::rgba_palette const& pal) + mapnik::rgba_palette_ptr const& pal) { save_to_file(view,filename,type,pal); } diff --git a/bindings/python/mapnik_palette.cpp b/bindings/python/mapnik_palette.cpp index 12cf2fdec..08ab80e92 100644 --- a/bindings/python/mapnik_palette.cpp +++ b/bindings/python/mapnik_palette.cpp @@ -55,7 +55,7 @@ void export_palette () { using namespace boost::python; - class_, std::shared_ptr, boost::noncopyable >("Palette",no_init) //, init( diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index f6bb1ca21..b00c44c8b 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.hpp @@ -46,6 +46,7 @@ namespace mapnik { class Map; class rgba_palette; class image_32; +typedef std::shared_ptr rgba_palette_ptr; class ImageWriterException : public std::exception { @@ -84,7 +85,7 @@ template MAPNIK_DECL void save_to_file(T const& image, std::string const& filename, std::string const& type, - rgba_palette const& palette); + rgba_palette_ptr const& palette); // guess type from file extension template @@ -94,7 +95,7 @@ MAPNIK_DECL void save_to_file(T const& image, template MAPNIK_DECL void save_to_file(T const& image, std::string const& filename, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template MAPNIK_DECL std::string save_to_string(T const& image, @@ -103,7 +104,7 @@ MAPNIK_DECL std::string save_to_string(T const& image, template MAPNIK_DECL std::string save_to_string(T const& image, std::string const& type, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template MAPNIK_DECL void save_to_stream @@ -111,7 +112,7 @@ MAPNIK_DECL void save_to_stream T const& image, std::ostream & stream, std::string const& type, - rgba_palette const& palette + rgba_palette_ptr const& palette ); template @@ -125,7 +126,7 @@ MAPNIK_DECL void save_to_stream template void save_as_png(T const& image, std::string const& filename, - rgba_palette const& palette); + rgba_palette_ptr const& palette); #if defined(HAVE_JPEG) template @@ -224,7 +225,7 @@ MAPNIK_DECL void save_to_file (image_32 const& image, MAPNIK_DECL void save_to_file (image_32 const& image, std::string const& file, std::string const& type, - rgba_palette const& palette); + rgba_palette_ptr const& palette); /////////////////////////////////////////////////////////////////////////// @@ -234,14 +235,14 @@ MAPNIK_DECL std::string save_to_string(image_32 const& image, MAPNIK_DECL std::string save_to_string(image_32 const& image, std::string const& type, - rgba_palette const& palette); + rgba_palette_ptr const& palette); /////////////////////////////////////////////////////////////////////////// MAPNIK_DECL void save_to_stream(image_32 const& image, std::ostream & stream, std::string const& type, - rgba_palette const& palette); + rgba_palette_ptr const& palette); MAPNIK_DECL void save_to_stream(image_32 const& image, std::ostream & stream, @@ -252,7 +253,7 @@ MAPNIK_DECL void save_to_stream(image_32 const& image, extern template MAPNIK_DECL void save_to_file(image_data_rgba8 const&, std::string const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); extern template MAPNIK_DECL void save_to_file(image_data_rgba8 const&, std::string const&, @@ -260,7 +261,7 @@ extern template MAPNIK_DECL void save_to_file(image_data_rgba8 extern template MAPNIK_DECL void save_to_file(image_data_rgba8 const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); extern template MAPNIK_DECL void save_to_file(image_data_rgba8 const&, std::string const&); @@ -269,7 +270,7 @@ extern template MAPNIK_DECL void save_to_file(image_data_rgba8 extern template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); extern template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&, @@ -277,7 +278,7 @@ extern template MAPNIK_DECL void save_to_file > (im extern template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); extern template MAPNIK_DECL void save_to_file > (image_view const&, std::string const&); @@ -287,21 +288,21 @@ extern template MAPNIK_DECL std::string save_to_string(image_d extern template MAPNIK_DECL std::string save_to_string(image_data_rgba8 const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); extern template MAPNIK_DECL std::string save_to_string > (image_view const&, std::string const&); extern template MAPNIK_DECL std::string save_to_string > (image_view const&, std::string const&, - rgba_palette const&); + rgba_palette_ptr const&); #ifdef _MSC_VER template MAPNIK_DECL void save_to_stream( image_data_rgba8 const& image, std::ostream & stream, std::string const& type, - rgba_palette const& palette + rgba_palette_ptr const& palette ); template MAPNIK_DECL void save_to_stream( @@ -314,7 +315,7 @@ template MAPNIK_DECL void save_to_stream > ( image_view const& image, std::ostream & stream, std::string const& type, - rgba_palette const& palette + rgba_palette_ptr const& palette ); template MAPNIK_DECL void save_to_stream > ( diff --git a/include/mapnik/image_util_png.hpp b/include/mapnik/image_util_png.hpp new file mode 100644 index 000000000..9a3f6d7b9 --- /dev/null +++ b/include/mapnik/image_util_png.hpp @@ -0,0 +1,48 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2014 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_IMAGE_UTIL_PNG_HPP +#define MAPNIK_IMAGE_UTIL_PNG_HPP + +// mapnik +#include + +// stl +#include +#include + +namespace mapnik { + +struct png_saver : public mapnik::util::static_visitor<> +{ + png_saver(std::ostream &, std::string &, rgba_palette_ptr const& = nullptr); + template + void operator() (T const&) const; + private: + std::ostream _stream; + std::string _t; + rgba_palette_ptr _pal; +}; + +} // end ns + +#endif // MAPNIK_IMAGE_UTIL_PNG_HPP diff --git a/include/mapnik/palette.hpp b/include/mapnik/palette.hpp index 5dc3a4cdf..950a76984 100644 --- a/include/mapnik/palette.hpp +++ b/include/mapnik/palette.hpp @@ -130,6 +130,8 @@ private: std::vector alpha_pal_; }; +typedef std::shared_ptr rgba_palette_ptr; + } // namespace mapnik #endif // MAPNIK_PALETTE_HPP diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp index 7034ca293..4efd781ff 100644 --- a/include/mapnik/png_io.hpp +++ b/include/mapnik/png_io.hpp @@ -607,7 +607,7 @@ void save_as_png8(T1 & file, mapnik::image_data_gray8::pixel_type * row_out = reduced_image.getRow(y); for (unsigned x = 0; x < width; ++x) { - row_out[x] = tree.quantize(row[x]); + row_out[x] = tree->quantize(row[x]); } } save_as_png(file, palette, reduced_image, width, height, 8, alphaTable, opts); @@ -635,7 +635,7 @@ void save_as_png8(T1 & file, for (unsigned x = 0; x < width; ++x) { - index = tree.quantize(row[x]); + index = tree->quantize(row[x]); if (x%2 == 0) { index = index<<4; @@ -657,14 +657,14 @@ void save_as_png8_hex(T1 & file, if (width + height > 3) // at least 3 pixels (hextree implementation requirement) { // structure for color quantization - hextree tree(opts.colors); + std::shared_ptr> tree = std::make_shared>(opts.colors); if (opts.trans_mode >= 0) { - tree.setTransMode(opts.trans_mode); + tree->setTransMode(opts.trans_mode); } if (opts.gamma > 0) { - tree.setGamma(opts.gamma); + tree->setGamma(opts.gamma); } for (unsigned y = 0; y < height; ++y) @@ -673,13 +673,13 @@ void save_as_png8_hex(T1 & file, for (unsigned x = 0; x < width; ++x) { unsigned val = row[x]; - tree.insert(mapnik::rgba(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val))); + tree->insert(mapnik::rgba(U2RED(val), U2GREEN(val), U2BLUE(val), U2ALPHA(val))); } } //transparency values per palette index std::vector pal; - tree.create_palette(pal); + tree->create_palette(pal); std::vector palette; std::vector alphaTable; for (unsigned i=0; i >(file, image, tree, palette, alphaTable, opts); + save_as_png8> >(file, image, tree, palette, alphaTable, opts); } else { @@ -698,10 +698,10 @@ void save_as_png8_hex(T1 & file, template void save_as_png8_pal(T1 & file, T2 const& image, - rgba_palette const& pal, + rgba_palette_ptr const& pal, png_options const& opts) { - save_as_png8(file, image, pal, pal.palette(), pal.alphaTable(), opts); + save_as_png8(file, image, pal, pal->palette(), pal->alphaTable(), opts); } } diff --git a/src/image_util.cpp b/src/image_util.cpp index a5bb8e98f..55e7cdf3f 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -20,18 +20,7 @@ * *****************************************************************************/ -#if defined(HAVE_PNG) -extern "C" -{ -#include -} -#endif - // mapnik -#if defined(HAVE_PNG) -#include -#endif - #if defined(HAVE_TIFF) #include #endif @@ -45,6 +34,7 @@ extern "C" #endif #include +#include #include #include #include @@ -52,6 +42,7 @@ extern "C" #include #include #include +#include #ifdef HAVE_CAIRO #include @@ -84,7 +75,7 @@ namespace mapnik template std::string save_to_string(T const& image, std::string const& type, - rgba_palette const& palette) + rgba_palette_ptr const& palette) { std::ostringstream ss(std::ios::out|std::ios::binary); save_to_stream(image, ss, type, palette); @@ -104,7 +95,7 @@ template void save_to_file(T const& image, std::string const& filename, std::string const& type, - rgba_palette const& palette) + rgba_palette_ptr const& palette) { std::ofstream file (filename.c_str(), std::ios::out| std::ios::trunc|std::ios::binary); if (file) @@ -127,134 +118,6 @@ void save_to_file(T const& image, else throw ImageWriterException("Could not write file to " + filename ); } -#if defined(HAVE_PNG) - -void handle_png_options(std::string const& type, - png_options & opts) -{ - if (type == "png" || type == "png24" || type == "png32") - { - opts.paletted = false; - return; - } - else if (type == "png8" || type == "png256") - { - opts.paletted = true; - return; - } - boost::char_separator sep(":"); - boost::tokenizer< boost::char_separator > tokens(type, sep); - bool set_colors = false; - bool set_gamma = false; - for (std::string const& t : tokens) - { - if (t == "png8" || t == "png256") - { - opts.paletted = true; - } - else if (t == "png" || t == "png24" || t == "png32") - { - opts.paletted = false; - } - else if (t == "m=o") - { - opts.use_hextree = false; - } - else if (t == "m=h") - { - opts.use_hextree = true; - } - else if (t == "e=miniz") - { - opts.use_miniz = true; - } - else if (boost::algorithm::starts_with(t, "c=")) - { - set_colors = true; - if (!mapnik::util::string2int(t.substr(2),opts.colors) || opts.colors < 1 || opts.colors > 256) - { - throw ImageWriterException("invalid color parameter: " + t.substr(2)); - } - } - else if (boost::algorithm::starts_with(t, "t=")) - { - if (!mapnik::util::string2int(t.substr(2),opts.trans_mode) || opts.trans_mode < 0 || opts.trans_mode > 2) - { - throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2)); - } - } - else if (boost::algorithm::starts_with(t, "g=")) - { - set_gamma = true; - if (!mapnik::util::string2double(t.substr(2),opts.gamma) || opts.gamma < 0) - { - throw ImageWriterException("invalid gamma parameter: " + t.substr(2)); - } - } - else if (boost::algorithm::starts_with(t, "z=")) - { - /* - #define Z_NO_COMPRESSION 0 - #define Z_BEST_SPEED 1 - #define Z_BEST_COMPRESSION 9 - #define Z_DEFAULT_COMPRESSION (-1) - */ - if (!mapnik::util::string2int(t.substr(2),opts.compression) - || opts.compression < Z_DEFAULT_COMPRESSION - || opts.compression > 10) // use 10 here rather than Z_BEST_COMPRESSION (9) to allow for MZ_UBER_COMPRESSION - { - throw ImageWriterException("invalid compression parameter: " + t.substr(2) + " (only -1 through 10 are valid)"); - } - } - else if (boost::algorithm::starts_with(t, "s=")) - { - std::string s = t.substr(2); - if (s == "default") - { - opts.strategy = Z_DEFAULT_STRATEGY; - } - else if (s == "filtered") - { - opts.strategy = Z_FILTERED; - } - else if (s == "huff") - { - opts.strategy = Z_HUFFMAN_ONLY; - } - else if (s == "rle") - { - opts.strategy = Z_RLE; - } - else if (s == "fixed") - { - opts.strategy = Z_FIXED; - } - else - { - throw ImageWriterException("invalid compression strategy parameter: " + s); - } - } - else - { - throw ImageWriterException("unhandled png option: " + t); - } - } - // validation - if (!opts.paletted && set_colors) - { - throw ImageWriterException("invalid color parameter: unavailable for true color (non-paletted) images"); - } - if (!opts.paletted && set_gamma) - { - throw ImageWriterException("invalid gamma parameter: unavailable for true color (non-paletted) images"); - } - if ((opts.use_miniz == false) && opts.compression > Z_BEST_COMPRESSION) - { - throw ImageWriterException("invalid compression value: (only -1 through 9 are valid)"); - } -} -#endif - #if defined(HAVE_TIFF) void handle_tiff_options(std::string const& type, tiff_config & config) @@ -666,10 +529,26 @@ void handle_webp_options(std::string const& type, #endif template -void save_to_stream(T const& image, +void save_to_stream(image_view const& image, std::ostream & stream, std::string const& type, - rgba_palette const& palette) + rgba_palette_ptr const& palette) +{ + save_to_stream(image.data(), stream, type, palette); +} + +void save_to_stream(image_32 const& image, + std::ostream & stream, + std::string const& type, + rgba_palette_ptr const& palette) +{ + save_to_stream(image.data(), stream, type, palette); +} + +void save_to_stream(image_data_any const& image, + std::ostream & stream, + std::string const& type, + rgba_palette_ptr const& palette) { if (stream && image.width() > 0 && image.height() > 0) { @@ -677,20 +556,7 @@ void save_to_stream(T const& image, std::transform(t.begin(), t.end(), t.begin(), ::tolower); if (t == "png" || boost::algorithm::starts_with(t, "png")) { -#if defined(HAVE_PNG) - if (palette.valid()) - { - png_options opts; - handle_png_options(t,opts); - save_as_png8_pal(stream, image, palette, opts); - } - else - { - save_to_stream(image,stream,type); - } -#else - throw ImageWriterException("png output is not enabled in your build of Mapnik"); -#endif + mapnik::util::apply_visitor(png_saver(stream, t, palette), image); } else if (boost::algorithm::starts_with(t, "tif")) { @@ -705,9 +571,22 @@ void save_to_stream(T const& image, else throw ImageWriterException("Could not write to empty stream" ); } - template -void save_to_stream(T const& image, +void save_to_stream(image_view const& image, + std::ostream & stream, + std::string const& type) +{ + save_to_stream(image.data(), stream, type); +} + +void save_to_stream(image_32 const& image, + std::ostream & stream, + std::string const& type) +{ + save_to_stream(image.data(), stream, type); +} + +void save_to_stream(image_data_any const& image, std::ostream & stream, std::string const& type) { @@ -717,27 +596,7 @@ void save_to_stream(T const& image, std::transform(t.begin(), t.end(), t.begin(), ::tolower); if (t == "png" || boost::algorithm::starts_with(t, "png")) { -#if defined(HAVE_PNG) - png_options opts; - handle_png_options(t,opts); - if (opts.paletted) - { - if (opts.use_hextree) - { - save_as_png8_hex(stream, image, opts); - } - else - { - save_as_png8_oct(stream, image, opts); - } - } - else - { - save_as_png(stream, image, opts); - } -#else - throw ImageWriterException("png output is not enabled in your build of Mapnik"); -#endif + mapnik::util::apply_visitor(png_saver(stream, t), image); } else if (boost::algorithm::starts_with(t, "tif")) { @@ -800,7 +659,7 @@ void save_to_file(T const& image, std::string const& filename) } template -void save_to_file(T const& image, std::string const& filename, rgba_palette const& palette) +void save_to_file(T const& image, std::string const& filename, rgba_palette_ptr const& palette) { boost::optional type = type_from_filename(filename); if (type) @@ -899,21 +758,21 @@ template void save_to_file(image_data_rgba8 const&, template void save_to_file(image_data_rgba8 const&, std::string const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template void save_to_file(image_data_rgba8 const&, std::string const&); template void save_to_file(image_data_rgba8 const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template std::string save_to_string(image_data_rgba8 const&, std::string const&); template std::string save_to_string(image_data_rgba8 const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template void save_to_file > (image_view const&, std::string const&, @@ -922,21 +781,21 @@ template void save_to_file > (image_view > (image_view const&, std::string const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template void save_to_file > (image_view const&, std::string const&); template void save_to_file > (image_view const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); template std::string save_to_string > (image_view const&, std::string const&); template std::string save_to_string > (image_view const&, std::string const&, - rgba_palette const& palette); + rgba_palette_ptr const& palette); void save_to_file(image_32 const& image,std::string const& file) { @@ -953,7 +812,7 @@ void save_to_file (image_32 const& image, void save_to_file (image_32 const& image, std::string const& file, std::string const& type, - rgba_palette const& palette) + rgba_palette_ptr const& palette) { save_to_file(image.data(), file, type, palette); } @@ -966,7 +825,7 @@ std::string save_to_string(image_32 const& image, std::string save_to_string(image_32 const& image, std::string const& type, - rgba_palette const& palette) + rgba_palette_ptr const& palette) { return save_to_string(image.data(), type, palette); } diff --git a/src/image_util_png.cpp b/src/image_util_png.cpp new file mode 100644 index 000000000..344a8a151 --- /dev/null +++ b/src/image_util_png.cpp @@ -0,0 +1,241 @@ +/***************************************************************************** + * + * This file is part of Mapnik (c++ mapping toolkit) + * + * Copyright (C) 2014 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 + * + *****************************************************************************/ + +#if defined(HAVE_PNG) +extern "C" +{ +#include +} +#endif + +// mapnik +#if defined(HAVE_PNG) +#include +#endif + +#include +#include + +// boost +#include + +// stl +#include +#include + +namespace mapnik +{ + +#if defined(HAVE_PNG) + +void handle_png_options(std::string const& type, + png_options & opts) +{ + if (type == "png" || type == "png24" || type == "png32") + { + opts.paletted = false; + return; + } + else if (type == "png8" || type == "png256") + { + opts.paletted = true; + return; + } + boost::char_separator sep(":"); + boost::tokenizer< boost::char_separator > tokens(type, sep); + bool set_colors = false; + bool set_gamma = false; + for (std::string const& t : tokens) + { + if (t == "png8" || t == "png256") + { + opts.paletted = true; + } + else if (t == "png" || t == "png24" || t == "png32") + { + opts.paletted = false; + } + else if (t == "m=o") + { + opts.use_hextree = false; + } + else if (t == "m=h") + { + opts.use_hextree = true; + } + else if (t == "e=miniz") + { + opts.use_miniz = true; + } + else if (boost::algorithm::starts_with(t, "c=")) + { + set_colors = true; + if (!mapnik::util::string2int(t.substr(2),opts.colors) || opts.colors < 1 || opts.colors > 256) + { + throw ImageWriterException("invalid color parameter: " + t.substr(2)); + } + } + else if (boost::algorithm::starts_with(t, "t=")) + { + if (!mapnik::util::string2int(t.substr(2),opts.trans_mode) || opts.trans_mode < 0 || opts.trans_mode > 2) + { + throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2)); + } + } + else if (boost::algorithm::starts_with(t, "g=")) + { + set_gamma = true; + if (!mapnik::util::string2double(t.substr(2),opts.gamma) || opts.gamma < 0) + { + throw ImageWriterException("invalid gamma parameter: " + t.substr(2)); + } + } + else if (boost::algorithm::starts_with(t, "z=")) + { + /* + #define Z_NO_COMPRESSION 0 + #define Z_BEST_SPEED 1 + #define Z_BEST_COMPRESSION 9 + #define Z_DEFAULT_COMPRESSION (-1) + */ + if (!mapnik::util::string2int(t.substr(2),opts.compression) + || opts.compression < Z_DEFAULT_COMPRESSION + || opts.compression > 10) // use 10 here rather than Z_BEST_COMPRESSION (9) to allow for MZ_UBER_COMPRESSION + { + throw ImageWriterException("invalid compression parameter: " + t.substr(2) + " (only -1 through 10 are valid)"); + } + } + else if (boost::algorithm::starts_with(t, "s=")) + { + std::string s = t.substr(2); + if (s == "default") + { + opts.strategy = Z_DEFAULT_STRATEGY; + } + else if (s == "filtered") + { + opts.strategy = Z_FILTERED; + } + else if (s == "huff") + { + opts.strategy = Z_HUFFMAN_ONLY; + } + else if (s == "rle") + { + opts.strategy = Z_RLE; + } + else if (s == "fixed") + { + opts.strategy = Z_FIXED; + } + else + { + throw ImageWriterException("invalid compression strategy parameter: " + s); + } + } + else + { + throw ImageWriterException("unhandled png option: " + t); + } + } + // validation + if (!opts.paletted && set_colors) + { + throw ImageWriterException("invalid color parameter: unavailable for true color (non-paletted) images"); + } + if (!opts.paletted && set_gamma) + { + throw ImageWriterException("invalid gamma parameter: unavailable for true color (non-paletted) images"); + } + if ((opts.use_miniz == false) && opts.compression > Z_BEST_COMPRESSION) + { + throw ImageWriterException("invalid compression value: (only -1 through 9 are valid)"); + } +} +#endif + +png_saver::png_saver(std::ostream & stream, std::string const& t, rgba_palette_ptr const& pal): + _stream(stream), _t(t), _pal(pal) {} + +void png_saver::operator() (mapnik::image_data_rgba8 const& image) const +{ +#if defined(HAVE_PNG) + png_options opts; + handle_png_options(_t, opts); + if (_pal && _pal->valid()) + { + png_options opts; + handle_png_options(t,opts); + save_as_png8_pal(stream, image, _pal, opts); + } + else if (opts.paletted) + { + if (opts.use_hextree) + { + save_as_png8_hex(_stream, image, opts); + } + else + { + save_as_png8_oct(_stream, image, opts); + } + } + else + { + save_as_png(_stream, image, opts); + } +#else + throw ImageWriterException("png output is not enabled in your build of Mapnik"); +#endif +} + +void png_saver::operator() (mapnik::image_data_gray8 const& image) const +{ +#if defined(HAVE_PNG) + png_options opts; + handle_png_options(_t, opts); + save_as_png(_stream, image, opts); +#else + throw ImageWriterException("png output is not enabled in your build of Mapnik"); +#endif +} + +void png_saver::operator() (mapnik::image_data_gray16 const& image) const +{ +#if defined(HAVE_PNG) + png_options opts; + handle_png_options(_t, opts); + save_as_png(_stream, image, opts); +#else + throw ImageWriterException("png output is not enabled in your build of Mapnik"); +#endif +} + +void png_saver::operator() (mapnik::image_data_gray32f const& image) const +{ +#if defined(HAVE_PNG) + png_options opts; + handle_png_options(_t, opts); + save_as_png(_stream, image, opts); +#else + throw ImageWriterException("png output is not enabled in your build of Mapnik"); +#endif +}