From 4981d1421e31f4229bb3d00d8b6dc93f21b03871 Mon Sep 17 00:00:00 2001 From: Vikas Arora Date: Tue, 21 Aug 2012 10:27:37 -0700 Subject: DO NOT MERGE Support WebP Alpha (Lossless) images Android/Skia supports pre-multiplied Alpha. WebP image format supports Alpha via color modes MODE_RGBA & MODE_RGBA_4444 (corresponding ones for premultiplied alpha are MODE_rgbA & MODE_rgbA_4444). The pre-requisite change for this one is the libwebp patch: https://googleplex-android-review.googlesource.com/#/c/219333/ Change-Id: I30b0d8d4b0325eb3c925371ac8f3a9b7d4801639 --- src/images/SkImageDecoder_libwebp.cpp | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp index b2aea24..3ca1254 100644 --- a/src/images/SkImageDecoder_libwebp.cpp +++ b/src/images/SkImageDecoder_libwebp.cpp @@ -34,7 +34,6 @@ extern "C" { // If moving libwebp out of skia source tree, path for webp headers must be // updated accordingly. Here, we enforce using local copy in webp sub-directory. #include "webp/decode.h" -#include "webp/decode_vp8.h" #include "webp/encode.h" } @@ -146,16 +145,20 @@ static bool return_false(const SkBitmap& bm, const char msg[]) { return false; // must always return false } -static WEBP_CSP_MODE webp_decode_mode(SkBitmap* decodedBitmap) { +static WEBP_CSP_MODE webp_decode_mode(SkBitmap* decodedBitmap, int hasAlpha) { WEBP_CSP_MODE mode = MODE_LAST; SkBitmap::Config config = decodedBitmap->config(); + // For images that have alpha, choose appropriate color mode (MODE_rgbA, + // MODE_rgbA_4444) that pre-multiplies RGB pixel values with transparency + // factor (alpha). if (config == SkBitmap::kARGB_8888_Config) { - mode = MODE_RGBA; + mode = hasAlpha ? MODE_rgbA : MODE_RGBA; } else if (config == SkBitmap::kARGB_4444_Config) { - mode = MODE_RGBA_4444; + mode = hasAlpha ? MODE_rgbA_4444 : MODE_RGBA_4444; } else if (config == SkBitmap::kRGB_565_Config) { mode = MODE_RGB_565; } + SkASSERT(mode != MODE_LAST); return mode; } @@ -211,8 +214,8 @@ static bool webp_idecode(SkStream* stream, WebPDecoderConfig& config) { static bool webp_get_config_resize(WebPDecoderConfig& config, SkBitmap* decodedBitmap, - int width, int height) { - WEBP_CSP_MODE mode = webp_decode_mode(decodedBitmap); + int width, int height, int hasAlpha) { + WEBP_CSP_MODE mode = webp_decode_mode(decodedBitmap, hasAlpha); if (mode == MODE_LAST) { return false; } @@ -239,10 +242,12 @@ static bool webp_get_config_resize(WebPDecoderConfig& config, static bool webp_get_config_resize_crop(WebPDecoderConfig& config, SkBitmap* decodedBitmap, - SkIRect region) { + SkIRect region, int hasAlpha) { - if (!webp_get_config_resize(config, decodedBitmap, - region.width(), region.height())) return false; + if (!webp_get_config_resize( + config, decodedBitmap, region.width(), region.height(), hasAlpha)) { + return false; + } config.options.use_cropping = 1; config.options.crop_left = region.fLeft; @@ -360,7 +365,7 @@ bool SkWEBPImageDecoder::onDecodeRegion(SkBitmap* decodedBitmap, SkAutoLockPixels alp(*bitmap); WebPDecoderConfig config; - if (!webp_get_config_resize_crop(config, bitmap, rect)) { + if (!webp_get_config_resize_crop(config, bitmap, rect, hasAlpha)) { return false; } @@ -418,7 +423,8 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, SkAutoLockPixels alp(*decodedBitmap); WebPDecoderConfig config; - if (!webp_get_config_resize(config, decodedBitmap, origWidth, origHeight)) { + if (!webp_get_config_resize(config, decodedBitmap, origWidth, origHeight, + hasAlpha)) { return false; } @@ -560,7 +566,7 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, static SkImageDecoder* DFactory(SkStream* stream) { int width, height, hasAlpha; if (!webp_parse_header(stream, &width, &height, &hasAlpha)) { - return false; + return NULL; } // Magic matches, call decoder -- cgit v1.1