mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01:00
* add an option to bypass_filtering in VP8Io.
This will make the decoder skip the filtering process if needed, resulting in speed-up, but also non-compliant (blocky?) output + Add a versioning check for VP8InitIo(), since we've adding a field to VP8Io + add some more error checks while at it Change-Id: I4e9899edc24ecf8600cbb27aa4038490b7b2cef3
This commit is contained in:
parent
b97a4003c0
commit
5b70b378bd
@ -20,10 +20,13 @@ static void SetOk(VP8Decoder* const dec) {
|
|||||||
dec->error_msg_ = "OK";
|
dec->error_msg_ = "OK";
|
||||||
}
|
}
|
||||||
|
|
||||||
void VP8InitIo(VP8Io* const io) {
|
int VP8InitIoInternal(VP8Io* const io, int version) {
|
||||||
|
if (version != WEBP_DECODER_ABI_VERSION)
|
||||||
|
return 0; // mismatch error
|
||||||
if (io) {
|
if (io) {
|
||||||
memset(io, 0, sizeof(*io));
|
memset(io, 0, sizeof(*io));
|
||||||
}
|
}
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
VP8Decoder* VP8New() {
|
VP8Decoder* VP8New() {
|
||||||
@ -100,7 +103,7 @@ static int ParseSegmentHeader(VP8BitReader* br,
|
|||||||
} else {
|
} else {
|
||||||
hdr->update_map_ = 0;
|
hdr->update_map_ = 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return !br->eof_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paragraph 9.5
|
// Paragraph 9.5
|
||||||
@ -170,7 +173,7 @@ static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
|
|||||||
dec->filter_levels_[0] = hdr->level_;
|
dec->filter_levels_[0] = hdr->level_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1;
|
return !br->eof_;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_le32(const uint8_t* const data) {
|
static inline uint32_t get_le32(const uint8_t* const data) {
|
||||||
@ -214,12 +217,16 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
|||||||
"RIFF: WEBP signature not found.");
|
"RIFF: WEBP signature not found.");
|
||||||
}
|
}
|
||||||
riff_size = get_le32(buf + 4);
|
riff_size = get_le32(buf + 4);
|
||||||
|
if (riff_size < 12) {
|
||||||
|
return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
|
||||||
|
"RIFF: Truncated header.");
|
||||||
|
}
|
||||||
if (memcmp(buf + 12, "VP8 ", 4)) {
|
if (memcmp(buf + 12, "VP8 ", 4)) {
|
||||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||||
"RIFF: Invalid compression format.");
|
"RIFF: Invalid compression format.");
|
||||||
}
|
}
|
||||||
chunk_size = get_le32(buf + 16);
|
chunk_size = get_le32(buf + 16);
|
||||||
if ((chunk_size > riff_size + 8) || (chunk_size & 1)) {
|
if (chunk_size > riff_size - 12) {
|
||||||
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||||
"RIFF: Inconsistent size information.");
|
"RIFF: Inconsistent size information.");
|
||||||
}
|
}
|
||||||
@ -235,6 +242,12 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
|
|||||||
frm_hdr->profile_ = (bits >> 1) & 7;
|
frm_hdr->profile_ = (bits >> 1) & 7;
|
||||||
frm_hdr->show_ = (bits >> 4) & 1;
|
frm_hdr->show_ = (bits >> 4) & 1;
|
||||||
frm_hdr->partition_length_ = (bits >> 5);
|
frm_hdr->partition_length_ = (bits >> 5);
|
||||||
|
if (frm_hdr->profile_ > 3)
|
||||||
|
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
|
||||||
|
"Incorrect keyframe parameters.");
|
||||||
|
if (!frm_hdr->show_)
|
||||||
|
return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
|
||||||
|
"Frame not displayable.");
|
||||||
buf += 3;
|
buf += 3;
|
||||||
buf_size -= 3;
|
buf_size -= 3;
|
||||||
}
|
}
|
||||||
@ -603,13 +616,15 @@ int VP8Decode(VP8Decoder* const dec, VP8Io* const io) {
|
|||||||
"Allocation failed");
|
"Allocation failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (io->setup && !io->setup(io)) {
|
if (io->setup && !io->setup(io)) {
|
||||||
VP8Clear(dec);
|
VP8Clear(dec);
|
||||||
return VP8SetError(dec, VP8_STATUS_USER_ABORT,
|
return VP8SetError(dec, VP8_STATUS_USER_ABORT,
|
||||||
"Frame setup failed");
|
"Frame setup failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable filtering per user request (_after_ setup() is called)
|
||||||
|
if (io->bypass_filtering) dec->filter_type_ = 0;
|
||||||
|
|
||||||
// Main decoding loop
|
// Main decoding loop
|
||||||
{
|
{
|
||||||
const int ret = ParseFrame(dec, io);
|
const int ret = ParseFrame(dec, io);
|
||||||
|
@ -18,6 +18,8 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define WEBP_DECODER_ABI_VERSION 0x0001
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Lower-level API
|
// Lower-level API
|
||||||
//
|
//
|
||||||
@ -72,16 +74,29 @@ struct VP8Io {
|
|||||||
// Input buffer.
|
// Input buffer.
|
||||||
uint32_t data_size;
|
uint32_t data_size;
|
||||||
const uint8_t* data;
|
const uint8_t* data;
|
||||||
|
|
||||||
|
// If true, in-loop filtering will not be performed even if present in the
|
||||||
|
// bitstream. Switching off filtering may speed up decoding at the expense
|
||||||
|
// of more visible blocking. Note that output will also be non-compliant
|
||||||
|
// with the VP8 specifications.
|
||||||
|
int bypass_filtering;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Internal, version-checked, entry point
|
||||||
|
extern int VP8InitIoInternal(VP8Io* const, int);
|
||||||
|
|
||||||
// Main decoding object. This is an opaque structure.
|
// Main decoding object. This is an opaque structure.
|
||||||
typedef struct VP8Decoder VP8Decoder;
|
typedef struct VP8Decoder VP8Decoder;
|
||||||
|
|
||||||
// Create a new decoder object.
|
// Create a new decoder object.
|
||||||
VP8Decoder* VP8New();
|
VP8Decoder* VP8New();
|
||||||
|
|
||||||
// Can be called to make sure 'io' is initialized properly.
|
// Must be called to make sure 'io' is initialized properly.
|
||||||
void VP8InitIo(VP8Io* const io);
|
// Returns false in case of version mismatch. Upon such failure, no other
|
||||||
|
// decoding function should be called (VP8Decode, VP8GetHeaders, ...)
|
||||||
|
static inline int VP8InitIo(VP8Io* const io) {
|
||||||
|
return VP8InitIoInternal(io, WEBP_DECODER_ABI_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
// Start decoding a new picture. Returns true if ok.
|
// Start decoding a new picture. Returns true if ok.
|
||||||
int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
|
int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io);
|
||||||
|
Loading…
Reference in New Issue
Block a user