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

Unified Diff: third_party/libwebp/dec/alpha.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/alpha.c
diff --git a/third_party/libwebp/dec/alpha.c b/third_party/libwebp/dec/alpha.c
index 3052ced777ebf3595fac67af9ad279420244fdbc..6e65de90302a14422e7f26076cf49eddeb8d7c39 100644
--- a/third_party/libwebp/dec/alpha.c
+++ b/third_party/libwebp/dec/alpha.c
@@ -1,4 +1,4 @@
-// Copyright 2011 Google Inc.
+// Copyright 2011 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,60 +10,131 @@
// Author: Skal (pascal.massimino@gmail.com)
#include <stdlib.h>
-#include "vp8i.h"
-
-#ifdef WEBP_EXPERIMENTAL_FEATURES
-
-#include "zlib.h"
+#include "./vp8i.h"
+#include "./vp8li.h"
+#include "../utils/filters.h"
+#include "../utils/quant_levels.h"
+#include "../webp/format_constants.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
+// TODO(skal): move to dsp/ ?
+static void CopyPlane(const uint8_t* src, int src_stride,
+ uint8_t* dst, int dst_stride, int width, int height) {
+ while (height-- > 0) {
+ memcpy(dst, src, width);
+ src += src_stride;
+ dst += dst_stride;
+ }
+}
+
+//------------------------------------------------------------------------------
+// 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'stride', 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, int stride, uint8_t* output) {
+ uint8_t* decoded_data = NULL;
+ const size_t decoded_size = height * width;
+ uint8_t* unfiltered_data = NULL;
+ WEBP_FILTER_TYPE filter;
+ int pre_processing;
+ int rsrv;
+ int ok = 0;
+ int method;
+
+ assert(width > 0 && height > 0 && stride >= width);
+ assert(data != NULL && output != NULL);
+
+ if (data_size <= ALPHA_HEADER_LEN) {
+ return 0;
+ }
+
+ method = (data[0] >> 0) & 0x03;
+ filter = (data[0] >> 2) & 0x03;
+ 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 ||
+ rsrv != 0) {
+ return 0;
+ }
+
+ if (method == ALPHA_NO_COMPRESSION) {
+ ok = (data_size >= decoded_size);
+ decoded_data = (uint8_t*)data + ALPHA_HEADER_LEN;
+ } else {
+ decoded_data = (uint8_t*)malloc(decoded_size);
+ if (decoded_data == NULL) return 0;
+ ok = VP8LDecodeAlphaImageStream(width, height,
+ data + ALPHA_HEADER_LEN,
+ data_size - ALPHA_HEADER_LEN,
+ decoded_data);
+ }
+
+ if (ok) {
+ WebPFilterFunc unfilter_func = WebPUnfilters[filter];
+ if (unfilter_func != NULL) {
+ unfiltered_data = (uint8_t*)malloc(decoded_size);
+ if (unfiltered_data == NULL) {
+ ok = 0;
+ goto Error;
+ }
+ // TODO(vikas): Implement on-the-fly decoding & filter mechanism to decode
+ // and apply filter per image-row.
+ unfilter_func(decoded_data, width, height, 1, width, unfiltered_data);
+ // Construct raw_data (height x stride) from alpha data (height x width).
+ CopyPlane(unfiltered_data, width, output, stride, width, height);
+ free(unfiltered_data);
+ } else {
+ // Construct raw_data (height x stride) from alpha data (height x width).
+ CopyPlane(decoded_data, width, output, stride, width, height);
+ }
+ if (pre_processing == ALPHA_PREPROCESSED_LEVELS) {
+ ok = DequantizeLevels(decoded_data, width, height);
+ }
+ }
+
+ Error:
+ if (method != ALPHA_NO_COMPRESSION) {
+ free(decoded_data);
+ }
+ return ok;
+}
+
//------------------------------------------------------------------------------
const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
int row, int num_rows) {
- uint8_t* output = dec->alpha_plane_;
const int stride = dec->pic_hdr_.width_;
- if (row < 0 || row + num_rows > dec->pic_hdr_.height_) {
- return NULL; // sanity check
+
+ if (row < 0 || num_rows < 0 || row + num_rows > dec->pic_hdr_.height_) {
+ return NULL; // sanity check.
}
- if (row == 0) {
- // TODO(skal): for now, we just decompress everything during the first call.
- // Later, we'll decode progressively, but we need to store the
- // z_stream state.
- const uint8_t* data = dec->alpha_data_;
- size_t data_size = dec->alpha_data_size_;
- const size_t output_size = stride * dec->pic_hdr_.height_;
- int ret = Z_OK;
- z_stream strm;
-
- memset(&strm, 0, sizeof(strm));
- if (inflateInit(&strm) != Z_OK) {
- return 0;
- }
- strm.avail_in = data_size;
- strm.next_in = (unsigned char*)data;
- do {
- strm.avail_out = output_size;
- strm.next_out = output;
- ret = inflate(&strm, Z_NO_FLUSH);
- if (ret == Z_NEED_DICT || ret == Z_DATA_ERROR || ret == Z_MEM_ERROR) {
- break;
- }
- } while (strm.avail_out == 0);
- inflateEnd(&strm);
- if (ret != Z_STREAM_END) {
- return NULL; // error
+ if (row == 0) {
+ // Decode everything during the first call.
+ if (!DecodeAlpha(dec->alpha_data_, (size_t)dec->alpha_data_size_,
+ dec->pic_hdr_.width_, dec->pic_hdr_.height_, stride,
+ dec->alpha_plane_)) {
+ return NULL; // Error.
}
}
- return output + row * stride;
+
+ // Return a pointer to the current decoded row.
+ return dec->alpha_plane_ + row * stride;
}
#if defined(__cplusplus) || defined(c_plusplus)
} // extern "C"
#endif
-
-#endif // WEBP_EXPERIMENTAL_FEATURES

Powered by Google App Engine
This is Rietveld 408576698