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

Unified Diff: third_party/libwebp/dec/alpha.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/README.chromium ('k') | third_party/libwebp/dec/alphai.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/libwebp/dec/alpha.c
diff --git a/third_party/libwebp/dec/alpha.c b/third_party/libwebp/dec/alpha.c
index b5e68919ca699b237b70588e3aa034f0150fa3d8..93729a035f1897290098656a3c42e17277a45ac7 100644
--- a/third_party/libwebp/dec/alpha.c
+++ b/third_party/libwebp/dec/alpha.c
@@ -12,104 +12,150 @@
// Author: Skal (pascal.massimino@gmail.com)
#include <stdlib.h>
+#include "./alphai.h"
#include "./vp8i.h"
#include "./vp8li.h"
-#include "../utils/filters.h"
#include "../utils/quant_levels_dec.h"
#include "../webp/format_constants.h"
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
+//------------------------------------------------------------------------------
+// ALPHDecoder object.
+
+ALPHDecoder* ALPHNew(void) {
+ ALPHDecoder* const dec = (ALPHDecoder*)calloc(1, sizeof(*dec));
+ return dec;
+}
+
+void ALPHDelete(ALPHDecoder* const dec) {
+ if (dec != NULL) {
+ VP8LDelete(dec->vp8l_dec_);
+ dec->vp8l_dec_ = NULL;
+ free(dec);
+ }
+}
//------------------------------------------------------------------------------
-// Decodes the compressed data 'data' of size 'data_size' into the 'output'.
-// The 'output' buffer should be pre-allocated and must be of the same
-// dimension 'height'x'width', as that of the image.
-//
-// Returns 1 on successfully decoding the compressed alpha and
-// 0 if either:
-// error in bit-stream header (invalid compression mode or filter), or
-// error returned by appropriate compression method.
-
-static int DecodeAlpha(const uint8_t* data, size_t data_size,
- int width, int height, uint8_t* output) {
- WEBP_FILTER_TYPE filter;
- int pre_processing;
- int rsrv;
+// Decoding.
+
+// Initialize alpha decoding by parsing the alpha header and decoding the image
+// header for alpha data stored using lossless compression.
+// Returns false in case of error in alpha header (data too short, invalid
+// compression method or filter, error in lossless header data etc).
+static int ALPHInit(ALPHDecoder* const dec, const uint8_t* data,
+ size_t data_size, int width, int height, uint8_t* output) {
int ok = 0;
- int method;
const uint8_t* const alpha_data = data + ALPHA_HEADER_LEN;
const size_t alpha_data_size = data_size - ALPHA_HEADER_LEN;
+ int rsrv;
assert(width > 0 && height > 0);
assert(data != NULL && output != NULL);
+ dec->width_ = width;
+ dec->height_ = height;
+
if (data_size <= ALPHA_HEADER_LEN) {
return 0;
}
- method = (data[0] >> 0) & 0x03;
- filter = (data[0] >> 2) & 0x03;
- pre_processing = (data[0] >> 4) & 0x03;
+ dec->method_ = (data[0] >> 0) & 0x03;
+ dec->filter_ = (data[0] >> 2) & 0x03;
+ dec->pre_processing_ = (data[0] >> 4) & 0x03;
rsrv = (data[0] >> 6) & 0x03;
- if (method < ALPHA_NO_COMPRESSION ||
- method > ALPHA_LOSSLESS_COMPRESSION ||
- filter >= WEBP_FILTER_LAST ||
- pre_processing > ALPHA_PREPROCESSED_LEVELS ||
+ if (dec->method_ < ALPHA_NO_COMPRESSION ||
+ dec->method_ > ALPHA_LOSSLESS_COMPRESSION ||
+ dec->filter_ >= WEBP_FILTER_LAST ||
+ dec->pre_processing_ > ALPHA_PREPROCESSED_LEVELS ||
rsrv != 0) {
return 0;
}
- if (method == ALPHA_NO_COMPRESSION) {
- const size_t alpha_decoded_size = height * width;
+ if (dec->method_ == ALPHA_NO_COMPRESSION) {
+ const size_t alpha_decoded_size = dec->width_ * dec->height_;
ok = (alpha_data_size >= alpha_decoded_size);
- if (ok) memcpy(output, alpha_data, alpha_decoded_size);
} else {
- ok = VP8LDecodeAlphaImageStream(width, height, alpha_data, alpha_data_size,
- output);
+ assert(dec->method_ == ALPHA_LOSSLESS_COMPRESSION);
+ ok = VP8LDecodeAlphaHeader(dec, alpha_data, alpha_data_size, output);
}
+ return ok;
+}
- if (ok) {
- WebPUnfilterFunc unfilter_func = WebPUnfilters[filter];
- if (unfilter_func != NULL) {
- // TODO(vikas): Implement on-the-fly decoding & filter mechanism to decode
- // and apply filter per image-row.
- unfilter_func(width, height, width, output);
+// Decodes, unfilters and dequantizes *at least* 'num_rows' rows of alpha
+// starting from row number 'row'. It assumes that rows up to (row - 1) have
+// already been decoded.
+// Returns false in case of bitstream error.
+static int ALPHDecode(VP8Decoder* const dec, int row, int num_rows) {
+ ALPHDecoder* const alph_dec = dec->alph_dec_;
+ const int width = alph_dec->width_;
+ const int height = alph_dec->height_;
+ WebPUnfilterFunc unfilter_func = WebPUnfilters[alph_dec->filter_];
+ uint8_t* const output = dec->alpha_plane_;
+ if (alph_dec->method_ == ALPHA_NO_COMPRESSION) {
+ const size_t offset = row * width;
+ const size_t num_pixels = num_rows * width;
+ assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN + offset + num_pixels);
+ memcpy(dec->alpha_plane_ + offset,
+ dec->alpha_data_ + ALPHA_HEADER_LEN + offset, num_pixels);
+ } else { // alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION
+ assert(alph_dec->vp8l_dec_ != NULL);
+ if (!VP8LDecodeAlphaImageStream(alph_dec, row + num_rows)) {
+ return 0;
}
- if (pre_processing == ALPHA_PREPROCESSED_LEVELS) {
- ok = DequantizeLevels(output, width, height);
+ }
+
+ if (unfilter_func != NULL) {
+ unfilter_func(width, height, width, row, num_rows, output);
+ }
+
+ if (alph_dec->pre_processing_ == ALPHA_PREPROCESSED_LEVELS) {
+ if (!DequantizeLevels(output, width, height, row, num_rows)) {
+ return 0;
}
}
- return ok;
+ if (row + num_rows == dec->pic_hdr_.height_) {
+ dec->is_alpha_decoded_ = 1;
+ }
+ return 1;
}
//------------------------------------------------------------------------------
+// Main entry point.
const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
int row, int num_rows) {
const int width = dec->pic_hdr_.width_;
const int height = dec->pic_hdr_.height_;
- if (row < 0 || num_rows < 0 || row + num_rows > height) {
+ if (row < 0 || num_rows <= 0 || row + num_rows > height) {
return NULL; // sanity check.
}
if (row == 0) {
- // Decode everything during the first call.
- assert(!dec->is_alpha_decoded_);
- if (!DecodeAlpha(dec->alpha_data_, (size_t)dec->alpha_data_size_,
- width, height, dec->alpha_plane_)) {
- return NULL; // Error.
+ // Initialize decoding.
+ assert(dec->alpha_plane_ != NULL);
+ dec->alph_dec_ = ALPHNew();
+ if (dec->alph_dec_ == NULL) return NULL;
+ if (!ALPHInit(dec->alph_dec_, dec->alpha_data_, dec->alpha_data_size_,
+ width, height, dec->alpha_plane_)) {
+ ALPHDelete(dec->alph_dec_);
+ dec->alph_dec_ = NULL;
+ return NULL;
}
- dec->is_alpha_decoded_ = 1;
+ }
+
+ if (!dec->is_alpha_decoded_) {
+ int ok = 0;
+ assert(dec->alph_dec_ != NULL);
+ ok = ALPHDecode(dec, row, num_rows);
+ if (!ok || dec->is_alpha_decoded_) {
+ ALPHDelete(dec->alph_dec_);
+ dec->alph_dec_ = NULL;
+ }
+ if (!ok) return NULL; // Error.
}
// Return a pointer to the current decoded row.
return dec->alpha_plane_ + row * width;
}
-#if defined(__cplusplus) || defined(c_plusplus)
-} // extern "C"
-#endif
« no previous file with comments | « third_party/libwebp/README.chromium ('k') | third_party/libwebp/dec/alphai.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698