Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1438)

Unified Diff: Source/core/platform/image-decoders/png/PNGImageDecoder.cpp

Issue 15466004: Make image decoders faster by refactoring hot loops that fills the lines of ImageFrame. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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()

Powered by Google App Engine
This is Rietveld 408576698