diff options
author | glen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-05 23:03:34 +0000 |
---|---|---|
committer | glen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-05 23:03:34 +0000 |
commit | 105513ed46986be8c3089497bc6b960f4648044f (patch) | |
tree | 61bf803b0b97ec3ed0c9da962acfcd20ebb9e894 /base/gfx | |
parent | 68d3c9eabf88ed410127c6ef3ffaf6f007c74a19 (diff) | |
download | chromium_src-105513ed46986be8c3089497bc6b960f4648044f.zip chromium_src-105513ed46986be8c3089497bc6b960f4648044f.tar.gz chromium_src-105513ed46986be8c3089497bc6b960f4648044f.tar.bz2 |
Retry. I believe the code (with your width() * bbp fix) is correct.
The UMR errors occur when the source image contain alpha. I believe the issue comes from webkit glue image decoder, and the reason this only started triggering valgrind errors is that the old ones were masked by the change detailed in bug 12640
Also adds valgrind suppression for the new code.
BUG=12891,12640
TEST=none
Review URL: http://codereview.chromium.org/118297
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17792 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/gfx')
-rw-r--r-- | base/gfx/png_encoder.cc | 42 |
1 files changed, 37 insertions, 5 deletions
diff --git a/base/gfx/png_encoder.cc b/base/gfx/png_encoder.cc index 5021721..9ff4d61 100644 --- a/base/gfx/png_encoder.cc +++ b/base/gfx/png_encoder.cc @@ -5,6 +5,7 @@ #include "base/basictypes.h" #include "base/gfx/png_encoder.h" #include "base/logging.h" +#include "base/scoped_ptr.h" #include "third_party/skia/include/core/SkBitmap.h" extern "C" { @@ -197,9 +198,40 @@ bool PNGEncoder::Encode(const unsigned char* input, ColorFormat format, bool PNGEncoder::EncodeBGRASkBitmap(const SkBitmap& input, bool discard_transparency, std::vector<unsigned char>* output) { - SkAutoLockPixels input_lock(input); - DCHECK(input.empty() || input.bytesPerPixel() == 4); - return Encode(static_cast<unsigned char*>(input.getPixels()), - PNGEncoder::FORMAT_BGRA, input.width(), input.height(), - input.rowBytes(), discard_transparency, output); + static const int bbp = 4; + + SkAutoLockPixels lock_input(input); + CHECK(!input.empty()); + CHECK(input.bytesPerPixel() == bbp); + CHECK(input.getConfig() == SkBitmap::kARGB_8888_Config); + CHECK(input.width() > 1 && input.height() > 1); + + // SkBitmaps are premultiplied, we need to unpremultiply them. + scoped_array<unsigned char> divided( + new unsigned char[input.width() * input.height() * bbp]); + + int i = 0; + for (int y = 0; y < input.height(); y++) { + for (int x = 0; x < input.width(); x++) { + uint32 pixel = input.getAddr32(0, y)[x]; + + int alpha = SkColorGetA(pixel); + if (alpha != 0 && alpha != 255) { + divided[i + 0] = (SkColorGetR(pixel) << 8) / alpha; + divided[i + 1] = (SkColorGetG(pixel) << 8) / alpha; + divided[i + 2] = (SkColorGetB(pixel) << 8) / alpha; + divided[i + 3] = alpha; + } else { + divided[i + 0] = SkColorGetR(pixel); + divided[i + 1] = SkColorGetG(pixel); + divided[i + 2] = SkColorGetB(pixel); + divided[i + 3] = alpha; + } + i += bbp; + } + } + + return Encode(divided.get(), + PNGEncoder::FORMAT_RGBA, input.width(), input.height(), + input.width() * bbp, discard_transparency, output); } |