| 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 |