OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. |
3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. | 3 * Copyright (C) Research In Motion Limited 2009-2010. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
57 enum FrameDisposalMethod { | 57 enum FrameDisposalMethod { |
58 // If you change the numeric values of these, make sure you audit | 58 // If you change the numeric values of these, make sure you audit |
59 // all users, as some users may cast raw values to/from these | 59 // all users, as some users may cast raw values to/from these |
60 // constants. | 60 // constants. |
61 DisposeNotSpecified, // Leave frame in framebuffer | 61 DisposeNotSpecified, // Leave frame in framebuffer |
62 DisposeKeep, // Leave frame in framebuffer | 62 DisposeKeep, // Leave frame in framebuffer |
63 DisposeOverwriteBgcolor, // Clear frame to transparent | 63 DisposeOverwriteBgcolor, // Clear frame to transparent |
64 DisposeOverwritePrevious // Clear frame to previous framebuffer | 64 DisposeOverwritePrevious // Clear frame to previous framebuffer |
65 // contents | 65 // contents |
66 }; | 66 }; |
67 // Indicates how transparent pixels of the current frame rectangle are | |
68 // blended with those of the previous frame buffer. | |
69 // Notes: | |
70 // * GIF always uses 'BlendAtopPreviousFrame'. | |
71 // * WebP also gives 'BlendAtopBgcolor' option. This is useful for cases | |
Peter Kasting
2013/08/22 20:04:36
Nit: So you never stated clearly in the private em
urvang (Google)
2013/08/22 23:25:14
Short answer: WebP does have a background color co
Peter Kasting
2013/08/22 23:39:31
Uggghhhh, I can't believe you guys put in somethin
urvang (Google)
2013/08/23 00:13:35
I completely understand your point. We would have
Peter Kasting
2013/08/23 00:17:55
"Behave inconsistently" is a bug, not a use case.
urvang (Google)
2013/08/23 00:21:32
Point taken.
The spec is, in fact, locked in term
| |
72 // where one wants to transform a few opaque pixels of previous frame | |
73 // into non-opaque pixels in the current frame. | |
74 enum AlphaBlendSourceForSubframe { | |
Peter Kasting
2013/08/22 20:04:36
Nit: Since I was mistaken about thinking this was
urvang (Google)
2013/08/22 23:25:14
Using the name 'AlphaBlendSource'.
| |
75 BlendAtopPreviousFrame, // Compose the rectangle of current frame by blending it with corresponding pixels in the previous (disposed) framebuffer. | |
Peter Kasting
2013/08/22 20:04:36
Nit: Put these comments above the enum values (and
urvang (Google)
2013/08/22 23:25:14
Done.
| |
76 BlendAtopBgcolor, // Compose the rectangle of current frame by over- writing the corresponding pixels in the previous (disposed) framebuffer. | |
77 }; | |
67 typedef uint32_t PixelData; | 78 typedef uint32_t PixelData; |
68 | 79 |
69 ImageFrame(); | 80 ImageFrame(); |
70 | 81 |
71 ImageFrame(const ImageFrame& other) { operator=(other); } | 82 ImageFrame(const ImageFrame& other) { operator=(other); } |
72 | 83 |
73 // For backends which refcount their data, this operator doesn't need to | 84 // For backends which refcount their data, this operator doesn't need to |
74 // create a new copy of the image data, only increase the ref count. | 85 // create a new copy of the image data, only increase the ref count. |
75 ImageFrame& operator=(const ImageFrame& other); | 86 ImageFrame& operator=(const ImageFrame& other); |
76 | 87 |
(...skipping 30 matching lines...) Expand all Loading... | |
107 // Returns a caller-owned pointer to the underlying native image data. | 118 // Returns a caller-owned pointer to the underlying native image data. |
108 // (Actual use: This pointer will be owned by BitmapImage and freed in | 119 // (Actual use: This pointer will be owned by BitmapImage and freed in |
109 // FrameData::clear()). | 120 // FrameData::clear()). |
110 PassRefPtr<NativeImageSkia> asNewNativeImage() const; | 121 PassRefPtr<NativeImageSkia> asNewNativeImage() const; |
111 | 122 |
112 bool hasAlpha() const; | 123 bool hasAlpha() const; |
113 const IntRect& originalFrameRect() const { return m_originalFrameRect; } | 124 const IntRect& originalFrameRect() const { return m_originalFrameRect; } |
114 FrameStatus status() const { return m_status; } | 125 FrameStatus status() const { return m_status; } |
115 unsigned duration() const { return m_duration; } | 126 unsigned duration() const { return m_duration; } |
116 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } | 127 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } |
128 AlphaBlendSourceForSubframe alphaBlendSource() const { return m_alphaBle ndSource; } | |
117 bool premultiplyAlpha() const { return m_premultiplyAlpha; } | 129 bool premultiplyAlpha() const { return m_premultiplyAlpha; } |
118 SkBitmap::Allocator* allocator() const { return m_allocator; } | 130 SkBitmap::Allocator* allocator() const { return m_allocator; } |
119 const SkBitmap& getSkBitmap() const { return m_bitmap->bitmap(); } | 131 const SkBitmap& getSkBitmap() const { return m_bitmap->bitmap(); } |
120 | 132 |
121 size_t requiredPreviousFrameIndex() const | 133 size_t requiredPreviousFrameIndex() const |
122 { | 134 { |
123 ASSERT(m_requiredPreviousFrameIndexValid); | 135 ASSERT(m_requiredPreviousFrameIndexValid); |
124 return m_requiredPreviousFrameIndex; | 136 return m_requiredPreviousFrameIndex; |
125 } | 137 } |
126 #if !ASSERT_DISABLED | 138 #if !ASSERT_DISABLED |
127 bool requiredPreviousFrameIndexValid() const { return m_requiredPrevious FrameIndexValid; } | 139 bool requiredPreviousFrameIndexValid() const { return m_requiredPrevious FrameIndexValid; } |
128 #endif | 140 #endif |
129 void setHasAlpha(bool alpha); | 141 void setHasAlpha(bool alpha); |
130 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } | 142 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } |
131 void setStatus(FrameStatus status); | 143 void setStatus(FrameStatus status); |
132 void setDuration(unsigned duration) { m_duration = duration; } | 144 void setDuration(unsigned duration) { m_duration = duration; } |
133 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; } | 145 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod = method; } |
146 void setAlphaBlendSource(AlphaBlendSourceForSubframe source) { m_alphaBl endSource = source; } | |
134 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = p remultiplyAlpha; } | 147 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = p remultiplyAlpha; } |
135 void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; } | 148 void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator = allocator; } |
136 void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = NativeImageSkia::c reate(bitmap); } | 149 void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = NativeImageSkia::c reate(bitmap); } |
137 | 150 |
138 void setRequiredPreviousFrameIndex(size_t previousFrameIndex) | 151 void setRequiredPreviousFrameIndex(size_t previousFrameIndex) |
139 { | 152 { |
140 m_requiredPreviousFrameIndex = previousFrameIndex; | 153 m_requiredPreviousFrameIndex = previousFrameIndex; |
141 #if !ASSERT_DISABLED | 154 #if !ASSERT_DISABLED |
142 m_requiredPreviousFrameIndexValid = true; | 155 m_requiredPreviousFrameIndexValid = true; |
143 #endif | 156 #endif |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
192 | 205 |
193 RefPtr<NativeImageSkia> m_bitmap; | 206 RefPtr<NativeImageSkia> m_bitmap; |
194 SkBitmap::Allocator* m_allocator; | 207 SkBitmap::Allocator* m_allocator; |
195 bool m_hasAlpha; | 208 bool m_hasAlpha; |
196 // This will always just be the entire buffer except for GIF or WebP | 209 // This will always just be the entire buffer except for GIF or WebP |
197 // frames whose original rect was smaller than the overall image size. | 210 // frames whose original rect was smaller than the overall image size. |
198 IntRect m_originalFrameRect; | 211 IntRect m_originalFrameRect; |
199 FrameStatus m_status; | 212 FrameStatus m_status; |
200 unsigned m_duration; | 213 unsigned m_duration; |
201 FrameDisposalMethod m_disposalMethod; | 214 FrameDisposalMethod m_disposalMethod; |
215 AlphaBlendSourceForSubframe m_alphaBlendSource; | |
202 bool m_premultiplyAlpha; | 216 bool m_premultiplyAlpha; |
203 | 217 |
204 // The frame that must be decoded before this frame can be decoded. | 218 // The frame that must be decoded before this frame can be decoded. |
205 // WTF::notFound if this frame doesn't require any previous frame. | 219 // WTF::notFound if this frame doesn't require any previous frame. |
206 // This is used by ImageDecoder::clearCacheExceptFrame(), and will never | 220 // This is used by ImageDecoder::clearCacheExceptFrame(), and will never |
207 // be read for image formats that do not have multiple frames. | 221 // be read for image formats that do not have multiple frames. |
208 size_t m_requiredPreviousFrameIndex; | 222 size_t m_requiredPreviousFrameIndex; |
209 #if !ASSERT_DISABLED | 223 #if !ASSERT_DISABLED |
210 bool m_requiredPreviousFrameIndexValid; | 224 bool m_requiredPreviousFrameIndexValid; |
211 #endif | 225 #endif |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
376 // If the image has a cursor hot-spot, stores it in the argument | 390 // If the image has a cursor hot-spot, stores it in the argument |
377 // and returns true. Otherwise returns false. | 391 // and returns true. Otherwise returns false. |
378 virtual bool hotSpot(IntPoint&) const { return false; } | 392 virtual bool hotSpot(IntPoint&) const { return false; } |
379 | 393 |
380 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator) | 394 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator) |
381 { | 395 { |
382 // FIXME: this doesn't work for images with multiple frames. | 396 // FIXME: this doesn't work for images with multiple frames. |
383 if (m_frameBufferCache.isEmpty()) { | 397 if (m_frameBufferCache.isEmpty()) { |
384 m_frameBufferCache.resize(1); | 398 m_frameBufferCache.resize(1); |
385 m_frameBufferCache[0].setRequiredPreviousFrameIndex( | 399 m_frameBufferCache[0].setRequiredPreviousFrameIndex( |
386 findRequiredPreviousFrame(0)); | 400 findRequiredPreviousFrame(0, false)); |
387 } | 401 } |
388 m_frameBufferCache[0].setMemoryAllocator(allocator); | 402 m_frameBufferCache[0].setMemoryAllocator(allocator); |
389 } | 403 } |
390 | 404 |
391 protected: | 405 protected: |
392 // Calculates the most recent frame whose image data may be needed in | 406 // Calculates the most recent frame whose image data may be needed in |
393 // order to decode frame |frameIndex|, based on frame disposal methods. | 407 // order to decode frame |frameIndex|, based on frame disposal methods |
408 // and 'frameRectIsOpaque', where 'frameRectIsOpaque' signifies whether | |
Peter Kasting
2013/08/22 20:04:36
Nit: Use || instead of '' to denote variable names
urvang (Google)
2013/08/22 23:25:14
Done.
| |
409 // the rectangle of frame at 'frameIndex' is known to be opaque. | |
394 // If no previous frame's data is required, returns WTF::notFound. | 410 // If no previous frame's data is required, returns WTF::notFound. |
395 // | 411 // |
396 // This function requires that the previous frame's | 412 // This function requires that the previous frame's |
397 // |m_requiredPreviousFrameIndex| member has been set correctly. The | 413 // |m_requiredPreviousFrameIndex| member has been set correctly. The |
398 // easiest way to ensure this is for subclasses to call this method and | 414 // easiest way to ensure this is for subclasses to call this method and |
399 // store the result on the frame via setRequiredPreviousFrameIndex() | 415 // store the result on the frame via setRequiredPreviousFrameIndex() |
400 // as soon as the frame has been created and parsed sufficiently to | 416 // as soon as the frame has been created and parsed sufficiently to |
401 // determine the disposal method; assuming this happens for all frames | 417 // determine the disposal method; assuming this happens for all frames |
402 // in order, the required invariant will hold. | 418 // in order, the required invariant will hold. |
403 // | 419 // |
404 // Image formats which do not use more than one frame do not need to | 420 // Image formats which do not use more than one frame do not need to |
405 // worry about this; see comments on | 421 // worry about this; see comments on |
406 // ImageFrame::m_requiredPreviousFrameIndex. | 422 // ImageFrame::m_requiredPreviousFrameIndex. |
407 size_t findRequiredPreviousFrame(size_t frameIndex); | 423 size_t findRequiredPreviousFrame(size_t frameIndex, bool frameRectIsOpaq ue); |
408 | 424 |
409 virtual void clearFrameBuffer(size_t frameIndex); | 425 virtual void clearFrameBuffer(size_t frameIndex); |
410 | 426 |
411 RefPtr<SharedBuffer> m_data; // The encoded data. | 427 RefPtr<SharedBuffer> m_data; // The encoded data. |
412 Vector<ImageFrame, 1> m_frameBufferCache; | 428 Vector<ImageFrame, 1> m_frameBufferCache; |
413 bool m_premultiplyAlpha; | 429 bool m_premultiplyAlpha; |
414 bool m_ignoreGammaAndColorProfile; | 430 bool m_ignoreGammaAndColorProfile; |
415 ImageOrientation m_orientation; | 431 ImageOrientation m_orientation; |
416 | 432 |
417 private: | 433 private: |
418 // Some code paths compute the size of the image as "width * height * 4" | 434 // Some code paths compute the size of the image as "width * height * 4" |
419 // and return it as a (signed) int. Avoid overflow. | 435 // and return it as a (signed) int. Avoid overflow. |
420 static bool isOverSize(unsigned width, unsigned height) | 436 static bool isOverSize(unsigned width, unsigned height) |
421 { | 437 { |
422 unsigned long long total_size = static_cast<unsigned long long>(widt h) | 438 unsigned long long total_size = static_cast<unsigned long long>(widt h) |
423 * static_cast<unsigned long long>(heig ht); | 439 * static_cast<unsigned long long>(heig ht); |
424 return total_size > ((1 << 29) - 1); | 440 return total_size > ((1 << 29) - 1); |
425 } | 441 } |
426 | 442 |
427 IntSize m_size; | 443 IntSize m_size; |
428 bool m_sizeAvailable; | 444 bool m_sizeAvailable; |
429 bool m_isAllDataReceived; | 445 bool m_isAllDataReceived; |
430 bool m_failed; | 446 bool m_failed; |
431 }; | 447 }; |
432 | 448 |
433 } // namespace WebCore | 449 } // namespace WebCore |
434 | 450 |
435 #endif | 451 #endif |
OLD | NEW |