diff options
Diffstat (limited to 'base/gfx/png_decoder.cc')
-rw-r--r-- | base/gfx/png_decoder.cc | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/base/gfx/png_decoder.cc b/base/gfx/png_decoder.cc index e493464..bd6beb4 100644 --- a/base/gfx/png_decoder.cc +++ b/base/gfx/png_decoder.cc @@ -261,8 +261,8 @@ class PngReadStructDestroyer { // static bool PNGDecoder::Decode(const unsigned char* input, size_t input_size, - ColorFormat format, std::vector<unsigned char>* output, - int* w, int* h) { + ColorFormat format, std::vector<unsigned char>* output, + int* w, int* h) { if (input_size < 8) return false; // Input data too small to be a png @@ -324,7 +324,22 @@ bool PNGDecoder::Decode(const std::vector<unsigned char>* data, &decoded_data, &width, &height)) { bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); bitmap->allocPixels(); - memcpy(bitmap->getPixels(), &decoded_data.front(), width * height * 4); + unsigned char* bitmap_data = + reinterpret_cast<unsigned char*>(bitmap->getAddr32(0, 0)); + for (int i = width * height * 4 - 4; i >= 0; i -= 4) { + unsigned char alpha = decoded_data[i + 3]; + if (alpha != 0 && alpha != 255) { + bitmap_data[i + 3] = alpha; + bitmap_data[i] = (decoded_data[i] * alpha) >> 8; + bitmap_data[i + 1] = (decoded_data[i + 1] * alpha) >> 8; + bitmap_data[i + 2] = (decoded_data[i + 2] * alpha) >> 8; + } else { + bitmap_data[i + 3] = alpha; + bitmap_data[i] = decoded_data[i]; + bitmap_data[i + 1] = decoded_data[i + 1]; + bitmap_data[i + 2] = decoded_data[i + 2]; + } + } return true; } return false; |