aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/images
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-26 21:35:17 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2014-02-26 21:35:17 +0000
commit5007aab81ad1394f4ab7833ea230f6462aa07e69 (patch)
tree97876213d3c1e20f7ea77bf1d9898cb1f0aad675 /src/images
parent4ebe3821888d550d8a8b89341ec251ba942f0225 (diff)
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
Diffstat (limited to 'src/images')
-rw-r--r--src/images/SkImageDecoder_libwebp.cpp93
1 files changed, 86 insertions, 7 deletions
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);