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

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

Issue 116213006: Update libwebp to 0.4.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: After Blink Roll Created 6 years, 11 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
« no previous file with comments | « third_party/libwebp/dec/frame.c ('k') | third_party/libwebp/dec/io.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/libwebp/dec/idec.c
diff --git a/third_party/libwebp/dec/idec.c b/third_party/libwebp/dec/idec.c
index 61635ec99c47987648a8af965c02ace9de7f4ed8..40d5ff6e0d3d855ad71ee9000b9c92260baefbe4 100644
--- a/third_party/libwebp/dec/idec.c
+++ b/third_party/libwebp/dec/idec.c
@@ -15,14 +15,11 @@
#include <string.h>
#include <stdlib.h>
+#include "./alphai.h"
#include "./webpi.h"
#include "./vp8i.h"
#include "../utils/utils.h"
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
// In append mode, buffer allocations increase as multiples of this value.
// Needs to be a power of 2.
#define CHUNK_SIZE 4096
@@ -31,11 +28,13 @@ extern "C" {
//------------------------------------------------------------------------------
// Data structures for memory and states
-// Decoding states. State normally flows like HEADER->PARTS0->DATA->DONE.
+// Decoding states. State normally flows as:
+// WEBP_HEADER->VP8_HEADER->VP8_PARTS0->VP8_DATA->DONE for a lossy image, and
+// WEBP_HEADER->VP8L_HEADER->VP8L_DATA->DONE for a lossless image.
// If there is any error the decoder goes into state ERROR.
typedef enum {
- STATE_PRE_VP8, // All data before that of the first VP8 chunk.
- STATE_VP8_FRAME_HEADER, // For VP8 Frame header (within VP8 chunk).
+ STATE_WEBP_HEADER, // All the data before that of the VP8/VP8L chunk.
+ STATE_VP8_HEADER, // The VP8 Frame header (within the VP8 chunk).
STATE_VP8_PARTS0,
STATE_VP8_DATA,
STATE_VP8L_HEADER,
@@ -102,7 +101,7 @@ static WEBP_INLINE size_t MemDataSize(const MemBuffer* mem) {
// Check if we need to preserve the compressed alpha data, as it may not have
// been decoded yet.
static int NeedCompressedAlpha(const WebPIDecoder* const idec) {
- if (idec->state_ == STATE_PRE_VP8) {
+ if (idec->state_ == STATE_WEBP_HEADER) {
// We haven't parsed the headers yet, so we don't know whether the image is
// lossy or lossless. This also means that we haven't parsed the ALPH chunk.
return 0;
@@ -111,7 +110,7 @@ static int NeedCompressedAlpha(const WebPIDecoder* const idec) {
return 0; // ALPH chunk is not present for lossless images.
} else {
const VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
- assert(dec != NULL); // Must be true as idec->state_ != STATE_PRE_VP8.
+ assert(dec != NULL); // Must be true as idec->state_ != STATE_WEBP_HEADER.
return (dec->alpha_data_ != NULL) && !dec->is_alpha_decoded_;
}
}
@@ -141,7 +140,22 @@ static void DoRemap(WebPIDecoder* const idec, ptrdiff_t offset) {
}
assert(last_part >= 0);
dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_;
- if (NeedCompressedAlpha(idec)) dec->alpha_data_ += offset;
+ if (NeedCompressedAlpha(idec)) {
+ ALPHDecoder* const alph_dec = dec->alph_dec_;
+ dec->alpha_data_ += offset;
+ if (alph_dec != NULL) {
+ if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
+ VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
+ assert(alph_vp8l_dec != NULL);
+ assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
+ VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
+ dec->alpha_data_ + ALPHA_HEADER_LEN,
+ dec->alpha_data_size_ - ALPHA_HEADER_LEN);
+ } else { // alph_dec->method_ == ALPHA_NO_COMPRESSION
+ // Nothing special to do in this case.
+ }
+ }
+ }
} else { // Resize lossless bitreader
VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
VP8LBitReaderSetBuffer(&dec->br_, new_base, MemDataSize(mem));
@@ -268,7 +282,7 @@ static void RestoreContext(const MBContext* context, VP8Decoder* const dec,
static VP8StatusCode IDecError(WebPIDecoder* const idec, VP8StatusCode error) {
if (idec->state_ == STATE_VP8_DATA) {
VP8Io* const io = &idec->io_;
- if (io->teardown) {
+ if (io->teardown != NULL) {
io->teardown(io);
}
}
@@ -311,15 +325,9 @@ static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
return VP8_STATUS_OUT_OF_MEMORY;
}
idec->dec_ = dec;
-#ifdef WEBP_USE_THREAD
- dec->use_threads_ = (idec->params_.options != NULL) &&
- (idec->params_.options->use_threads > 0);
-#else
- dec->use_threads_ = 0;
-#endif
dec->alpha_data_ = headers.alpha_data;
dec->alpha_data_size_ = headers.alpha_data_size;
- ChangeState(idec, STATE_VP8_FRAME_HEADER, headers.offset);
+ ChangeState(idec, STATE_VP8_HEADER, headers.offset);
} else {
VP8LDecoder* const dec = VP8LNew();
if (dec == NULL) {
@@ -334,13 +342,14 @@ static VP8StatusCode DecodeWebPHeaders(WebPIDecoder* const idec) {
static VP8StatusCode DecodeVP8FrameHeader(WebPIDecoder* const idec) {
const uint8_t* data = idec->mem_.buf_ + idec->mem_.start_;
const size_t curr_size = MemDataSize(&idec->mem_);
+ int width, height;
uint32_t bits;
if (curr_size < VP8_FRAME_HEADER_SIZE) {
// Not enough data bytes to extract VP8 Frame Header.
return VP8_STATUS_SUSPENDED;
}
- if (!VP8GetInfo(data, curr_size, idec->chunk_size_, NULL, NULL)) {
+ if (!VP8GetInfo(data, curr_size, idec->chunk_size_, &width, &height)) {
return IDecError(idec, VP8_STATUS_BITSTREAM_ERROR);
}
@@ -407,7 +416,10 @@ static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
if (dec->status_ != VP8_STATUS_OK) {
return IDecError(idec, dec->status_);
}
-
+ // This change must be done before calling VP8InitFrame()
+ dec->mt_method_ = VP8GetThreadMethod(params->options, NULL,
+ io->width, io->height);
+ VP8InitDithering(params->options, dec);
if (!CopyParts0Data(idec)) {
return IDecError(idec, VP8_STATUS_OUT_OF_MEMORY);
}
@@ -433,16 +445,11 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
VP8Io* const io = &idec->io_;
assert(dec->ready_);
-
for (; dec->mb_y_ < dec->mb_h_; ++dec->mb_y_) {
VP8BitReader* token_br = &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
- if (dec->mb_x_ == 0) {
- VP8InitScanline(dec);
- }
- for (; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) {
+ for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
MBContext context;
SaveContext(dec, token_br, &context);
-
if (!VP8DecodeMB(dec, token_br)) {
RestoreContext(&context, dec, token_br);
// We shouldn't fail when MAX_MB data was available
@@ -451,19 +458,18 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
}
return VP8_STATUS_SUSPENDED;
}
- // Reconstruct and emit samples.
- VP8ReconstructBlock(dec);
-
// Release buffer only if there is only one partition
if (dec->num_parts_ == 1) {
idec->mem_.start_ = token_br->buf_ - idec->mem_.buf_;
assert(idec->mem_.start_ <= idec->mem_.end_);
}
}
+ VP8InitScanline(dec); // Prepare for next scanline
+
+ // Reconstruct, filter and emit the row.
if (!VP8ProcessRow(dec, io)) {
return IDecError(idec, VP8_STATUS_USER_ABORT);
}
- dec->mb_x_ = 0;
}
// Synchronize the thread and check for errors.
if (!VP8ExitCritical(dec, io)) {
@@ -475,7 +481,8 @@ static VP8StatusCode DecodeRemaining(WebPIDecoder* const idec) {
return VP8_STATUS_OK;
}
-static int ErrorStatusLossless(WebPIDecoder* const idec, VP8StatusCode status) {
+static VP8StatusCode ErrorStatusLossless(WebPIDecoder* const idec,
+ VP8StatusCode status) {
if (status == VP8_STATUS_SUSPENDED || status == VP8_STATUS_NOT_ENOUGH_DATA) {
return VP8_STATUS_SUSPENDED;
}
@@ -532,14 +539,14 @@ static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) {
static VP8StatusCode IDecode(WebPIDecoder* idec) {
VP8StatusCode status = VP8_STATUS_SUSPENDED;
- if (idec->state_ == STATE_PRE_VP8) {
+ if (idec->state_ == STATE_WEBP_HEADER) {
status = DecodeWebPHeaders(idec);
} else {
if (idec->dec_ == NULL) {
return VP8_STATUS_SUSPENDED; // can't continue if we have no decoder.
}
}
- if (idec->state_ == STATE_VP8_FRAME_HEADER) {
+ if (idec->state_ == STATE_VP8_HEADER) {
status = DecodeVP8FrameHeader(idec);
}
if (idec->state_ == STATE_VP8_PARTS0) {
@@ -566,7 +573,7 @@ WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
return NULL;
}
- idec->state_ = STATE_PRE_VP8;
+ idec->state_ = STATE_WEBP_HEADER;
idec->chunk_size_ = 0;
InitMemBuffer(&idec->mem_);
@@ -574,7 +581,8 @@ WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
VP8InitIo(&idec->io_);
WebPResetDecParams(&idec->params_);
- idec->params_.output = output_buffer ? output_buffer : &idec->output_;
+ idec->params_.output = (output_buffer != NULL) ? output_buffer
+ : &idec->output_;
WebPInitCustomIo(&idec->params_, &idec->io_); // Plug the I/O functions.
return idec;
@@ -608,11 +616,11 @@ void WebPIDelete(WebPIDecoder* idec) {
if (!idec->is_lossless_) {
if (idec->state_ == STATE_VP8_DATA) {
// Synchronize the thread, clean-up and check for errors.
- VP8ExitCritical(idec->dec_, &idec->io_);
+ VP8ExitCritical((VP8Decoder*)idec->dec_, &idec->io_);
}
- VP8Delete(idec->dec_);
+ VP8Delete((VP8Decoder*)idec->dec_);
} else {
- VP8LDelete(idec->dec_);
+ VP8LDelete((VP8LDecoder*)idec->dec_);
}
}
ClearMemBuffer(&idec->mem_);
@@ -827,7 +835,7 @@ int WebPISetIOHooks(WebPIDecoder* const idec,
VP8IoSetupHook setup,
VP8IoTeardownHook teardown,
void* user_data) {
- if (idec == NULL || idec->state_ > STATE_PRE_VP8) {
+ if (idec == NULL || idec->state_ > STATE_WEBP_HEADER) {
return 0;
}
@@ -839,6 +847,3 @@ int WebPISetIOHooks(WebPIDecoder* const idec,
return 1;
}
-#if defined(__cplusplus) || defined(c_plusplus)
-} // extern "C"
-#endif
« no previous file with comments | « third_party/libwebp/dec/frame.c ('k') | third_party/libwebp/dec/io.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698