From 4689ce16353fec7a7193c1ba4b6f5a9e0bce060e Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Fri, 20 Jan 2017 16:53:58 +0100 Subject: [PATCH] cwebp: add a -sharp_yuv option for 'sharp' RGB->YUV conversion Change-Id: I6edd5b44d693da50f702fa8218f14872874d91ba --- README | 1 + examples/cwebp.c | 7 ++++++- man/cwebp.1 | 6 +++++- src/enc/config_enc.c | 3 +++ src/enc/webp_enc.c | 2 +- src/webp/encode.h | 6 ++++-- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/README b/README index 400d23ab..0caab280 100644 --- a/README +++ b/README @@ -241,6 +241,7 @@ Options: -sharpness ....... filter sharpness (0:most .. 7:least sharp), default=0 -strong ................ use strong filter instead of simple (default) -nostrong .............. use simple filter instead of strong + -sharp_yuv ............. use sharper (and slower) RGB->YUV conversion -partition_limit . limit quality to fit the 512k limit on the first partition (0=no degradation ... 100=full) -pass ............ analysis pass number (1..10) diff --git a/examples/cwebp.c b/examples/cwebp.c index 8d186873..27e51382 100644 --- a/examples/cwebp.c +++ b/examples/cwebp.c @@ -549,6 +549,8 @@ static void HelpLong(void) { printf(" -strong ................ use strong filter instead " "of simple (default)\n"); printf(" -nostrong .............. use simple filter instead of strong\n"); + printf(" -sharp_yuv ............. use sharper (and slower) RGB->YUV " + "conversion\n"); printf(" -partition_limit . limit quality to fit the 512k limit on\n"); printf(" " "the first partition (0=no degradation ... 100=full)\n"); @@ -787,6 +789,8 @@ int main(int argc, const char *argv[]) { config.filter_type = 0; } else if (!strcmp(argv[c], "-sharpness") && c < argc - 1) { config.filter_sharpness = ExUtilGetInt(argv[++c], 0, &parse_error); + } else if (!strcmp(argv[c], "-sharp_yuv")) { + config.use_sharp_yuv = 1; } else if (!strcmp(argv[c], "-pass") && c < argc - 1) { config.pass = ExUtilGetInt(argv[++c], 0, &parse_error); } else if (!strcmp(argv[c], "-pre") && c < argc - 1) { @@ -945,7 +949,8 @@ int main(int argc, const char *argv[]) { // Read the input. We need to decide if we prefer ARGB or YUVA // samples, depending on the expected compression mode (this saves // some conversion steps). - picture.use_argb = (config.lossless || config.preprocessing > 0 || + picture.use_argb = (config.lossless || config.use_sharp_yuv || + config.preprocessing > 0 || crop || (resize_w | resize_h) > 0); if (verbose) { StopwatchReset(&stop_watch); diff --git a/man/cwebp.1 b/man/cwebp.1 index 12fb472f..81cbaa9b 100644 --- a/man/cwebp.1 +++ b/man/cwebp.1 @@ -1,5 +1,5 @@ .\" Hey, EMACS: -*- nroff -*- -.TH CWEBP 1 "September 02, 2016" +.TH CWEBP 1 "January 20, 2017" .SH NAME cwebp \- compress an image file to a WebP file .SH SYNOPSIS @@ -166,6 +166,10 @@ Use strong filtering (if filtering is being used thanks to the Disable strong filtering (if filtering is being used thanks to the \fB\-f\fP option) and use simple filtering instead. .TP +.B \-sharp_yuv +Use more accurate and sharper RGB->YUV conversion if needed. Note that this +process is slower than the default 'fast' RGB->YUV conversion. +.TP .BI \-sns " int Specify the amplitude of the spatial noise shaping. Spatial noise shaping (or \fBsns\fP for short) refers to a general collection of built\-in algorithms diff --git a/src/enc/config_enc.c b/src/enc/config_enc.c index 9921fc45..4589dc06 100644 --- a/src/enc/config_enc.c +++ b/src/enc/config_enc.c @@ -54,6 +54,7 @@ int WebPConfigInitInternal(WebPConfig* config, config->low_memory = 0; config->near_lossless = 100; config->use_delta_palette = 0; + config->use_sharp_yuv = 0; // TODO(skal): tune. switch (preset) { @@ -122,6 +123,8 @@ int WebPValidateConfig(const WebPConfig* config) { if (config->use_delta_palette < 0 || config->use_delta_palette > 1) { return 0; } + if (config->use_sharp_yuv < 0 || config->use_sharp_yuv > 1) return 0; + return 1; } diff --git a/src/enc/webp_enc.c b/src/enc/webp_enc.c index 328d07e9..f18461ef 100644 --- a/src/enc/webp_enc.c +++ b/src/enc/webp_enc.c @@ -342,7 +342,7 @@ int WebPEncode(const WebPConfig* config, WebPPicture* pic) { if (pic->use_argb || pic->y == NULL || pic->u == NULL || pic->v == NULL) { // Make sure we have YUVA samples. - if (config->preprocessing & 4) { + if (config->use_sharp_yuv || (config->preprocessing & 4)) { if (!WebPPictureSharpARGBToYUVA(pic)) { return 0; } diff --git a/src/webp/encode.h b/src/webp/encode.h index 5b6337ce..35fde1d0 100644 --- a/src/webp/encode.h +++ b/src/webp/encode.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define WEBP_ENCODER_ABI_VERSION 0x020d // MAJOR(8b) + MINOR(8b) +#define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. @@ -142,7 +142,9 @@ struct WebPConfig { // value is 0. int use_delta_palette; // reserved for future lossless feature - uint32_t pad[3]; // padding for later use + int use_sharp_yuv; // if needed, use sharp (and slow) RGB->YUV conversion + + uint32_t pad[2]; // padding for later use }; // Enumerate some predefined settings for WebPConfig, depending on the type