2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved.
3 * Copyright (C) 2008-2009 Torch Mobile, Inc.
4 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
5 * Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #ifndef ImageDecoder_h
30 #define ImageDecoder_h
33 #include "ImageSource.h"
34 #include "PlatformString.h"
35 #include "SharedBuffer.h"
36 #include <wtf/Assertions.h>
37 #include <wtf/RefPtr.h>
38 #include <wtf/Vector.h>
41 #include "NativeImageSkia.h"
42 #include "SkColorPriv.h"
50 // FIXME: Do we want better encapsulation?
51 typedef Vector<char> ColorProfile;
53 // ImageFrame represents the decoded image data. This buffer is what all
54 // decoders write a single frame into.
57 enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
58 enum FrameDisposalMethod {
59 // If you change the numeric values of these, make sure you audit
60 // all users, as some users may cast raw values to/from these
62 DisposeNotSpecified, // Leave frame in framebuffer
63 DisposeKeep, // Leave frame in framebuffer
64 DisposeOverwriteBgcolor, // Clear frame to transparent
65 DisposeOverwritePrevious // Clear frame to previous framebuffer
68 #if USE(SKIA) || PLATFORM(QT)
69 typedef uint32_t PixelData;
71 typedef unsigned PixelData;
76 ImageFrame(const ImageFrame& other) { operator=(other); }
78 // For backends which refcount their data, this operator doesn't need to
79 // create a new copy of the image data, only increase the ref count.
80 ImageFrame& operator=(const ImageFrame& other);
82 // These do not touch other metadata, only the raw pixel data.
83 void clearPixelData();
84 void zeroFillPixelData();
86 // Makes this frame have an independent copy of the provided image's
87 // pixel data, so that modifications in one frame are not reflected in
88 // the other. Returns whether the copy succeeded.
89 bool copyBitmapData(const ImageFrame&);
91 // Makes this frame reference the provided image's pixel data, so that
92 // modifications in one frame are reflected in the other.
93 void copyReferenceToBitmapData(const ImageFrame&);
95 // Copies the pixel data at [(startX, startY), (endX, startY)) to the
96 // same X-coordinates on each subsequent row up to but not including
98 void copyRowNTimes(int startX, int endX, int startY, int endY)
100 ASSERT(startX < width());
101 ASSERT(endX <= width());
102 ASSERT(startY < height());
103 ASSERT(endY <= height());
104 const int rowBytes = (endX - startX) * sizeof(PixelData);
105 const PixelData* const startAddr = getAddr(startX, startY);
106 for (int destY = startY + 1; destY < endY; ++destY)
107 memcpy(getAddr(startX, destY), startAddr, rowBytes);
110 // Allocates space for the pixel data. Must be called before any pixels
111 // are written. Must only be called once. Returns whether allocation
113 bool setSize(int newWidth, int newHeight);
115 // Returns a caller-owned pointer to the underlying native image data.
116 // (Actual use: This pointer will be owned by BitmapImage and freed in
117 // FrameData::clear()).
118 NativeImagePtr asNewNativeImage() const;
120 bool hasAlpha() const;
121 const IntRect& originalFrameRect() const { return m_originalFrameRect; }
122 FrameStatus status() const { return m_status; }
123 unsigned duration() const { return m_duration; }
124 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
125 bool premultiplyAlpha() const { return m_premultiplyAlpha; }
127 void setHasAlpha(bool alpha);
128 void setColorProfile(const ColorProfile&);
129 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
130 void setStatus(FrameStatus status);
131 void setDuration(unsigned duration) { m_duration = duration; }
132 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
133 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
135 inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
137 setRGBA(getAddr(x, y), r, g, b, a);
141 void setPixmap(const QPixmap& pixmap);
146 typedef RetainPtr<CFMutableDataRef> NativeBackingStore;
148 typedef Vector<PixelData> NativeBackingStore;
154 inline PixelData* getAddr(int x, int y)
157 return m_bitmap.bitmap().getAddr32(x, y);
159 m_image = m_pixmap.toImage();
160 m_pixmap = QPixmap();
161 return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x;
163 return m_bytes + (y * width()) + x;
167 inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
169 if (m_premultiplyAlpha && !a)
172 if (m_premultiplyAlpha && a < 255) {
173 float alphaPercent = a / 255.0f;
174 r = static_cast<unsigned>(r * alphaPercent);
175 g = static_cast<unsigned>(g * alphaPercent);
176 b = static_cast<unsigned>(b * alphaPercent);
179 // we are sure to call the NoCheck version, since we may
180 // deliberately pass non-premultiplied values, and we don't want
182 *dest = SkPackARGB32NoCheck(a, r, g, b);
184 *dest = (a << 24 | r << 16 | g << 8 | b);
190 NativeImageSkia m_bitmap;
192 mutable QPixmap m_pixmap;
193 mutable QImage m_image;
197 NativeBackingStore m_backingStore;
198 PixelData* m_bytes; // The memory is backed by m_backingStore.
201 ColorProfile m_colorProfile;
203 IntRect m_originalFrameRect; // This will always just be the entire
204 // buffer except for GIF frames whose
205 // original rect was smaller than the
206 // overall image size.
207 FrameStatus m_status;
209 FrameDisposalMethod m_disposalMethod;
210 bool m_premultiplyAlpha;
213 // ImageDecoder is a base for all format-specific decoders
214 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
216 // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
217 // at decode time. Image decoders will downsample any images larger than
218 // |m_maxNumPixels|. FIXME: Not yet supported by all decoders.
220 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
222 ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
224 , m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
225 , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
226 , m_sizeAvailable(false)
228 , m_isAllDataReceived(false)
229 , m_failed(false) { }
231 virtual ~ImageDecoder() { }
233 // Returns a caller-owned decoder of the appropriate type. Returns 0 if
234 // we can't sniff a supported type from the provided data (possibly
235 // because there isn't enough data yet).
236 static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
238 virtual String filenameExtension() const = 0;
240 bool isAllDataReceived() const { return m_isAllDataReceived; }
242 virtual void setData(SharedBuffer* data, bool allDataReceived)
247 m_isAllDataReceived = allDataReceived;
250 // Lazily-decodes enough of the image to get the size (if possible).
251 // FIXME: Right now that has to be done by each subclass; factor the
252 // decode call out and use it here.
253 virtual bool isSizeAvailable()
255 return !m_failed && m_sizeAvailable;
258 virtual IntSize size() const { return m_size; }
260 IntSize scaledSize() const
262 return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
265 // This will only differ from size() for ICO (where each frame is a
266 // different icon) or other formats where different frames are different
267 // sizes. This does NOT differ from size() for GIF, since decoding GIFs
268 // composites any smaller frames against previous frames to create full-
270 virtual IntSize frameSizeAtIndex(size_t) const
275 // Returns whether the size is legal (i.e. not going to result in
276 // overflow elsewhere). If not, marks decoding as failed.
277 virtual bool setSize(unsigned width, unsigned height)
279 if (isOverSize(width, height))
281 m_size = IntSize(width, height);
282 m_sizeAvailable = true;
286 // Lazily-decodes enough of the image to get the frame count (if
287 // possible), without decoding the individual frames.
288 // FIXME: Right now that has to be done by each subclass; factor the
289 // decode call out and use it here.
290 virtual size_t frameCount() { return 1; }
292 virtual int repetitionCount() const { return cAnimationNone; }
294 // Decodes as much of the requested frame as possible, and returns an
295 // ImageDecoder-owned pointer.
296 virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
298 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
299 bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
301 // Sets the "decode failure" flag. For caller convenience (since so
302 // many callers want to return false after calling this), returns false
303 // to enable easy tailcalling. Subclasses may override this to also
304 // clean up any local data.
305 virtual bool setFailed()
311 bool failed() const { return m_failed; }
313 // Clears decoded pixel data from before the provided frame unless that
314 // data may be needed to decode future frames (e.g. due to GIF frame
316 virtual void clearFrameBufferCache(size_t) { }
318 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
319 void setMaxNumPixels(int m) { m_maxNumPixels = m; }
323 void prepareScaleDataIfNecessary();
324 int upperBoundScaledX(int origX, int searchStart = 0);
325 int lowerBoundScaledX(int origX, int searchStart = 0);
326 int upperBoundScaledY(int origY, int searchStart = 0);
327 int lowerBoundScaledY(int origY, int searchStart = 0);
328 int scaledY(int origY, int searchStart = 0);
330 RefPtr<SharedBuffer> m_data; // The encoded data.
331 Vector<ImageFrame> m_frameBufferCache;
332 ColorProfile m_colorProfile;
334 Vector<int> m_scaledColumns;
335 Vector<int> m_scaledRows;
336 bool m_premultiplyAlpha;
337 bool m_ignoreGammaAndColorProfile;
340 // Some code paths compute the size of the image as "width * height * 4"
341 // and return it as a (signed) int. Avoid overflow.
342 static bool isOverSize(unsigned width, unsigned height)
344 unsigned long long total_size = static_cast<unsigned long long>(width)
345 * static_cast<unsigned long long>(height);
346 return total_size > ((1 << 29) - 1);
350 bool m_sizeAvailable;
352 bool m_isAllDataReceived;
356 } // namespace WebCore