Index: src/ports/SkImageDecoder_CG.cpp |
diff --git a/src/ports/SkImageDecoder_CG.cpp b/src/ports/SkImageDecoder_CG.cpp |
index 8bf30d2cc9b1ba15978fcdfd7d2f7e4631ebe00e..7bebf394da5947dba78ea65b5cb01c95bf63d5bd 100644 |
--- a/src/ports/SkImageDecoder_CG.cpp |
+++ b/src/ports/SkImageDecoder_CG.cpp |
@@ -50,6 +50,56 @@ protected: |
virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); |
}; |
+static void argb_4444_force_opaque(void* row, int count) { |
+ uint16_t* row16 = (uint16_t*)row; |
+ for (int i = 0; i < count; ++i) { |
+ row16[i] |= 0xF000; |
+ } |
+} |
+ |
+static void argb_8888_force_opaque(void* row, int count) { |
+ // can use RGBA or BGRA, they have the same shift for alpha |
+ const uint32_t alphaMask = 0xFF << SK_RGBA_A32_SHIFT; |
+ uint32_t* row32 = (uint32_t*)row; |
+ for (int i = 0; i < count; ++i) { |
+ row32[i] |= alphaMask; |
+ } |
+} |
+ |
+static void alpha_8_force_opaque(void* row, int count) { |
+ memset(row, 0xFF, count); |
+} |
+ |
+static void force_opaque(SkBitmap* bm) { |
+ SkAutoLockPixels alp(*bm); |
+ if (!bm->getPixels()) { |
+ return; |
+ } |
+ |
+ void (*proc)(void*, int); |
+ switch (bm->colorType()) { |
+ case kARGB_4444_SkColorType: |
+ proc = argb_4444_force_opaque; |
+ break; |
+ case kRGBA_8888_SkColorType: |
+ case kBGRA_8888_SkColorType: |
+ proc = argb_8888_force_opaque; |
+ break; |
+ case kAlpha_8_SkColorType: |
+ proc = alpha_8_force_opaque; |
+ break; |
+ default: |
+ return; |
+ } |
+ |
+ char* row = (char*)bm->getPixels(); |
+ for (int y = 0; y < bm->height(); ++y) { |
+ proc(row, bm->width()); |
+ row += bm->rowBytes(); |
+ } |
+ bm->setAlphaType(kOpaque_SkAlphaType); |
+} |
+ |
#define BITMAP_INFO (kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast) |
bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
@@ -89,8 +139,10 @@ bool SkImageDecoder_CG::onDecode(SkStream* stream, SkBitmap* bm, Mode mode) { |
case kCGImageAlphaNone: |
case kCGImageAlphaNoneSkipLast: |
case kCGImageAlphaNoneSkipFirst: |
- SkASSERT(SkBitmap::ComputeIsOpaque(*bm)); |
- bm->setAlphaType(kOpaque_SkAlphaType); |
+ // We're opaque, but we can't rely on the data always having 0xFF |
+ // in the alpha slot (which Skia wants), so we have to ram it in |
+ // ourselves. |
+ force_opaque(bm); |
break; |
default: |
// we don't know if we're opaque or not, so compute it. |