Upstream version 7.36.149.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 WebCore {
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     ImageFrame(const ImageFrame& other) { operator=(other); }
74
75     // For backends which refcount their data, this operator doesn't need to
76     // create a new copy of the image data, only increase the ref count.
77     ImageFrame& operator=(const ImageFrame& other);
78
79     // These do not touch other metadata, only the raw pixel data.
80     void clearPixelData();
81     void zeroFillPixelData();
82     void zeroFillFrameRect(const IntRect&);
83
84     // Makes this frame have an independent copy of the provided image's
85     // pixel data, so that modifications in one frame are not reflected in
86     // the other.  Returns whether the copy succeeded.
87     bool copyBitmapData(const ImageFrame&);
88
89     // Copies the pixel data at [(startX, startY), (endX, startY)) to the
90     // same X-coordinates on each subsequent row up to but not including
91     // endY.
92     void copyRowNTimes(int startX, int endX, int startY, int endY)
93     {
94         ASSERT(startX < width());
95         ASSERT(endX <= width());
96         ASSERT(startY < height());
97         ASSERT(endY <= height());
98         const int rowBytes = (endX - startX) * sizeof(PixelData);
99         const PixelData* const startAddr = getAddr(startX, startY);
100         for (int destY = startY + 1; destY < endY; ++destY)
101             memcpy(getAddr(startX, destY), startAddr, rowBytes);
102     }
103
104     // Allocates space for the pixel data.  Must be called before any pixels
105     // are written.  Must only be called once.  Returns whether allocation
106     // succeeded.
107     bool setSize(int newWidth, int newHeight);
108
109     // Returns a caller-owned pointer to the underlying native image data.
110     // (Actual use: This pointer will be owned by BitmapImage and freed in
111     // FrameData::clear()).
112     PassRefPtr<NativeImageSkia> asNewNativeImage() const;
113
114     bool hasAlpha() const;
115     const IntRect& originalFrameRect() const { return m_originalFrameRect; }
116     Status status() const { return m_status; }
117     unsigned duration() const { return m_duration; }
118     DisposalMethod disposalMethod() const { return m_disposalMethod; }
119     AlphaBlendSource alphaBlendSource() const { return m_alphaBlendSource; }
120     bool premultiplyAlpha() const { return m_premultiplyAlpha; }
121     SkBitmap::Allocator* allocator() const { return m_allocator; }
122     const SkBitmap& getSkBitmap() const { return m_bitmap; }
123     // Returns true if the pixels changed, but the bitmap has not yet been notified.
124     bool pixelsChanged() const { return m_pixelsChanged; }
125
126     size_t requiredPreviousFrameIndex() const
127     {
128         ASSERT(m_requiredPreviousFrameIndexValid);
129         return m_requiredPreviousFrameIndex;
130     }
131 #if !ASSERT_DISABLED
132     bool requiredPreviousFrameIndexValid() const { return m_requiredPreviousFrameIndexValid; }
133 #endif
134     void setHasAlpha(bool alpha);
135     void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; }
136     void setStatus(Status);
137     void setDuration(unsigned duration) { m_duration = duration; }
138     void setDisposalMethod(DisposalMethod disposalMethod) { m_disposalMethod = disposalMethod; }
139     void setAlphaBlendSource(AlphaBlendSource alphaBlendSource) { m_alphaBlendSource = alphaBlendSource; }
140     void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = premultiplyAlpha; }
141     void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; }
142     void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = bitmap; }
143     // The pixelsChanged flag needs to be set when the raw pixel data was directly modified
144     // (e.g. through a pointer or setRGBA). The flag is usually set after a batch of changes was made.
145     void setPixelsChanged(bool pixelsChanged) { m_pixelsChanged = pixelsChanged; }
146
147     void setRequiredPreviousFrameIndex(size_t previousFrameIndex)
148     {
149         m_requiredPreviousFrameIndex = previousFrameIndex;
150 #if !ASSERT_DISABLED
151         m_requiredPreviousFrameIndexValid = true;
152 #endif
153     }
154
155     inline PixelData* getAddr(int x, int y)
156     {
157         return m_bitmap.getAddr32(x, y);
158     }
159
160     inline void setRGBA(int x, int y, unsigned r, unsigned g, unsigned b, unsigned a)
161     {
162         setRGBA(getAddr(x, y), r, g, b, a);
163     }
164
165     static const unsigned div255 = static_cast<unsigned>(1.0 / 255 * (1 << 24)) + 1;
166
167     inline void setRGBA(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
168     {
169         if (m_premultiplyAlpha && a < 255) {
170             if (!a) {
171                 *dest = 0;
172                 return;
173             }
174
175             unsigned alpha = a * div255;
176             r = (r * alpha) >> 24;
177             g = (g * alpha) >> 24;
178             b = (b * alpha) >> 24;
179         }
180
181         // Call the "NoCheck" version since we may deliberately pass non-premultiplied
182         // values, and we don't want an assert.
183         *dest = SkPackARGB32NoCheck(a, r, g, b);
184     }
185
186     inline void setRGBARaw(PixelData* dest, unsigned r, unsigned g, unsigned b, unsigned a)
187     {
188         *dest = SkPackARGB32NoCheck(a, r, g, b);
189     }
190
191     // Notifies the SkBitmap if any pixels changed and resets the flag.
192     inline void notifyBitmapIfPixelsChanged()
193     {
194         if (m_pixelsChanged)
195             m_bitmap.notifyPixelsChanged();
196         m_pixelsChanged = false;
197     }
198
199 private:
200     int width() const
201     {
202         return m_bitmap.width();
203     }
204
205     int height() const
206     {
207         return m_bitmap.height();
208     }
209
210     SkBitmap m_bitmap;
211     SkBitmap::Allocator* m_allocator;
212     bool m_hasAlpha;
213     // This will always just be the entire buffer except for GIF or WebP
214     // frames whose original rect was smaller than the overall image size.
215     IntRect m_originalFrameRect;
216     Status m_status;
217     unsigned m_duration;
218     DisposalMethod m_disposalMethod;
219     AlphaBlendSource m_alphaBlendSource;
220     bool m_premultiplyAlpha;
221     // True if the pixels changed, but the bitmap has not yet been notified.
222     bool m_pixelsChanged;
223
224     // The frame that must be decoded before this frame can be decoded.
225     // WTF::kNotFound if this frame doesn't require any previous frame.
226     // This is used by ImageDecoder::clearCacheExceptFrame(), and will never
227     // be read for image formats that do not have multiple frames.
228     size_t m_requiredPreviousFrameIndex;
229 #if !ASSERT_DISABLED
230     bool m_requiredPreviousFrameIndexValid;
231 #endif
232 };
233
234 } // namespace WebCore
235
236 #endif