summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorglen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 02:44:33 +0000
committerglen@chromium.org <glen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-06-04 02:44:33 +0000
commit4b2fc165182614072ee2fa1c2130c7a5f484a125 (patch)
treec40a2c00f3c94881499bed1c67dd7aaa95ff30fa /base
parent47aef530fe0221533b954264831eebaa792764b6 (diff)
downloadchromium_src-4b2fc165182614072ee2fa1c2130c7a5f484a125.zip
chromium_src-4b2fc165182614072ee2fa1c2130c7a5f484a125.tar.gz
chromium_src-4b2fc165182614072ee2fa1c2130c7a5f484a125.tar.bz2
PNGEncoder wasn't accounting for SkBitmap's premultiplied alpha (PNGDecoder was, however).
BUG=12891 Review URL: http://codereview.chromium.org/118106 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@17590 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/gfx/png_encoder.cc37
1 files changed, 33 insertions, 4 deletions
diff --git a/base/gfx/png_encoder.cc b/base/gfx/png_encoder.cc
index 5021721..d9e22db 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(),
+ // This only works with images with four bytes per pixel.
+ static const int bbp = 4;
+
+ DCHECK(input.empty() || input.bytesPerPixel() == bbp);
+
+ // SkBitmaps are premultiplied, we need to unpremultiply them.
+ scoped_ptr<unsigned char> divided;
+ divided.reset(new unsigned char[input.width() * input.height() * bbp]);
+
+ SkAutoLockPixels lock_input(input);
+ int i = 0;
+ for (int y = 0; y < input.height(); y++) {
+ uint32* src_row = input.getAddr32(0, y);
+ for (int x = 0; x < input.width(); x++) {
+ int alpha = SkColorGetA(src_row[x]);
+ if (alpha != 0 && alpha != 255) {
+ divided.get()[i + 0] = (SkColorGetR(src_row[x]) << 8) / alpha;
+ divided.get()[i + 1] = (SkColorGetG(src_row[x]) << 8) / alpha;
+ divided.get()[i + 2] = (SkColorGetB(src_row[x]) << 8) / alpha;
+ divided.get()[i + 3] = alpha;
+ } else {
+ divided.get()[i + 0] = SkColorGetR(src_row[x]);
+ divided.get()[i + 1] = SkColorGetG(src_row[x]);
+ divided.get()[i + 2] = SkColorGetB(src_row[x]);
+ divided.get()[i + 3] = SkColorGetA(src_row[x]);
+ }
+ i += bbp;
+ }
+ }
+
+ return Encode(divided.release(),
+ PNGEncoder::FORMAT_RGBA, input.width(), input.height(),
input.rowBytes(), discard_transparency, output);
}