example_util: add ExUtilDecodeWebPIncremental

simplifies ExUtilDecodeWebP() call

Change-Id: I33b42ec1c398b9fc0a895ad9deb89ab01a33b3da
This commit is contained in:
James Zern 2014-04-26 14:26:13 -07:00 committed by Pascal Massimino
parent 8e5f90b086
commit 1b2fe14de5
4 changed files with 53 additions and 23 deletions

View File

@ -706,7 +706,11 @@ int main(int argc, const char *argv[]) {
return -1; return -1;
} }
status = ExUtilDecodeWebP(data, data_size, incremental, verbose, &config); if (incremental) {
status = ExUtilDecodeWebPIncremental(data, data_size, verbose, &config);
} else {
status = ExUtilDecodeWebP(data, data_size, verbose, &config);
}
End: End:
free((void*)data); free((void*)data);
ok = (status == VP8_STATUS_OK); ok = (status == VP8_STATUS_OK);

View File

@ -118,6 +118,15 @@ static const char* const kStatusMessages[] = {
"UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
}; };
static void PrintAnimationWarning(const WebPDecoderConfig* const config) {
if (config->input.has_animation) {
fprintf(stderr,
"Error! Decoding of an animated WebP file is not supported.\n"
" Use webpmux to extract the individual frames or\n"
" vwebp to view this image.\n");
}
}
void ExUtilPrintWebPError(const char* const in_file, int status) { void ExUtilPrintWebPError(const char* const in_file, int status) {
fprintf(stderr, "Decoding of %s failed.\n", in_file); fprintf(stderr, "Decoding of %s failed.\n", in_file);
fprintf(stderr, "Status: %d", status); fprintf(stderr, "Status: %d", status);
@ -149,28 +158,41 @@ int ExUtilLoadWebP(const char* const in_file,
return 1; return 1;
} }
//------------------------------------------------------------------------------
VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size, VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size,
int incremental, int verbose, int verbose, WebPDecoderConfig* const config) {
WebPDecoderConfig* const config) {
Stopwatch stop_watch; Stopwatch stop_watch;
VP8StatusCode status = VP8_STATUS_OK; VP8StatusCode status = VP8_STATUS_OK;
if (config == NULL) return 0; if (config == NULL) return VP8_STATUS_INVALID_PARAM;
PrintAnimationWarning(config);
if (verbose) {
StopwatchReset(&stop_watch); StopwatchReset(&stop_watch);
}
if (config->input.has_animation) {
fprintf(stderr,
"Error! Decoding of an animated WebP file is not supported.\n"
" Use webpmux to extract the individual frames or\n"
" vwebp to view this image.\n");
}
// Decoding call. // Decoding call.
if (!incremental) {
status = WebPDecode(data, data_size, config); status = WebPDecode(data, data_size, config);
} else {
if (verbose) {
const double decode_time = StopwatchReadAndReset(&stop_watch);
fprintf(stderr, "Time to decode picture: %.3fs\n", decode_time);
}
return status;
}
VP8StatusCode ExUtilDecodeWebPIncremental(
const uint8_t* const data, size_t data_size,
int verbose, WebPDecoderConfig* const config) {
Stopwatch stop_watch;
VP8StatusCode status = VP8_STATUS_OK;
if (config == NULL) return VP8_STATUS_INVALID_PARAM;
PrintAnimationWarning(config);
StopwatchReset(&stop_watch);
// Decoding call.
{
WebPIDecoder* const idec = WebPIDecode(data, data_size, config); WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
if (idec == NULL) { if (idec == NULL) {
fprintf(stderr, "Failed during WebPINewDecoder().\n"); fprintf(stderr, "Failed during WebPINewDecoder().\n");

View File

@ -53,17 +53,21 @@ int ExUtilLoadWebP(const char* const in_file,
const uint8_t** data, size_t* data_size, const uint8_t** data, size_t* data_size,
struct WebPBitstreamFeatures* bitstream); struct WebPBitstreamFeatures* bitstream);
// Decodes the WebP contained in 'data'. 'config' is a structure previously // Decodes the WebP contained in 'data'.
// initialized by WebPInitDecoderConfig(). 'config->output' should have the // 'config' is a structure previously initialized by WebPInitDecoderConfig().
// desired colorspace selected. If 'incremental' is set to true the WebP // 'config->output' should have the desired colorspace selected. 'verbose' will
// incremental decoder will be used. 'verbose' will cause decode timing to be // cause decode timing to be reported.
// reported.
// Returns the decoder status. On success 'config->output' will contain the // Returns the decoder status. On success 'config->output' will contain the
// decoded picture. // decoded picture.
enum VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size, enum VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size,
int incremental, int verbose, int verbose,
struct WebPDecoderConfig* const config); struct WebPDecoderConfig* const config);
// Same as ExUtilDecodeWebP(), but using the incremental decoder.
enum VP8StatusCode ExUtilDecodeWebPIncremental(
const uint8_t* const data, size_t data_size,
int verbose, struct WebPDecoderConfig* const config);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

View File

@ -43,7 +43,7 @@ int ReadWebP(const char* const in_file, WebPPicture* const pic,
const int has_alpha = keep_alpha && bitstream->has_alpha; const int has_alpha = keep_alpha && bitstream->has_alpha;
output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB; output_buffer->colorspace = has_alpha ? MODE_RGBA : MODE_RGB;
status = ExUtilDecodeWebP(data, data_size, 0, 0, &config); status = ExUtilDecodeWebP(data, data_size, 0, &config);
if (status == VP8_STATUS_OK) { if (status == VP8_STATUS_OK) {
const uint8_t* const rgba = output_buffer->u.RGBA.rgba; const uint8_t* const rgba = output_buffer->u.RGBA.rgba;
const int stride = output_buffer->u.RGBA.stride; const int stride = output_buffer->u.RGBA.stride;