+2006-02-09 Dave Hyatt <hyatt@apple.com
+
+ Minor image cleanup. Move some variables that all the
+ image decoders have in common up into the base class.
+
+ Stub out the boring parts of the JPEG decoder also, so that
+ the patch that does the decoding will be all meat. :)
+
+ Reviewed by mjs
+
+ * WebCore.vcproj/WebCore/WebCore.vcproj:
+ * platform/image-decoders/ImageDecoder.h:
+ (WebCore::ImageDecoder::m_failed):
+ (WebCore::ImageDecoder::size):
+ (WebCore::ImageDecoder::failed):
+ (WebCore::ImageDecoder::setFailed):
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::GIFImageDecoder):
+ (WebCore::GIFImageDecoder::~GIFImageDecoder):
+ (WebCore::GIFImageDecoder::setData):
+ (WebCore::GIFImageDecoder::isSizeAvailable):
+ (WebCore::GIFImageDecoder::repetitionCount):
+ (WebCore::GIFImageDecoder::frameBufferAtIndex):
+ (WebCore::GIFImageDecoder::decode):
+ (WebCore::GIFImageDecoder::decodingHalted):
+ (WebCore::GIFImageDecoder::haveDecodedRow):
+ (WebCore::GIFImageDecoder::gifComplete):
+ * platform/image-decoders/gif/GIFImageDecoder.h:
+ * platform/image-decoders/jpeg/JPEGImageDecoder.cpp: Added.
+ (WebCore::JPEGImageReader::JPEGImageReader):
+ (WebCore::JPEGImageReader::~JPEGImageReader):
+ (WebCore::JPEGImageReader::close):
+ (WebCore::JPEGImageReader::decode):
+ (WebCore::JPEGImageDecoder::JPEGImageDecoder):
+ (WebCore::JPEGImageDecoder::~JPEGImageDecoder):
+ (WebCore::JPEGImageDecoder::setData):
+ (WebCore::JPEGImageDecoder::isSizeAvailable):
+ (WebCore::JPEGImageDecoder::frameBufferAtIndex):
+ (WebCore::JPEGImageDecoder::decode):
+ * platform/image-decoders/jpeg/JPEGImageDecoder.h:
+ * platform/image-decoders/png/PNGImageDecoder.cpp:
+ (WebCore::PNGImageDecoder::PNGImageDecoder):
+ * platform/image-decoders/png/PNGImageDecoder.h:
+
2006-02-09 Maciej Stachowiak <mjs@apple.com>
Rubber-stamped by Hyatt.
RelativePath="..\..\platform\image-decoders\jpeg\jmorecfg.h"\r
>\r
</File>\r
+ <File\r
+ RelativePath="..\..\platform\image-decoders\jpeg\JPEGImageDecoder.cpp"\r
+ >\r
+ </File>\r
+ <File\r
+ RelativePath="..\..\platform\image-decoders\jpeg\JPEGImageDecoder.h"\r
+ >\r
+ </File>\r
<File\r
RelativePath="..\..\platform\image-decoders\jpeg\jpegint.h"\r
>\r
class ImageDecoder
{
public:
+ ImageDecoder() :m_sizeAvailable(false), m_failed(false) {}
virtual ~ImageDecoder() {}
// All specific decoder plugins must do something with the data they are given.
virtual bool isSizeAvailable() const = 0;
// Requests the size.
- virtual IntSize size() const = 0;
+ virtual IntSize size() const { return m_size; }
// The total number of frames for the image. Classes that support multiple frames
// will scan the image data for the answer if they need to (without necessarily
// back the buffer.
virtual RGBA32Buffer frameBufferAtIndex(size_t index) = 0;
+ bool failed() const { return m_failed; }
+ void setFailed() { m_failed = true; }
+
protected:
ByteArray m_data; // The encoded data.
Vector<RGBA32Buffer> m_frameBufferCache;
+ bool m_sizeAvailable;
+ mutable bool m_failed;
+ IntSize m_size;
};
}
};
GIFImageDecoder::GIFImageDecoder()
-: m_frameCountValid(true), m_sizeAvailable(false), m_failed(false), m_impl(0)
+: m_frameCountValid(true), m_reader(0)
{}
GIFImageDecoder::~GIFImageDecoder()
{
- delete m_impl;
+ delete m_reader;
}
// Take the data and store it.
m_frameCountValid = false;
// Create the GIF reader.
- if (!m_impl && !m_failed)
- m_impl = new GIFImageDecoderPrivate(this);
+ if (!m_reader && !m_failed)
+ m_reader = new GIFImageDecoderPrivate(this);
}
// Whether or not the size information has been decoded yet.
bool GIFImageDecoder::isSizeAvailable() const
{
// If we have pending data to decode, send it to the GIF reader now.
- if (!m_sizeAvailable && m_impl) {
+ if (!m_sizeAvailable && m_reader) {
if (m_failed)
return false;
return m_sizeAvailable;
}
-// Requests the size.
-IntSize GIFImageDecoder::size() const
-{
- return m_size;
-}
-
// The total number of frames for the image. Will scan the image data for the answer
// (without necessarily decoding all of the individual frames).
int GIFImageDecoder::frameCount()
{
// We don't have to do any decoding to determine this, since the loop count was determined after
// the initial query for size.
- if (m_impl)
- return m_impl->repetitionCount();
+ if (m_reader)
+ return m_reader->repetitionCount();
return cAnimationNone;
}
return RGBA32Buffer();
const RGBA32Buffer& frame = m_frameBufferCache[index];
- if (frame.status() != RGBA32Buffer::FrameComplete && m_impl)
+ if (frame.status() != RGBA32Buffer::FrameComplete && m_reader)
// Decode this frame.
decode(GIFFullQuery, index+1);
if (m_failed)
return;
- m_failed = !m_impl->decode(m_data, query, haltAtFrame);
+ m_failed = !m_reader->decode(m_data, query, haltAtFrame);
if (m_failed) {
- delete m_impl;
- m_impl = 0;
+ delete m_reader;
+ m_reader = 0;
}
}
void GIFImageDecoder::decodingHalted(unsigned bytesLeft)
{
- m_impl->setReadOffset(m_data.size() - bytesLeft);
+ m_reader->setReadOffset(m_data.size() - bytesLeft);
}
void GIFImageDecoder::haveDecodedRow(unsigned frameIndex,
unsigned colorMapSize;
unsigned char* colorMap;
- m_impl->getColorMap(colorMap, colorMapSize);
+ m_reader->getColorMap(colorMap, colorMapSize);
if (!colorMap)
return;
// within the overall image. The rows we are decoding are within this
// sub-rectangle. This means that if the GIF frame's sub-rectangle is (x,y,w,h) then row 0 is really row
// y, and each row goes from x to x+w.
- unsigned dstPos = (m_impl->frameYOffset() + rowNumber) * m_size.width() + m_impl->frameXOffset();
+ unsigned dstPos = (m_reader->frameYOffset() + rowNumber) * m_size.width() + m_reader->frameXOffset();
unsigned* dst = buffer.bytes().data() + dstPos;
unsigned* currDst = dst;
unsigned char* currentRowByte = rowBuffer;
- bool hasAlpha = m_impl->isTransparent();
+ bool hasAlpha = m_reader->isTransparent();
while (currentRowByte != rowEnd) {
- if ((!hasAlpha || *currentRowByte != m_impl->transparentPixel()) && *currentRowByte < colorMapSize) {
+ if ((!hasAlpha || *currentRowByte != m_reader->transparentPixel()) && *currentRowByte < colorMapSize) {
unsigned colorIndex = *currentRowByte * 3;
unsigned red = colorMap[colorIndex];
unsigned green = colorMap[colorIndex + 1];
void GIFImageDecoder::gifComplete()
{
- delete m_impl;
- m_impl = 0;
+ delete m_reader;
+ m_reader = 0;
}
}
// Whether or not the size information has been decoded yet.
virtual bool isSizeAvailable() const;
- // Requests the size.
- virtual IntSize size() const;
-
// The total number of frames for the image. Will scan the image data for the answer
// (without necessarily decoding all of the individual frames).
virtual int frameCount();
void gifComplete();
private:
- bool m_frameCountValid : 1;
- bool m_sizeAvailable : 1;
- mutable bool m_failed : 1;
- IntSize m_size;
- mutable GIFImageDecoderPrivate* m_impl;
+ bool m_frameCountValid;
+ mutable GIFImageDecoderPrivate* m_reader;
};
}
--- /dev/null
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.
+ *
+ * Portions are Copyright (C) 2001 mozilla.org
+ *
+ * Other contributors:
+ * Stuart Parmenter <pavlov@mozilla.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Alternatively, the contents of this file may be used under the terms
+ * of either the Mozilla Public License Version 1.1, found at
+ * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
+ * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
+ * (the "GPL"), in which case the provisions of the MPL or the GPL are
+ * applicable instead of those above. If you wish to allow use of your
+ * version of this file only under the terms of one of those two
+ * licenses (the MPL or the GPL) and not to allow others to use your
+ * version of this file under the LGPL, indicate your decision by
+ * deletingthe provisions above and replace them with the notice and
+ * other provisions required by the MPL or the GPL, as the case may be.
+ * If you do not delete the provisions above, a recipient may use your
+ * version of this file under any of the LGPL, the MPL or the GPL.
+ */
+
+#include "JPEGImageDecoder.h"
+
+namespace WebCore {
+
+class JPEGImageReader
+{
+public:
+ JPEGImageReader(JPEGImageDecoder* decoder)
+ : m_readOffset(0)
+ {
+ }
+
+ ~JPEGImageReader()
+ {
+ close();
+ }
+
+ void close() {
+ m_readOffset = 0;
+ }
+
+ void decode(const ByteArray& data, bool sizeOnly)
+ {
+ m_decodingSizeOnly = sizeOnly;
+
+ // FIXME: Implement
+ }
+
+private:
+ unsigned m_readOffset;
+ bool m_decodingSizeOnly;
+};
+
+JPEGImageDecoder::JPEGImageDecoder()
+: m_reader(0)
+{}
+
+JPEGImageDecoder::~JPEGImageDecoder()
+{
+ delete m_reader;
+}
+
+// Take the data and store it.
+void JPEGImageDecoder::setData(const ByteArray& data, bool allDataReceived)
+{
+ if (m_failed)
+ return;
+
+ // Cache our new data.
+ ImageDecoder::setData(data, allDataReceived);
+
+ // Create the JPEG reader.
+ if (!m_reader && !m_failed)
+ m_reader = new JPEGImageReader(this);
+}
+
+// Whether or not the size information has been decoded yet.
+bool JPEGImageDecoder::isSizeAvailable() const
+{
+ // If we have pending data to decode, send it to the JPEG reader now.
+ if (!m_sizeAvailable && m_reader) {
+ if (m_failed)
+ return false;
+
+ // The decoder will go ahead and aggressively consume everything up until the
+ // size is encountered.
+ decode(true);
+ }
+
+ return m_sizeAvailable;
+}
+
+RGBA32Buffer JPEGImageDecoder::frameBufferAtIndex(size_t index)
+{
+ if (index != 0)
+ return RGBA32Buffer();
+
+ if (m_frameBufferCache.isEmpty())
+ m_frameBufferCache.resize(1);
+
+ const RGBA32Buffer& frame = m_frameBufferCache[0];
+ if (frame.status() != RGBA32Buffer::FrameComplete && m_reader)
+ // Decode this frame.
+ decode();
+
+ return frame;
+}
+
+// Feed data to the JPEG reader.
+void JPEGImageDecoder::decode(bool sizeOnly) const
+{
+ if (m_failed)
+ return;
+
+ m_reader->decode(m_data, sizeOnly);
+
+ if (m_failed || (!m_frameBufferCache.isEmpty() && m_frameBufferCache[0].status() == RGBA32Buffer::FrameComplete)) {
+ delete m_reader;
+ m_reader = 0;
+ }
+}
+
+}
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef PNG_DECODER_H_
-#define PNG_DECODER_H_
+#ifndef JPEG_DECODER_H_
+#define JPEG_DECODER_H_
#include "ImageDecoder.h"
class JPEGImageReader;
-// This class decodes the PNG image format.
+// This class decodes the JPEG image format.
class JPEGImageDecoder : public ImageDecoder
{
public:
void decode(bool sizeOnly = false) const;
- void setFailed() { m_failed = true; }
-
JPEGImageReader* reader() { return m_reader; }
- // Callbacks from libpng
- void decodingFailed() { m_failed = true; }
- void headerAvailable();
- void rowAvailable(unsigned char* rowBuffer, unsigned rowIndex, int interlacePass);
- void pngComplete();
-
private:
- bool m_sizeAvailable;
- mutable bool m_failed;
- IntSize m_size;
mutable JPEGImageReader* m_reader;
};
};
PNGImageDecoder::PNGImageDecoder()
-: m_sizeAvailable(false)
-, m_failed(false)
-, m_reader(0)
+: m_reader(0)
{}
PNGImageDecoder::~PNGImageDecoder()
return m_sizeAvailable;
}
-// Requests the size.
-IntSize PNGImageDecoder::size() const
-{
- return m_size;
-}
-
-
RGBA32Buffer PNGImageDecoder::frameBufferAtIndex(size_t index)
{
if (index != 0)
// Whether or not the size information has been decoded yet.
virtual bool isSizeAvailable() const;
- // Requests the size.
- virtual IntSize size() const;
-
virtual RGBA32Buffer frameBufferAtIndex(size_t index);
void decode(bool sizeOnly = false) const;
- void setFailed() { m_failed = true; }
-
PNGImageReader* reader() { return m_reader; }
// Callbacks from libpng
void pngComplete();
private:
- bool m_sizeAvailable;
- mutable bool m_failed;
- IntSize m_size;
mutable PNGImageReader* m_reader;
};