void png_saver_pal::operator() (T const& image) const { #if defined(HAVE_PNG) throw ImageWriterException("Mapnik does not support grayscale images for 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 process_rgba8_png(T const& image, std::string const& t, std::ostream & stream) { #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 }
void save_to_file(T const& image, std::string const& filename, std::string const& type) { std::ofstream file (filename.c_str(), std::ios::out| std::ios::trunc|std::ios::binary); if (file) { save_to_stream(image, file, type); } else throw ImageWriterException("Could not write file to " + filename ); }
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<char> sep(":"); boost::tokenizer< boost::char_separator<char> > 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)"); } }
void png_saver_pal::operator()<image_view_null> (image_view_null const& image) const { throw ImageWriterException("null image views not supported for png"); }
void handle_png_options(std::string const& type, int * colors, int * compression, int * strategy, int * trans_mode, double * gamma, bool * use_octree, bool * use_miniz) { if (type == "png" || type == "png24" || type == "png32") { // Shortcut when the user didn't specify any flags after the colon. // Paletted images specify "png8 or png256". *colors = -1; return; } // TODO - convert to spirit parser if (type.length() > 6){ boost::char_separator<char> sep(":"); boost::tokenizer< boost::char_separator<char> > tokens(type, sep); BOOST_FOREACH(std::string t, tokens) { if (t == "png" || t == "png24" || t == "png32") { *colors = -1; } else if (t == "m=h") { *use_octree = false; } else if (t == "m=o") { *use_octree = true; } else if (t == "e=miniz") { *use_miniz = true; } else if (boost::algorithm::starts_with(t, "c=")) { if (*colors < 0) throw ImageWriterException("invalid color parameter: unavailable for true color images"); if (!mapnik::util::string2int(t.substr(2),*colors) || *colors < 1 || *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),*trans_mode) || *trans_mode < 0 || *trans_mode > 2) throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2)); } else if (boost::algorithm::starts_with(t, "g=")) { if (*colors < 0) throw ImageWriterException("invalid gamma parameter: unavailable for true color images"); if (!mapnik::util::string2double(t.substr(2),*gamma) || *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),*compression) || *compression < Z_DEFAULT_COMPRESSION || *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 const& s = t.substr(2); if (s == "default") { *strategy = Z_DEFAULT_STRATEGY; } else if (s == "filtered") { *strategy = Z_FILTERED; } else if (s == "huff") { *strategy = Z_HUFFMAN_ONLY; } else if (s == "rle") { *strategy = Z_RLE; } else if (s == "fixed") { *strategy = Z_FIXED; } else { throw ImageWriterException("invalid compression strategy parameter: " + s); } } } if ((*use_miniz == false) && *compression > Z_BEST_COMPRESSION) { throw ImageWriterException("invalid compression value: (only -1 through 9 are valid)"); } }
void save_to_stream(T const& image, std::ostream & stream, std::string const& type) { if (stream) { //all this should go into image_writer factory if (type == "png") save_as_png(stream, image); else if (boost::algorithm::istarts_with(type, std::string("png256")) || boost::algorithm::istarts_with(type, std::string("png8")) ) { int colors = 256; int trans_mode = -1; double gamma = -1; bool use_octree = true; if (type.length() > 6){ boost::char_separator<char> sep(":"); boost::tokenizer< boost::char_separator<char> > tokens(type, sep); BOOST_FOREACH(string t, tokens) { if (t == "m=h") { use_octree = false; } if (t == "m=o") { use_octree = true; } if (boost::algorithm::istarts_with(t,std::string("c="))) { try { colors = boost::lexical_cast<int>(t.substr(2)); if (colors < 0 || colors > 256) throw ImageWriterException("invalid color parameter: " + t.substr(2) + " out of bounds"); } catch(boost::bad_lexical_cast &) { throw ImageWriterException("invalid color parameter: " + t.substr(2)); } } if (boost::algorithm::istarts_with(t, std::string("t="))) { try { trans_mode= boost::lexical_cast<int>(t.substr(2)); if (trans_mode < 0 || trans_mode > 2) throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2) + " out of bounds"); } catch(boost::bad_lexical_cast &) { throw ImageWriterException("invalid trans_mode parameter: " + t.substr(2)); } } if (boost::algorithm::istarts_with(t, std::string("g="))) { try { gamma= boost::lexical_cast<double>(t.substr(2)); if (gamma < 0) throw ImageWriterException("invalid gamma parameter: " + t.substr(2) + " out of bounds"); } catch(boost::bad_lexical_cast &) { throw ImageWriterException("invalid gamma parameter: " + t.substr(2)); } } } } if (use_octree) save_as_png256(stream, image, colors); else save_as_png256_hex(stream, image, colors, trans_mode, gamma); }