summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-06-20 13:01:08 +0200
commit49233e234e5c787396cadb2cea33b31ae0cd65c1 (patch)
tree5410cb9a8fd53168bb60d62c54b654d86f03c38d /Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
parentb211c645d8ab690f713515dfdc84d80b11c27d2c (diff)
Imported WebKit commit 3a8c29f35d00659d2ce7a0ccdfa8304f14e82327 (http://svn.webkit.org/repository/webkit/trunk@120813)
New snapshot with Windows build fixes
Diffstat (limited to 'Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp')
-rw-r--r--Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp90
1 files changed, 77 insertions, 13 deletions
diff --git a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index 815b0961d..138d5c512 100644
--- a/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/Source/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -41,12 +41,17 @@
#include "PNGImageDecoder.h"
#include "png.h"
+#include <wtf/OwnArrayPtr.h>
#include <wtf/PassOwnPtr.h>
#if PLATFORM(CHROMIUM)
#include "TraceEvent.h"
#endif
+#if USE(QCMSLIB)
+#include "qcms.h"
+#endif
+
#if defined(PNG_LIBPNG_VER_MAJOR) && defined(PNG_LIBPNG_VER_MINOR) && (PNG_LIBPNG_VER_MAJOR > 1 || (PNG_LIBPNG_VER_MAJOR == 1 && PNG_LIBPNG_VER_MINOR >= 4))
#define JMPBUF(png_ptr) png_jmpbuf(png_ptr)
#else
@@ -107,10 +112,14 @@ class PNGImageReader
public:
PNGImageReader(PNGImageDecoder* decoder)
: m_readOffset(0)
+ , m_currentBufferSize(0)
, m_decodingSizeOnly(false)
- , m_interlaceBuffer(0)
, m_hasAlpha(false)
- , m_currentBufferSize(0)
+ , m_interlaceBuffer(0)
+#if USE(QCMSLIB)
+ , m_transform(0)
+ , m_rowBuffer()
+#endif
{
m_png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, decodingFailed, decodingWarning);
m_info = png_create_info_struct(m_png);
@@ -127,13 +136,16 @@ public:
if (m_png && m_info)
// This will zero the pointers.
png_destroy_read_struct(&m_png, &m_info, 0);
+#if USE(QCMSLIB)
+ if (m_transform)
+ qcms_transform_release(m_transform);
+ m_transform = 0;
+#endif
delete[] m_interlaceBuffer;
m_interlaceBuffer = 0;
m_readOffset = 0;
}
- unsigned currentBufferSize() const { return m_currentBufferSize; }
-
bool decode(const SharedBuffer& data, bool sizeOnly)
{
m_decodingSizeOnly = sizeOnly;
@@ -157,25 +169,57 @@ public:
return false;
}
- bool decodingSizeOnly() const { return m_decodingSizeOnly; }
png_structp pngPtr() const { return m_png; }
png_infop infoPtr() const { return m_info; }
- png_bytep interlaceBuffer() const { return m_interlaceBuffer; }
- bool hasAlpha() const { return m_hasAlpha; }
void setReadOffset(unsigned offset) { m_readOffset = offset; }
- void setHasAlpha(bool b) { m_hasAlpha = b; }
+ unsigned currentBufferSize() const { return m_currentBufferSize; }
+ bool decodingSizeOnly() const { return m_decodingSizeOnly; }
+ void setHasAlpha(bool hasAlpha) { m_hasAlpha = hasAlpha; }
+ bool hasAlpha() const { return m_hasAlpha; }
+ png_bytep interlaceBuffer() const { return m_interlaceBuffer; }
void createInterlaceBuffer(int size) { m_interlaceBuffer = new png_byte[size]; }
+#if USE(QCMSLIB)
+ png_bytep rowBuffer() const { return m_rowBuffer.get(); }
+ void createRowBuffer(int size) { m_rowBuffer = adoptArrayPtr(new png_byte[size]); }
+ qcms_transform* colorTransform() const { return m_transform; }
+
+ void createColorTransform(const ColorProfile& colorProfile, bool hasAlpha)
+ {
+ if (m_transform)
+ qcms_transform_release(m_transform);
+ m_transform = 0;
+
+ if (colorProfile.isEmpty())
+ return;
+ qcms_profile* deviceProfile = ImageDecoder::qcmsOutputDeviceProfile();
+ if (!deviceProfile)
+ return;
+ qcms_profile* inputProfile = qcms_profile_from_memory(colorProfile.data(), colorProfile.size());
+ if (!inputProfile)
+ return;
+ // We currently only support color profiles for RGB and RGBA images.
+ ASSERT(icSigRgbData == qcms_profile_get_color_space(inputProfile));
+ qcms_data_type dataFormat = hasAlpha ? QCMS_DATA_RGBA_8 : QCMS_DATA_RGB_8;
+ // FIXME: Don't force perceptual intent if the image profile contains an intent.
+ m_transform = qcms_transform_create(inputProfile, dataFormat, deviceProfile, dataFormat, QCMS_INTENT_PERCEPTUAL);
+ qcms_profile_release(inputProfile);
+ }
+#endif
private:
- unsigned m_readOffset;
- bool m_decodingSizeOnly;
png_structp m_png;
png_infop m_info;
- png_bytep m_interlaceBuffer;
- bool m_hasAlpha;
+ unsigned m_readOffset;
unsigned m_currentBufferSize;
+ bool m_decodingSizeOnly;
+ bool m_hasAlpha;
+ png_bytep m_interlaceBuffer;
+#if USE(QCMSLIB)
+ qcms_transform* m_transform;
+ OwnArrayPtr<png_byte> m_rowBuffer;
+#endif
};
PNGImageDecoder::PNGImageDecoder(ImageSource::AlphaOption alphaOption,
@@ -298,6 +342,10 @@ void PNGImageDecoder::headerAvailable()
// the color profile or we'd need to decode into a gray-scale image buffer and
// hand that to CoreGraphics.
readColorProfile(png, info, m_colorProfile);
+#if USE(QCMSLIB)
+ m_reader->createColorTransform(m_colorProfile, colorType & PNG_COLOR_MASK_ALPHA);
+ m_colorProfile.clear();
+#endif
}
// The options we set here match what Mozilla does.
@@ -367,8 +415,8 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
return;
}
+ unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
if (PNG_INTERLACE_ADAM7 == png_get_interlace_type(png, m_reader->infoPtr())) {
- unsigned colorChannels = m_reader->hasAlpha() ? 4 : 3;
m_reader->createInterlaceBuffer(colorChannels * size().width() * size().height());
if (!m_reader->interlaceBuffer()) {
longjmp(JMPBUF(png), 1);
@@ -376,6 +424,15 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
}
}
+#if USE(QCMSLIB)
+ if (m_reader->colorTransform()) {
+ m_reader->createRowBuffer(colorChannels * size().width());
+ if (!m_reader->rowBuffer()) {
+ longjmp(JMPBUF(png), 1);
+ return;
+ }
+ }
+#endif
buffer.setStatus(ImageFrame::FramePartial);
buffer.setHasAlpha(false);
buffer.setColorProfile(m_colorProfile);
@@ -433,6 +490,13 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
png_progressive_combine_row(m_reader->pngPtr(), row, rowBuffer);
}
+#if USE(QCMSLIB)
+ if (qcms_transform* transform = m_reader->colorTransform()) {
+ qcms_transform_data(transform, row, m_reader->rowBuffer(), size().width());
+ row = m_reader->rowBuffer();
+ }
+#endif
+
// Write the decoded row pixels to the frame buffer.
int width = scaledSize().width();
bool nonTrivialAlpha = false;