[SCM] WebKit Debian packaging branch, debian/unstable, updated. debian/1.1.18-1-697-g2f78b87
pkasting at chromium.org
pkasting at chromium.org
Wed Jan 20 22:25:15 UTC 2010
The following commit has been merged in the debian/unstable branch:
commit c5642a5c5161d7349081f9cc88c3c8741b825e85
Author: pkasting at chromium.org <pkasting at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Fri Jan 15 01:45:23 2010 +0000
Simplify image decoders by making downsampling functions available at
all times, allowing much duplicated logic to be collapsed.
https://bugs.webkit.org/show_bug.cgi?id=28751
Reviewed by Adam Barth.
* platform/graphics/ImageSource.cpp:
(WebCore::ImageSource::setData):
* platform/image-decoders/ImageDecoder.cpp:
(WebCore::ImageDecoder::prepareScaleDataIfNecessary):
* platform/image-decoders/ImageDecoder.h:
(WebCore::ImageDecoder::ImageDecoder):
(WebCore::ImageDecoder::scaledSize):
(WebCore::ImageDecoder::setMaxNumPixels):
* platform/image-decoders/gif/GIFImageDecoder.cpp:
(WebCore::GIFImageDecoder::sizeNowAvailable):
(WebCore::GIFImageDecoder::initFrameBuffer):
(WebCore::GIFImageDecoder::haveDecodedRow):
(WebCore::GIFImageDecoder::frameComplete):
* platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
(WebCore::JPEGImageDecoder::setSize):
(WebCore::JPEGImageDecoder::outputScanlines):
* platform/image-decoders/jpeg/JPEGImageDecoder.h:
* platform/image-decoders/png/PNGImageDecoder.cpp:
(WebCore::PNGImageDecoder::headerAvailable):
(WebCore::PNGImageDecoder::rowAvailable):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53309 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1ac12b4..a1f2a63 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,32 @@
+2010-01-14 Peter Kasting <pkasting at google.com>
+
+ Reviewed by Adam Barth.
+
+ Simplify image decoders by making downsampling functions available at
+ all times, allowing much duplicated logic to be collapsed.
+ https://bugs.webkit.org/show_bug.cgi?id=28751
+
+ * platform/graphics/ImageSource.cpp:
+ (WebCore::ImageSource::setData):
+ * platform/image-decoders/ImageDecoder.cpp:
+ (WebCore::ImageDecoder::prepareScaleDataIfNecessary):
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::ImageDecoder::ImageDecoder):
+ (WebCore::ImageDecoder::scaledSize):
+ (WebCore::ImageDecoder::setMaxNumPixels):
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::sizeNowAvailable):
+ (WebCore::GIFImageDecoder::initFrameBuffer):
+ (WebCore::GIFImageDecoder::haveDecodedRow):
+ (WebCore::GIFImageDecoder::frameComplete):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.cpp:
+ (WebCore::JPEGImageDecoder::setSize):
+ (WebCore::JPEGImageDecoder::outputScanlines):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.h:
+ * platform/image-decoders/png/PNGImageDecoder.cpp:
+ (WebCore::PNGImageDecoder::headerAvailable):
+ (WebCore::PNGImageDecoder::rowAvailable):
+
2010-01-14 Jian Li <jianli at chromium.org>
Reviewed by Eric Seidel.
diff --git a/WebCore/platform/graphics/ImageSource.cpp b/WebCore/platform/graphics/ImageSource.cpp
index 244f3ed..bac4f0a 100644
--- a/WebCore/platform/graphics/ImageSource.cpp
+++ b/WebCore/platform/graphics/ImageSource.cpp
@@ -35,12 +35,6 @@
#include "ImageDecoder.h"
#endif
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
-#ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS
-#define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024)
-#endif
-#endif
-
namespace WebCore {
ImageSource::ImageSource()
@@ -81,6 +75,9 @@ void ImageSource::setData(SharedBuffer* data, bool allDataReceived)
if (!m_decoder) {
m_decoder = static_cast<NativeImageSourcePtr>(ImageDecoder::create(*data));
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
+#ifndef IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS
+#define IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS (1024 * 1024)
+#endif
if (m_decoder)
m_decoder->setMaxNumPixels(IMAGE_DECODER_DOWN_SAMPLING_MAX_NUMBER_OF_PIXELS);
#endif
diff --git a/WebCore/platform/image-decoders/ImageDecoder.cpp b/WebCore/platform/image-decoders/ImageDecoder.cpp
index e9a947e..62f6bec 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/ImageDecoder.cpp
@@ -23,9 +23,8 @@
#include "ImageDecoder.h"
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
#include <algorithm>
-#endif
+#include <cmath>
#include "BMPImageDecoder.h"
#include "GIFImageDecoder.h"
@@ -184,8 +183,6 @@ int RGBA32Buffer::height() const
#endif
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
-
namespace {
enum MatchType {
@@ -210,6 +207,9 @@ inline void fillScaledValues(Vector<int>& scaledValues, double scaleRate, int le
template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, int valueToMatch, int searchStart)
{
+ if (scaledValues.isEmpty())
+ return valueToMatch;
+
const int* dataStart = scaledValues.data();
const int* dataEnd = dataStart + scaledValues.size();
const int* matched = std::lower_bound(dataStart + searchStart, dataEnd, valueToMatch);
@@ -228,18 +228,19 @@ template <MatchType type> int getScaledValue(const Vector<int>& scaledValues, in
void ImageDecoder::prepareScaleDataIfNecessary()
{
- int width = m_size.width();
- int height = m_size.height();
+ int width = size().width();
+ int height = size().height();
int numPixels = height * width;
- if (m_maxNumPixels <= 0 || numPixels <= m_maxNumPixels) {
+ if (m_maxNumPixels > 0 && numPixels > m_maxNumPixels) {
+ m_scaled = true;
+ double scale = sqrt(m_maxNumPixels / (double)numPixels);
+ fillScaledValues(m_scaledColumns, scale, width);
+ fillScaledValues(m_scaledRows, scale, height);
+ } else if (m_scaled) {
m_scaled = false;
- return;
+ m_scaledColumns.clear();
+ m_scaledRows.clear();
}
-
- m_scaled = true;
- double scale = sqrt(m_maxNumPixels / (double)numPixels);
- fillScaledValues(m_scaledColumns, scale, width);
- fillScaledValues(m_scaledRows, scale, height);
}
int ImageDecoder::upperBoundScaledX(int origX, int searchStart)
@@ -267,6 +268,4 @@ int ImageDecoder::scaledY(int origY, int searchStart)
return getScaledValue<Exact>(m_scaledRows, origY, searchStart);
}
-#endif // ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
-
}
diff --git a/WebCore/platform/image-decoders/ImageDecoder.h b/WebCore/platform/image-decoders/ImageDecoder.h
index 558dc77..85aeb93 100644
--- a/WebCore/platform/image-decoders/ImageDecoder.h
+++ b/WebCore/platform/image-decoders/ImageDecoder.h
@@ -130,11 +130,6 @@ namespace WebCore {
setRGBA(getAddr(x, y), r, g, b, a);
}
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- const IntRect& scaledRect() const { return m_scaledRect; }
- void setScaledRect(const IntRect& r) { m_scaledRect = r; }
-#endif
-
#if PLATFORM(QT)
void setDecodedImage(const QImage& image);
QImage decodedImage() const { return m_image; }
@@ -192,9 +187,6 @@ namespace WebCore {
unsigned m_duration; // The animation delay.
FrameDisposalMethod m_disposalMethod;
// What to do with this frame's data when initializing the next frame.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- IntRect m_scaledRect;
-#endif
};
// The ImageDecoder class represents a base class for specific image format decoders
@@ -207,13 +199,11 @@ namespace WebCore {
// biggest size that decoded images can have. Image decoders will deflate those
// images that are bigger than m_maxNumPixels. (Not supported by all image decoders yet)
ImageDecoder()
- : m_failed(false)
+ : m_scaled(false)
+ , m_failed(false)
, m_sizeAvailable(false)
, m_isAllDataReceived(false)
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
, m_maxNumPixels(-1)
- , m_scaled(false)
-#endif
{
}
@@ -252,6 +242,11 @@ namespace WebCore {
return m_size;
}
+ IntSize scaledSize() const
+ {
+ return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
+ }
+
// Returns the size of frame |index|. This will only differ from size()
// for formats where different frames are different sizes (namely ICO,
// where each frame represents a different icon within the master file).
@@ -307,26 +302,20 @@ namespace WebCore {
#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
void setMaxNumPixels(int m) { m_maxNumPixels = m; }
- IntSize scaledSize() const { return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : m_size; }
#endif
protected:
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
void prepareScaleDataIfNecessary();
int upperBoundScaledX(int origX, int searchStart = 0);
int lowerBoundScaledX(int origX, int searchStart = 0);
int upperBoundScaledY(int origY, int searchStart = 0);
int lowerBoundScaledY(int origY, int searchStart = 0);
int scaledY(int origY, int searchStart = 0);
-#endif
RefPtr<SharedBuffer> m_data; // The encoded data.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- int m_maxNumPixels;
Vector<int> m_scaledColumns;
Vector<int> m_scaledRows;
bool m_scaled;
-#endif
Vector<RGBA32Buffer> m_frameBufferCache;
bool m_failed;
@@ -345,6 +334,7 @@ namespace WebCore {
IntSize m_size;
bool m_sizeAvailable;
bool m_isAllDataReceived;
+ int m_maxNumPixels;
};
} // namespace WebCore
diff --git a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
index 3fd442f..c3a6f2d 100644
--- a/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/gif/GIFImageDecoder.cpp
@@ -248,9 +248,7 @@ bool GIFImageDecoder::sizeNowAvailable(unsigned width, unsigned height)
{
if (!setSize(width, height))
return false;
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
prepareScaleDataIfNecessary();
-#endif
return true;
}
@@ -272,27 +270,15 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
frameRect.setHeight(size().height() - m_reader->frameYOffset());
RGBA32Buffer* const buffer = &m_frameBufferCache[frameIndex];
- buffer->setRect(frameRect);
-
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (m_scaled) {
- int left = upperBoundScaledX(frameRect.x());
- int right = lowerBoundScaledX(frameRect.right(), left);
- int top = upperBoundScaledY(frameRect.y());
- int bottom = lowerBoundScaledY(frameRect.bottom(), top);
- buffer->setScaledRect(IntRect(left, top, right - left, bottom - top));
- } else
- buffer->setScaledRect(frameRect);
-#endif
-
+ int left = upperBoundScaledX(frameRect.x());
+ int right = lowerBoundScaledX(frameRect.right(), left);
+ int top = upperBoundScaledY(frameRect.y());
+ int bottom = lowerBoundScaledY(frameRect.bottom(), top);
+ buffer->setRect(IntRect(left, top, right - left, bottom - top));
+
if (frameIndex == 0) {
// This is the first frame, so we're not relying on any previous data.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- const IntSize& bufferSize = scaledSize();
-#else
- const IntSize& bufferSize = size();
-#endif
- if (!buffer->setSize(bufferSize.width(), bufferSize.height())) {
+ if (!buffer->setSize(scaledSize().width(), scaledSize().height())) {
m_failed = true;
return false;
}
@@ -322,13 +308,8 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
} else {
// We want to clear the previous frame to transparent, without
// affecting pixels in the image outside of the frame.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- const IntRect& prevRect = prevBuffer->scaledRect();
- const IntSize& bufferSize = scaledSize();
-#else
const IntRect& prevRect = prevBuffer->rect();
- const IntSize& bufferSize = size();
-#endif
+ const IntSize& bufferSize = scaledSize();
if ((frameIndex == 0)
|| prevRect.contains(IntRect(IntPoint(), bufferSize))) {
// Clearing the first frame, or a frame the size of the whole
@@ -358,27 +339,6 @@ bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex)
return true;
}
-static inline void copyOnePixel(const GIFImageDecoderPrivate* reader, const unsigned char* sourceAddr, unsigned char* colorMap,
- unsigned colorMapSize, bool writeTransparentPixels, RGBA32Buffer& buffer, int x, int y, bool& sawAlpha)
-{
- const unsigned char sourceValue = *sourceAddr;
- if ((!reader->isTransparent() || (sourceValue != reader->transparentPixel())) && (sourceValue < colorMapSize)) {
- const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
- buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
- } else {
- sawAlpha = true;
- // We may or may not need to write transparent pixels to the buffer.
- // If we're compositing against a previous image, it's wrong, and if
- // we're writing atop a cleared, fully transparent buffer, it's
- // unnecessary; but if we're decoding an interlaced gif and
- // displaying it "Haeberli"-style, we must write these for passes
- // beyond the first, or the initial passes will "show through" the
- // later ones.
- if (writeTransparentPixels)
- buffer.setRGBA(x, y, 0, 0, 0, 0);
- }
-}
-
bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
unsigned char* rowBuffer,
unsigned char* rowEnd,
@@ -388,12 +348,16 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
{
// The pixel data and coordinates supplied to us are relative to the frame's
// origin within the entire image size, i.e.
- // (m_reader->frameXOffset(), m_reader->frameYOffset()).
- int x = m_reader->frameXOffset();
- int y = m_reader->frameYOffset() + rowNumber;
-
- // Sanity-check the arguments.
- if ((rowBuffer == 0) || (y >= size().height()))
+ // (m_reader->frameXOffset(), m_reader->frameYOffset()). There is no
+ // guarantee that
+ // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
+ // we must ensure we don't run off the end of either the source data or the
+ // row's X-coordinates.
+ int xBegin = upperBoundScaledX(m_reader->frameXOffset());
+ int yBegin = upperBoundScaledY(m_reader->frameYOffset() + rowNumber);
+ int xEnd = lowerBoundScaledX(std::min(xBegin + (rowEnd - rowBuffer), size().width()) - 1, xBegin + 1) + 1;
+ int yEnd = lowerBoundScaledY(std::min(yBegin + static_cast<int>(repeatCount), size().height()) - 1, yBegin + 1) + 1;
+ if (!rowBuffer || (xBegin < 0) || (yBegin < 0) || (xEnd <= xBegin) || (yEnd <= yBegin))
return true;
// Get the colormap.
@@ -408,58 +372,30 @@ bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameIndex))
return false;
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- int destYBegin = y;
- int destYEnd = std::min(y + static_cast<int>(repeatCount), size().height());
- int destXBegin = x;
- int destXEnd = std::min(x + (rowEnd - rowBuffer), size().width());
-
- if (m_scaled) {
- destYBegin = upperBoundScaledY(destYBegin);
- if (destYBegin < 0)
- return true;
- destYEnd = lowerBoundScaledY(destYEnd - 1, destYBegin + 1);
- if (destYEnd < destYBegin)
- return true;
-
- destXBegin = upperBoundScaledX(destXBegin);
- if (destXBegin < 0)
- return true;
- destXEnd = lowerBoundScaledX(destXEnd - 1, destXBegin + 1);
- if (destXEnd < destXBegin)
- return true;
-
- ++destXEnd;
- ++destYEnd;
- x = destXBegin;
- y = destYBegin;
- }
-#endif
-
- // Write one row's worth of data into the frame. There is no guarantee that
- // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so
- // we must ensure we don't run off the end of either the source data or the
- // row's X-coordinates.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (m_scaled) {
- for (; x < destXEnd; ++x) {
- unsigned char* sourceAddr = rowBuffer + m_scaledColumns[x] - m_reader->frameXOffset();
- copyOnePixel(m_reader, sourceAddr, colorMap, colorMapSize, writeTransparentPixels, buffer, x, y, m_currentBufferSawAlpha);
+ // Write one row's worth of data into the frame.
+ for (int x = xBegin; x < xEnd; ++x) {
+ const unsigned char sourceValue = *(rowBuffer + (m_scaled ? m_scaledColumns[x] : x) - m_reader->frameXOffset());
+ if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparentPixel())) && (sourceValue < colorMapSize)) {
+ const size_t colorIndex = static_cast<size_t>(sourceValue) * 3;
+ buffer.setRGBA(x, yBegin, colorMap[colorIndex], colorMap[colorIndex + 1], colorMap[colorIndex + 2], 255);
+ } else {
+ m_currentBufferSawAlpha = true;
+ // We may or may not need to write transparent pixels to the buffer.
+ // If we're compositing against a previous image, it's wrong, and if
+ // we're writing atop a cleared, fully transparent buffer, it's
+ // unnecessary; but if we're decoding an interlaced gif and
+ // displaying it "Haeberli"-style, we must write these for passes
+ // beyond the first, or the initial passes will "show through" the
+ // later ones.
+ if (writeTransparentPixels)
+ buffer.setRGBA(x, yBegin, 0, 0, 0, 0);
}
- } else
-#endif
- for (unsigned char* sourceAddr = rowBuffer; sourceAddr < rowEnd && x < size().width(); ++sourceAddr, ++x)
- copyOnePixel(m_reader, sourceAddr, colorMap, colorMapSize, writeTransparentPixels, buffer, x, y, m_currentBufferSawAlpha);
-
- // Tell the frame to copy the row data if need be.
- if (repeatCount > 1) {
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- buffer.copyRowNTimes(destXBegin, destXEnd, destYBegin, destYEnd);
-#else
- buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static_cast<int>(repeatCount), size().height()));
-#endif
}
+ // Tell the frame to copy the row data if need be.
+ if (repeatCount > 1)
+ buffer.copyRowNTimes(xBegin, xEnd, yBegin, yEnd);
+
return true;
}
@@ -478,11 +414,7 @@ void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
if (!m_currentBufferSawAlpha) {
// The whole frame was non-transparent, so it's possible that the entire
// resulting buffer was non-transparent, and we can setHasAlpha(false).
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (buffer.scaledRect().contains(IntRect(IntPoint(), scaledSize())))
-#else
- if (buffer.rect().contains(IntRect(IntPoint(), size())))
-#endif
+ if (buffer.rect().contains(IntRect(IntPoint(), scaledSize())))
buffer.setHasAlpha(false);
else if (frameIndex > 0) {
// Tricky case. This frame does not have alpha only if everywhere
@@ -507,11 +439,7 @@ void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
// it had no alpha, and its rect is contained in the current frame's
// rect, we know the current frame has no alpha.
if ((prevBuffer->disposalMethod() == RGBA32Buffer::DisposeOverwriteBgcolor)
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- && !prevBuffer->hasAlpha() && buffer.scaledRect().contains(prevBuffer->scaledRect()))
-#else
&& !prevBuffer->hasAlpha() && buffer.rect().contains(prevBuffer->rect()))
-#endif
buffer.setHasAlpha(false);
}
}
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
index 5d47835..577cbcc 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.cpp
@@ -431,6 +431,14 @@ bool JPEGImageDecoder::isSizeAvailable()
return ImageDecoder::isSizeAvailable();
}
+bool JPEGImageDecoder::setSize(unsigned width, unsigned height)
+{
+ if (!ImageDecoder::setSize(width, height))
+ return false;
+ prepareScaleDataIfNecessary();
+ return true;
+}
+
RGBA32Buffer* JPEGImageDecoder::frameBufferAtIndex(size_t index)
{
if (index)
@@ -460,78 +468,6 @@ void JPEGImageDecoder::decode(bool sizeOnly)
}
}
-static void convertCMYKToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- , bool scaled, const Vector<int>& scaledColumns
-#endif
- )
-{
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (scaled) {
- int numColumns = scaledColumns.size();
- for (int x = 0; x < numColumns; ++x) {
- JSAMPLE* jsample = src + scaledColumns[x] * 4;
- unsigned c = jsample[0];
- unsigned m = jsample[1];
- unsigned y = jsample[2];
- unsigned k = jsample[3];
- dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);
- }
- return;
- }
-#endif
- for (JDIMENSION x = 0; x < srcWidth; ++x) {
- unsigned c = *src++;
- unsigned m = *src++;
- unsigned y = *src++;
- unsigned k = *src++;
-
- // Source is 'Inverted CMYK', output is RGB.
- // See: http://www.easyrgb.com/math.php?MATH=M12#text12
- // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
-
- // From CMYK to CMY
- // C = C * ( 1 - K ) + K
- // M = M * ( 1 - K ) + K
- // Y = Y * ( 1 - K ) + K
-
- // From Inverted CMYK to CMY is thus:
- // C = (1-iC) * (1 - (1-iK)) + (1-iK) => 1 - iC*iK
- // Same for M and Y
-
- // Convert from CMY (0..1) to RGB (0..1)
- // R = 1 - C => 1 - (1 - iC*iK) => iC*iK
- // G = 1 - M => 1 - (1 - iM*iK) => iM*iK
- // B = 1 - Y => 1 - (1 - iY*iK) => iY*iK
-
- dest.setRGBA(x, destY, c * k / 255, m * k / 255, y * k / 255, 0xFF);
- }
-}
-
-static void convertRGBToRGBA(RGBA32Buffer& dest, int destY, JSAMPROW src, JDIMENSION srcWidth
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- , bool scaled, const Vector<int>& scaledColumns
-#endif
- )
-{
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (scaled) {
- int numColumns = scaledColumns.size();
- for (int x = 0; x < numColumns; ++x) {
- JSAMPLE* jsample = src + scaledColumns[x] * 3;
- dest.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
- }
- return;
- }
-#endif
- for (JDIMENSION x = 0; x < srcWidth; ++x) {
- unsigned r = *src++;
- unsigned g = *src++;
- unsigned b = *src++;
- dest.setRGBA(x, destY, r, g, b, 0xFF);
- }
-}
-
bool JPEGImageDecoder::outputScanlines()
{
if (m_frameBufferCache.isEmpty())
@@ -540,17 +476,7 @@ bool JPEGImageDecoder::outputScanlines()
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
- int bufferWidth = size().width();
- int bufferHeight = size().height();
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- // Let's resize our buffer now to the correct width/height.
- if (m_scaled) {
- bufferWidth = m_scaledColumns.size();
- bufferHeight = m_scaledRows.size();
- }
-#endif
-
- if (!buffer.setSize(bufferWidth, bufferHeight)) {
+ if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
m_failed = true;
return false;
}
@@ -572,27 +498,32 @@ bool JPEGImageDecoder::outputScanlines()
if (jpeg_read_scanlines(info, samples, 1) != 1)
return false;
- int destY = sourceY;
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (m_scaled) {
- destY = scaledY(sourceY);
- if (destY < 0)
- continue;
+ int destY = scaledY(sourceY);
+ if (destY < 0)
+ continue;
+ int width = m_scaled ? m_scaledColumns.size() : info->output_width;
+ for (int x = 0; x < width; ++x) {
+ JSAMPLE* jsample = *samples + (m_scaled ? m_scaledColumns[x] : x) * ((info->out_color_space == JCS_RGB) ? 3 : 4);
+ if (info->out_color_space == JCS_RGB)
+ buffer.setRGBA(x, destY, jsample[0], jsample[1], jsample[2], 0xFF);
+ else if (info->out_color_space == JCS_CMYK) {
+ // Source is 'Inverted CMYK', output is RGB.
+ // See: http://www.easyrgb.com/math.php?MATH=M12#text12
+ // Or: http://www.ilkeratalay.com/colorspacesfaq.php#rgb
+ // From CMYK to CMY:
+ // X = X * (1 - K ) + K [for X = C, M, or Y]
+ // Thus, from Inverted CMYK to CMY is:
+ // X = (1-iX) * (1 - (1-iK)) + (1-iK) => 1 - iX*iK
+ // From CMY (0..1) to RGB (0..1):
+ // R = 1 - C => 1 - (1 - iC*iK) => iC*iK [G and B similar]
+ unsigned k = jsample[3];
+ buffer.setRGBA(x, destY, jsample[0] * k / 255, jsample[1] * k / 255, jsample[2] * k / 255, 0xFF);
+ } else {
+ ASSERT_NOT_REACHED();
+ m_failed = true;
+ return false;
+ }
}
- if (info->out_color_space == JCS_RGB)
- convertRGBToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);
- else if (info->out_color_space == JCS_CMYK)
- convertCMYKToRGBA(buffer, destY, *samples, info->output_width, m_scaled, m_scaledColumns);
- else
- return false;
-#else
- if (info->out_color_space == JCS_RGB)
- convertRGBToRGBA(buffer, destY, *samples, info->output_width);
- else if (info->out_color_space == JCS_CMYK)
- convertCMYKToRGBA(buffer, destY, *samples, info->output_width);
- else
- return false;
-#endif
}
return true;
diff --git a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
index 4a822d7..8a4b50f 100644
--- a/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
+++ b/WebCore/platform/image-decoders/jpeg/JPEGImageDecoder.h
@@ -47,6 +47,8 @@ namespace WebCore {
// Whether or not the size information has been decoded yet.
virtual bool isSizeAvailable();
+ virtual bool setSize(unsigned width, unsigned height);
+
virtual RGBA32Buffer* frameBufferAtIndex(size_t index);
virtual bool supportsAlpha() const { return false; }
@@ -58,16 +60,6 @@ namespace WebCore {
bool outputScanlines();
void jpegComplete();
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- bool setSize(int width, int height)
- {
- if (!ImageDecoder::setSize(width, height))
- return false;
- prepareScaleDataIfNecessary();
- return true;
- }
-#endif
-
private:
JPEGImageReader* m_reader;
};
diff --git a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
index 7d9cdd0..8a6e914 100644
--- a/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
+++ b/WebCore/platform/image-decoders/png/PNGImageDecoder.cpp
@@ -256,9 +256,7 @@ void PNGImageDecoder::headerAvailable()
longjmp(png->jmpbuf, 1);
return;
}
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
prepareScaleDataIfNecessary();
-#endif
}
int bitDepth, colorType, interlaceType, compressionType, filterType, channels;
@@ -330,14 +328,7 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
// Initialize the framebuffer if needed.
RGBA32Buffer& buffer = m_frameBufferCache[0];
if (buffer.status() == RGBA32Buffer::FrameEmpty) {
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- int width = m_scaled ? m_scaledColumns.size() : size().width();
- int height = m_scaled ? m_scaledRows.size() : size().height();
-#else
- int width = size().width();
- int height = size().height();
-#endif
- if (!buffer.setSize(width, height)) {
+ if (!buffer.setSize(scaledSize().width(), scaledSize().height())) {
static_cast<PNGImageDecoder*>(png_get_progressive_ptr(reader()->pngPtr()))->decodingFailed();
longjmp(reader()->pngPtr()->jmpbuf, 1);
return;
@@ -396,33 +387,15 @@ void PNGImageDecoder::rowAvailable(unsigned char* rowBuffer, unsigned rowIndex,
row = rowBuffer;
// Copy the data into our buffer.
-#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
- if (m_scaled) {
- int destY = scaledY(rowIndex);
- if (destY < 0)
- return;
- int columns = m_scaledColumns.size();
- bool sawAlpha = buffer.hasAlpha();
- for (int x = 0; x < columns; ++x) {
- png_bytep pixel = row + m_scaledColumns[x] * colorChannels;
- unsigned alpha = (hasAlpha ? pixel[3] : 255);
- buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha);
- if (!sawAlpha && alpha < 255) {
- sawAlpha = true;
- buffer.setHasAlpha(true);
- }
- }
+ int width = scaledSize().width();
+ int destY = scaledY(rowIndex);
+ if (destY < 0)
return;
- }
-#endif
- int width = size().width();
bool sawAlpha = buffer.hasAlpha();
for (int x = 0; x < width; x++) {
- unsigned red = *row++;
- unsigned green = *row++;
- unsigned blue = *row++;
- unsigned alpha = (hasAlpha ? *row++ : 255);
- buffer.setRGBA(x, rowIndex, red, green, blue, alpha);
+ png_bytep pixel = row + (m_scaled ? m_scaledColumns[x] : x) * colorChannels;
+ unsigned alpha = hasAlpha ? pixel[3] : 255;
+ buffer.setRGBA(x, destY, pixel[0], pixel[1], pixel[2], alpha);
if (!sawAlpha && alpha < 255) {
sawAlpha = true;
buffer.setHasAlpha(true);
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list