| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2010 Google Inc. All rights reserved. | 2 * Copyright (C) 2010 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
| 6 * are met: | 6 * are met: |
| 7 * | 7 * |
| 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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 116 ImageFrame& frame = m_frameBufferCache[index]; | 116 ImageFrame& frame = m_frameBufferCache[index]; |
| 117 if (frame.status() == ImageFrame::FrameComplete) | 117 if (frame.status() == ImageFrame::FrameComplete) |
| 118 return &frame; | 118 return &frame; |
| 119 | 119 |
| 120 if (RuntimeEnabledFeatures::animatedWebPEnabled()) { | 120 if (RuntimeEnabledFeatures::animatedWebPEnabled()) { |
| 121 Vector<size_t> framesToDecode; | 121 Vector<size_t> framesToDecode; |
| 122 size_t frameToDecode = index; | 122 size_t frameToDecode = index; |
| 123 do { | 123 do { |
| 124 framesToDecode.append(frameToDecode); | 124 framesToDecode.append(frameToDecode); |
| 125 frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFr
ameIndex(); | 125 frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFr
ameIndex(); |
| 126 } while (frameToDecode != notFound && m_frameBufferCache[frameToDecode].
status() != ImageFrame::FrameComplete); | 126 } while (frameToDecode != kNotFound && m_frameBufferCache[frameToDecode]
.status() != ImageFrame::FrameComplete); |
| 127 | 127 |
| 128 ASSERT(m_demux); | 128 ASSERT(m_demux); |
| 129 for (size_t i = framesToDecode.size(); i > 0; --i) { | 129 for (size_t i = framesToDecode.size(); i > 0; --i) { |
| 130 size_t frameIndex = framesToDecode[i - 1]; | 130 size_t frameIndex = framesToDecode[i - 1]; |
| 131 if ((m_formatFlags & ANIMATION_FLAG) && !initFrameBuffer(frameIndex)
) | 131 if ((m_formatFlags & ANIMATION_FLAG) && !initFrameBuffer(frameIndex)
) |
| 132 return 0; | 132 return 0; |
| 133 WebPIterator webpFrame; | 133 WebPIterator webpFrame; |
| 134 if (!WebPDemuxGetFrame(m_demux, frameIndex + 1, &webpFrame)) | 134 if (!WebPDemuxGetFrame(m_demux, frameIndex + 1, &webpFrame)) |
| 135 return 0; | 135 return 0; |
| 136 PlatformInstrumentation::willDecodeImage("WEBP"); | 136 PlatformInstrumentation::willDecodeImage("WEBP"); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 m_haveReadAnimationParameters = true; | 231 m_haveReadAnimationParameters = true; |
| 232 } | 232 } |
| 233 | 233 |
| 234 const size_t oldFrameCount = m_frameBufferCache.size(); | 234 const size_t oldFrameCount = m_frameBufferCache.size(); |
| 235 if (newFrameCount > oldFrameCount) { | 235 if (newFrameCount > oldFrameCount) { |
| 236 m_frameBufferCache.resize(newFrameCount); | 236 m_frameBufferCache.resize(newFrameCount); |
| 237 for (size_t i = oldFrameCount; i < newFrameCount; ++i) { | 237 for (size_t i = oldFrameCount; i < newFrameCount; ++i) { |
| 238 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); | 238 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); |
| 239 if (!hasAnimation) { | 239 if (!hasAnimation) { |
| 240 ASSERT(!i); | 240 ASSERT(!i); |
| 241 m_frameBufferCache[i].setRequiredPreviousFrameIndex(notFound); | 241 m_frameBufferCache[i].setRequiredPreviousFrameIndex(kNotFound); |
| 242 continue; | 242 continue; |
| 243 } | 243 } |
| 244 WebPIterator animatedFrame; | 244 WebPIterator animatedFrame; |
| 245 WebPDemuxGetFrame(m_demux, i + 1, &animatedFrame); | 245 WebPDemuxGetFrame(m_demux, i + 1, &animatedFrame); |
| 246 ASSERT(animatedFrame.complete == 1); | 246 ASSERT(animatedFrame.complete == 1); |
| 247 m_frameBufferCache[i].setDuration(animatedFrame.duration); | 247 m_frameBufferCache[i].setDuration(animatedFrame.duration); |
| 248 m_frameBufferCache[i].setDisposalMethod(animatedFrame.dispose_method
== WEBP_MUX_DISPOSE_BACKGROUND ? ImageFrame::DisposeOverwriteBgcolor : ImageFra
me::DisposeKeep); | 248 m_frameBufferCache[i].setDisposalMethod(animatedFrame.dispose_method
== WEBP_MUX_DISPOSE_BACKGROUND ? ImageFrame::DisposeOverwriteBgcolor : ImageFra
me::DisposeKeep); |
| 249 m_frameBufferCache[i].setAlphaBlendSource(animatedFrame.blend_method
== WEBP_MUX_BLEND ? ImageFrame::BlendAtopPreviousFrame : ImageFrame::BlendAtopB
gcolor); | 249 m_frameBufferCache[i].setAlphaBlendSource(animatedFrame.blend_method
== WEBP_MUX_BLEND ? ImageFrame::BlendAtopPreviousFrame : ImageFrame::BlendAtopB
gcolor); |
| 250 IntRect frameRect(animatedFrame.x_offset, animatedFrame.y_offset, an
imatedFrame.width, animatedFrame.height); | 250 IntRect frameRect(animatedFrame.x_offset, animatedFrame.y_offset, an
imatedFrame.width, animatedFrame.height); |
| 251 // Make sure the frameRect doesn't extend outside the buffer. | 251 // Make sure the frameRect doesn't extend outside the buffer. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 262 return true; | 262 return true; |
| 263 } | 263 } |
| 264 | 264 |
| 265 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) | 265 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) |
| 266 { | 266 { |
| 267 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 267 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 268 if (buffer.status() != ImageFrame::FrameEmpty) // Already initialized. | 268 if (buffer.status() != ImageFrame::FrameEmpty) // Already initialized. |
| 269 return true; | 269 return true; |
| 270 | 270 |
| 271 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(
); | 271 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(
); |
| 272 if (requiredPreviousFrameIndex == notFound) { | 272 if (requiredPreviousFrameIndex == kNotFound) { |
| 273 // This frame doesn't rely on any previous data. | 273 // This frame doesn't rely on any previous data. |
| 274 if (!buffer.setSize(size().width(), size().height())) | 274 if (!buffer.setSize(size().width(), size().height())) |
| 275 return setFailed(); | 275 return setFailed(); |
| 276 m_frameBackgroundHasAlpha = !buffer.originalFrameRect().contains(IntRect
(IntPoint(), size())); | 276 m_frameBackgroundHasAlpha = !buffer.originalFrameRect().contains(IntRect
(IntPoint(), size())); |
| 277 } else { | 277 } else { |
| 278 const ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameI
ndex]; | 278 const ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameI
ndex]; |
| 279 ASSERT(prevBuffer.status() == ImageFrame::FrameComplete); | 279 ASSERT(prevBuffer.status() == ImageFrame::FrameComplete); |
| 280 | 280 |
| 281 // Preserve the last frame as the starting state for this frame. | 281 // Preserve the last frame as the starting state for this frame. |
| 282 if (!buffer.copyBitmapData(prevBuffer)) | 282 if (!buffer.copyBitmapData(prevBuffer)) |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 409 } | 409 } |
| 410 } | 410 } |
| 411 #endif // USE(QCMSLIB) | 411 #endif // USE(QCMSLIB) |
| 412 | 412 |
| 413 // During the decoding of current frame, we may have set some pixels to be t
ransparent (i.e. alpha < 255). | 413 // During the decoding of current frame, we may have set some pixels to be t
ransparent (i.e. alpha < 255). |
| 414 // However, the value of each of these pixels should have been determined by
blending it against the value | 414 // However, the value of each of these pixels should have been determined by
blending it against the value |
| 415 // of that pixel in the previous frame if alpha blend source was 'BlendAtopP
reviousFrame'. So, we correct these | 415 // of that pixel in the previous frame if alpha blend source was 'BlendAtopP
reviousFrame'. So, we correct these |
| 416 // pixels based on disposal method of the previous frame and the previous fr
ame buffer. | 416 // pixels based on disposal method of the previous frame and the previous fr
ame buffer. |
| 417 // FIXME: This could be avoided if libwebp decoder had an API that used the
previous required frame | 417 // FIXME: This could be avoided if libwebp decoder had an API that used the
previous required frame |
| 418 // to do the alpha-blending by itself. | 418 // to do the alpha-blending by itself. |
| 419 if ((m_formatFlags & ANIMATION_FLAG) && frameIndex && buffer.alphaBlendSourc
e() == ImageFrame::BlendAtopPreviousFrame && buffer.requiredPreviousFrameIndex()
!= notFound) { | 419 if ((m_formatFlags & ANIMATION_FLAG) && frameIndex && buffer.alphaBlendSourc
e() == ImageFrame::BlendAtopPreviousFrame && buffer.requiredPreviousFrameIndex()
!= kNotFound) { |
| 420 ImageFrame& prevBuffer = m_frameBufferCache[frameIndex - 1]; | 420 ImageFrame& prevBuffer = m_frameBufferCache[frameIndex - 1]; |
| 421 ASSERT(prevBuffer.status() == ImageFrame::FrameComplete); | 421 ASSERT(prevBuffer.status() == ImageFrame::FrameComplete); |
| 422 ImageFrame::DisposalMethod prevDisposalMethod = prevBuffer.disposalMetho
d(); | 422 ImageFrame::DisposalMethod prevDisposalMethod = prevBuffer.disposalMetho
d(); |
| 423 if (prevDisposalMethod == ImageFrame::DisposeKeep) { // Restore transpar
ent pixels to pixels in previous canvas. | 423 if (prevDisposalMethod == ImageFrame::DisposeKeep) { // Restore transpar
ent pixels to pixels in previous canvas. |
| 424 for (int y = m_decodedHeight; y < decodedHeight; ++y) { | 424 for (int y = m_decodedHeight; y < decodedHeight; ++y) { |
| 425 const int canvasY = top + y; | 425 const int canvasY = top + y; |
| 426 for (int x = 0; x < width; ++x) { | 426 for (int x = 0; x < width; ++x) { |
| 427 const int canvasX = left + x; | 427 const int canvasX = left + x; |
| 428 ImageFrame::PixelData& pixel = *buffer.getAddr(canvasX, canv
asY); | 428 ImageFrame::PixelData& pixel = *buffer.getAddr(canvasX, canv
asY); |
| 429 // FIXME: Use alpha-blending when alpha is between 0 and 255
. | 429 // FIXME: Use alpha-blending when alpha is between 0 and 255
. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 526 case VP8_STATUS_SUSPENDED: | 526 case VP8_STATUS_SUSPENDED: |
| 527 applyPostProcessing(frameIndex); | 527 applyPostProcessing(frameIndex); |
| 528 return false; | 528 return false; |
| 529 default: | 529 default: |
| 530 clear(); | 530 clear(); |
| 531 return setFailed(); | 531 return setFailed(); |
| 532 } | 532 } |
| 533 } | 533 } |
| 534 | 534 |
| 535 } // namespace WebCore | 535 } // namespace WebCore |
| OLD | NEW |