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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
46 #include "wtf/RetainPtr.h" | 46 #include "wtf/RetainPtr.h" |
47 #endif | 47 #endif |
48 #endif | 48 #endif |
49 | 49 |
50 namespace WebCore { | 50 namespace WebCore { |
51 | 51 |
52 // ImageFrame represents the decoded image data. This buffer is what all | 52 // ImageFrame represents the decoded image data. This buffer is what all |
53 // decoders write a single frame into. | 53 // decoders write a single frame into. |
54 class ImageFrame { | 54 class ImageFrame { |
55 public: | 55 public: |
56 enum FrameStatus { FrameEmpty, FramePartial, FrameComplete }; | 56 enum Status { FrameEmpty, FramePartial, FrameComplete }; |
57 enum FrameDisposalMethod { | 57 enum DisposalMethod { |
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 fully transparent |
64 DisposeOverwritePrevious // Clear frame to previous framebuffer | 64 DisposeOverwritePrevious // Clear frame to previous framebuffer cont
ents |
65 // contents | 65 }; |
| 66 // Indicates how non-opaque pixels in the current frame rectangle |
| 67 // are blended with those in the previous frame. |
| 68 // Notes: |
| 69 // * GIF always uses 'BlendAtopPreviousFrame'. |
| 70 // * WebP also uses the 'BlendAtopBgcolor' option. This is useful for |
| 71 // cases where one wants to transform a few opaque pixels of the |
| 72 // previous frame into non-opaque pixels in the current frame. |
| 73 enum AlphaBlendSource { |
| 74 // Blend non-opaque pixels atop the corresponding pixels in the |
| 75 // initial buffer state (i.e. any previous frame buffer after having |
| 76 // been properly disposed). |
| 77 BlendAtopPreviousFrame, |
| 78 |
| 79 // Blend non-opaque pixels against fully transparent (i.e. simply |
| 80 // overwrite the corresponding pixels). |
| 81 BlendAtopBgcolor, |
66 }; | 82 }; |
67 typedef uint32_t PixelData; | 83 typedef uint32_t PixelData; |
68 | 84 |
69 ImageFrame(); | 85 ImageFrame(); |
70 | 86 |
71 ImageFrame(const ImageFrame& other) { operator=(other); } | 87 ImageFrame(const ImageFrame& other) { operator=(other); } |
72 | 88 |
73 // For backends which refcount their data, this operator doesn't need to | 89 // 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. | 90 // create a new copy of the image data, only increase the ref count. |
75 ImageFrame& operator=(const ImageFrame& other); | 91 ImageFrame& operator=(const ImageFrame& other); |
(...skipping 28 matching lines...) Expand all Loading... |
104 // succeeded. | 120 // succeeded. |
105 bool setSize(int newWidth, int newHeight); | 121 bool setSize(int newWidth, int newHeight); |
106 | 122 |
107 // Returns a caller-owned pointer to the underlying native image data. | 123 // Returns a caller-owned pointer to the underlying native image data. |
108 // (Actual use: This pointer will be owned by BitmapImage and freed in | 124 // (Actual use: This pointer will be owned by BitmapImage and freed in |
109 // FrameData::clear()). | 125 // FrameData::clear()). |
110 PassRefPtr<NativeImageSkia> asNewNativeImage() const; | 126 PassRefPtr<NativeImageSkia> asNewNativeImage() const; |
111 | 127 |
112 bool hasAlpha() const; | 128 bool hasAlpha() const; |
113 const IntRect& originalFrameRect() const { return m_originalFrameRect; } | 129 const IntRect& originalFrameRect() const { return m_originalFrameRect; } |
114 FrameStatus status() const { return m_status; } | 130 Status status() const { return m_status; } |
115 unsigned duration() const { return m_duration; } | 131 unsigned duration() const { return m_duration; } |
116 FrameDisposalMethod disposalMethod() const { return m_disposalMethod; } | 132 DisposalMethod disposalMethod() const { return m_disposalMethod; } |
| 133 AlphaBlendSource alphaBlendSource() const { return m_alphaBlendSource; } |
117 bool premultiplyAlpha() const { return m_premultiplyAlpha; } | 134 bool premultiplyAlpha() const { return m_premultiplyAlpha; } |
118 SkBitmap::Allocator* allocator() const { return m_allocator; } | 135 SkBitmap::Allocator* allocator() const { return m_allocator; } |
119 const SkBitmap& getSkBitmap() const { return m_bitmap->bitmap(); } | 136 const SkBitmap& getSkBitmap() const { return m_bitmap->bitmap(); } |
120 | 137 |
121 size_t requiredPreviousFrameIndex() const | 138 size_t requiredPreviousFrameIndex() const |
122 { | 139 { |
123 ASSERT(m_requiredPreviousFrameIndexValid); | 140 ASSERT(m_requiredPreviousFrameIndexValid); |
124 return m_requiredPreviousFrameIndex; | 141 return m_requiredPreviousFrameIndex; |
125 } | 142 } |
126 #if !ASSERT_DISABLED | 143 #if !ASSERT_DISABLED |
127 bool requiredPreviousFrameIndexValid() const { return m_requiredPrevious
FrameIndexValid; } | 144 bool requiredPreviousFrameIndexValid() const { return m_requiredPrevious
FrameIndexValid; } |
128 #endif | 145 #endif |
129 void setHasAlpha(bool alpha); | 146 void setHasAlpha(bool alpha); |
130 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } | 147 void setOriginalFrameRect(const IntRect& r) { m_originalFrameRect = r; } |
131 void setStatus(FrameStatus status); | 148 void setStatus(Status); |
132 void setDuration(unsigned duration) { m_duration = duration; } | 149 void setDuration(unsigned duration) { m_duration = duration; } |
133 void setDisposalMethod(FrameDisposalMethod method) { m_disposalMethod =
method; } | 150 void setDisposalMethod(DisposalMethod disposalMethod) { m_disposalMethod
= disposalMethod; } |
| 151 void setAlphaBlendSource(AlphaBlendSource alphaBlendSource) { m_alphaBle
ndSource = alphaBlendSource; } |
134 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = p
remultiplyAlpha; } | 152 void setPremultiplyAlpha(bool premultiplyAlpha) { m_premultiplyAlpha = p
remultiplyAlpha; } |
135 void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator =
allocator; } | 153 void setMemoryAllocator(SkBitmap::Allocator* allocator) { m_allocator =
allocator; } |
136 void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = NativeImageSkia::c
reate(bitmap); } | 154 void setSkBitmap(const SkBitmap& bitmap) { m_bitmap = NativeImageSkia::c
reate(bitmap); } |
137 | 155 |
138 void setRequiredPreviousFrameIndex(size_t previousFrameIndex) | 156 void setRequiredPreviousFrameIndex(size_t previousFrameIndex) |
139 { | 157 { |
140 m_requiredPreviousFrameIndex = previousFrameIndex; | 158 m_requiredPreviousFrameIndex = previousFrameIndex; |
141 #if !ASSERT_DISABLED | 159 #if !ASSERT_DISABLED |
142 m_requiredPreviousFrameIndexValid = true; | 160 m_requiredPreviousFrameIndexValid = true; |
143 #endif | 161 #endif |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 { | 207 { |
190 return m_bitmap->bitmap().height(); | 208 return m_bitmap->bitmap().height(); |
191 } | 209 } |
192 | 210 |
193 RefPtr<NativeImageSkia> m_bitmap; | 211 RefPtr<NativeImageSkia> m_bitmap; |
194 SkBitmap::Allocator* m_allocator; | 212 SkBitmap::Allocator* m_allocator; |
195 bool m_hasAlpha; | 213 bool m_hasAlpha; |
196 // This will always just be the entire buffer except for GIF or WebP | 214 // 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. | 215 // frames whose original rect was smaller than the overall image size. |
198 IntRect m_originalFrameRect; | 216 IntRect m_originalFrameRect; |
199 FrameStatus m_status; | 217 Status m_status; |
200 unsigned m_duration; | 218 unsigned m_duration; |
201 FrameDisposalMethod m_disposalMethod; | 219 DisposalMethod m_disposalMethod; |
| 220 AlphaBlendSource m_alphaBlendSource; |
202 bool m_premultiplyAlpha; | 221 bool m_premultiplyAlpha; |
203 | 222 |
204 // The frame that must be decoded before this frame can be decoded. | 223 // The frame that must be decoded before this frame can be decoded. |
205 // WTF::notFound if this frame doesn't require any previous frame. | 224 // WTF::notFound if this frame doesn't require any previous frame. |
206 // This is used by ImageDecoder::clearCacheExceptFrame(), and will never | 225 // This is used by ImageDecoder::clearCacheExceptFrame(), and will never |
207 // be read for image formats that do not have multiple frames. | 226 // be read for image formats that do not have multiple frames. |
208 size_t m_requiredPreviousFrameIndex; | 227 size_t m_requiredPreviousFrameIndex; |
209 #if !ASSERT_DISABLED | 228 #if !ASSERT_DISABLED |
210 bool m_requiredPreviousFrameIndexValid; | 229 bool m_requiredPreviousFrameIndexValid; |
211 #endif | 230 #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 | 395 // If the image has a cursor hot-spot, stores it in the argument |
377 // and returns true. Otherwise returns false. | 396 // and returns true. Otherwise returns false. |
378 virtual bool hotSpot(IntPoint&) const { return false; } | 397 virtual bool hotSpot(IntPoint&) const { return false; } |
379 | 398 |
380 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator) | 399 virtual void setMemoryAllocator(SkBitmap::Allocator* allocator) |
381 { | 400 { |
382 // FIXME: this doesn't work for images with multiple frames. | 401 // FIXME: this doesn't work for images with multiple frames. |
383 if (m_frameBufferCache.isEmpty()) { | 402 if (m_frameBufferCache.isEmpty()) { |
384 m_frameBufferCache.resize(1); | 403 m_frameBufferCache.resize(1); |
385 m_frameBufferCache[0].setRequiredPreviousFrameIndex( | 404 m_frameBufferCache[0].setRequiredPreviousFrameIndex( |
386 findRequiredPreviousFrame(0)); | 405 findRequiredPreviousFrame(0, false)); |
387 } | 406 } |
388 m_frameBufferCache[0].setMemoryAllocator(allocator); | 407 m_frameBufferCache[0].setMemoryAllocator(allocator); |
389 } | 408 } |
390 | 409 |
391 protected: | 410 protected: |
392 // Calculates the most recent frame whose image data may be needed in | 411 // Calculates the most recent frame whose image data may be needed in |
393 // order to decode frame |frameIndex|, based on frame disposal methods. | 412 // order to decode frame |frameIndex|, based on frame disposal methods |
| 413 // and |frameRectIsOpaque|, where |frameRectIsOpaque| signifies whether |
| 414 // the rectangle of frame at |frameIndex| is known to be opaque. |
394 // If no previous frame's data is required, returns WTF::notFound. | 415 // If no previous frame's data is required, returns WTF::notFound. |
395 // | 416 // |
396 // This function requires that the previous frame's | 417 // This function requires that the previous frame's |
397 // |m_requiredPreviousFrameIndex| member has been set correctly. The | 418 // |m_requiredPreviousFrameIndex| member has been set correctly. The |
398 // easiest way to ensure this is for subclasses to call this method and | 419 // easiest way to ensure this is for subclasses to call this method and |
399 // store the result on the frame via setRequiredPreviousFrameIndex() | 420 // store the result on the frame via setRequiredPreviousFrameIndex() |
400 // as soon as the frame has been created and parsed sufficiently to | 421 // as soon as the frame has been created and parsed sufficiently to |
401 // determine the disposal method; assuming this happens for all frames | 422 // determine the disposal method; assuming this happens for all frames |
402 // in order, the required invariant will hold. | 423 // in order, the required invariant will hold. |
403 // | 424 // |
404 // Image formats which do not use more than one frame do not need to | 425 // Image formats which do not use more than one frame do not need to |
405 // worry about this; see comments on | 426 // worry about this; see comments on |
406 // ImageFrame::m_requiredPreviousFrameIndex. | 427 // ImageFrame::m_requiredPreviousFrameIndex. |
407 size_t findRequiredPreviousFrame(size_t frameIndex); | 428 size_t findRequiredPreviousFrame(size_t frameIndex, bool frameRectIsOpaq
ue); |
408 | 429 |
409 virtual void clearFrameBuffer(size_t frameIndex); | 430 virtual void clearFrameBuffer(size_t frameIndex); |
410 | 431 |
411 RefPtr<SharedBuffer> m_data; // The encoded data. | 432 RefPtr<SharedBuffer> m_data; // The encoded data. |
412 Vector<ImageFrame, 1> m_frameBufferCache; | 433 Vector<ImageFrame, 1> m_frameBufferCache; |
413 bool m_premultiplyAlpha; | 434 bool m_premultiplyAlpha; |
414 bool m_ignoreGammaAndColorProfile; | 435 bool m_ignoreGammaAndColorProfile; |
415 ImageOrientation m_orientation; | 436 ImageOrientation m_orientation; |
416 | 437 |
417 private: | 438 private: |
418 // Some code paths compute the size of the image as "width * height * 4" | 439 // Some code paths compute the size of the image as "width * height * 4" |
419 // and return it as a (signed) int. Avoid overflow. | 440 // and return it as a (signed) int. Avoid overflow. |
420 static bool isOverSize(unsigned width, unsigned height) | 441 static bool isOverSize(unsigned width, unsigned height) |
421 { | 442 { |
422 unsigned long long total_size = static_cast<unsigned long long>(widt
h) | 443 unsigned long long total_size = static_cast<unsigned long long>(widt
h) |
423 * static_cast<unsigned long long>(heig
ht); | 444 * static_cast<unsigned long long>(heig
ht); |
424 return total_size > ((1 << 29) - 1); | 445 return total_size > ((1 << 29) - 1); |
425 } | 446 } |
426 | 447 |
427 IntSize m_size; | 448 IntSize m_size; |
428 bool m_sizeAvailable; | 449 bool m_sizeAvailable; |
429 bool m_isAllDataReceived; | 450 bool m_isAllDataReceived; |
430 bool m_failed; | 451 bool m_failed; |
431 }; | 452 }; |
432 | 453 |
433 } // namespace WebCore | 454 } // namespace WebCore |
434 | 455 |
435 #endif | 456 #endif |
OLD | NEW |