Chromium Code Reviews| 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 |