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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 if (SkGetPackedA32(pixel) != 0xff) { | 132 if (SkGetPackedA32(pixel) != 0xff) { |
133 blink::ImageFrame::PixelData prevPixel = *dst.getAddr(canvasX, canvasY); | 133 blink::ImageFrame::PixelData prevPixel = *dst.getAddr(canvasX, canvasY); |
134 pixel = blendSrcOverDstNonPremultiplied(pixel, prevPixel); | 134 pixel = blendSrcOverDstNonPremultiplied(pixel, prevPixel); |
135 } | 135 } |
136 } | 136 } |
137 } | 137 } |
138 | 138 |
139 namespace blink { | 139 namespace blink { |
140 | 140 |
141 WEBPImageDecoder::WEBPImageDecoder(AlphaOption alphaOption, | 141 WEBPImageDecoder::WEBPImageDecoder(AlphaOption alphaOption, |
142 GammaAndColorProfileOption colorOptions, | 142 ColorSpaceOption colorOptions, |
143 size_t maxDecodedBytes) | 143 size_t maxDecodedBytes) |
144 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes), | 144 : ImageDecoder(alphaOption, colorOptions, maxDecodedBytes), |
145 m_decoder(0), | 145 m_decoder(0), |
146 m_formatFlags(0), | 146 m_formatFlags(0), |
147 m_frameBackgroundHasAlpha(false), | 147 m_frameBackgroundHasAlpha(false), |
148 m_demux(0), | 148 m_demux(0), |
149 m_demuxState(WEBP_DEMUX_PARSING_HEADER), | 149 m_demuxState(WEBP_DEMUX_PARSING_HEADER), |
150 m_haveAlreadyParsedThisData(false), | 150 m_haveAlreadyParsedThisData(false), |
151 m_repetitionCount(cAnimationLoopOnce), | 151 m_repetitionCount(cAnimationLoopOnce), |
152 m_decodedHeight(0) { | 152 m_decodedHeight(0) { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
240 // an ANIM chunk must precede the ANMF frame chunks. | 240 // an ANIM chunk must precede the ANMF frame chunks. |
241 m_repetitionCount = WebPDemuxGetI(m_demux, WEBP_FF_LOOP_COUNT); | 241 m_repetitionCount = WebPDemuxGetI(m_demux, WEBP_FF_LOOP_COUNT); |
242 // Repetition count is always <= 16 bits. | 242 // Repetition count is always <= 16 bits. |
243 ASSERT(m_repetitionCount == (m_repetitionCount & 0xffff)); | 243 ASSERT(m_repetitionCount == (m_repetitionCount & 0xffff)); |
244 if (!m_repetitionCount) | 244 if (!m_repetitionCount) |
245 m_repetitionCount = cAnimationLoopInfinite; | 245 m_repetitionCount = cAnimationLoopInfinite; |
246 // FIXME: Implement ICC profile support for animated images. | 246 // FIXME: Implement ICC profile support for animated images. |
247 m_formatFlags &= ~ICCP_FLAG; | 247 m_formatFlags &= ~ICCP_FLAG; |
248 } | 248 } |
249 | 249 |
250 if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile()) | 250 if ((m_formatFlags & ICCP_FLAG) && !ignoresColorSpace()) |
251 readColorProfile(); | 251 readColorProfile(); |
252 } | 252 } |
253 | 253 |
254 ASSERT(isDecodedSizeAvailable()); | 254 ASSERT(isDecodedSizeAvailable()); |
255 | 255 |
256 size_t frameCount = WebPDemuxGetI(m_demux, WEBP_FF_FRAME_COUNT); | 256 size_t frameCount = WebPDemuxGetI(m_demux, WEBP_FF_FRAME_COUNT); |
257 updateAggressivePurging(frameCount); | 257 updateAggressivePurging(frameCount); |
258 | 258 |
259 return true; | 259 return true; |
260 } | 260 } |
261 | 261 |
262 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) { | 262 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) { |
263 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 263 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
264 if (buffer.getStatus() != ImageFrame::FrameEmpty) // Already initialized. | 264 if (buffer.getStatus() != ImageFrame::FrameEmpty) // Already initialized. |
265 return true; | 265 return true; |
266 | 266 |
267 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(); | 267 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(); |
268 if (requiredPreviousFrameIndex == kNotFound) { | 268 if (requiredPreviousFrameIndex == kNotFound) { |
269 // This frame doesn't rely on any previous data. | 269 // This frame doesn't rely on any previous data. |
270 if (!buffer.setSizeAndColorProfile(size().width(), size().height(), | 270 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), |
271 colorProfile())) | 271 colorSpace())) |
272 return setFailed(); | 272 return setFailed(); |
273 m_frameBackgroundHasAlpha = | 273 m_frameBackgroundHasAlpha = |
274 !buffer.originalFrameRect().contains(IntRect(IntPoint(), size())); | 274 !buffer.originalFrameRect().contains(IntRect(IntPoint(), size())); |
275 } else { | 275 } else { |
276 ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameIndex]; | 276 ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameIndex]; |
277 ASSERT(prevBuffer.getStatus() == ImageFrame::FrameComplete); | 277 ASSERT(prevBuffer.getStatus() == ImageFrame::FrameComplete); |
278 | 278 |
279 // Preserve the last frame as the starting state for this frame. We try | 279 // Preserve the last frame as the starting state for this frame. We try |
280 // to reuse |prevBuffer| as starting state to avoid copying. | 280 // to reuse |prevBuffer| as starting state to avoid copying. |
281 // For BlendAtopPreviousFrame, both frames are required, so we can't | 281 // For BlendAtopPreviousFrame, both frames are required, so we can't |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 WebPChunkIterator chunkIterator; | 335 WebPChunkIterator chunkIterator; |
336 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { | 336 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { |
337 WebPDemuxReleaseChunkIterator(&chunkIterator); | 337 WebPDemuxReleaseChunkIterator(&chunkIterator); |
338 return; | 338 return; |
339 } | 339 } |
340 | 340 |
341 const char* profileData = | 341 const char* profileData = |
342 reinterpret_cast<const char*>(chunkIterator.chunk.bytes); | 342 reinterpret_cast<const char*>(chunkIterator.chunk.bytes); |
343 size_t profileSize = chunkIterator.chunk.size; | 343 size_t profileSize = chunkIterator.chunk.size; |
344 | 344 |
345 setColorSpaceAndComputeTransform(profileData, profileSize, | 345 setColorSpaceAndComputeTransform(profileData, profileSize); |
346 false /* useSRGB */); | |
347 | 346 |
348 WebPDemuxReleaseChunkIterator(&chunkIterator); | 347 WebPDemuxReleaseChunkIterator(&chunkIterator); |
349 } | 348 } |
350 | 349 |
351 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) { | 350 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) { |
352 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 351 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
353 int width; | 352 int width; |
354 int decodedHeight; | 353 int decodedHeight; |
355 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0)) | 354 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0)) |
356 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062 | 355 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062 |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 if (failed()) | 514 if (failed()) |
516 return false; | 515 return false; |
517 | 516 |
518 ASSERT(isDecodedSizeAvailable()); | 517 ASSERT(isDecodedSizeAvailable()); |
519 | 518 |
520 ASSERT(m_frameBufferCache.size() > frameIndex); | 519 ASSERT(m_frameBufferCache.size() > frameIndex); |
521 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 520 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
522 ASSERT(buffer.getStatus() != ImageFrame::FrameComplete); | 521 ASSERT(buffer.getStatus() != ImageFrame::FrameComplete); |
523 | 522 |
524 if (buffer.getStatus() == ImageFrame::FrameEmpty) { | 523 if (buffer.getStatus() == ImageFrame::FrameEmpty) { |
525 if (!buffer.setSizeAndColorProfile(size().width(), size().height(), | 524 if (!buffer.setSizeAndColorSpace(size().width(), size().height(), |
526 colorProfile())) | 525 colorSpace())) |
527 return setFailed(); | 526 return setFailed(); |
528 buffer.setStatus(ImageFrame::FramePartial); | 527 buffer.setStatus(ImageFrame::FramePartial); |
529 // The buffer is transparent outside the decoded area while the image is | 528 // The buffer is transparent outside the decoded area while the image is |
530 // loading. The correct alpha value for the frame will be set when it is | 529 // loading. The correct alpha value for the frame will be set when it is |
531 // fully decoded. | 530 // fully decoded. |
532 buffer.setHasAlpha(true); | 531 buffer.setHasAlpha(true); |
533 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); | 532 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); |
534 } | 533 } |
535 | 534 |
536 const IntRect& frameRect = buffer.originalFrameRect(); | 535 const IntRect& frameRect = buffer.originalFrameRect(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 return false; | 576 return false; |
578 } | 577 } |
579 // FALLTHROUGH | 578 // FALLTHROUGH |
580 default: | 579 default: |
581 clear(); | 580 clear(); |
582 return setFailed(); | 581 return setFailed(); |
583 } | 582 } |
584 } | 583 } |
585 | 584 |
586 } // namespace blink | 585 } // namespace blink |
OLD | NEW |