Index: blimp/common/compositor/webp_decoder.cc |
diff --git a/blimp/common/compositor/webp_decoder.cc b/blimp/common/compositor/webp_decoder.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..108f13cc03c191d19351604f7e124b54b68a9366 |
--- /dev/null |
+++ b/blimp/common/compositor/webp_decoder.cc |
@@ -0,0 +1,77 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "blimp/common/compositor/webp_decoder.h" |
+ |
+#include "base/logging.h" |
+#include "third_party/libwebp/webp/decode.h" |
+#include "third_party/libwebp/webp/demux.h" |
+#include "third_party/skia/include/core/SkBitmap.h" |
+ |
+namespace { |
+#if SK_B32_SHIFT // Output little-endian RGBA pixels (Android). |
+inline WEBP_CSP_MODE outputMode(bool hasAlpha) { |
+ return hasAlpha ? MODE_rgbA : MODE_RGBA; |
+} |
+#else // Output little-endian BGRA pixels. |
+inline WEBP_CSP_MODE outputMode(bool hasAlpha) { |
+ return hasAlpha ? MODE_bgrA : MODE_BGRA; |
+} |
+#endif |
+ |
+} // namespace |
+ |
+namespace blimp { |
+ |
+bool WebPDecoder(const void* input, size_t input_size, SkBitmap* bitmap) { |
+ // Assuming only one frame. |
urvang
2016/02/10 23:54:42
A few choices here, based on the expected behavior
nyquist
2016/02/11 05:19:23
Going for (2) for now, using WebPDecode. I'll defi
|
+ WebPData inputData = {reinterpret_cast<const uint8_t*>(input), input_size}; |
+ WebPDemuxState demuxState(WEBP_DEMUX_PARSING_HEADER); |
+ WebPDemuxer* demux = WebPDemuxPartial(&inputData, &demuxState); |
+ |
+ uint32_t width = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); |
+ uint32_t height = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); |
+ // ... (Get information about the features present in the WebP file). |
+ uint32_t flags = WebPDemuxGetI(demux, WEBP_FF_FORMAT_FLAGS); |
+ |
+ DCHECK(bitmap); |
+ bitmap->allocN32Pixels(width, height); |
+ |
+ // TODO(nyquist): Iterate over all frames. |
+ WebPIterator iter; |
+ bool success = false; |
+ if (WebPDemuxGetFrame(demux, 1, &iter)) { |
+ // do { |
+ // // ... (Consume 'iter'; e.g. Decode 'iter.fragment' with WebPDecode(), |
+ // // ... and get other frame properties like width, height, offsets etc. |
+ // // ... see 'struct WebPIterator' below for more info). |
+ // } while (WebPDemuxNextFrame(&iter)); |
+ WebPDecBuffer decoderBuffer; |
+ WebPIDecoder* decoder = WebPINewDecoder(&decoderBuffer); |
urvang
2016/02/10 23:54:43
Note that WebPIDecoder is used for incremental dec
nyquist
2016/02/11 05:19:23
Thanks! That was for sure simpler.
Updated to use
|
+ WebPInitDecBuffer(&decoderBuffer); |
+ WEBP_CSP_MODE mode = outputMode((flags & ALPHA_FLAG) != 0); |
+ decoderBuffer.colorspace = mode; |
+ decoderBuffer.u.RGBA.stride = width * 4; |
+ decoderBuffer.u.RGBA.size = decoderBuffer.u.RGBA.stride * height; |
+ decoderBuffer.is_external_memory = 1; |
+ decoderBuffer.u.RGBA.rgba = |
+ reinterpret_cast<uint8_t*>(bitmap->getAddr32(0, 0)); |
+ |
+ success = |
+ VP8_STATUS_OK == |
+ WebPIUpdate(decoder, static_cast<const uint8_t*>(input), input_size); |
+ // applyPostProcessing(1); |
+ WebPIDelete(decoder); |
+ WebPDemuxReleaseIterator(&iter); |
+ } |
+ WebPDemuxDelete(demux); |
+ |
+ // Set the bitmap's opaqueness based on what we saw. |
+ bitmap->setAlphaType(flags & ALPHA_FLAG ? kPremul_SkAlphaType |
+ : kOpaque_SkAlphaType); |
+ |
+ return success; |
+} |
+ |
+} // namespace blimp |