12c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org/*
22c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * Copyright 2010, The Android Open Source Project
32c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org *
42c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * Licensed under the Apache License, Version 2.0 (the "License");
52c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * you may not use this file except in compliance with the License.
62c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * You may obtain a copy of the License at
72c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org *
82c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org *     http://www.apache.org/licenses/LICENSE-2.0
92c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org *
102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * Unless required by applicable law or agreed to in writing, software
112c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * distributed under the License is distributed on an "AS IS" BASIS,
122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * See the License for the specific language governing permissions and
142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org * limitations under the License.
152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org */
162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
172c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkImageDecoder.h"
182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkImageEncoder.h"
192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkColorPriv.h"
202c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkScaledBitmapSampler.h"
212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkStream.h"
222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkTemplates.h"
232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkUtils.h"
242c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
252c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// A WebP decoder only, on top of (subset of) libwebp
262c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// For more information on WebP image format, and libwebp library, see:
272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//   http://code.google.com/speed/webp/
282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//   http://www.webmproject.org/code/#libwebp_webp_image_decoder_library
292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//   http://review.webmproject.org/gitweb?p=libwebp.git
302c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
312c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include <stdio.h>
322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgextern "C" {
332c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// If moving libwebp out of skia source tree, path for webp headers must be
342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// updated accordingly. Here, we enforce using local copy in webp sub-directory.
352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "webp/decode.h"
362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "webp/encode.h"
372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#ifdef ANDROID
402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include <cutils/properties.h>
412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// Key to lookup the size of memory buffer set in system property
432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic const char KEY_MEM_CAP[] = "ro.media.dec.webp.memcap";
442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#endif
452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// this enables timing code to report milliseconds for a decode
472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//#define TIME_DECODE
482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////
502c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////
512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// Define VP8 I/O on top of Skia stream
532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////
552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////
562c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
572c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic const size_t WEBP_VP8_HEADER_SIZE = 64;
582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16);
592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// Parse headers of RIFF container, and check for valid Webp (VP8) content.
612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool webp_parse_header(SkStream* stream, int* width, int* height, int* alpha) {
622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    unsigned char buffer[WEBP_VP8_HEADER_SIZE];
632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const uint32_t contentSize = stream->getLength();
642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const size_t len = stream->read(buffer, WEBP_VP8_HEADER_SIZE);
652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const uint32_t read_bytes =
662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            (contentSize < WEBP_VP8_HEADER_SIZE) ? contentSize : WEBP_VP8_HEADER_SIZE;
672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (len != read_bytes) {
682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false; // can't read enough
692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPBitstreamFeatures features;
722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    VP8StatusCode status = WebPGetFeatures(buffer, read_bytes, &features);
732c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (VP8_STATUS_OK != status) {
742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false; // Invalid WebP file.
752c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    *width = features.width;
772c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    *height = features.height;
782c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    *alpha = features.has_alpha;
792c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // sanity check for image size that's about to be decoded.
812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    {
822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        Sk64 size;
832c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        size.setMul(*width, *height);
842c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (size.isNeg() || !size.is32()) {
852c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return false;
862c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
872c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        // now check that if we are 4-bytes per pixel, we also don't overflow
882c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (size.get32() > (0x7FFFFFFF >> 2)) {
892c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return false;
902c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgclass SkWEBPImageDecoder: public SkImageDecoder {
962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgpublic:
972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkWEBPImageDecoder() {
982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fInputStream = NULL;
992c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fOrigWidth = 0;
1002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fOrigHeight = 0;
1012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fHasAlpha = 0;
1022c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1032c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    virtual ~SkWEBPImageDecoder() {
1042c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        SkSafeUnref(fInputStream);
1052c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1062c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1072c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    virtual Format getFormat() const SK_OVERRIDE {
1082c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return kWEBP_Format;
1092c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1112c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgprotected:
1122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    virtual bool onBuildTileIndex(SkStream *stream, int *width, int *height) SK_OVERRIDE;
1139da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.com    virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE;
1142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE;
1152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgprivate:
117746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com    /**
118746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com     *  Called when determining the output config to request to webp.
119746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com     *  If the image does not have alpha, there is no need to premultiply.
120746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com     *  If the caller wants unpremultiplied colors, that is respected.
121746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com     */
122746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com    bool shouldPremultiply() const {
123746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com        return SkToBool(fHasAlpha) && !this->getRequireUnpremultipliedColors();
124746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com    }
125746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com
1262c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height);
127746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com
1282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkStream* fInputStream;
1292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int fOrigWidth;
1302c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int fOrigHeight;
1312c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int fHasAlpha;
1322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1332c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    typedef SkImageDecoder INHERITED;
1342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org};
1352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org//////////////////////////////////////////////////////////////////////////
1372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#ifdef TIME_DECODE
1392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkTime.h"
1412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgclass AutoTimeMillis {
1432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgpublic:
1442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    AutoTimeMillis(const char label[]) :
1452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fLabel(label) {
1462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (NULL == fLabel) {
1472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            fLabel = "";
1482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
1492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        fNow = SkTime::GetMSecs();
1502c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    ~AutoTimeMillis() {
1522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        SkDebugf("---- Time (ms): %s %d\n", fLabel, SkTime::GetMSecs() - fNow);
1532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgprivate:
1552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const char* fLabel;
1562c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkMSec fNow;
1572c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org};
1582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#endif
1602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
1622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// This guy exists just to aid in debugging, as it allows debuggers to just
1642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// set a break-point in one place to see all error exists.
1652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool return_false(const SkBitmap& bm, const char msg[]) {
1662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkDEBUGF(("libwebp error %s [%d %d]", msg, bm.width(), bm.height()));
1672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return false; // must always return false
1682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
1692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
170746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.comstatic WEBP_CSP_MODE webp_decode_mode(const SkBitmap* decodedBitmap, bool premultiply) {
1712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WEBP_CSP_MODE mode = MODE_LAST;
1722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkBitmap::Config config = decodedBitmap->config();
173746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com
1742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (config == SkBitmap::kARGB_8888_Config) {
175746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com        mode = premultiply ? MODE_rgbA : MODE_RGBA;
1762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    } else if (config == SkBitmap::kARGB_4444_Config) {
177746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com        mode = premultiply ? MODE_rgbA_4444 : MODE_RGBA_4444;
1782c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    } else if (config == SkBitmap::kRGB_565_Config) {
179746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com        mode = MODE_RGB_565;
1802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkASSERT(MODE_LAST != mode);
1822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return mode;
1832c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
1842c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1852c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// Incremental WebP image decoding. Reads input buffer of 64K size iteratively
1862c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org// and decodes this block to appropriate color-space as per config object.
1872c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool webp_idecode(SkStream* stream, WebPDecoderConfig* config) {
1882c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPIDecoder* idec = WebPIDecode(NULL, 0, config);
1892c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (NULL == idec) {
1902c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        WebPFreeDecBuffer(&config->output);
1912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
1922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
1932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
1942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    stream->rewind();
1952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const uint32_t contentSize = stream->getLength();
1962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const uint32_t readBufferSize = (contentSize < WEBP_IDECODE_BUFFER_SZ) ?
1972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                       contentSize : WEBP_IDECODE_BUFFER_SZ;
1982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkAutoMalloc srcStorage(readBufferSize);
1992c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    unsigned char* input = (uint8_t*)srcStorage.get();
2002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (NULL == input) {
2012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        WebPIDelete(idec);
2022c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        WebPFreeDecBuffer(&config->output);
2032c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
2042c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2052c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
206f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com    bool success = true;
207f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com    VP8StatusCode status = VP8_STATUS_SUSPENDED;
208f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com    do {
209f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com        const size_t bytesRead = stream->read(input, readBufferSize);
2102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (0 == bytesRead) {
211f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com            success = false;
2122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            break;
2132c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
2142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
215f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com        status = WebPIAppend(idec, input, bytesRead);
216f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com        if (VP8_STATUS_OK != status && VP8_STATUS_SUSPENDED != status) {
217f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com            success = false;
2182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            break;
2192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
220f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com    } while (VP8_STATUS_OK != status);
2212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    srcStorage.free();
2222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPIDelete(idec);
2232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPFreeDecBuffer(&config->output);
2242c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
225f034b56c7451036c96563a10b8e77bee7947d11cscroggo@google.com    return success;
2262c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
2272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool webp_get_config_resize(WebPDecoderConfig* config,
2292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                   SkBitmap* decodedBitmap,
230746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com                                   int width, int height, bool premultiply) {
231746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com    WEBP_CSP_MODE mode = webp_decode_mode(decodedBitmap, premultiply);
2322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (MODE_LAST == mode) {
2332c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
2342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (0 == WebPInitDecoderConfig(config)) {
2372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
2382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->output.colorspace = mode;
2412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->output.u.RGBA.rgba = (uint8_t*)decodedBitmap->getPixels();
2422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->output.u.RGBA.stride = decodedBitmap->rowBytes();
2432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->output.u.RGBA.size = decodedBitmap->getSize();
2442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->output.is_external_memory = 1;
2452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (width != decodedBitmap->width() || height != decodedBitmap->height()) {
2472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        config->options.use_scaling = 1;
2482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        config->options.scaled_width = decodedBitmap->width();
2492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        config->options.scaled_height = decodedBitmap->height();
2502c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
2532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
2542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool webp_get_config_resize_crop(WebPDecoderConfig* config,
2562c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                        SkBitmap* decodedBitmap,
257746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com                                        const SkIRect& region, bool premultiply) {
2582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_get_config_resize(config, decodedBitmap, region.width(),
260746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com                                region.height(), premultiply)) {
2612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      return false;
2622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->options.use_cropping = 1;
2652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->options.crop_left = region.fLeft;
2662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->options.crop_top = region.fTop;
2672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->options.crop_width = region.width();
2682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    config->options.crop_height = region.height();
2692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
2712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
2722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2732c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgbool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap,
2742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                         int width, int height) {
27530f55c5612092994c3b185fc2e821f274d3ce0edcommit-bot@chromium.org    SkBitmap::Config config = this->getPrefConfig(k32Bit_SrcDepth, SkToBool(fHasAlpha));
2762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2772c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // YUV converter supports output in RGB565, RGBA4444 and RGBA8888 formats.
2782c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (fHasAlpha) {
2792c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (config != SkBitmap::kARGB_4444_Config) {
2802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            config = SkBitmap::kARGB_8888_Config;
2812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
2822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    } else {
2832c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (config != SkBitmap::kRGB_565_Config &&
2842c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            config != SkBitmap::kARGB_4444_Config) {
2852c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            config = SkBitmap::kARGB_8888_Config;
2862c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
2872c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2882c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2892c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!this->chooseFromOneChoice(config, width, height)) {
2902c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
2912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
2922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    decodedBitmap->setConfig(config, width, height, 0);
2942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    decodedBitmap->setIsOpaque(!fHasAlpha);
2962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
2972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
2982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
2992c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgbool SkWEBPImageDecoder::onBuildTileIndex(SkStream* stream,
3012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                          int *width, int *height) {
3022c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int origWidth, origHeight, hasAlpha;
3032c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) {
3042c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
3052c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3062c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3072c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    stream->rewind();
3082c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    *width = origWidth;
3092c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    *height = origHeight;
3102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3112c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkRefCnt_SafeAssign(this->fInputStream, stream);
3122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    this->fOrigWidth = origWidth;
3132c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    this->fOrigHeight = origHeight;
3142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    this->fHasAlpha = hasAlpha;
3152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
3172c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
3182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic bool is_config_compatible(const SkBitmap& bitmap) {
3202c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkBitmap::Config config = bitmap.config();
3212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return config == SkBitmap::kARGB_4444_Config ||
3222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org           config == SkBitmap::kRGB_565_Config ||
3232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org           config == SkBitmap::kARGB_8888_Config;
3242c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
3252c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3269da03b7e9819927e7d247aec2bab591e4a3addb7scroggo@google.combool SkWEBPImageDecoder::onDecodeSubset(SkBitmap* decodedBitmap,
3272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                        const SkIRect& region) {
3282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkIRect rect = SkIRect::MakeWH(fOrigWidth, fOrigHeight);
3292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3302c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!rect.intersect(region)) {
3312c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        // If the requested region is entirely outsides the image, return false
3322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
3332c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const int sampleSize = this->getSampleSize();
3362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkScaledBitmapSampler sampler(rect.width(), rect.height(), sampleSize);
3372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const int width = sampler.scaledWidth();
3382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const int height = sampler.scaledHeight();
3392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // The image can be decoded directly to decodedBitmap if
3412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    //   1. the region is within the image range
3422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    //   2. bitmap's config is compatible
3432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    //   3. bitmap's size is same as the required region (after sampled)
3442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    bool directDecode = (rect == region) &&
3452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                        (decodedBitmap->isNull() ||
3462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                         (is_config_compatible(*decodedBitmap) &&
3472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                         (decodedBitmap->width() == width) &&
3482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                         (decodedBitmap->height() == height)));
3499be663614630f2c1d9d473db8a48579e9ecacb39commit-bot@chromium.org
3509be663614630f2c1d9d473db8a48579e9ecacb39commit-bot@chromium.org    SkBitmap tmpBitmap;
3512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkBitmap *bitmap = decodedBitmap;
3522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!directDecode) {
3549be663614630f2c1d9d473db8a48579e9ecacb39commit-bot@chromium.org        bitmap = &tmpBitmap;
3552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3562c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3572c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (bitmap->isNull()) {
3582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (!setDecodeConfig(bitmap, width, height)) {
3592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return false;
3602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
3612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        // alloc from native heap if it is a temp bitmap. (prevent GC)
3622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        bool allocResult = (bitmap == decodedBitmap)
3632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                               ? allocPixelRef(bitmap, NULL)
3642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                               : bitmap->allocPixels();
3652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (!allocResult) {
3662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return return_false(*decodedBitmap, "allocPixelRef");
3672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
3682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    } else {
3692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        // This is also called in setDecodeConfig in above block.
3702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        // i.e., when bitmap->isNull() is true.
3712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        if (!chooseFromOneChoice(bitmap->config(), width, height)) {
3722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return false;
3732c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        }
3742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3752c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkAutoLockPixels alp(*bitmap);
3772c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPDecoderConfig config;
378746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com    if (!webp_get_config_resize_crop(&config, bitmap, rect,
379746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com                                     this->shouldPremultiply())) {
3802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
3812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3832c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // Decode the WebP image data stream using WebP incremental decoding for
3842c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // the specified cropped image-region.
3852c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_idecode(this->fInputStream, &config)) {
3862c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
3872c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3882c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3892c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!directDecode) {
3902c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        cropBitmap(decodedBitmap, bitmap, sampleSize, region.x(), region.y(),
3912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                   region.width(), region.height(), rect.x(), rect.y());
3922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
3932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return true;
3942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
3952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
3962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgbool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap,
3972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                  Mode mode) {
3982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#ifdef TIME_DECODE
3992c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    AutoTimeMillis atm("WEBP Decode");
4002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#endif
4012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4022c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int origWidth, origHeight, hasAlpha;
4032c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) {
4042c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
4052c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
4062c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    this->fHasAlpha = hasAlpha;
4072c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4082c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const int sampleSize = this->getSampleSize();
4092c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize);
410a80d3ddc590d6b5bd1893836f8aca89412267c39scroggo@google.com    if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(),
411a80d3ddc590d6b5bd1893836f8aca89412267c39scroggo@google.com                         sampler.scaledHeight())) {
412a80d3ddc590d6b5bd1893836f8aca89412267c39scroggo@google.com        return false;
413a80d3ddc590d6b5bd1893836f8aca89412267c39scroggo@google.com    }
4142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // If only bounds are requested, done
4162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (SkImageDecoder::kDecodeBounds_Mode == mode) {
4172c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return true;
4182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
4192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4202c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!this->allocPixelRef(decodedBitmap, NULL)) {
4212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return return_false(*decodedBitmap, "allocPixelRef");
4222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
4232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4242c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkAutoLockPixels alp(*decodedBitmap);
4252c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4262c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPDecoderConfig config;
4272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_get_config_resize(&config, decodedBitmap, origWidth, origHeight,
428746b6b83a7e954f59a6c6dd44e3e8216dc11a8bbscroggo@google.com                                this->shouldPremultiply())) {
4292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
4302c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
4312c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // Decode the WebP image data stream using WebP incremental decoding.
4332c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return webp_idecode(stream, &config);
4342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
4352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
4372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgtypedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width,
4392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                 const SkPMColor* SK_RESTRICT ctable);
4402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
4422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                             const SkPMColor*) {
4432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  const uint32_t* SK_RESTRICT src = (const uint32_t*)in;
4442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  for (int i = 0; i < width; ++i) {
4452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      const uint32_t c = *src++;
4462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[0] = SkGetPackedR32(c);
4472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[1] = SkGetPackedG32(c);
4482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[2] = SkGetPackedB32(c);
4492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb += 3;
4502c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  }
4512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
4522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
4542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                           const SkPMColor*) {
4552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  const uint16_t* SK_RESTRICT src = (const uint16_t*)in;
4562c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  for (int i = 0; i < width; ++i) {
4572c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      const uint16_t c = *src++;
4582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[0] = SkPacked16ToR32(c);
4592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[1] = SkPacked16ToG32(c);
4602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[2] = SkPacked16ToB32(c);
4612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb += 3;
4622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  }
4632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
4642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
4662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                             const SkPMColor*) {
4672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in;
4682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  for (int i = 0; i < width; ++i) {
4692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      const SkPMColor16 c = *src++;
4702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[0] = SkPacked4444ToR32(c);
4712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[1] = SkPacked4444ToG32(c);
4722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[2] = SkPacked4444ToB32(c);
4732c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb += 3;
4742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  }
4752c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
4762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4772c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width,
4782c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                          const SkPMColor* SK_RESTRICT ctable) {
4792c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  const uint8_t* SK_RESTRICT src = (const uint8_t*)in;
4802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  for (int i = 0; i < width; ++i) {
4812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      const uint32_t c = ctable[*src++];
4822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[0] = SkGetPackedR32(c);
4832c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[1] = SkGetPackedG32(c);
4842c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb[2] = SkGetPackedB32(c);
4852c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      rgb += 3;
4862c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  }
4872c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
4882c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
4892c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic ScanlineImporter ChooseImporter(const SkBitmap::Config& config) {
4902c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    switch (config) {
4912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        case SkBitmap::kARGB_8888_Config:
4922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return ARGB_8888_To_RGB;
4932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        case SkBitmap::kRGB_565_Config:
4942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return RGB_565_To_RGB;
4952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        case SkBitmap::kARGB_4444_Config:
4962c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return ARGB_4444_To_RGB;
4972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        case SkBitmap::kIndex8_Config:
4982c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return Index8_To_RGB;
4992c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        default:
5002c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org            return NULL;
5012c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5022c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
5032c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5042c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic int stream_writer(const uint8_t* data, size_t data_size,
5052c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                         const WebPPicture* const picture) {
5062c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  SkWStream* const stream = (SkWStream*)picture->custom_ptr;
5072c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org  return stream->write(data, data_size) ? 1 : 0;
5082c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
5092c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5102c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgclass SkWEBPImageEncoder : public SkImageEncoder {
5112c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgprotected:
5122c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK_OVERRIDE;
5132c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5142c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgprivate:
5152c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    typedef SkImageEncoder INHERITED;
5162c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org};
5172c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5182c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgbool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm,
5192c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                                  int quality) {
5202c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const SkBitmap::Config config = bm.getConfig();
5212c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const ScanlineImporter scanline_import = ChooseImporter(config);
5222c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (NULL == scanline_import) {
5232c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
5242c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5252c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5262c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkAutoLockPixels alp(bm);
5272c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    SkAutoLockColors ctLocker;
5282c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (NULL == bm.getPixels()) {
5292c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
5302c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5312c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5322c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPConfig webp_config;
53330f55c5612092994c3b185fc2e821f274d3ce0edcommit-bot@chromium.org    if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, (float) quality)) {
5342c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return false;
5352c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5362c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5372c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPPicture pic;
5382c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPPictureInit(&pic);
5392c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    pic.width = bm.width();
5402c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    pic.height = bm.height();
5412c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    pic.writer = stream_writer;
5422c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    pic.custom_ptr = (void*)stream;
5432c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5442c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const SkPMColor* colors = ctLocker.lockColors(bm);
5452c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const uint8_t* src = (uint8_t*)bm.getPixels();
5462c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    const int rgbStride = pic.width * 3;
5472c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5482c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // Import (for each scanline) the bit-map image (in appropriate color-space)
5492c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // to RGB color space.
5502c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    uint8_t* rgb = new uint8_t[rgbStride * pic.height];
5512c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    for (int y = 0; y < pic.height; ++y) {
5522c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        scanline_import(src + y * bm.rowBytes(), rgb + y * rgbStride,
5532c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org                        pic.width, colors);
5542c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5552c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5568e917f65315cc85f2c22480e57ac960c014065d6reed@google.com    bool ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride));
5572c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    delete[] rgb;
5582c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5592c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    ok = ok && WebPEncode(&webp_config, &pic);
5602c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    WebPPictureFree(&pic);
5612c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5622c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return ok;
5632c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
5642c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5652c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5662c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
5672c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgDEFINE_DECODER_CREATOR(WEBPImageDecoder);
5682c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgDEFINE_ENCODER_CREATOR(WEBPImageEncoder);
5692c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
5702c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5712c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org#include "SkTRegistry.h"
5722c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5732c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic SkImageDecoder* sk_libwebp_dfactory(SkStream* stream) {
5742c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    int width, height, hasAlpha;
5752c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    if (!webp_parse_header(stream, &width, &height, &hasAlpha)) {
5762c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org        return NULL;
5772c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    }
5782c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5792c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    // Magic matches, call decoder
5802c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org    return SkNEW(SkWEBPImageDecoder);
5812c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
5822c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
58306a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic SkImageDecoder::Format get_format_webp(SkStream* stream) {
58406a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com    int width, height, hasAlpha;
58506a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com    if (webp_parse_header(stream, &width, &height, &hasAlpha)) {
58606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com        return SkImageDecoder::kWEBP_Format;
58706a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com    }
58806a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com    return SkImageDecoder::kUnknown_Format;
58906a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com}
59006a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.com
5912c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) {
5922c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org      return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NULL;
5932c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org}
5942c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.org
5952c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic SkTRegistry<SkImageDecoder*, SkStream*> gDReg(sk_libwebp_dfactory);
59606a7d944591332081e2e8a4d9b9ca88d76a2f9c8scroggo@google.comstatic SkTRegistry<SkImageDecoder::Format, SkStream*> gFormatReg(get_format_webp);
5972c5e316d42796d958b5656410fcb2cd0218b785ecommit-bot@chromium.orgstatic SkTRegistry<SkImageEncoder*, SkImageEncoder::Type> gEReg(sk_libwebp_efactory);
598