Index: Source/core/platform/image-decoders/png/PNGImageDecoder.cpp |
diff --git a/Source/core/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/core/platform/image-decoders/png/PNGImageDecoder.cpp |
index 93352a65ef68b2e8b9537629fcb4fbe1ea222520..f70bd80bffd20e0f9f5827a90ea6ea55a4a663e5 100644 |
--- a/Source/core/platform/image-decoders/png/PNGImageDecoder.cpp |
+++ b/Source/core/platform/image-decoders/png/PNGImageDecoder.cpp |
@@ -42,8 +42,9 @@ |
#include "core/platform/PlatformInstrumentation.h" |
#include "png.h" |
-#include <wtf/OwnArrayPtr.h> |
-#include <wtf/PassOwnPtr.h> |
+#include "wtf/MathExtras.h" |
+#include "wtf/OwnArrayPtr.h" |
+#include "wtf/PassOwnPtr.h" |
#if USE(QCMSLIB) |
#include "qcms.h" |
@@ -402,6 +403,29 @@ void PNGImageDecoder::headerAvailable() |
} |
} |
+static inline void setPixelRGB(ImageFrame::PixelData* dest, png_bytep pixel) |
+{ |
+ *dest = 0xFF000000U | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; |
+} |
+ |
+static inline void setPixelRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) |
+{ |
+ unsigned char a = pixel[3]; |
+ *dest = a << 24 | pixel[0] << 16 | pixel[1] << 8 | pixel[2]; |
+ nonTrivialAlphaMask |= (255 - a); |
+} |
+ |
+static inline void setPixelPremultipliedRGBA(ImageFrame::PixelData* dest, png_bytep pixel, unsigned char& nonTrivialAlphaMask) |
+{ |
+ unsigned char a = pixel[3]; |
+ unsigned char r = WTF::fastDivideBy255(pixel[0] * a); |
Noel Gordon
2013/05/25 05:58:26
Agree with Peter that we should consolidate these
|
+ unsigned char g = WTF::fastDivideBy255(pixel[1] * a); |
+ unsigned char b = WTF::fastDivideBy255(pixel[2] * a); |
+ |
+ *dest = a << 24 | r << 16 | g << 8 | b; |
Noel Gordon
2013/05/25 05:58:26
A second reason to consolidate is that here, and e
|
+ nonTrivialAlphaMask |= (255 - a); |
Noel Gordon
2013/05/25 05:58:26
If nonTrivialAlphaMask was initialized to 255 say,
|
+} |
+ |
void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int) |
{ |
if (m_frameBufferCache.isEmpty()) |
@@ -500,27 +524,37 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, |
// Write the decoded row pixels to the frame buffer. |
ImageFrame::PixelData* address = buffer.getAddr(0, y); |
int width = scaledSize().width(); |
- bool nonTrivialAlpha = false; |
+ unsigned char nonTrivialAlphaMask = 0; |
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING) |
Noel Gordon
2013/05/25 05:58:26
Yes, was removed at https://codereview.chromium.or
|
- for (int x = 0; x < width; ++x) { |
- png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels; |
- unsigned alpha = hasAlpha ? pixel[3] : 255; |
- buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); |
- nonTrivialAlpha |= alpha < 255; |
- } |
-#else |
- ASSERT(!m_scaled); |
- png_bytep pixel = row; |
- for (int x = 0; x < width; ++x, pixel += colorChannels) { |
- unsigned alpha = hasAlpha ? pixel[3] : 255; |
- buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); |
- nonTrivialAlpha |= alpha < 255; |
- } |
+ if (m_scaled) { |
+ for (int x = 0; x < width; ++x) { |
+ png_bytep pixel = row + m_scaledColumns[x] * colorChannels; |
+ unsigned alpha = hasAlpha ? pixel[3] : 255; |
+ buffer.setRGBA(address++, pixel[0], pixel[1], pixel[2], alpha); |
+ nonTrivialAlphaMask |= (255 - alpha); |
+ } |
+ } else |
#endif |
+ { |
+ png_bytep pixel = row; |
+ if (hasAlpha) { |
+ if (buffer.premultiplyAlpha()) { |
+ for (int x = 0; x < width; ++x, pixel += 4) |
+ setPixelPremultipliedRGBA(address++, pixel, nonTrivialAlphaMask); |
+ } else { |
+ for (int x = 0; x < width; ++x, pixel += 4) |
+ setPixelRGBA(address++, pixel, nonTrivialAlphaMask); |
+ } |
+ } else { |
+ for (int x = 0; x < width; ++x, pixel += 3) |
+ setPixelRGB(address++, pixel); |
+ } |
+ } |
+ |
- if (nonTrivialAlpha && !buffer.hasAlpha()) |
- buffer.setHasAlpha(nonTrivialAlpha); |
+ if (nonTrivialAlphaMask && !buffer.hasAlpha()) |
+ buffer.setHasAlpha(true); |
} |
void PNGImageDecoder::pngComplete() |