1a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org/* 2a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * Copyright 2010, The Android Open Source Project 3a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * 4a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * Licensed under the Apache License, Version 2.0 (the "License"); 5a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * you may not use this file except in compliance with the License. 6a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * You may obtain a copy of the License at 7a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * 8a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * http://www.apache.org/licenses/LICENSE-2.0 9a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * 10a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * Unless required by applicable law or agreed to in writing, software 11a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * distributed under the License is distributed on an "AS IS" BASIS, 12a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * See the License for the specific language governing permissions and 14a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org * limitations under the License. 15a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org */ 16a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 17a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkImageDecoder.h" 18a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkImageEncoder.h" 19a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkColorPriv.h" 20a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkScaledBitmapSampler.h" 21a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkStream.h" 22a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkTemplates.h" 23a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkUtils.h" 24a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 25a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// A WebP decoder only, on top of (subset of) libwebp 26a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// For more information on WebP image format, and libwebp library, see: 27a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// http://code.google.com/speed/webp/ 28a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// http://www.webmproject.org/code/#libwebp_webp_image_decoder_library 29a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// http://review.webmproject.org/gitweb?p=libwebp.git 30a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 31a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include <stdio.h> 32a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgextern "C" { 33a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// If moving libwebp out of skia source tree, path for webp headers must be 34a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// updated accordingly. Here, we enforce using local copy in webp sub-directory. 35a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "webp/decode.h" 36a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "webp/encode.h" 37a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 38a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 39a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// this enables timing code to report milliseconds for a decode 40a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org//#define TIME_DECODE 41a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 42a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////// 43a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////// 44a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 45a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// Define VP8 I/O on top of Skia stream 46a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 47a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////// 48a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////// 49a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 50a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic const size_t WEBP_VP8_HEADER_SIZE = 64; 51a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic const size_t WEBP_IDECODE_BUFFER_SZ = (1 << 16); 52a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 53a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// Parse headers of RIFF container, and check for valid Webp (VP8) content. 54a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool webp_parse_header(SkStream* stream, int* width, int* height, int* alpha) { 55a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org unsigned char buffer[WEBP_VP8_HEADER_SIZE]; 563c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com size_t bytesToRead = WEBP_VP8_HEADER_SIZE; 573c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com size_t totalBytesRead = 0; 583c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com do { 593c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com unsigned char* dst = buffer + totalBytesRead; 603c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com const size_t bytesRead = stream->read(dst, bytesToRead); 613c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com if (0 == bytesRead) { 623c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com // Could not read any bytes. Check to see if we are at the end (exit 633c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com // condition), and continue reading if not. Important for streams 643c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com // that do not have all the data ready. 653c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com continue; 663c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com } 673c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com bytesToRead -= bytesRead; 683c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com totalBytesRead += bytesRead; 693c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com SkASSERT(bytesToRead + totalBytesRead == WEBP_VP8_HEADER_SIZE); 703c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com } while (!stream->isAtEnd() && bytesToRead > 0); 71a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 72a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPBitstreamFeatures features; 733c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com VP8StatusCode status = WebPGetFeatures(buffer, totalBytesRead, &features); 74a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (VP8_STATUS_OK != status) { 75a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; // Invalid WebP file. 76a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 77a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org *width = features.width; 78a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org *height = features.height; 79a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org *alpha = features.has_alpha; 80a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 81a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // sanity check for image size that's about to be decoded. 82a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org { 8357212f9469c8056bab3c85243dbb904e386eab95reed@google.com int64_t size = sk_64_mul(*width, *height); 8457212f9469c8056bab3c85243dbb904e386eab95reed@google.com if (!sk_64_isS32(size)) { 85a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 86a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 87a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // now check that if we are 4-bytes per pixel, we also don't overflow 8857212f9469c8056bab3c85243dbb904e386eab95reed@google.com if (sk_64_asS32(size) > (0x7FFFFFFF >> 2)) { 89a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 90a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 91a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 92a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 93a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 94a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 95a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgclass SkWEBPImageDecoder: public SkImageDecoder { 96a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgpublic: 97a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkWEBPImageDecoder() { 98a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fInputStream = NULL; 99a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fOrigWidth = 0; 100a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fOrigHeight = 0; 101a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fHasAlpha = 0; 102a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 103a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org virtual ~SkWEBPImageDecoder() { 104a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkSafeUnref(fInputStream); 105a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 106a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 107a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org virtual Format getFormat() const SK_OVERRIDE { 108a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return kWEBP_Format; 109a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 110a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 111a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgprotected: 112b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.com virtual bool onBuildTileIndex(SkStreamRewindable *stream, int *width, int *height) SK_OVERRIDE; 1137e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.com virtual bool onDecodeSubset(SkBitmap* bitmap, const SkIRect& rect) SK_OVERRIDE; 114a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode) SK_OVERRIDE; 115a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 116a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgprivate: 1172bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com /** 1182bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com * Called when determining the output config to request to webp. 1192bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com * If the image does not have alpha, there is no need to premultiply. 1202bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com * If the caller wants unpremultiplied colors, that is respected. 1212bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com */ 1222bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com bool shouldPremultiply() const { 1232bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com return SkToBool(fHasAlpha) && !this->getRequireUnpremultipliedColors(); 1242bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com } 1252bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com 126a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org bool setDecodeConfig(SkBitmap* decodedBitmap, int width, int height); 1272bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com 128a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkStream* fInputStream; 129a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int fOrigWidth; 130a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int fOrigHeight; 131a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int fHasAlpha; 132a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 133a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org typedef SkImageDecoder INHERITED; 134a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org}; 135a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 136a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org////////////////////////////////////////////////////////////////////////// 137a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 138a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#ifdef TIME_DECODE 139a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 140a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#include "SkTime.h" 141a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 142a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgclass AutoTimeMillis { 143a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgpublic: 144a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org AutoTimeMillis(const char label[]) : 145a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fLabel(label) { 146a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (NULL == fLabel) { 147a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fLabel = ""; 148a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 149a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org fNow = SkTime::GetMSecs(); 150a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 151a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org ~AutoTimeMillis() { 152a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkDebugf("---- Time (ms): %s %d\n", fLabel, SkTime::GetMSecs() - fNow); 153a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 154a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgprivate: 155a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const char* fLabel; 156a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkMSec fNow; 157a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org}; 158a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 159a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#endif 160a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 161a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 162a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 163a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// This guy exists just to aid in debugging, as it allows debuggers to just 164a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// set a break-point in one place to see all error exists. 165a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool return_false(const SkBitmap& bm, const char msg[]) { 166a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkDEBUGF(("libwebp error %s [%d %d]", msg, bm.width(), bm.height())); 167a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; // must always return false 168a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 169a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 1702bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.comstatic WEBP_CSP_MODE webp_decode_mode(const SkBitmap* decodedBitmap, bool premultiply) { 171a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WEBP_CSP_MODE mode = MODE_LAST; 1720689d7b12e7c427a077b003d3d8ae759d86f798freed const SkColorType ct = decodedBitmap->colorType(); 1732bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com 1740689d7b12e7c427a077b003d3d8ae759d86f798freed if (ct == kN32_SkColorType) { 175dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com #if SK_PMCOLOR_BYTE_ORDER(B,G,R,A) 176dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com mode = premultiply ? MODE_bgrA : MODE_BGRA; 177dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com #elif SK_PMCOLOR_BYTE_ORDER(R,G,B,A) 178dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com mode = premultiply ? MODE_rgbA : MODE_RGBA; 179dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com #else 180dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com #error "Skia uses BGRA or RGBA byte order" 181dedd44adea3b87faea4bcd833c6a508a6db8fcfdhalcanary@google.com #endif 1820689d7b12e7c427a077b003d3d8ae759d86f798freed } else if (ct == kARGB_4444_SkColorType) { 1832bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com mode = premultiply ? MODE_rgbA_4444 : MODE_RGBA_4444; 1840689d7b12e7c427a077b003d3d8ae759d86f798freed } else if (ct == kRGB_565_SkColorType) { 1852bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com mode = MODE_RGB_565; 186a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 187a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkASSERT(MODE_LAST != mode); 188a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return mode; 189a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 190a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 191a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// Incremental WebP image decoding. Reads input buffer of 64K size iteratively 192a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org// and decodes this block to appropriate color-space as per config object. 193a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool webp_idecode(SkStream* stream, WebPDecoderConfig* config) { 194a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPIDecoder* idec = WebPIDecode(NULL, 0, config); 195a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (NULL == idec) { 196a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPFreeDecBuffer(&config->output); 197a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 198a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 199a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 2004d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com if (!stream->rewind()) { 2014d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com SkDebugf("Failed to rewind webp stream!"); 2024d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com return false; 2034d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com } 2043c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com const size_t readBufferSize = stream->hasLength() ? 2053c8730a84e469cfc71866a2f8d6bfd1d2ea689e3scroggo@google.com SkTMin(stream->getLength(), WEBP_IDECODE_BUFFER_SZ) : WEBP_IDECODE_BUFFER_SZ; 206a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkAutoMalloc srcStorage(readBufferSize); 207a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org unsigned char* input = (uint8_t*)srcStorage.get(); 208a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (NULL == input) { 209a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPIDelete(idec); 210a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPFreeDecBuffer(&config->output); 211a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 212a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 213a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 21480e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com bool success = true; 21580e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com VP8StatusCode status = VP8_STATUS_SUSPENDED; 21680e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com do { 21780e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com const size_t bytesRead = stream->read(input, readBufferSize); 218a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (0 == bytesRead) { 21980e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com success = false; 220a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org break; 221a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 222a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 22380e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com status = WebPIAppend(idec, input, bytesRead); 22480e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com if (VP8_STATUS_OK != status && VP8_STATUS_SUSPENDED != status) { 22580e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com success = false; 226a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org break; 227a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 22880e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com } while (VP8_STATUS_OK != status); 229a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org srcStorage.free(); 230a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPIDelete(idec); 231a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPFreeDecBuffer(&config->output); 232a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 23380e18c93bbeefe54f8192a380586e6468f179917scroggo@google.com return success; 234a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 235a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 236a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool webp_get_config_resize(WebPDecoderConfig* config, 237a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkBitmap* decodedBitmap, 2382bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com int width, int height, bool premultiply) { 2392bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com WEBP_CSP_MODE mode = webp_decode_mode(decodedBitmap, premultiply); 240a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (MODE_LAST == mode) { 241a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 242a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 243a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 244a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (0 == WebPInitDecoderConfig(config)) { 245a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 246a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 247a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 248a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->output.colorspace = mode; 249a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->output.u.RGBA.rgba = (uint8_t*)decodedBitmap->getPixels(); 2508b169311b59ab84e8ca6f3630a1e960cc1be751erobertphillips@google.com config->output.u.RGBA.stride = (int) decodedBitmap->rowBytes(); 251a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->output.u.RGBA.size = decodedBitmap->getSize(); 252a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->output.is_external_memory = 1; 253a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 254a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (width != decodedBitmap->width() || height != decodedBitmap->height()) { 255a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.use_scaling = 1; 256a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.scaled_width = decodedBitmap->width(); 257a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.scaled_height = decodedBitmap->height(); 258a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 259a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 260a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 261a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 262a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 263a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool webp_get_config_resize_crop(WebPDecoderConfig* config, 264a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkBitmap* decodedBitmap, 2652bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com const SkIRect& region, bool premultiply) { 266a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 267a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_get_config_resize(config, decodedBitmap, region.width(), 2682bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com region.height(), premultiply)) { 269a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 270a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 271a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 272a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.use_cropping = 1; 273a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.crop_left = region.fLeft; 274a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.crop_top = region.fTop; 275a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.crop_width = region.width(); 276a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org config->options.crop_height = region.height(); 277a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 278a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 279a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 280a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 2816c22573edb234ad14df947278cfed010669a39a7reedbool SkWEBPImageDecoder::setDecodeConfig(SkBitmap* decodedBitmap, int width, int height) { 2826c22573edb234ad14df947278cfed010669a39a7reed SkColorType colorType = this->getPrefColorType(k32Bit_SrcDepth, SkToBool(fHasAlpha)); 283a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 284a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // YUV converter supports output in RGB565, RGBA4444 and RGBA8888 formats. 285a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (fHasAlpha) { 2866c22573edb234ad14df947278cfed010669a39a7reed if (colorType != kARGB_4444_SkColorType) { 2876c22573edb234ad14df947278cfed010669a39a7reed colorType = kN32_SkColorType; 288a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 289a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } else { 2906c22573edb234ad14df947278cfed010669a39a7reed if (colorType != kRGB_565_SkColorType && colorType != kARGB_4444_SkColorType) { 2916c22573edb234ad14df947278cfed010669a39a7reed colorType = kN32_SkColorType; 292a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 293a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 294a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 2955926b86b90c68bffefbdc8639e41b5bc9102cec6reed#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER 2966c22573edb234ad14df947278cfed010669a39a7reed if (!this->chooseFromOneChoice(colorType, width, height)) { 297a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 298a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 2995926b86b90c68bffefbdc8639e41b5bc9102cec6reed#endif 300a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 3016c22573edb234ad14df947278cfed010669a39a7reed SkAlphaType alphaType = kOpaque_SkAlphaType; 302915b972a818d0279eb926af38ba6952daa17a63ecommit-bot@chromium.org if (SkToBool(fHasAlpha)) { 303915b972a818d0279eb926af38ba6952daa17a63ecommit-bot@chromium.org if (this->getRequireUnpremultipliedColors()) { 3046c22573edb234ad14df947278cfed010669a39a7reed alphaType = kUnpremul_SkAlphaType; 305915b972a818d0279eb926af38ba6952daa17a63ecommit-bot@chromium.org } else { 3066c22573edb234ad14df947278cfed010669a39a7reed alphaType = kPremul_SkAlphaType; 307915b972a818d0279eb926af38ba6952daa17a63ecommit-bot@chromium.org } 308915b972a818d0279eb926af38ba6952daa17a63ecommit-bot@chromium.org } 3096c22573edb234ad14df947278cfed010669a39a7reed return decodedBitmap->setInfo(SkImageInfo::Make(width, height, colorType, alphaType)); 310a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 311a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 312b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.combool SkWEBPImageDecoder::onBuildTileIndex(SkStreamRewindable* stream, 313a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int *width, int *height) { 314a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int origWidth, origHeight, hasAlpha; 315a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { 316a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 317a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 318a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 3194d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com if (!stream->rewind()) { 3204d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com SkDebugf("Failed to rewind webp stream!"); 3214d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com return false; 3224d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com } 3234d213ab944d96ad60a243ac1ad21c793c1acc80ascroggo@google.com 324a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org *width = origWidth; 325a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org *height = origHeight; 326a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 327a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkRefCnt_SafeAssign(this->fInputStream, stream); 328a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org this->fOrigWidth = origWidth; 329a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org this->fOrigHeight = origHeight; 330a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org this->fHasAlpha = hasAlpha; 331a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 332a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 333a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 334a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 335a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic bool is_config_compatible(const SkBitmap& bitmap) { 3360689d7b12e7c427a077b003d3d8ae759d86f798freed const SkColorType ct = bitmap.colorType(); 3370689d7b12e7c427a077b003d3d8ae759d86f798freed return ct == kARGB_4444_SkColorType || ct == kRGB_565_SkColorType || ct == kN32_SkColorType; 338a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 339a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 3407e6fceeffd250d99eff9f1dbb459a916ae4a754escroggo@google.combool SkWEBPImageDecoder::onDecodeSubset(SkBitmap* decodedBitmap, 341a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkIRect& region) { 342a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkIRect rect = SkIRect::MakeWH(fOrigWidth, fOrigHeight); 343a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 344a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!rect.intersect(region)) { 345a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // If the requested region is entirely outsides the image, return false 346a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 347a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 348a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 349a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const int sampleSize = this->getSampleSize(); 350a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkScaledBitmapSampler sampler(rect.width(), rect.height(), sampleSize); 351a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const int width = sampler.scaledWidth(); 352a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const int height = sampler.scaledHeight(); 353a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 354a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // The image can be decoded directly to decodedBitmap if 355a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // 1. the region is within the image range 356a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // 2. bitmap's config is compatible 357a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // 3. bitmap's size is same as the required region (after sampled) 358a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org bool directDecode = (rect == region) && 359a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org (decodedBitmap->isNull() || 360a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org (is_config_compatible(*decodedBitmap) && 361a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org (decodedBitmap->width() == width) && 362a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org (decodedBitmap->height() == height))); 363a9f142e9f0e96ba6766479545a66654d8b3ebdc4commit-bot@chromium.org 364a9f142e9f0e96ba6766479545a66654d8b3ebdc4commit-bot@chromium.org SkBitmap tmpBitmap; 365a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkBitmap *bitmap = decodedBitmap; 366a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 367a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!directDecode) { 368a9f142e9f0e96ba6766479545a66654d8b3ebdc4commit-bot@chromium.org bitmap = &tmpBitmap; 369a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 370a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 371a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (bitmap->isNull()) { 372a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!setDecodeConfig(bitmap, width, height)) { 373a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 374a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 375a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // alloc from native heap if it is a temp bitmap. (prevent GC) 376a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org bool allocResult = (bitmap == decodedBitmap) 377a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org ? allocPixelRef(bitmap, NULL) 378848250415eddc54075f7eb8795e8db79e749c6abreed : bitmap->tryAllocPixels(); 379a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!allocResult) { 380a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return return_false(*decodedBitmap, "allocPixelRef"); 381a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 3825926b86b90c68bffefbdc8639e41b5bc9102cec6reed#ifdef SK_SUPPORT_LEGACY_IMAGEDECODER_CHOOSER 383a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } else { 384a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // This is also called in setDecodeConfig in above block. 385a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // i.e., when bitmap->isNull() is true. 3866c22573edb234ad14df947278cfed010669a39a7reed if (!chooseFromOneChoice(bitmap->colorType(), width, height)) { 387a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 388a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 3895926b86b90c68bffefbdc8639e41b5bc9102cec6reed#endif 390a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 391a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 392a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkAutoLockPixels alp(*bitmap); 393a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPDecoderConfig config; 3942bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com if (!webp_get_config_resize_crop(&config, bitmap, rect, 3952bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com this->shouldPremultiply())) { 396a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 397a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 398a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 399a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // Decode the WebP image data stream using WebP incremental decoding for 400a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // the specified cropped image-region. 401a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_idecode(this->fInputStream, &config)) { 402a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 403a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 404a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 405a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!directDecode) { 406a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org cropBitmap(decodedBitmap, bitmap, sampleSize, region.x(), region.y(), 407a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org region.width(), region.height(), rect.x(), rect.y()); 408a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 409a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 410a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 411a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 412a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgbool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, 413a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org Mode mode) { 414a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#ifdef TIME_DECODE 415a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org AutoTimeMillis atm("WEBP Decode"); 416a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org#endif 417a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 418a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int origWidth, origHeight, hasAlpha; 419a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_parse_header(stream, &origWidth, &origHeight, &hasAlpha)) { 420a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 421a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 422a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org this->fHasAlpha = hasAlpha; 423a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 424a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const int sampleSize = this->getSampleSize(); 425a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkScaledBitmapSampler sampler(origWidth, origHeight, sampleSize); 426bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com if (!setDecodeConfig(decodedBitmap, sampler.scaledWidth(), 427bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com sampler.scaledHeight())) { 428bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com return false; 429bc69ce982f8374742ca910587485f0d741350c2dscroggo@google.com } 430a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 431a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // If only bounds are requested, done 432a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (SkImageDecoder::kDecodeBounds_Mode == mode) { 433a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return true; 434a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 435a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 436a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!this->allocPixelRef(decodedBitmap, NULL)) { 437a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return return_false(*decodedBitmap, "allocPixelRef"); 438a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 439a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 440a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkAutoLockPixels alp(*decodedBitmap); 441a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 442a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPDecoderConfig config; 443a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_get_config_resize(&config, decodedBitmap, origWidth, origHeight, 4442bbc2c945bb0ecf18fd6473af74ad1a2f5e727a7scroggo@google.com this->shouldPremultiply())) { 445a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 446a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 447a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 448a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // Decode the WebP image data stream using WebP incremental decoding. 449a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return webp_idecode(stream, &config); 450a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 451a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 452a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 453a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 4545007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org#include "SkUnPreMultiply.h" 4555007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org 456a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgtypedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width, 457a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor* SK_RESTRICT ctable); 458a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 459a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 460a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor*) { 461a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint32_t* SK_RESTRICT src = (const uint32_t*)in; 462a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org for (int i = 0; i < width; ++i) { 463a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint32_t c = *src++; 464a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[0] = SkGetPackedR32(c); 465a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[1] = SkGetPackedG32(c); 466a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[2] = SkGetPackedB32(c); 467a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb += 3; 468a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 469a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 470a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 4715007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.orgstatic void ARGB_8888_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, 4725007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkPMColor*) { 4735007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const uint32_t* SK_RESTRICT src = (const uint32_t*)in; 4745007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkUnPreMultiply::Scale* SK_RESTRICT table = 4755007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org SkUnPreMultiply::GetScaleTable(); 4765007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org for (int i = 0; i < width; ++i) { 4775007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const uint32_t c = *src++; 4785007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t a = SkGetPackedA32(c); 4795007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t r = SkGetPackedR32(c); 4805007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t g = SkGetPackedG32(c); 4815007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t b = SkGetPackedB32(c); 4825007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (0 != a && 255 != a) { 4835007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org SkUnPreMultiply::Scale scale = table[a]; 4845007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org r = SkUnPreMultiply::ApplyScale(scale, r); 4855007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org g = SkUnPreMultiply::ApplyScale(scale, g); 4865007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org b = SkUnPreMultiply::ApplyScale(scale, b); 4875007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 4885007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[0] = r; 4895007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[1] = g; 4905007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[2] = b; 4915007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[3] = a; 4925007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb += 4; 4935007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 4945007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org} 4955007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org 496a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 497a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor*) { 498a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint16_t* SK_RESTRICT src = (const uint16_t*)in; 499a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org for (int i = 0; i < width; ++i) { 500a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint16_t c = *src++; 501a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[0] = SkPacked16ToR32(c); 502a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[1] = SkPacked16ToG32(c); 503a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[2] = SkPacked16ToB32(c); 504a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb += 3; 505a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 506a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 507a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 508a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 509a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor*) { 510a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in; 511a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org for (int i = 0; i < width; ++i) { 512a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor16 c = *src++; 513a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[0] = SkPacked4444ToR32(c); 514a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[1] = SkPacked4444ToG32(c); 515a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[2] = SkPacked4444ToB32(c); 516a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb += 3; 517a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 518a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 519a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 5205007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.orgstatic void ARGB_4444_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, 5215007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkPMColor*) { 5225007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in; 5235007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkUnPreMultiply::Scale* SK_RESTRICT table = 5245007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org SkUnPreMultiply::GetScaleTable(); 5255007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org for (int i = 0; i < width; ++i) { 5265007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const SkPMColor16 c = *src++; 5275007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t a = SkPacked4444ToA32(c); 5285007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t r = SkPacked4444ToR32(c); 5295007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t g = SkPacked4444ToG32(c); 5305007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org uint8_t b = SkPacked4444ToB32(c); 5315007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (0 != a && 255 != a) { 5325007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org SkUnPreMultiply::Scale scale = table[a]; 5335007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org r = SkUnPreMultiply::ApplyScale(scale, r); 5345007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org g = SkUnPreMultiply::ApplyScale(scale, g); 5355007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org b = SkUnPreMultiply::ApplyScale(scale, b); 5365007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 5375007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[0] = r; 5385007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[1] = g; 5395007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[2] = b; 5405007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb[3] = a; 5415007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org rgb += 4; 5425007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 5435007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org} 5445007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org 545a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, 546a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor* SK_RESTRICT ctable) { 547a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint8_t* SK_RESTRICT src = (const uint8_t*)in; 548a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org for (int i = 0; i < width; ++i) { 549a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint32_t c = ctable[*src++]; 550a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[0] = SkGetPackedR32(c); 551a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[1] = SkGetPackedG32(c); 552a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb[2] = SkGetPackedB32(c); 553a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org rgb += 3; 554a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 555a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 556a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 5570689d7b12e7c427a077b003d3d8ae759d86f798freedstatic ScanlineImporter ChooseImporter(SkColorType ct, bool hasAlpha, int* bpp) { 5580689d7b12e7c427a077b003d3d8ae759d86f798freed switch (ct) { 5590689d7b12e7c427a077b003d3d8ae759d86f798freed case kN32_SkColorType: 5605007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (hasAlpha) { 5615007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 4; 5625007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org return ARGB_8888_To_RGBA; 5635007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } else { 5645007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 3; 5655007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org return ARGB_8888_To_RGB; 5665007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 5670689d7b12e7c427a077b003d3d8ae759d86f798freed case kARGB_4444_SkColorType: 5685007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (hasAlpha) { 5695007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 4; 5705007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org return ARGB_4444_To_RGBA; 5715007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } else { 5725007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 3; 5735007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org return ARGB_4444_To_RGB; 5745007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 5750689d7b12e7c427a077b003d3d8ae759d86f798freed case kRGB_565_SkColorType: 5765007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 3; 577a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return RGB_565_To_RGB; 5780689d7b12e7c427a077b003d3d8ae759d86f798freed case kIndex_8_SkColorType: 5795007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org *bpp = 3; 580a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return Index8_To_RGB; 581a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org default: 582a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return NULL; 583a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 584a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 585a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 586a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic int stream_writer(const uint8_t* data, size_t data_size, 587a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const WebPPicture* const picture) { 588a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkWStream* const stream = (SkWStream*)picture->custom_ptr; 589a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return stream->write(data, data_size) ? 1 : 0; 590a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 591a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 592a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgclass SkWEBPImageEncoder : public SkImageEncoder { 593a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgprotected: 594a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org virtual bool onEncode(SkWStream* stream, const SkBitmap& bm, int quality) SK_OVERRIDE; 595a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 596a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgprivate: 597a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org typedef SkImageEncoder INHERITED; 598a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org}; 599a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 600a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgbool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, 601a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int quality) { 6025007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const bool hasAlpha = !bm.isOpaque(); 6035007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org int bpp = -1; 6040689d7b12e7c427a077b003d3d8ae759d86f798freed const ScanlineImporter scanline_import = ChooseImporter(bm.colorType(), hasAlpha, &bpp); 605a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (NULL == scanline_import) { 606a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 607a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 6085007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (-1 == bpp) { 6095007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org return false; 6105007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 611a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 612a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkAutoLockPixels alp(bm); 613a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org SkAutoLockColors ctLocker; 614a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (NULL == bm.getPixels()) { 615a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 616a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 617a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 618a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPConfig webp_config; 619bff83f61fa0dafafa4734e791c34551d4cb8b811commit-bot@chromium.org if (!WebPConfigPreset(&webp_config, WEBP_PRESET_DEFAULT, (float) quality)) { 620a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return false; 621a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 622a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 623a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPPicture pic; 624a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPPictureInit(&pic); 625a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org pic.width = bm.width(); 626a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org pic.height = bm.height(); 627a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org pic.writer = stream_writer; 628a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org pic.custom_ptr = (void*)stream; 629a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 630a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const SkPMColor* colors = ctLocker.lockColors(bm); 631a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org const uint8_t* src = (uint8_t*)bm.getPixels(); 6325007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org const int rgbStride = pic.width * bpp; 633a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 634a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // Import (for each scanline) the bit-map image (in appropriate color-space) 635a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // to RGB color space. 636a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org uint8_t* rgb = new uint8_t[rgbStride * pic.height]; 637a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org for (int y = 0; y < pic.height; ++y) { 638a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org scanline_import(src + y * bm.rowBytes(), rgb + y * rgbStride, 639a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org pic.width, colors); 640a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 641a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 6425007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org bool ok; 6435007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org if (bpp == 3) { 6445007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); 6455007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } else { 6465007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org ok = SkToBool(WebPPictureImportRGBA(&pic, rgb, rgbStride)); 6475007aab81ad1394f4ab7833ea230f6462aa07e69commit-bot@chromium.org } 648a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org delete[] rgb; 649a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 650a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org ok = ok && WebPEncode(&webp_config, &pic); 651a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org WebPPictureFree(&pic); 652a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 653a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return ok; 654a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 655a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 656a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 657a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 658a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgDEFINE_DECODER_CREATOR(WEBPImageDecoder); 659a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgDEFINE_ENCODER_CREATOR(WEBPImageEncoder); 660a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org/////////////////////////////////////////////////////////////////////////////// 661a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 662b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comstatic SkImageDecoder* sk_libwebp_dfactory(SkStreamRewindable* stream) { 663a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org int width, height, hasAlpha; 664a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org if (!webp_parse_header(stream, &width, &height, &hasAlpha)) { 665a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return NULL; 666a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org } 667a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 668a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org // Magic matches, call decoder 669a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return SkNEW(SkWEBPImageDecoder); 670a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 671a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 672b5571b3324cf18629a255ec85e189447069c9b14scroggo@google.comstatic SkImageDecoder::Format get_format_webp(SkStreamRewindable* stream) { 67339edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com int width, height, hasAlpha; 67439edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com if (webp_parse_header(stream, &width, &height, &hasAlpha)) { 67539edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return SkImageDecoder::kWEBP_Format; 67639edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com } 67739edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com return SkImageDecoder::kUnknown_Format; 67839edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com} 67939edf4cd94e6fbeb8c1187a588b314e9795c81e4scroggo@google.com 680a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.orgstatic SkImageEncoder* sk_libwebp_efactory(SkImageEncoder::Type t) { 681a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org return (SkImageEncoder::kWEBP_Type == t) ? SkNEW(SkWEBPImageEncoder) : NULL; 682a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org} 683a936e37cc76614868f5b489395bceeb340cc04cdcommit-bot@chromium.org 684bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comstatic SkImageDecoder_DecodeReg gDReg(sk_libwebp_dfactory); 685bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comstatic SkImageDecoder_FormatReg gFormatReg(get_format_webp); 686bd6343b1d60d2a85e930f33f4b06b4502b3e8caamtklein@google.comstatic SkImageEncoder_EncodeReg gEReg(sk_libwebp_efactory); 687