add a -z option to cwebp, and WebPConfigLosslessPreset() function

These are presets for lossless coding, similar to zlib.
The shortcut for lossless coding is now, e.g.:
   cwebp -z 5 in.png -o out_lossless.webp

There are 10 possible values for -z parameter:
   0 (fastest, lowest compression)
to 9 (slowest, best compression)

A reasonable tradeoff is -z 6, e.g.
-z 9 can be quite slow, so use with care.

This -z option is just a shortcut for some pre-defined
'-lossless -m xx -q yy' combinations.

Change-Id: I6ae716456456aea065469c916c2d5ca4d6c6cf04
This commit is contained in:
skal 2014-03-11 23:25:35 +01:00
parent 30176619c6
commit 65b99f1c92
4 changed files with 54 additions and 2 deletions

View File

@ -568,6 +568,8 @@ static void HelpLong(void) {
printf(" default, photo, picture,\n");
printf(" drawing, icon, text\n");
printf(" -preset must come first, as it overwrites other parameters.");
printf(" -z <int> ............... Activates lossless preset with given "
" level in [0:fast, ..., 9:slowest]\n");
printf("\n");
printf(" -m <int> ............... compression method (0=fast, 6=slowest)\n");
printf(" -segments <int> ........ number of segments to use (1..4)\n");
@ -672,6 +674,8 @@ int main(int argc, const char *argv[]) {
uint32_t background_color = 0xffffffu;
int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0;
int resize_w = 0, resize_h = 0;
int lossless_preset = 6;
int use_lossless_preset = -1; // -1=unset, 0=don't use, 1=use it
int show_progress = 0;
int keep_metadata = 0;
int metadata_written = 0;
@ -726,8 +730,13 @@ int main(int argc, const char *argv[]) {
picture.height = strtol(argv[++c], NULL, 0);
} else if (!strcmp(argv[c], "-m") && c < argc - 1) {
config.method = strtol(argv[++c], NULL, 0);
use_lossless_preset = 0; // disable -z option
} else if (!strcmp(argv[c], "-q") && c < argc - 1) {
config.quality = (float)strtod(argv[++c], NULL);
use_lossless_preset = 0; // disable -z option
} else if (!strcmp(argv[c], "-z") && c < argc - 1) {
lossless_preset = strtol(argv[++c], NULL, 0);
if (use_lossless_preset != 0) use_lossless_preset = 1;
} else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
config.alpha_quality = strtol(argv[++c], NULL, 0);
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
@ -916,6 +925,13 @@ int main(int argc, const char *argv[]) {
goto Error;
}
if (use_lossless_preset == 1) {
if (!WebPConfigLosslessPreset(&config, lossless_preset)) {
fprintf(stderr, "Invalid lossless preset (-z %d)\n", lossless_preset);
goto Error;
}
}
// Check for unsupported command line options for lossless mode and log
// warning for such options.
if (!quiet && config.lossless == 1) {

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH CWEBP 1 "December 12, 2013"
.TH CWEBP 1 "March 11, 2014"
.SH NAME
cwebp \- compress an image file to a WebP file
.SH SYNOPSIS
@ -32,6 +32,14 @@ Print the version number (as major.minor.revision) and exit.
.BI \-q " float
Specify the compression factor for RGB channels between 0 and 100. The default
is 75.
.TP
.BI \-z " int
Switch on \fBlossless\fP compression mode with the specified level between 0
and 9, with level 0 being the fastest, 9 being the slowest. Fast mode
produce larger file size than fast ones. A good default is \-z 6.
This option is actually a shortcut for some predefined setting for quality
and method. If options \-q or \-m are subsequently used, they will invalidate
the effect of this \-z option.
.br
In case of lossy compression (default), a small factor produces a smaller file
with lower quality. Best quality is achieved by using a value of 100.

View File

@ -138,3 +138,23 @@ int WebPValidateConfig(const WebPConfig* config) {
//------------------------------------------------------------------------------
#define MAX_LEVEL 9
// Mapping between -z level and -m / -q parameter settings.
static const struct {
uint8_t method_;
uint8_t quality_;
} kLosslessPresets[MAX_LEVEL + 1] = {
{ 0, 0 }, { 1, 20 }, { 2, 25 }, { 3, 30 }, { 3, 50 },
{ 4, 50 }, { 4, 75 }, { 4, 90 }, { 5, 90 }, { 6, 100 }
};
int WebPConfigLosslessPreset(WebPConfig* config, int level) {
if (config == NULL || level < 0 || level > MAX_LEVEL) return 0;
config->lossless = 1;
config->method = kLosslessPresets[level].method_;
config->quality = kLosslessPresets[level].quality_;
return 1;
}
//------------------------------------------------------------------------------

View File

@ -20,7 +20,7 @@
extern "C" {
#endif
#define WEBP_ENCODER_ABI_VERSION 0x0202 // MAJOR(8b) + MINOR(8b)
#define WEBP_ENCODER_ABI_VERSION 0x0203 // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference.
@ -167,6 +167,14 @@ static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
WEBP_ENCODER_ABI_VERSION);
}
// Activate the lossless compression mode with the desired efficiency level
// between 0 (fastest, lowest compression) and 9 (slower, best compression).
// A good default level is '6', providing a fair tradeoff between compression
// speed and final compressed size.
// This function will overwrite several fields from config: 'method', 'quality'
// and 'lossless'. Returns false in case of parameter error.
WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level);
// Returns true if 'config' is non-NULL and all configuration parameters are
// within their valid ranges.
WEBP_EXTERN(int) WebPValidateConfig(const WebPConfig* config);