Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(584)

Unified Diff: third_party/libwebp/dec/vp8.c

Issue 10832153: libwebp: update snapshot to v0.2.0-rc1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/libwebp/dec/vp8.c
diff --git a/third_party/libwebp/dec/vp8.c b/third_party/libwebp/dec/vp8.c
index 89b669aabad992cb178fa993d73aea6faa5d0b85..b0ccfa2a06d1ed73977324450b51bda12772b91d 100644
--- a/third_party/libwebp/dec/vp8.c
+++ b/third_party/libwebp/dec/vp8.c
@@ -1,4 +1,4 @@
-// Copyright 2010 Google Inc.
+// Copyright 2010 Google Inc. All Rights Reserved.
//
// This code is licensed under the same terms as WebM:
// Software License Agreement: http://www.webmproject.org/license/software/
@@ -10,8 +10,11 @@
// Author: Skal (pascal.massimino@gmail.com)
#include <stdlib.h>
-#include "vp8i.h"
-#include "webpi.h"
+
+#include "./vp8i.h"
+#include "./vp8li.h"
+#include "./webpi.h"
+#include "../utils/bit_reader.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
@@ -32,17 +35,18 @@ static void SetOk(VP8Decoder* const dec) {
}
int VP8InitIoInternal(VP8Io* const io, int version) {
- if (version != WEBP_DECODER_ABI_VERSION)
+ if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
return 0; // mismatch error
- if (io) {
+ }
+ if (io != NULL) {
memset(io, 0, sizeof(*io));
}
return 1;
}
VP8Decoder* VP8New(void) {
- VP8Decoder* dec = (VP8Decoder*)calloc(1, sizeof(VP8Decoder));
- if (dec) {
+ VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec));
+ if (dec != NULL) {
SetOk(dec);
WebPWorkerInit(&dec->worker_);
dec->ready_ = 0;
@@ -57,35 +61,46 @@ VP8StatusCode VP8Status(VP8Decoder* const dec) {
}
const char* VP8StatusMessage(VP8Decoder* const dec) {
- if (!dec) return "no object";
+ if (dec == NULL) return "no object";
if (!dec->error_msg_) return "OK";
return dec->error_msg_;
}
void VP8Delete(VP8Decoder* const dec) {
- if (dec) {
+ if (dec != NULL) {
VP8Clear(dec);
free(dec);
}
}
int VP8SetError(VP8Decoder* const dec,
- VP8StatusCode error, const char * const msg) {
- dec->status_ = error;
- dec->error_msg_ = msg;
- dec->ready_ = 0;
+ VP8StatusCode error, const char* const msg) {
+ // TODO This check would be unnecessary if alpha decompression was separated
+ // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to
+ // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression
+ // failure.
+ if (dec->status_ == VP8_STATUS_OK) {
+ dec->status_ = error;
+ dec->error_msg_ = msg;
+ dec->ready_ = 0;
+ }
return 0;
}
//------------------------------------------------------------------------------
-int VP8GetInfo(const uint8_t* data, uint32_t data_size, uint32_t chunk_size,
- int* width, int* height, int* has_alpha) {
- if (data_size < 10) {
+int VP8CheckSignature(const uint8_t* const data, size_t data_size) {
+ return (data_size >= 3 &&
+ data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a);
+}
+
+int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
+ int* const width, int* const height) {
+ if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) {
return 0; // not enough data
}
// check signature
- if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) {
+ if (!VP8CheckSignature(data + 3, data_size - 3)) {
return 0; // Wrong signature.
} else {
const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16);
@@ -93,14 +108,6 @@ int VP8GetInfo(const uint8_t* data, uint32_t data_size, uint32_t chunk_size,
const int w = ((data[7] << 8) | data[6]) & 0x3fff;
const int h = ((data[9] << 8) | data[8]) & 0x3fff;
- if (has_alpha) {
-#ifdef WEBP_EXPERIMENTAL_FEATURES
- if (data_size < 11) return 0;
- *has_alpha = !!(data[10] & 0x80); // the colorspace_ bit
-#else
- *has_alpha = 0;
-#endif
- }
if (!key_frame) { // Not a keyframe.
return 0;
}
@@ -130,7 +137,7 @@ int VP8GetInfo(const uint8_t* data, uint32_t data_size, uint32_t chunk_size,
// Header parsing
static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
- assert(hdr);
+ assert(hdr != NULL);
hdr->use_segment_ = 0;
hdr->update_map_ = 0;
hdr->absolute_delta_ = 1;
@@ -141,8 +148,8 @@ static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
// Paragraph 9.3
static int ParseSegmentHeader(VP8BitReader* br,
VP8SegmentHeader* hdr, VP8Proba* proba) {
- assert(br);
- assert(hdr);
+ assert(br != NULL);
+ assert(hdr != NULL);
hdr->use_segment_ = VP8Get(br);
if (hdr->use_segment_) {
hdr->update_map_ = VP8Get(br);
@@ -178,7 +185,7 @@ static int ParseSegmentHeader(VP8BitReader* br,
// is returned, and this is an unrecoverable error.
// If the partitions were positioned ok, VP8_STATUS_OK is returned.
static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
- const uint8_t* buf, uint32_t size) {
+ const uint8_t* buf, size_t size) {
VP8BitReader* const br = &dec->br_;
const uint8_t* sz = buf;
const uint8_t* buf_end = buf + size;
@@ -249,13 +256,12 @@ static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) {
// Topmost call
int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
const uint8_t* buf;
- uint32_t buf_size;
- uint32_t vp8_chunk_size;
- uint32_t bytes_skipped;
+ size_t buf_size;
VP8FrameHeader* frm_hdr;
VP8PictureHeader* pic_hdr;
VP8BitReader* br;
VP8StatusCode status;
+ WebPHeaderStructure headers;
if (dec == NULL) {
return 0;
@@ -266,16 +272,32 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
"null VP8Io passed to VP8GetHeaders()");
}
- buf = io->data;
- buf_size = io->data_size;
-
// Process Pre-VP8 chunks.
- status = WebPParseHeaders(&buf, &buf_size, &vp8_chunk_size, &bytes_skipped);
+ headers.data = io->data;
+ headers.data_size = io->data_size;
+ status = WebPParseHeaders(&headers);
if (status != VP8_STATUS_OK) {
return VP8SetError(dec, status, "Incorrect/incomplete header.");
}
+ if (headers.is_lossless) {
+ return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
+ "Unexpected lossless format encountered.");
+ }
+
+ if (dec->alpha_data_ == NULL) {
+ assert(dec->alpha_data_size_ == 0);
+ // We have NOT set alpha data yet. Set it now.
+ // (This is to ensure that dec->alpha_data_ is NOT reset to NULL if
+ // WebPParseHeaders() is called more than once, as in incremental decoding
+ // case.)
+ dec->alpha_data_ = headers.alpha_data;
+ dec->alpha_data_size_ = headers.alpha_data_size;
+ }
// Process the VP8 frame header.
+ buf = headers.data + headers.offset;
+ buf_size = headers.data_size - headers.offset;
+ assert(headers.data_size >= headers.offset); // WebPParseHeaders' guarantee
if (buf_size < 4) {
return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
"Truncated header.");
@@ -306,7 +328,7 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
"cannot parse picture header");
}
- if (buf[0] != 0x9d || buf[1] != 0x01 || buf[2] != 0x2a) {
+ if (!VP8CheckSignature(buf, buf_size)) {
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
"Bad code word");
}
@@ -343,9 +365,6 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
"bad partition length");
}
- dec->alpha_data_ = NULL;
- dec->alpha_data_size_ = 0;
-
br = &dec->br_;
VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_);
buf += frm_hdr->partition_length_;
@@ -419,17 +438,9 @@ int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
if (frm_hdr->partition_length_ < kTrailerSize ||
ext_buf[kTrailerSize - 1] != kTrailerMarker) {
- Error:
return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
"RIFF: Inconsistent extra information.");
}
- // Alpha
- size = (ext_buf[4] << 0) | (ext_buf[5] << 8) | (ext_buf[6] << 16);
- if (frm_hdr->partition_length_ < size + kTrailerSize) {
- goto Error;
- }
- dec->alpha_data_ = (size > 0) ? ext_buf - size : NULL;
- dec->alpha_data_size_ = size;
// Layer
size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16);
@@ -467,8 +478,9 @@ typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting
// Returns the position of the last non-zero coeff plus one
// (and 0 if there's no coeff at all)
static int GetCoeffs(VP8BitReader* const br, ProbaArray prob,
- int ctx, const uint16_t dq[2], int n, int16_t* out) {
- const uint8_t* p = prob[kBands[n]][ctx];
+ int ctx, const quant_t dq, int n, int16_t* out) {
+ // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'.
+ const uint8_t* p = prob[n][ctx];
if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit.
return 0;
}
@@ -749,7 +761,7 @@ int VP8Decode(VP8Decoder* const dec, VP8Io* const io) {
}
dec->ready_ = 0;
- return 1;
+ return ok;
}
void VP8Clear(VP8Decoder* const dec) {

Powered by Google App Engine
This is Rietveld 408576698