mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 12:28:26 +01:00
Merge "dwebp: move webp decoding to example_util"
This commit is contained in:
commit
9c0a60ccb3
@ -14,7 +14,7 @@ endif
|
|||||||
|
|
||||||
noinst_LTLIBRARIES = libexampleutil.la
|
noinst_LTLIBRARIES = libexampleutil.la
|
||||||
|
|
||||||
libexampleutil_la_SOURCES = example_util.c example_util.h
|
libexampleutil_la_SOURCES = example_util.c example_util.h stopwatch.h
|
||||||
|
|
||||||
dwebp_SOURCES = dwebp.c stopwatch.h
|
dwebp_SOURCES = dwebp.c stopwatch.h
|
||||||
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
dwebp_CPPFLAGS = $(AM_CPPFLAGS) $(USE_EXPERIMENTAL_CODE)
|
||||||
|
@ -571,11 +571,6 @@ static void Help(void) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* const kStatusMessages[] = {
|
|
||||||
"OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR",
|
|
||||||
"UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char* const kFormatType[] = {
|
static const char* const kFormatType[] = {
|
||||||
"unspecified", "lossy", "lossless"
|
"unspecified", "lossy", "lossless"
|
||||||
};
|
};
|
||||||
@ -671,27 +666,11 @@ int main(int argc, const char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
Stopwatch stop_watch;
|
|
||||||
VP8StatusCode status = VP8_STATUS_OK;
|
VP8StatusCode status = VP8_STATUS_OK;
|
||||||
size_t data_size = 0;
|
size_t data_size = 0;
|
||||||
const uint8_t* data = NULL;
|
const uint8_t* data = NULL;
|
||||||
|
if (!ExUtilLoadWebP(in_file, &data, &data_size, bitstream)) {
|
||||||
if (!ExUtilReadFile(in_file, &data, &data_size)) return -1;
|
goto End;
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
StopwatchReset(&stop_watch);
|
|
||||||
}
|
|
||||||
|
|
||||||
status = WebPGetFeatures(data, data_size, bitstream);
|
|
||||||
if (status != VP8_STATUS_OK) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bitstream->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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format) {
|
switch (format) {
|
||||||
@ -727,31 +706,12 @@ int main(int argc, const char *argv[]) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decoding call.
|
status = ExUtilDecodeWebP(data, data_size, incremental, verbose, &config);
|
||||||
if (!incremental) {
|
End:
|
||||||
status = WebPDecode(data, data_size, &config);
|
|
||||||
} else {
|
|
||||||
WebPIDecoder* const idec = WebPIDecode(data, data_size, &config);
|
|
||||||
if (idec == NULL) {
|
|
||||||
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
|
||||||
status = VP8_STATUS_OUT_OF_MEMORY;
|
|
||||||
goto end;
|
|
||||||
} else {
|
|
||||||
status = WebPIUpdate(idec, data, data_size);
|
|
||||||
WebPIDelete(idec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose) {
|
|
||||||
const double decode_time = StopwatchReadAndReset(&stop_watch);
|
|
||||||
fprintf(stderr, "Time to decode picture: %.3fs\n", decode_time);
|
|
||||||
}
|
|
||||||
end:
|
|
||||||
free((void*)data);
|
free((void*)data);
|
||||||
ok = (status == VP8_STATUS_OK);
|
ok = (status == VP8_STATUS_OK);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
fprintf(stderr, "Decoding of %s failed.\n", in_file);
|
ExUtilPrintWebPError(in_file, status);
|
||||||
fprintf(stderr, "Status: %d (%s)\n", status, kStatusMessages[status]);
|
|
||||||
goto Exit;
|
goto Exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,9 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "webp/decode.h"
|
||||||
|
#include "./stopwatch.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// File I/O
|
// File I/O
|
||||||
|
|
||||||
@ -107,3 +110,77 @@ int ExUtilWriteFile(const char* const file_name,
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// WebP decoding
|
||||||
|
|
||||||
|
static const char* const kStatusMessages[] = {
|
||||||
|
"OK", "OUT_OF_MEMORY", "INVALID_PARAM", "BITSTREAM_ERROR",
|
||||||
|
"UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
|
||||||
|
};
|
||||||
|
|
||||||
|
void ExUtilPrintWebPError(const char* const in_file, int status) {
|
||||||
|
fprintf(stderr, "Decoding of %s failed.\n", in_file);
|
||||||
|
fprintf(stderr, "Status: %d", status);
|
||||||
|
if (status >= VP8_STATUS_OK && status <= VP8_STATUS_NOT_ENOUGH_DATA) {
|
||||||
|
fprintf(stderr, "(%s)", kStatusMessages[status]);
|
||||||
|
}
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int ExUtilLoadWebP(const char* const in_file,
|
||||||
|
const uint8_t** data, size_t* data_size,
|
||||||
|
WebPBitstreamFeatures* bitstream) {
|
||||||
|
VP8StatusCode status;
|
||||||
|
if (!ExUtilReadFile(in_file, data, data_size)) return 0;
|
||||||
|
|
||||||
|
status = WebPGetFeatures(*data, *data_size, bitstream);
|
||||||
|
if (status != VP8_STATUS_OK) {
|
||||||
|
free((void*)*data);
|
||||||
|
*data = NULL;
|
||||||
|
*data_size = 0;
|
||||||
|
ExUtilPrintWebPError(in_file, status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size,
|
||||||
|
int incremental, int verbose,
|
||||||
|
WebPDecoderConfig* const config) {
|
||||||
|
Stopwatch stop_watch;
|
||||||
|
VP8StatusCode status = VP8_STATUS_OK;
|
||||||
|
if (config == NULL) return 0;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
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.
|
||||||
|
if (!incremental) {
|
||||||
|
status = WebPDecode(data, data_size, config);
|
||||||
|
} else {
|
||||||
|
WebPIDecoder* const idec = WebPIDecode(data, data_size, config);
|
||||||
|
if (idec == NULL) {
|
||||||
|
fprintf(stderr, "Failed during WebPINewDecoder().\n");
|
||||||
|
return VP8_STATUS_OUT_OF_MEMORY;
|
||||||
|
} else {
|
||||||
|
status = WebPIUpdate(idec, data, data_size);
|
||||||
|
WebPIDelete(idec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
const double decode_time = StopwatchReadAndReset(&stop_watch);
|
||||||
|
fprintf(stderr, "Time to decode picture: %.3fs\n", decode_time);
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -19,6 +19,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct WebPDecoderConfig;
|
||||||
|
struct WebPBitstreamFeatures;
|
||||||
|
|
||||||
// Allocates storage for entire file 'file_name' and returns contents and size
|
// Allocates storage for entire file 'file_name' and returns contents and size
|
||||||
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
// in 'data' and 'data_size'. Returns 1 on success, 0 otherwise. '*data' should
|
||||||
// be deleted using free().
|
// be deleted using free().
|
||||||
@ -35,6 +38,32 @@ int ExUtilReadFromStdin(const uint8_t** data, size_t* data_size);
|
|||||||
int ExUtilWriteFile(const char* const file_name,
|
int ExUtilWriteFile(const char* const file_name,
|
||||||
const uint8_t* data, size_t data_size);
|
const uint8_t* data, size_t data_size);
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// WebP decoding
|
||||||
|
|
||||||
|
// Prints an informative error message regarding decode failure of 'in_file'.
|
||||||
|
// 'status' is treated as a VP8StatusCode and if valid will be printed as a
|
||||||
|
// text string.
|
||||||
|
void ExUtilPrintWebPError(const char* const in_file, int status);
|
||||||
|
|
||||||
|
// Reads a WebP from 'in_file', returning the contents and size in 'data' and
|
||||||
|
// 'data_size'. 'bitstream' is populated using WebPGetFeatures().
|
||||||
|
// Returns true on success.
|
||||||
|
int ExUtilLoadWebP(const char* const in_file,
|
||||||
|
const uint8_t** data, size_t* data_size,
|
||||||
|
struct WebPBitstreamFeatures* bitstream);
|
||||||
|
|
||||||
|
// Decodes the WebP contained in 'data'. 'config' is a structure previously
|
||||||
|
// initialized by WebPInitDecoderConfig(). 'config->output' should have the
|
||||||
|
// desired colorspace selected. If 'incremental' is set to true the WebP
|
||||||
|
// incremental decoder will be used. 'verbose' will cause decode timing to be
|
||||||
|
// reported.
|
||||||
|
// Returns the decoder status. On success 'config->output' will contain the
|
||||||
|
// decoded picture.
|
||||||
|
enum VP8StatusCode ExUtilDecodeWebP(const uint8_t* const data, size_t data_size,
|
||||||
|
int incremental, int verbose,
|
||||||
|
struct WebPDecoderConfig* const config);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user