diff --git a/examples/cwebp.c b/examples/cwebp.c index bd60929c..7e7e4b53 100644 --- a/examples/cwebp.c +++ b/examples/cwebp.c @@ -744,6 +744,9 @@ static void HelpLong(void) { printf(" One of: none, fast (default) or best.\n"); printf(" -alpha_cleanup ......... Clean RGB values in transparent area.\n"); printf(" -noalpha ............... discard any transparency information.\n"); + printf(" -lossless .............. Encode image losslessly.\n"); + printf(" -hint ......... Specify image characteristics hint.\n"); + printf(" One of: photo or picture\n"); printf("\n"); printf(" -short ................. condense printed message\n"); @@ -866,6 +869,16 @@ int main(int argc, const char *argv[]) { } else if (!strcmp(argv[c], "-lossless")) { config.lossless = 1; picture.use_argb_input = 1; + } else if (!strcmp(argv[c], "-hint") && c < argc - 1) { + ++c; + if (!strcmp(argv[c], "photo")) { + config.image_hint = WEBP_HINT_PHOTO; + } else if (!strcmp(argv[c], "picture")) { + config.image_hint = WEBP_HINT_PICTURE; + } else { + fprintf(stderr, "Error! Unrecognized image hint: %s\n", argv[c]); + goto Error; + } } else if (!strcmp(argv[c], "-size") && c < argc - 1) { config.target_size = strtol(argv[++c], NULL, 0); } else if (!strcmp(argv[c], "-psnr") && c < argc - 1) { diff --git a/man/cwebp.1 b/man/cwebp.1 index 57574e7f..132359cd 100644 --- a/man/cwebp.1 +++ b/man/cwebp.1 @@ -162,6 +162,13 @@ The default is off. .B \-noalpha Using this option will discard the alpha channel. .TP +.B \-lossless +Encode the image without any loss. +.TP +.B \-hint string +Specify the hint about input image type. Possible values are: +\fBphoto\fP, and \fBpicture\fP. +.TP .B \-noasm Disable all assembly optimizations. .TP diff --git a/src/enc/config.c b/src/enc/config.c index 5e1b2540..6c5de30e 100644 --- a/src/enc/config.c +++ b/src/enc/config.c @@ -45,6 +45,7 @@ int WebPConfigInitInternal(WebPConfig* const config, config->alpha_filtering = 1; config->alpha_quality = 100; config->lossless = 0; + config->image_hint = WEBP_HINT_DEFAULT; // TODO(skal): tune. switch (preset) { @@ -119,6 +120,8 @@ int WebPValidateConfig(const WebPConfig* const config) { return 0; if (config->lossless < 0 || config->lossless > 1) return 0; + if (config->image_hint > WEBP_HINT_PHOTO) + return 0; return 1; } diff --git a/src/enc/vp8l.c b/src/enc/vp8l.c index 700149e2..5efbe376 100644 --- a/src/enc/vp8l.c +++ b/src/enc/vp8l.c @@ -139,19 +139,24 @@ static int AnalyzeEntropy(const WebPPicture* const pic, return 1; } -static int VP8LEncAnalyze(VP8LEncoder* const enc) { +static int VP8LEncAnalyze(VP8LEncoder* const enc, WebPImageHint image_hint) { const WebPPicture* const pic = enc->pic_; assert(pic != NULL && pic->argb != NULL); enc->use_palette_ = - AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_); + AnalyzeAndCreatePalette(pic, enc->palette_, &enc->palette_size_); if (!enc->use_palette_) { - double non_pred_entropy, pred_entropy; - if (!AnalyzeEntropy(pic, &non_pred_entropy, &pred_entropy)) { - return 0; - } + if (image_hint == WEBP_HINT_DEFAULT) { + double non_pred_entropy, pred_entropy; + if (!AnalyzeEntropy(pic, &non_pred_entropy, &pred_entropy)) { + return 0; + } - if (pred_entropy < 0.95 * non_pred_entropy) { + if (pred_entropy < 0.95 * non_pred_entropy) { + enc->use_predict_ = 1; + enc->use_cross_color_ = 1; + } + } else if (image_hint == WEBP_HINT_PHOTO) { enc->use_predict_ = 1; enc->use_cross_color_ = 1; } @@ -945,7 +950,7 @@ WebPEncodingError VP8LEncodeStream(const WebPConfig* const config, // --------------------------------------------------------------------------- // Analyze image (entropy, num_palettes etc) - if (!VP8LEncAnalyze(enc)) { + if (!VP8LEncAnalyze(enc, config->image_hint)) { err = VP8_ENC_ERROR_OUT_OF_MEMORY; goto Error; } diff --git a/src/webp/encode.h b/src/webp/encode.h index 837cff0b..36cb1342 100644 --- a/src/webp/encode.h +++ b/src/webp/encode.h @@ -46,6 +46,13 @@ WEBP_EXTERN(size_t) WebPEncodeBGRA(const uint8_t* bgra, //------------------------------------------------------------------------------ // Coding parameters +// Image characteristics hint for the underlying encoder. +typedef enum { + WEBP_HINT_DEFAULT = 0, // default preset. + WEBP_HINT_PICTURE, // digital picture, like portrait, inner shot + WEBP_HINT_PHOTO // outdoor photograph, with natural lighting +} WebPImageHint; + typedef struct { float quality; // between 0 (smallest file) and 100 (biggest) int target_size; // if non-zero, set the desired target size in bytes. @@ -77,6 +84,7 @@ typedef struct { int alpha_quality; // Between 0 (smallest size) and 100 (lossless). // Default is 100. int lossless; // Lossless encoding (0=lossy(default), 1=lossless). + WebPImageHint image_hint; // Hint for image type. } WebPConfig; // Enumerate some predefined settings for WebPConfig, depending on the type