webp: cleanup option handling
This commit is contained in:
parent
0fb718a4fd
commit
be7d0a55c2
2 changed files with 39 additions and 40 deletions
|
@ -39,6 +39,27 @@
|
||||||
|
|
||||||
namespace mapnik {
|
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 <typename T>
|
template <typename T>
|
||||||
int webp_stream_write(const uint8_t* data, size_t data_size, const WebPPicture* picture)
|
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 <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
void save_as_webp(T1& file,
|
void save_as_webp(T1& file,
|
||||||
float quality,
|
T2 const& image,
|
||||||
int method,
|
webp_options const& opts)
|
||||||
int lossless,
|
|
||||||
int image_hint,
|
|
||||||
bool alpha,
|
|
||||||
T2 const& image)
|
|
||||||
{
|
{
|
||||||
WebPConfig config;
|
WebPConfig config;
|
||||||
if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, quality))
|
if (!WebPConfigPreset(&config, WEBP_PRESET_DEFAULT, static_cast<float>(opts.quality)))
|
||||||
{
|
{
|
||||||
throw std::runtime_error("version mismatch");
|
throw std::runtime_error("version mismatch");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add additional tuning
|
// Add additional tuning
|
||||||
if (method >= 0) config.method = method;
|
if (opts.method >= 0) config.method = opts.method;
|
||||||
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
|
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
|
||||||
config.lossless = !!lossless;
|
config.lossless = !!opts.lossless;
|
||||||
config.image_hint = static_cast<WebPImageHint>(image_hint);
|
config.image_hint = static_cast<WebPImageHint>(opts.image_hint);
|
||||||
#else
|
#else
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma NOTE(compiling against webp that does not support lossless flag)
|
#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();
|
pic.height = image.height();
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
|
#if (WEBP_ENCODER_ABI_VERSION >> 8) >= 1
|
||||||
pic.use_argb = !!lossless;
|
pic.use_argb = !!opts.lossless;
|
||||||
// lossless fast track
|
// lossless fast track
|
||||||
if (pic.use_argb)
|
if (pic.use_argb)
|
||||||
{
|
{
|
||||||
|
@ -206,10 +223,10 @@ void save_as_webp(T1& file,
|
||||||
{
|
{
|
||||||
// different approach for lossy since ImportYUVAFromRGBA is needed
|
// different approach for lossy since ImportYUVAFromRGBA is needed
|
||||||
// to prepare WebPPicture and working with view pixels is not viable
|
// 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
|
#else
|
||||||
ok = import_image_data(image,pic,alpha);
|
ok = import_image_data(image,pic,opts.alpha);
|
||||||
#endif
|
#endif
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
|
@ -218,14 +235,12 @@ void save_as_webp(T1& file,
|
||||||
|
|
||||||
pic.writer = webp_stream_write<T1>;
|
pic.writer = webp_stream_write<T1>;
|
||||||
pic.custom_ptr = &file;
|
pic.custom_ptr = &file;
|
||||||
|
|
||||||
ok = WebPEncode(&config, &pic);
|
ok = WebPEncode(&config, &pic);
|
||||||
WebPPictureFree(&pic);
|
WebPPictureFree(&pic);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(webp_encoding_error(pic.error_code));
|
throw std::runtime_error(webp_encoding_error(pic.error_code));
|
||||||
}
|
}
|
||||||
|
|
||||||
file.flush();
|
file.flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -247,12 +247,7 @@ void handle_png_options(std::string const& type,
|
||||||
|
|
||||||
#if defined(HAVE_WEBP)
|
#if defined(HAVE_WEBP)
|
||||||
void handle_webp_options(std::string const& type,
|
void handle_webp_options(std::string const& type,
|
||||||
double & quality,
|
webp_options & opts)
|
||||||
int & method,
|
|
||||||
int & lossless,
|
|
||||||
int & image_hint,
|
|
||||||
bool & alpha
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
if (type == "webp")
|
if (type == "webp")
|
||||||
{
|
{
|
||||||
|
@ -268,7 +263,7 @@ void handle_webp_options(std::string const& type,
|
||||||
std::string val = t.substr(8);
|
std::string val = t.substr(8);
|
||||||
if (!val.empty())
|
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 + "'");
|
throw ImageWriterException("invalid webp quality: '" + val + "'");
|
||||||
}
|
}
|
||||||
|
@ -279,7 +274,7 @@ void handle_webp_options(std::string const& type,
|
||||||
std::string val = t.substr(7);
|
std::string val = t.substr(7);
|
||||||
if (!val.empty())
|
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 + "'");
|
throw ImageWriterException("invalid webp method: '" + val + "'");
|
||||||
}
|
}
|
||||||
|
@ -290,7 +285,7 @@ void handle_webp_options(std::string const& type,
|
||||||
std::string val = t.substr(9);
|
std::string val = t.substr(9);
|
||||||
if (!val.empty())
|
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 + "'");
|
throw ImageWriterException("invalid webp lossless: '" + val + "'");
|
||||||
}
|
}
|
||||||
|
@ -301,7 +296,7 @@ void handle_webp_options(std::string const& type,
|
||||||
std::string val = t.substr(11);
|
std::string val = t.substr(11);
|
||||||
if (!val.empty())
|
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 + "'");
|
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);
|
std::string val = t.substr(6);
|
||||||
if (!val.empty())
|
if (!val.empty())
|
||||||
{
|
{
|
||||||
if (!mapnik::util::string2bool(val,alpha))
|
if (!mapnik::util::string2bool(val,opts.alpha))
|
||||||
{
|
{
|
||||||
throw ImageWriterException("invalid webp alpha: '" + val + "'");
|
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"))
|
else if (boost::algorithm::starts_with(t, "webp"))
|
||||||
{
|
{
|
||||||
#if defined(HAVE_WEBP)
|
#if defined(HAVE_WEBP)
|
||||||
double quality = 90.0; // 0 lowest, 100 highest
|
webp_options opts;
|
||||||
int method = 3; // 0 if fastest, 6 slowest
|
handle_webp_options(t,opts);
|
||||||
int lossless = 0; // Lossless encoding (0=lossy(default), 1=lossless).
|
save_as_webp(stream, image, opts);
|
||||||
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<float>(quality), method, lossless, image_hint, alpha, image);
|
|
||||||
#else
|
#else
|
||||||
throw ImageWriterException("webp output is not enabled in your build of Mapnik");
|
throw ImageWriterException("webp output is not enabled in your build of Mapnik");
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue