[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

pkasting at chromium.org pkasting at chromium.org
Thu Apr 8 01:09:17 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit d7a400342281ec07268cda5e7bd524eba409e0e4
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