Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / platform / image-decoders / ImageFrame.h
1 /*
2  * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #ifndef ImageFrame_h
28 #define ImageFrame_h
29
30 #include "platform/PlatformExport.h"
31 #include "platform/geometry/IntRect.h"
32 #include "platform/graphics/skia/NativeImageSkia.h"
33 #include "wtf/Assertions.h"
34 #include "wtf/PassRefPtr.h"
35
36 namespace blink {
37
38 // ImageFrame represents the decoded image data.  This buffer is what all
39 // decoders write a single frame into.
40 class PLATFORM_EXPORT ImageFrame {
41 public:
42     enum Status { FrameEmpty, FramePartial, FrameComplete };
43     enum DisposalMethod {
44         // If you change the numeric values of these, make sure you audit
45         // all users, as some users may cast raw values to/from these
46         // constants.
47         DisposeNotSpecified, // Leave frame in framebuffer
48         DisposeKeep, // Leave frame in framebuffer
49         DisposeOverwriteBgcolor, // Clear frame to fully transparent
50         DisposeOverwritePrevious // Clear frame to previous framebuffer contents
51     };
52     // Indicates how non-opaque pixels in the current frame rectangle
53     // are blended with those in the previous frame.
54     // Notes:
55     // * GIF always uses 'BlendAtopPreviousFrame'.
56     // * WebP also uses the 'BlendAtopBgcolor' option. This is useful for
57     //   cases where one wants to transform a few opaque pixels of the
58     //   previous frame into non-opaque pixels in the current frame.
59     enum AlphaBlendSource {
60         // Blend non-opaque pixels atop the corresponding pixels in the
61         // initial buffer state (i.e. any previous frame buffer after having
62         // been properly disposed).
63         BlendAtopPreviousFrame,
64
65         // Blend non-opaque pixels against fully transparent (i.e. simply
66         // overwrite the corresponding pixels).
67         BlendAtopBgcolor,
68     };
69     typedef uint32_t PixelData;
70
71     ImageFrame();
72
73     // The assignment operator reads m_hasAlpha (inside setStatus()) before it
74     // sets it (in setHasAlpha()).  This doesn't cause any problems, since the
75     // setHasAlpha() call ensures all state is set correctly, but it means we
76     // need to initialize m_hasAlpha to some value before calling the operator
77     // lest any tools complain about using an uninitialized value.
78     ImageFrame(const ImageFrame& other) : m_hasAlpha(false) { operator=(other); }
79
80     // For backends which refcount their data, this operator doesn't need to
81     // create a new copy of the image data, only increase the ref count.
82     ImageFrame& operator=(const ImageFrame& other);
83
84     // These do not touch other metadata, only the raw pixel data.
85     void clearPixelData();
86     void zeroFillPixelData();
87     void zeroFillFrameRect(const IntRect&);
88
89     // Makes this frame have an independent copy of the provided image's
90     // pixel data, so that modifications in one frame are not reflected in
91     // the other.  Returns whether the copy succeeded.
92     bool copyBitmapData(const ImageFrame&);
93
94     // Copies the pixel data at [(startX, startY), (endX, startY)) to the
95     // same X-coordinates on each subsequent row up to but not including
96     // endY.
97     void copyRowNTimes(int startX, int endX, int startY, int endY)
98     {
99         ASSERT(startX < width());
100         ASSERT(endX <= width());
101         ASSERT(startY < height());
102         ASSERT(endY <= height());
103         const int rowBytes = (endX - startX) * sizeof(PixelData);
104         const PixelData* const startAddr = getAddr(startX, startY);
105         for (int destY = startY + 1; destY < endY; ++destY)
106             memcpy(getAddr(startX, destY), startAddr, rowBytes);
107     }
108
109     // Allocates space for the pixel data.  Must be called before any pixels
110     // are written.  Must only be called once.  Returns whether allocation
111     // succeeded.
112     bool setSize(int newWidth, int newHeight);
113
114     // Returns a caller-owned pointer to the underlying native image data.
115     // (Actual use: This pointer will be owned by BitmapImage and freed in
116     // FrameData::clear()).
117     PassRefPtr<NativeImageSkia> asNewNativeImage() const;
118
119     bool hasAlpha() const;
120     const IntRect& originalFrameRect() const { return m_originalFrameRect; }
121     Status status() const { return m_status; }
122     unsigned duration() const { return m_duration; }
123     DisposalMethod disposalMethod() const { return m_disposalMethod; }
124     AlphaBlendSource alphaBlendSource() const { return m_alphaBlendSource; }
125     bool premultiplyAlpha() const { return m_premultiplyAlpha; }
126     SkBitmap::Allocator* allocator() const { return m_allocator; }
127     const SkBitmap& getSkBitmap() const { return m_bitmap; }
128     // Returns true if the pixels changed, but the bitmap has not yet been notified.
129     bool pixelsChanged() const { return m_pixelsChanged; }
130
131     size_t requiredPreviousFrameIndex() const
132     {
133         ASSERT(m_requiredPreviousFrameIndexValid);
134         return m_requiredPreviousFrameIndex;
135     }
136 #if ENABLE(ASSERT)
137     bool requiredPreviousFrameIndexValid() const { return m_requiredPreviousFrameIndexValid; }
138 #endif
139     void setHasAlpha(bool alpha);
140     void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
141     void setStatus(Status);
142     void setDuration(unsigned duration) { m_duration = duration; }
143     void setDisposalMethod(DisposalMethod disposalMethod) { m_disposalMethod = disposalMethod; }
144     void setAlphaBlendSource(AlphaBlendSource alphaBlendSource) { m_alphaBlendSource = alphaBlendSource; }
145     void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
146     void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; }
147     void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = bitmap; }
148     // The pixelsChanged flag needs to be set when the raw pixel data was directly modified
149     // (e.g. through a pointer or setRGBA). The flag is usually set after a batch of changes was made.
150     void setPixelsChanged(bool pixelsChanged) { m_pixelsChanged = pixelsChanged; }
151
152     void setRequiredPreviousFrameIndex(size_t previousFrameIndex)
153     {
154         m_requiredPreviousFrameIndex = previousFrameIndex;
155 #if ENABLE(ASSERT)
156         m_requiredPreviousFrameIndexValid = true;
157 #endif
158     }
159
160     inline PixelData* getAddr(int x, int y)
161     {
162         return m_bitmap.getAddr32(x, y);
163     }
164
165     inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
166     {
167         setRGBA(getAddr(x, y), r, g, b, a);
168     }
169
170     inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
171     {
172         if (m_premultiplyAlpha)
173             setRGBAPremultiply(dest, r, g, b, a);
174         else
175             *dest = SkPackARGB32NoCheck(a, r, g, b);
176     }
177
178     static const unsigned div255 = static_cast<unsigned>(1.0 / 255 * (1 << 24)) + 1;
179
180     static inline void setRGBAPremultiply(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
181     {
182         if (a < 255) {
183             if (!a) {
184                 *dest = 0;
185                 return;
186             }
187
188             unsigned alpha = a * div255;
189             r = (r * alpha) >> 24;
190             g = (g * alpha) >> 24;
191             b = (b * alpha) >> 24;
192         }
193
194         // Call the "NoCheck" version since we may deliberately pass non-premultiplied
195         // values, and we don't want an assert.
196         *dest = SkPackARGB32NoCheck(a, r, g, b);
197     }
198
199     static inline void setRGBARaw(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
200     {
201         *dest = SkPackARGB32NoCheck(a, r, g, b);
202     }
203
204     // Notifies the SkBitmap if any pixels changed and resets the flag.
205     inline void notifyBitmapIfPixelsChanged()
206     {
207         if (m_pixelsChanged)
208             m_bitmap.notifyPixelsChanged();
209         m_pixelsChanged = false;
210     }
211
212 private:
213     int width() const
214     {
215         return m_bitmap.width();
216     }
217
218     int height() const
219     {
220         return m_bitmap.height();
221     }
222
223     SkBitmap m_bitmap;
224     SkBitmap::Allocator* m_allocator;
225     bool m_hasAlpha;
226     // This will always just be the entire buffer except for GIF or WebP
227     // frames whose original rect was smaller than the overall image size.
228     IntRect m_originalFrameRect;
229     Status m_status;
230     unsigned m_duration;
231     DisposalMethod m_disposalMethod;
232     AlphaBlendSource m_alphaBlendSource;
233     bool m_premultiplyAlpha;
234     // True if the pixels changed, but the bitmap has not yet been notified.
235     bool m_pixelsChanged;
236
237     // The frame that must be decoded before this frame can be decoded.
238     // WTF::kNotFound if this frame doesn't require any previous frame.
239     // This is used by ImageDecoder::clearCacheExceptFrame(), and will never
240     // be read for image formats that do not have multiple frames.
241     size_t m_requiredPreviousFrameIndex;
242 #if ENABLE(ASSERT)
243     bool m_requiredPreviousFrameIndexValid;
244 #endif
245 };
246
247 } // namespace blink
248
249 #endif