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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 } | 230 } |
231 | 231 |
232 ASSERT(isDecodedSizeAvailable()); | 232 ASSERT(isDecodedSizeAvailable()); |
233 | 233 |
234 size_t frameCount = WebPDemuxGetI(m_demux, WEBP_FF_FRAME_COUNT); | 234 size_t frameCount = WebPDemuxGetI(m_demux, WEBP_FF_FRAME_COUNT); |
235 updateAggressivePurging(frameCount); | 235 updateAggressivePurging(frameCount); |
236 | 236 |
237 return true; | 237 return true; |
238 } | 238 } |
239 | 239 |
240 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) { | 240 void WEBPImageDecoder::onInitFrameBuffer(size_t frameIndex) { |
| 241 // ImageDecoder::initFrameBuffer does a DCHECK if |frameIndex| exists. |
241 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 242 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
242 if (buffer.getStatus() != ImageFrame::FrameEmpty) // Already initialized. | |
243 return true; | |
244 | 243 |
245 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(); | 244 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(); |
246 if (requiredPreviousFrameIndex == kNotFound) { | 245 if (requiredPreviousFrameIndex == kNotFound) { |
247 // This frame doesn't rely on any previous data. | |
248 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), | |
249 colorSpace())) | |
250 return setFailed(); | |
251 m_frameBackgroundHasAlpha = | 246 m_frameBackgroundHasAlpha = |
252 !buffer.originalFrameRect().contains(IntRect(IntPoint(), size())); | 247 !buffer.originalFrameRect().contains(IntRect(IntPoint(), size())); |
253 } else { | 248 } else { |
254 ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameIndex]; | 249 const ImageFrame& prevBuffer = |
255 ASSERT(prevBuffer.getStatus() == ImageFrame::FrameComplete); | 250 m_frameBufferCache[requiredPreviousFrameIndex]; |
256 | |
257 // Preserve the last frame as the starting state for this frame. We try | |
258 // to reuse |prevBuffer| as starting state to avoid copying. | |
259 // For BlendAtopPreviousFrame, both frames are required, so we can't | |
260 // take over its image data using takeBitmapDataIfWritable. | |
261 if ((buffer.getAlphaBlendSource() == ImageFrame::BlendAtopPreviousFrame || | |
262 !buffer.takeBitmapDataIfWritable(&prevBuffer)) && | |
263 !buffer.copyBitmapData(prevBuffer)) | |
264 return setFailed(); | |
265 | |
266 if (prevBuffer.getDisposalMethod() == ImageFrame::DisposeOverwriteBgcolor) { | |
267 // We want to clear the previous frame to transparent, without | |
268 // affecting pixels in the image outside of the frame. | |
269 const IntRect& prevRect = prevBuffer.originalFrameRect(); | |
270 ASSERT(!prevRect.contains(IntRect(IntPoint(), size()))); | |
271 buffer.zeroFillFrameRect(prevRect); | |
272 } | |
273 | |
274 m_frameBackgroundHasAlpha = | 251 m_frameBackgroundHasAlpha = |
275 prevBuffer.hasAlpha() || | 252 prevBuffer.hasAlpha() || |
276 (prevBuffer.getDisposalMethod() == ImageFrame::DisposeOverwriteBgcolor); | 253 (prevBuffer.getDisposalMethod() == ImageFrame::DisposeOverwriteBgcolor); |
277 } | 254 } |
278 | 255 |
279 buffer.setStatus(ImageFrame::FramePartial); | |
280 // The buffer is transparent outside the decoded area while the image is | 256 // The buffer is transparent outside the decoded area while the image is |
281 // loading. The correct alpha value for the frame will be set when it is fully | 257 // loading. The correct alpha value for the frame will be set when it is fully |
282 // decoded. | 258 // decoded. |
283 buffer.setHasAlpha(true); | 259 buffer.setHasAlpha(true); |
284 return true; | 260 } |
| 261 |
| 262 bool WEBPImageDecoder::canReusePreviousFrameBuffer(size_t frameIndex) const { |
| 263 DCHECK(frameIndex < m_frameBufferCache.size()); |
| 264 return m_frameBufferCache[frameIndex].getAlphaBlendSource() != |
| 265 ImageFrame::BlendAtopPreviousFrame; |
285 } | 266 } |
286 | 267 |
287 size_t WEBPImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) { | 268 size_t WEBPImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) { |
288 // Don't clear if there are no frames, or only one. | 269 // Don't clear if there are no frames, or only one. |
289 if (m_frameBufferCache.size() <= 1) | 270 if (m_frameBufferCache.size() <= 1) |
290 return 0; | 271 return 0; |
291 | 272 |
292 // If |clearExceptFrame| has status FrameComplete, we only preserve that | 273 // If |clearExceptFrame| has status FrameComplete, we only preserve that |
293 // frame. Otherwise, we *also* preserve the most recent previous frame with | 274 // frame. Otherwise, we *also* preserve the most recent previous frame with |
294 // status FrameComplete whose data will be required to decode | 275 // status FrameComplete whose data will be required to decode |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
557 return false; | 538 return false; |
558 } | 539 } |
559 // FALLTHROUGH | 540 // FALLTHROUGH |
560 default: | 541 default: |
561 clear(); | 542 clear(); |
562 return setFailed(); | 543 return setFailed(); |
563 } | 544 } |
564 } | 545 } |
565 | 546 |
566 } // namespace blink | 547 } // namespace blink |
OLD | NEW |