diff options
author | glen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-06 00:43:00 +0000 |
---|---|---|
committer | glen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-06-06 00:43:00 +0000 |
commit | 596fe0c18f6bdcbb8a89adbdd53940927dfccbc3 (patch) | |
tree | e6ed6de2d16484bed2f29977edb631c41a422edc /base/gfx | |
parent | 71421c3fc725d9d55acba7a4233525f8b6e07350 (diff) | |
download | chromium_src-596fe0c18f6bdcbb8a89adbdd53940927dfccbc3.zip chromium_src-596fe0c18f6bdcbb8a89adbdd53940927dfccbc3.tar.gz chromium_src-596fe0c18f6bdcbb8a89adbdd53940927dfccbc3.tar.bz2 |
Re-Retry. This is the change from hell.
Revert DCHECKs to what they used to be - turns out a bunch of stuff in the code depended on input.empty() == true.
---
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.
TBR=Nick
BUG=12891,12640
TEST=none
Review URL: http://codereview.chromium.org/119271
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17811 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/gfx')
-rw-r--r-- | base/gfx/png_encoder.cc | 39 |
1 files changed, 34 insertions, 5 deletions
diff --git a/base/gfx/png_encoder.cc b/base/gfx/png_encoder.cc index 5021721..f8b4bf0 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,37 @@ 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); + DCHECK(input.empty() || input.bytesPerPixel() == bbp); + + // 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); } |