From be7d0a55c2003871ef3defe4a0e83efeb960ff46 Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 3 Oct 2013 23:59:10 -0700 Subject: [PATCH] webp: cleanup option handling --- include/mapnik/webp_io.hpp | 45 +++++++++++++++++++++++++------------- src/image_util.cpp | 34 ++++++++-------------------- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/include/mapnik/webp_io.hpp b/include/mapnik/webp_io.hpp index 5d715dc70..0ecda5c26 100644 --- a/include/mapnik/webp_io.hpp +++ b/include/mapnik/webp_io.hpp @@ -39,6 +39,27 @@ namespace mapnik { +struct webp_options { + double quality; // 0 lowest, 100 highest + int method; // 0 if fastest, 6 slowest + int lossless; // Lossless encoding (0=lossy(default), 1=lossless). + int image_hint; // used when lossless=1 + /* + WEBP_HINT_DEFAULT = 0, // default preset. + WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot + WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting + WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). + WEBP_HINT_LAST + */ + bool alpha; + webp_options() : + quality(90.0), + method(3), + lossless(0), + image_hint(3), + alpha(true) {} +}; + template int webp_stream_write(const uint8_t* data, size_t data_size, const WebPPicture* picture) { @@ -138,24 +159,20 @@ inline int import_image_data(image_data_32 const& im, template void save_as_webp(T1& file, - float quality, - int method, - int lossless, - int image_hint, - bool alpha, - T2 const& image) + T2 const& image, + webp_options const& opts) { WebPConfig config; - if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality)) + if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, static_cast(opts.quality))) { throw std::runtime_error("version mismatch"); } // Add additional tuning - if (method >= 0) config.method = method; + if (opts.method >= 0) config.method = opts.method; #if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1 - config.lossless = !!lossless; - config.image_hint = static_cast(image_hint); + config.lossless = !!opts.lossless; + config.image_hint = static_cast(opts.image_hint); #else #ifdef _MSC_VER #pragma NOTE(compiling against webp that does not support lossless flag) @@ -179,7 +196,7 @@ void save_as_webp(T1& file, pic.height = image.height(); int ok = 0; #if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1 - pic.use_argb = !!lossless; + pic.use_argb = !!opts.lossless; // lossless fast track if (pic.use_argb) { @@ -206,10 +223,10 @@ void save_as_webp(T1& file, { // different approach for lossy since ImportYUVAFromRGBA is needed // to prepare WebPPicture and working with view pixels is not viable - ok = import_image_data(image,pic,alpha); + ok = import_image_data(image,pic,opts.alpha); } #else - ok = import_image_data(image,pic,alpha); + ok = import_image_data(image,pic,opts.alpha); #endif if (!ok) { @@ -218,14 +235,12 @@ void save_as_webp(T1& file, pic.writer = webp_stream_write; pic.custom_ptr = &file; - ok = WebPEncode(&config, &pic); WebPPictureFree(&pic); if (!ok) { throw std::runtime_error(webp_encoding_error(pic.error_code)); } - file.flush(); } } diff --git a/src/image_util.cpp b/src/image_util.cpp index 1e323c38a..a1dfb5bc2 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -247,12 +247,7 @@ void handle_png_options(std::string const& type, #if defined(HAVE_WEBP) void handle_webp_options(std::string const& type, - double & quality, - int & method, - int & lossless, - int & image_hint, - bool & alpha - ) + webp_options & opts) { if (type == "webp") { @@ -268,7 +263,7 @@ void handle_webp_options(std::string const& type, std::string val = t.substr(8); if (!val.empty()) { - if (!mapnik::util::string2double(val,quality) || quality < 0.0 || quality > 100.0) + if (!mapnik::util::string2double(val,opts.quality) || opts.quality < 0.0 || opts.quality > 100.0) { throw ImageWriterException("invalid webp quality: '" + val + "'"); } @@ -279,7 +274,7 @@ void handle_webp_options(std::string const& type, std::string val = t.substr(7); if (!val.empty()) { - if (!mapnik::util::string2int(val,method) || method < 0 || method > 6) + if (!mapnik::util::string2int(val,opts.method) || opts.method < 0 || opts.method > 6) { throw ImageWriterException("invalid webp method: '" + val + "'"); } @@ -290,7 +285,7 @@ void handle_webp_options(std::string const& type, std::string val = t.substr(9); if (!val.empty()) { - if (!mapnik::util::string2int(val,lossless) || lossless < 0 || lossless > 1) + if (!mapnik::util::string2int(val,opts.lossless) || opts.lossless < 0 || opts.lossless > 1) { throw ImageWriterException("invalid webp lossless: '" + val + "'"); } @@ -301,7 +296,7 @@ void handle_webp_options(std::string const& type, std::string val = t.substr(11); if (!val.empty()) { - if (!mapnik::util::string2int(val,image_hint) || image_hint < 0 || image_hint > 3) + if (!mapnik::util::string2int(val,opts.image_hint) || opts.image_hint < 0 || opts.image_hint > 3) { throw ImageWriterException("invalid webp image_hint: '" + val + "'"); } @@ -312,7 +307,7 @@ void handle_webp_options(std::string const& type, std::string val = t.substr(6); if (!val.empty()) { - if (!mapnik::util::string2bool(val,alpha)) + if (!mapnik::util::string2bool(val,opts.alpha)) { throw ImageWriterException("invalid webp alpha: '" + val + "'"); } @@ -425,20 +420,9 @@ void save_to_stream(T const& image, else if (boost::algorithm::starts_with(t, "webp")) { #if defined(HAVE_WEBP) - double quality = 90.0; // 0 lowest, 100 highest - int method = 3; // 0 if fastest, 6 slowest - int lossless = 0; // Lossless encoding (0=lossy(default), 1=lossless). - int image_hint = 3; // used when lossless=1 - bool alpha = true; - /* - WEBP_HINT_DEFAULT = 0, // default preset. - WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot - WEBP_HINT_PHOTO, // outdoor photograph, with natural lighting - WEBP_HINT_GRAPH, // Discrete tone image (graph, map-tile etc). - WEBP_HINT_LAST - */ - handle_webp_options(t,quality,method,lossless, image_hint, alpha); - save_as_webp(stream, static_cast(quality), method, lossless, image_hint, alpha, image); + webp_options opts; + handle_webp_options(t,opts); + save_as_webp(stream, image, opts); #else throw ImageWriterException("webp output is not enabled in your build of Mapnik"); #endif