restore encode API compatibility

protect WebPConfigLosslessPreset/WebPMemoryWriterClear w/a
WEBP_ENCODER_ABI_VERSION check

Change-Id: If4debc15fee172a3f18079bc2bd29eb8447bc14b
This commit is contained in:
James Zern 2014-07-22 20:24:59 -07:00
parent 793368e8c6
commit c2fc52e4ec
7 changed files with 61 additions and 19 deletions

2
README
View File

@ -152,8 +152,6 @@ Options:
default, photo, picture, default, photo, picture,
drawing, icon, text drawing, icon, text
-preset must come first, as it overwrites other parameters -preset must come first, as it overwrites other parameters
-z <int> ............... activates lossless preset with given
level in [0:fast, ..., 9:slowest]
-m <int> ............... compression method (0=fast, 6=slowest) -m <int> ............... compression method (0=fast, 6=slowest)
-segments <int> ........ number of segments to use (1..4) -segments <int> ........ number of segments to use (1..4)

View File

@ -573,8 +573,10 @@ static void HelpLong(void) {
printf(" default, photo, picture,\n"); printf(" default, photo, picture,\n");
printf(" drawing, icon, text\n"); printf(" drawing, icon, text\n");
printf(" -preset must come first, as it overwrites other parameters\n"); printf(" -preset must come first, as it overwrites other parameters\n");
#if WEBP_ENCODER_ABI_VERSION > 0x0202
printf(" -z <int> ............... activates lossless preset with given\n" printf(" -z <int> ............... activates lossless preset with given\n"
" level in [0:fast, ..., 9:slowest]\n"); " level in [0:fast, ..., 9:slowest]\n");
#endif
printf("\n"); printf("\n");
printf(" -m <int> ............... compression method (0=fast, 6=slowest)\n"); printf(" -m <int> ............... compression method (0=fast, 6=slowest)\n");
printf(" -segments <int> ........ number of segments to use (1..4)\n"); printf(" -segments <int> ........ number of segments to use (1..4)\n");
@ -676,8 +678,10 @@ int main(int argc, const char *argv[]) {
uint32_t background_color = 0xffffffu; uint32_t background_color = 0xffffffu;
int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0; int crop = 0, crop_x = 0, crop_y = 0, crop_w = 0, crop_h = 0;
int resize_w = 0, resize_h = 0; int resize_w = 0, resize_h = 0;
#if WEBP_ENCODER_ABI_VERSION > 0x0202
int lossless_preset = 6; int lossless_preset = 6;
int use_lossless_preset = -1; // -1=unset, 0=don't use, 1=use it int use_lossless_preset = -1; // -1=unset, 0=don't use, 1=use it
#endif
int show_progress = 0; int show_progress = 0;
int keep_metadata = 0; int keep_metadata = 0;
int metadata_written = 0; int metadata_written = 0;
@ -732,13 +736,17 @@ int main(int argc, const char *argv[]) {
picture.height = strtol(argv[++c], NULL, 0); picture.height = strtol(argv[++c], NULL, 0);
} else if (!strcmp(argv[c], "-m") && c < argc - 1) { } else if (!strcmp(argv[c], "-m") && c < argc - 1) {
config.method = strtol(argv[++c], NULL, 0); config.method = strtol(argv[++c], NULL, 0);
#if WEBP_ENCODER_ABI_VERSION > 0x0202
use_lossless_preset = 0; // disable -z option use_lossless_preset = 0; // disable -z option
#endif
} else if (!strcmp(argv[c], "-q") && c < argc - 1) { } else if (!strcmp(argv[c], "-q") && c < argc - 1) {
config.quality = (float)strtod(argv[++c], NULL); config.quality = (float)strtod(argv[++c], NULL);
#if WEBP_ENCODER_ABI_VERSION > 0x0202
use_lossless_preset = 0; // disable -z option use_lossless_preset = 0; // disable -z option
} else if (!strcmp(argv[c], "-z") && c < argc - 1) { } else if (!strcmp(argv[c], "-z") && c < argc - 1) {
lossless_preset = strtol(argv[++c], NULL, 0); lossless_preset = strtol(argv[++c], NULL, 0);
if (use_lossless_preset != 0) use_lossless_preset = 1; if (use_lossless_preset != 0) use_lossless_preset = 1;
#endif
} else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) { } else if (!strcmp(argv[c], "-alpha_q") && c < argc - 1) {
config.alpha_quality = strtol(argv[++c], NULL, 0); config.alpha_quality = strtol(argv[++c], NULL, 0);
} else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) { } else if (!strcmp(argv[c], "-alpha_method") && c < argc - 1) {
@ -919,12 +927,14 @@ int main(int argc, const char *argv[]) {
goto Error; goto Error;
} }
#if WEBP_ENCODER_ABI_VERSION > 0x0202
if (use_lossless_preset == 1) { if (use_lossless_preset == 1) {
if (!WebPConfigLosslessPreset(&config, lossless_preset)) { if (!WebPConfigLosslessPreset(&config, lossless_preset)) {
fprintf(stderr, "Invalid lossless preset (-z %d)\n", lossless_preset); fprintf(stderr, "Invalid lossless preset (-z %d)\n", lossless_preset);
goto Error; goto Error;
} }
} }
#endif
// Check for unsupported command line options for lossless mode and log // Check for unsupported command line options for lossless mode and log
// warning for such options. // warning for such options.
@ -1116,7 +1126,11 @@ int main(int argc, const char *argv[]) {
return_value = 0; return_value = 0;
Error: Error:
#if WEBP_ENCODER_ABI_VERSION > 0x0202
WebPMemoryWriterClear(&memory_writer); WebPMemoryWriterClear(&memory_writer);
#else
free(memory_writer.mem);
#endif
free(picture.extra_info); free(picture.extra_info);
MetadataFree(&metadata); MetadataFree(&metadata);
WebPPictureFree(&picture); WebPPictureFree(&picture);

View File

@ -475,10 +475,20 @@ static WebPEncodingError SetFrame(const WebPConfig* const config,
// TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should // TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should
// also be a criteria, in addition to sizes. // also be a criteria, in addition to sizes.
if (mem1.size <= mem2.size) { if (mem1.size <= mem2.size) {
#if WEBP_ENCODER_ABI_VERSION > 0x0202
WebPMemoryWriterClear(&mem2); WebPMemoryWriterClear(&mem2);
#else
free(mem2.mem);
memset(&mem2, 0, sizeof(mem2));
#endif
GetEncodedData(&mem1, encoded_data); GetEncodedData(&mem1, encoded_data);
} else { } else {
#if WEBP_ENCODER_ABI_VERSION > 0x0202
WebPMemoryWriterClear(&mem1); WebPMemoryWriterClear(&mem1);
#else
free(mem1.mem);
memset(&mem1, 0, sizeof(mem1));
#endif
GetEncodedData(&mem2, encoded_data); GetEncodedData(&mem2, encoded_data);
} }
} else { } else {
@ -487,8 +497,13 @@ static WebPEncodingError SetFrame(const WebPConfig* const config,
return error_code; return error_code;
Err: Err:
#if WEBP_ENCODER_ABI_VERSION > 0x0202
WebPMemoryWriterClear(&mem1); WebPMemoryWriterClear(&mem1);
WebPMemoryWriterClear(&mem2); WebPMemoryWriterClear(&mem2);
#else
free(mem1.mem);
free(mem2.mem);
#endif
return error_code; return error_code;
} }

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*- .\" Hey, EMACS: -*- nroff -*-
.TH CWEBP 1 "April 19, 2014" .TH CWEBP 1 "July 22, 2014"
.SH NAME .SH NAME
cwebp \- compress an image file to a WebP file cwebp \- compress an image file to a WebP file
.SH SYNOPSIS .SH SYNOPSIS
@ -38,21 +38,22 @@ Print the version number (as major.minor.revision) and exit.
.BI \-q " float .BI \-q " float
Specify the compression factor for RGB channels between 0 and 100. The default Specify the compression factor for RGB channels between 0 and 100. The default
is 75. is 75.
.TP .\" TODO(jzern): restore post-v0.4.1
.BI \-z " int .\" .TP
Switch on \fBlossless\fP compression mode with the specified level between 0 .\" .BI \-z " int
and 9, with level 0 being the fastest, 9 being the slowest. Fast mode .\" Switch on \fBlossless\fP compression mode with the specified level between 0
produces larger file size than slower ones. A good default is \-z 6. .\" and 9, with level 0 being the fastest, 9 being the slowest. Fast mode
This option is actually a shortcut for some predefined settings for quality .\" produces larger file size than slower ones. A good default is \-z 6.
and method. If options \-q or \-m are subsequently used, they will invalidate .\" This option is actually a shortcut for some predefined settings for quality
the effect of this \-z option. .\" and method. If options \-q or \-m are subsequently used, they will invalidate
.br .\" the effect of this \-z option.
In case of lossy compression (default), a small factor produces a smaller file .\" .br
with lower quality. Best quality is achieved by using a value of 100. .\" In case of lossy compression (default), a small factor produces a smaller file
.br .\" with lower quality. Best quality is achieved by using a value of 100.
In case of lossless compression (specified by the \-lossless option), a small .\" .br
factor enables faster compression speed, but produces a larger file. Maximum .\" In case of lossless compression (specified by the \-lossless option), a small
compression is achieved by using a value of 100. .\" factor enables faster compression speed, but produces a larger file. Maximum
.\" compression is achieved by using a value of 100.
.TP .TP
.BI \-alpha_q " int .BI \-alpha_q " int
Specify the compression factor for alpha compression between 0 and 100. Specify the compression factor for alpha compression between 0 and 100.

View File

@ -138,6 +138,7 @@ int WebPValidateConfig(const WebPConfig* config) {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if WEBP_ENCODER_ABI_VERSION > 0x0202
#define MAX_LEVEL 9 #define MAX_LEVEL 9
// Mapping between -z level and -m / -q parameter settings. // Mapping between -z level and -m / -q parameter settings.
@ -156,5 +157,6 @@ int WebPConfigLosslessPreset(WebPConfig* config, int level) {
config->quality = kLosslessPresets[level].quality_; config->quality = kLosslessPresets[level].quality_;
return 1; return 1;
} }
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -571,6 +571,10 @@ int WebPPictureAllocYUVA(WebPPicture* const picture, int width, int height);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if WEBP_ENCODER_ABI_VERSION <= 0x0202
void WebPMemoryWriterClear(WebPMemoryWriter* writer);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View File

@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #endif
#define WEBP_ENCODER_ABI_VERSION 0x0205 // MAJOR(8b) + MINOR(8b) #define WEBP_ENCODER_ABI_VERSION 0x0202 // MAJOR(8b) + MINOR(8b)
// Note: forward declaring enumerations is not allowed in (strict) C and C++, // Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference. // the types are left here for reference.
@ -167,6 +167,7 @@ static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
WEBP_ENCODER_ABI_VERSION); WEBP_ENCODER_ABI_VERSION);
} }
#if WEBP_ENCODER_ABI_VERSION > 0x0202
// Activate the lossless compression mode with the desired efficiency level // Activate the lossless compression mode with the desired efficiency level
// between 0 (fastest, lowest compression) and 9 (slower, best compression). // between 0 (fastest, lowest compression) and 9 (slower, best compression).
// A good default level is '6', providing a fair tradeoff between compression // A good default level is '6', providing a fair tradeoff between compression
@ -174,6 +175,7 @@ static WEBP_INLINE int WebPConfigPreset(WebPConfig* config,
// This function will overwrite several fields from config: 'method', 'quality' // This function will overwrite several fields from config: 'method', 'quality'
// and 'lossless'. Returns false in case of parameter error. // and 'lossless'. Returns false in case of parameter error.
WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level); WEBP_EXTERN(int) WebPConfigLosslessPreset(WebPConfig* config, int level);
#endif
// Returns true if 'config' is non-NULL and all configuration parameters are // Returns true if 'config' is non-NULL and all configuration parameters are
// within their valid ranges. // within their valid ranges.
@ -229,12 +231,18 @@ struct WebPMemoryWriter {
// The following must be called first before any use. // The following must be called first before any use.
WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer); WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
#if WEBP_ENCODER_ABI_VERSION > 0x0202
// The following must be called to deallocate writer->mem memory. The 'writer' // The following must be called to deallocate writer->mem memory. The 'writer'
// object itself is not deallocated. // object itself is not deallocated.
WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer); WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer);
#endif
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon // The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
// completion, writer.mem and writer.size will hold the coded data. // completion, writer.mem and writer.size will hold the coded data.
#if WEBP_ENCODER_ABI_VERSION > 0x0202
// writer.mem must be freed by calling WebPMemoryWriterClear. // writer.mem must be freed by calling WebPMemoryWriterClear.
#else
// writer.mem must be freed by calling 'free(writer.mem)'.
#endif
WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size, WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
const WebPPicture* picture); const WebPPicture* picture);