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"
51 cairo_surface_t * cairo_surface_map_to_image (cairo_surface_t *surface,
52 const cairo_rectangle_int_t *extents);
54 void cairo_surface_unmap_image (cairo_surface_t *surface,
55 cairo_surface_t *image);
64 struct CairoImageSurface {
65 CairoImageSurface() : m_surface( NULL ){}
73 cairo_surface_t* surface = (cairo_surface_t*)cairo_surface_get_user_data( m_surface, (const cairo_user_data_key_t *)0x80 );
76 printf( "unmap image!!\n" );
77 cairo_surface_unmap_image( surface, m_surface );
78 cairo_surface_destroy( surface );
81 cairo_surface_destroy( m_surface );
85 cairo_surface_t* m_surface;
90 // FIXME: Do we want better encapsulation?
91 typedef Vector<char> ColorProfile;
93 // ImageFrame represents the decoded image data. This buffer is what all
94 // decoders write a single frame into.
97 enum FrameStatus { FrameEmpty, FramePartial, FrameComplete };
98 enum FrameDisposalMethod {
99 // If you change the numeric values of these, make sure you audit
100 // all users, as some users may cast raw values to/from these
102 DisposeNotSpecified, // Leave frame in framebuffer
103 DisposeKeep, // Leave frame in framebuffer
104 DisposeOverwriteBgcolor, // Clear frame to transparent
105 DisposeOverwritePrevious // Clear frame to previous framebuffer
108 #if USE(SKIA) || PLATFORM(QT)
109 typedef uint32_t PixelData;
111 typedef unsigned PixelData;
116 ImageFrame(const ImageFrame& other) { operator=(other); }
118 // For backends which refcount their data, this operator doesn't need to
119 // create a new copy of the image data, only increase the ref count.
120 ImageFrame& operator=(const ImageFrame& other);
122 // These do not touch other metadata, only the raw pixel data.
123 void clearPixelData();
124 void zeroFillPixelData();
126 // Makes this frame have an independent copy of the provided image's
127 // pixel data, so that modifications in one frame are not reflected in
128 // the other. Returns whether the copy succeeded.
129 bool copyBitmapData(const ImageFrame&);
131 // Makes this frame reference the provided image's pixel data, so that
132 // modifications in one frame are reflected in the other.
133 void copyReferenceToBitmapData(const ImageFrame&);
135 // Copies the pixel data at [(startX, startY), (endX, startY)) to the
136 // same X-coordinates on each subsequent row up to but not including
138 void copyRowNTimes(int startX, int endX, int startY, int endY)
140 ASSERT(startX < width());
141 ASSERT(endX <= width());
142 ASSERT(startY < height());
143 ASSERT(endY <= height());
144 const int rowBytes = (endX - startX) * sizeof(PixelData);
145 const PixelData* const startAddr = getAddr(startX, startY);
146 for (int destY = startY + 1; destY < endY; ++destY)
147 memcpy(getAddr(startX, destY), startAddr, rowBytes);
150 // Allocates space for the pixel data. Must be called before any pixels
151 // are written. Must only be called once. Returns whether allocation
153 bool setSize(int newWidth, int newHeight);
155 // Returns a caller-owned pointer to the underlying native image data.
156 // (Actual use: This pointer will be owned by BitmapImage and freed in
157 // FrameData::clear()).
158 NativeImagePtr asNewNativeImage() const;
160 bool hasAlpha() const;
161 const IntRect& originalFrameRect() const { return m_originalFrameRect; }
162 FrameStatus status() const { return m_status; }
163 unsigned duration() const { return m_duration; }
164 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; }
165 bool premultiplyAlpha() const { return m_premultiplyAlpha; }
167 void setHasAlpha(bool alpha);
168 void setColorProfile(const ColorProfile&);
169 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
170 void setStatus(FrameStatus status);
171 void setDuration(unsigned duration) { m_duration = duration; }
172 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; }
173 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
175 inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
177 setRGBA(getAddr(x, y), r, g, b, a);
181 void setPixmap(const QPixmap& pixmap);
186 typedef RetainPtr<CFMutableDataRef> NativeBackingStore;
188 // typedef CairoImageSurface NativeBackingStore;
190 typedef Vector<PixelData> NativeBackingStore;
196 inline PixelData* getAddr(int x, int y)
199 return m_bitmap.bitmap().getAddr32(x, y);
201 m_image = m_pixmap.toImage();
202 m_pixmap = QPixmap();
203 return reinterpret_cast_ptr<QRgb*>(m_image.scanLine(y)) + x;
205 return m_bytes + (y * width()) + x;
209 inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
211 if (m_premultiplyAlpha && !a)
214 if (m_premultiplyAlpha && a < 255) {
215 float alphaPercent = a / 255.0f;
216 r = static_cast<unsigned>(r * alphaPercent);
217 g = static_cast<unsigned>(g * alphaPercent);
218 b = static_cast<unsigned>(b * alphaPercent);
221 // we are sure to call the NoCheck version, since we may
222 // deliberately pass non-premultiplied values, and we don't want
224 *dest = SkPackARGB32NoCheck(a, r, g, b);
226 *dest = (a << 24 | r << 16 | g << 8 | b);
232 NativeImageSkia m_bitmap;
234 mutable QPixmap m_pixmap;
235 mutable QImage m_image;
239 NativeBackingStore m_backingStore;
240 PixelData* m_bytes; // The memory is backed by m_backingStore.
243 ColorProfile m_colorProfile;
245 IntRect m_originalFrameRect; // This will always just be the entire
246 // buffer except for GIF frames whose
247 // original rect was smaller than the
248 // overall image size.
249 FrameStatus m_status;
251 FrameDisposalMethod m_disposalMethod;
252 bool m_premultiplyAlpha;
255 // ImageDecoder is a base for all format-specific decoders
256 // (e.g. JPEGImageDecoder). This base manages the ImageFrame cache.
258 // ENABLE(IMAGE_DECODER_DOWN_SAMPLING) allows image decoders to downsample
259 // at decode time. Image decoders will downsample any images larger than
260 // |m_maxNumPixels|. FIXME: Not yet supported by all decoders.
262 WTF_MAKE_NONCOPYABLE(ImageDecoder); WTF_MAKE_FAST_ALLOCATED;
264 ImageDecoder(ImageSource::AlphaOption alphaOption, ImageSource::GammaAndColorProfileOption gammaAndColorProfileOption)
266 , m_premultiplyAlpha(alphaOption == ImageSource::AlphaPremultiplied)
267 , m_ignoreGammaAndColorProfile(gammaAndColorProfileOption == ImageSource::GammaAndColorProfileIgnored)
268 , m_sizeAvailable(false)
270 , m_isAllDataReceived(false)
271 , m_failed(false) { }
273 virtual ~ImageDecoder() { }
275 // Returns a caller-owned decoder of the appropriate type. Returns 0 if
276 // we can't sniff a supported type from the provided data (possibly
277 // because there isn't enough data yet).
278 static ImageDecoder* create(const SharedBuffer& data, ImageSource::AlphaOption, ImageSource::GammaAndColorProfileOption);
280 virtual String filenameExtension() const = 0;
282 bool isAllDataReceived() const { return m_isAllDataReceived; }
284 virtual void setData(SharedBuffer* data, bool allDataReceived)
289 m_isAllDataReceived = allDataReceived;
292 // Lazily-decodes enough of the image to get the size (if possible).
293 // FIXME: Right now that has to be done by each subclass; factor the
294 // decode call out and use it here.
295 virtual bool isSizeAvailable()
297 return !m_failed && m_sizeAvailable;
300 virtual IntSize size() const { return m_size; }
302 IntSize scaledSize() const
304 return m_scaled ? IntSize(m_scaledColumns.size(), m_scaledRows.size()) : size();
307 // This will only differ from size() for ICO (where each frame is a
308 // different icon) or other formats where different frames are different
309 // sizes. This does NOT differ from size() for GIF, since decoding GIFs
310 // composites any smaller frames against previous frames to create full-
312 virtual IntSize frameSizeAtIndex(size_t) const
317 // Returns whether the size is legal (i.e. not going to result in
318 // overflow elsewhere). If not, marks decoding as failed.
319 virtual bool setSize(unsigned width, unsigned height)
321 if (isOverSize(width, height))
323 m_size = IntSize(width, height);
324 m_sizeAvailable = true;
328 // Lazily-decodes enough of the image to get the frame count (if
329 // possible), without decoding the individual frames.
330 // FIXME: Right now that has to be done by each subclass; factor the
331 // decode call out and use it here.
332 virtual size_t frameCount() { return 1; }
334 virtual int repetitionCount() const { return cAnimationNone; }
336 // Decodes as much of the requested frame as possible, and returns an
337 // ImageDecoder-owned pointer.
338 virtual ImageFrame* frameBufferAtIndex(size_t) = 0;
340 void setIgnoreGammaAndColorProfile(bool flag) { m_ignoreGammaAndColorProfile = flag; }
341 bool ignoresGammaAndColorProfile() const { return m_ignoreGammaAndColorProfile; }
343 // Sets the "decode failure" flag. For caller convenience (since so
344 // many callers want to return false after calling this), returns false
345 // to enable easy tailcalling. Subclasses may override this to also
346 // clean up any local data.
347 virtual bool setFailed()
353 bool failed() const { return m_failed; }
355 // Clears decoded pixel data from before the provided frame unless that
356 // data may be needed to decode future frames (e.g. due to GIF frame
358 virtual void clearFrameBufferCache(size_t) { }
360 #if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
361 void setMaxNumPixels(int m) { m_maxNumPixels = m; }
365 void prepareScaleDataIfNecessary();
366 int upperBoundScaledX(int origX, int searchStart = 0);
367 int lowerBoundScaledX(int origX, int searchStart = 0);
368 int upperBoundScaledY(int origY, int searchStart = 0);
369 int lowerBoundScaledY(int origY, int searchStart = 0);
370 int scaledY(int origY, int searchStart = 0);
372 RefPtr<SharedBuffer> m_data; // The encoded data.
373 Vector<ImageFrame> m_frameBufferCache;
374 ColorProfile m_colorProfile;
376 Vector<int> m_scaledColumns;
377 Vector<int> m_scaledRows;
378 bool m_premultiplyAlpha;
379 bool m_ignoreGammaAndColorProfile;
382 // Some code paths compute the size of the image as "width * height * 4"
383 // and return it as a (signed) int. Avoid overflow.
384 static bool isOverSize(unsigned width, unsigned height)
386 unsigned long long total_size = static_cast<unsigned long long>(width)
387 * static_cast<unsigned long long>(height);
388 return total_size > ((1 << 29) - 1);
392 bool m_sizeAvailable;
394 bool m_isAllDataReceived;
398 } // namespace WebCore