From 5007aab81ad1394f4ab7833ea230f6462aa07e69 Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Wed, 26 Feb 2014 21:35:17 +0000 Subject: Upstream changes from Android R=scroggo@google.com, reed@google.com Author: djsollen@google.com Review URL: https://codereview.chromium.org/176963003 git-svn-id: http://skia.googlecode.com/svn/trunk@13600 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/images/SkImageDecoder_libwebp.cpp | 93 ++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 7 deletions(-) (limited to 'src/images') diff --git a/src/images/SkImageDecoder_libwebp.cpp b/src/images/SkImageDecoder_libwebp.cpp index 05925d03a2..49d5bd1cca 100644 --- a/src/images/SkImageDecoder_libwebp.cpp +++ b/src/images/SkImageDecoder_libwebp.cpp @@ -444,6 +444,8 @@ bool SkWEBPImageDecoder::onDecode(SkStream* stream, SkBitmap* decodedBitmap, /////////////////////////////////////////////////////////////////////////////// +#include "SkUnPreMultiply.h" + typedef void (*ScanlineImporter)(const uint8_t* in, uint8_t* out, int width, const SkPMColor* SK_RESTRICT ctable); @@ -459,6 +461,31 @@ static void ARGB_8888_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } +static void ARGB_8888_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, + const SkPMColor*) { + const uint32_t* SK_RESTRICT src = (const uint32_t*)in; + const SkUnPreMultiply::Scale* SK_RESTRICT table = + SkUnPreMultiply::GetScaleTable(); + for (int i = 0; i < width; ++i) { + const uint32_t c = *src++; + uint8_t a = SkGetPackedA32(c); + uint8_t r = SkGetPackedR32(c); + uint8_t g = SkGetPackedG32(c); + uint8_t b = SkGetPackedB32(c); + if (0 != a && 255 != a) { + SkUnPreMultiply::Scale scale = table[a]; + r = SkUnPreMultiply::ApplyScale(scale, r); + g = SkUnPreMultiply::ApplyScale(scale, g); + b = SkUnPreMultiply::ApplyScale(scale, b); + } + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + rgb[3] = a; + rgb += 4; + } +} + static void RGB_565_To_RGB(const uint8_t* in, uint8_t* rgb, int width, const SkPMColor*) { const uint16_t* SK_RESTRICT src = (const uint16_t*)in; @@ -483,6 +510,31 @@ static void ARGB_4444_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } +static void ARGB_4444_To_RGBA(const uint8_t* in, uint8_t* rgb, int width, + const SkPMColor*) { + const SkPMColor16* SK_RESTRICT src = (const SkPMColor16*)in; + const SkUnPreMultiply::Scale* SK_RESTRICT table = + SkUnPreMultiply::GetScaleTable(); + for (int i = 0; i < width; ++i) { + const SkPMColor16 c = *src++; + uint8_t a = SkPacked4444ToA32(c); + uint8_t r = SkPacked4444ToR32(c); + uint8_t g = SkPacked4444ToG32(c); + uint8_t b = SkPacked4444ToB32(c); + if (0 != a && 255 != a) { + SkUnPreMultiply::Scale scale = table[a]; + r = SkUnPreMultiply::ApplyScale(scale, r); + g = SkUnPreMultiply::ApplyScale(scale, g); + b = SkUnPreMultiply::ApplyScale(scale, b); + } + rgb[0] = r; + rgb[1] = g; + rgb[2] = b; + rgb[3] = a; + rgb += 4; + } +} + static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, const SkPMColor* SK_RESTRICT ctable) { const uint8_t* SK_RESTRICT src = (const uint8_t*)in; @@ -495,15 +547,31 @@ static void Index8_To_RGB(const uint8_t* in, uint8_t* rgb, int width, } } -static ScanlineImporter ChooseImporter(const SkBitmap::Config& config) { +static ScanlineImporter ChooseImporter(const SkBitmap::Config& config, + bool hasAlpha, + int* bpp) { switch (config) { case SkBitmap::kARGB_8888_Config: - return ARGB_8888_To_RGB; + if (hasAlpha) { + *bpp = 4; + return ARGB_8888_To_RGBA; + } else { + *bpp = 3; + return ARGB_8888_To_RGB; + } + case SkBitmap::kARGB_4444_Config: + if (hasAlpha) { + *bpp = 4; + return ARGB_4444_To_RGBA; + } else { + *bpp = 3; + return ARGB_4444_To_RGB; + } case SkBitmap::kRGB_565_Config: + *bpp = 3; return RGB_565_To_RGB; - case SkBitmap::kARGB_4444_Config: - return ARGB_4444_To_RGB; case SkBitmap::kIndex8_Config: + *bpp = 3; return Index8_To_RGB; default: return NULL; @@ -527,10 +595,16 @@ private: bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, int quality) { const SkBitmap::Config config = bm.config(); - const ScanlineImporter scanline_import = ChooseImporter(config); + const bool hasAlpha = !bm.isOpaque(); + int bpp = -1; + const ScanlineImporter scanline_import = ChooseImporter(config, hasAlpha, + &bpp); if (NULL == scanline_import) { return false; } + if (-1 == bpp) { + return false; + } SkAutoLockPixels alp(bm); SkAutoLockColors ctLocker; @@ -552,7 +626,7 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, const SkPMColor* colors = ctLocker.lockColors(bm); const uint8_t* src = (uint8_t*)bm.getPixels(); - const int rgbStride = pic.width * 3; + const int rgbStride = pic.width * bpp; // Import (for each scanline) the bit-map image (in appropriate color-space) // to RGB color space. @@ -562,7 +636,12 @@ bool SkWEBPImageEncoder::onEncode(SkWStream* stream, const SkBitmap& bm, pic.width, colors); } - bool ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); + bool ok; + if (bpp == 3) { + ok = SkToBool(WebPPictureImportRGB(&pic, rgb, rgbStride)); + } else { + ok = SkToBool(WebPPictureImportRGBA(&pic, rgb, rgbStride)); + } delete[] rgb; ok = ok && WebPEncode(&webp_config, &pic); -- cgit v1.2.3