| 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 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 224 // an ANIM chunk must precede the ANMF frame chunks. | 224 // an ANIM chunk must precede the ANMF frame chunks. |
| 225 m_repetitionCount = WebPDemuxGetI(m_demux, WEBP_FF_LOOP_COUNT); | 225 m_repetitionCount = WebPDemuxGetI(m_demux, WEBP_FF_LOOP_COUNT); |
| 226 // Repetition count is always <= 16 bits. | 226 // Repetition count is always <= 16 bits. |
| 227 ASSERT(m_repetitionCount == (m_repetitionCount & 0xffff)); | 227 ASSERT(m_repetitionCount == (m_repetitionCount & 0xffff)); |
| 228 if (!m_repetitionCount) | 228 if (!m_repetitionCount) |
| 229 m_repetitionCount = cAnimationLoopInfinite; | 229 m_repetitionCount = cAnimationLoopInfinite; |
| 230 // FIXME: Implement ICC profile support for animated images. | 230 // FIXME: Implement ICC profile support for animated images. |
| 231 m_formatFlags &= ~ICCP_FLAG; | 231 m_formatFlags &= ~ICCP_FLAG; |
| 232 } | 232 } |
| 233 | 233 |
| 234 #if USE(QCMSLIB) | |
| 235 if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile()) | 234 if ((m_formatFlags & ICCP_FLAG) && !ignoresGammaAndColorProfile()) |
| 236 readColorProfile(); | 235 readColorProfile(); |
| 237 #endif | |
| 238 } | 236 } |
| 239 | 237 |
| 240 ASSERT(isDecodedSizeAvailable()); | 238 ASSERT(isDecodedSizeAvailable()); |
| 241 return true; | 239 return true; |
| 242 } | 240 } |
| 243 | 241 |
| 244 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) | 242 bool WEBPImageDecoder::initFrameBuffer(size_t frameIndex) |
| 245 { | 243 { |
| 246 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 244 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 247 if (buffer.getStatus() != ImageFrame::FrameEmpty) // Already initialized. | 245 if (buffer.getStatus() != ImageFrame::FrameEmpty) // Already initialized. |
| 248 return true; | 246 return true; |
| 249 | 247 |
| 250 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(
); | 248 const size_t requiredPreviousFrameIndex = buffer.requiredPreviousFrameIndex(
); |
| 251 if (requiredPreviousFrameIndex == kNotFound) { | 249 if (requiredPreviousFrameIndex == kNotFound) { |
| 252 // This frame doesn't rely on any previous data. | 250 // This frame doesn't rely on any previous data. |
| 253 if (!buffer.setSize(size().width(), size().height())) | 251 if (!buffer.setSizeAndColorProfile(size().width(), size().height(), colo
rProfile())) |
| 254 return setFailed(); | 252 return setFailed(); |
| 255 m_frameBackgroundHasAlpha = !buffer.originalFrameRect().contains(IntRect
(IntPoint(), size())); | 253 m_frameBackgroundHasAlpha = !buffer.originalFrameRect().contains(IntRect
(IntPoint(), size())); |
| 256 } else { | 254 } else { |
| 257 const ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameI
ndex]; | 255 const ImageFrame& prevBuffer = m_frameBufferCache[requiredPreviousFrameI
ndex]; |
| 258 ASSERT(prevBuffer.getStatus() == ImageFrame::FrameComplete); | 256 ASSERT(prevBuffer.getStatus() == ImageFrame::FrameComplete); |
| 259 | 257 |
| 260 // Preserve the last frame as the starting state for this frame. | 258 // Preserve the last frame as the starting state for this frame. |
| 261 if (!buffer.copyBitmapData(prevBuffer)) | 259 if (!buffer.copyBitmapData(prevBuffer)) |
| 262 return setFailed(); | 260 return setFailed(); |
| 263 | 261 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 293 | 291 |
| 294 void WEBPImageDecoder::clearFrameBuffer(size_t frameIndex) | 292 void WEBPImageDecoder::clearFrameBuffer(size_t frameIndex) |
| 295 { | 293 { |
| 296 if (m_demux && m_demuxState >= WEBP_DEMUX_PARSED_HEADER && m_frameBufferCach
e[frameIndex].getStatus() == ImageFrame::FramePartial) { | 294 if (m_demux && m_demuxState >= WEBP_DEMUX_PARSED_HEADER && m_frameBufferCach
e[frameIndex].getStatus() == ImageFrame::FramePartial) { |
| 297 // Clear the decoder state so that this partial frame can be decoded aga
in when requested. | 295 // Clear the decoder state so that this partial frame can be decoded aga
in when requested. |
| 298 clearDecoder(); | 296 clearDecoder(); |
| 299 } | 297 } |
| 300 ImageDecoder::clearFrameBuffer(frameIndex); | 298 ImageDecoder::clearFrameBuffer(frameIndex); |
| 301 } | 299 } |
| 302 | 300 |
| 303 #if USE(QCMSLIB) | |
| 304 | |
| 305 void WEBPImageDecoder::readColorProfile() | 301 void WEBPImageDecoder::readColorProfile() |
| 306 { | 302 { |
| 307 WebPChunkIterator chunkIterator; | 303 WebPChunkIterator chunkIterator; |
| 308 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { | 304 if (!WebPDemuxGetChunk(m_demux, "ICCP", 1, &chunkIterator)) { |
| 309 WebPDemuxReleaseChunkIterator(&chunkIterator); | 305 WebPDemuxReleaseChunkIterator(&chunkIterator); |
| 310 return; | 306 return; |
| 311 } | 307 } |
| 312 | 308 |
| 313 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.
bytes); | 309 const char* profileData = reinterpret_cast<const char*>(chunkIterator.chunk.
bytes); |
| 314 size_t profileSize = chunkIterator.chunk.size; | 310 size_t profileSize = chunkIterator.chunk.size; |
| 315 | 311 |
| 316 setColorProfileAndTransform(profileData, profileSize, true /* hasAlpha */, f
alse /* useSRGB */); | 312 setColorProfileAndComputeTransform(profileData, profileSize, true /* hasAlph
a */, false /* useSRGB */); |
| 317 | 313 |
| 318 WebPDemuxReleaseChunkIterator(&chunkIterator); | 314 WebPDemuxReleaseChunkIterator(&chunkIterator); |
| 319 } | 315 } |
| 320 | 316 |
| 321 #endif // USE(QCMSLIB) | |
| 322 | |
| 323 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) | 317 void WEBPImageDecoder::applyPostProcessing(size_t frameIndex) |
| 324 { | 318 { |
| 325 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 319 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 326 int width; | 320 int width; |
| 327 int decodedHeight; | 321 int decodedHeight; |
| 328 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0)) | 322 if (!WebPIDecGetRGB(m_decoder, &decodedHeight, &width, 0, 0)) |
| 329 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062 | 323 return; // See also https://bugs.webkit.org/show_bug.cgi?id=74062 |
| 330 if (decodedHeight <= 0) | 324 if (decodedHeight <= 0) |
| 331 return; | 325 return; |
| 332 | 326 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 455 if (failed()) | 449 if (failed()) |
| 456 return false; | 450 return false; |
| 457 | 451 |
| 458 ASSERT(isDecodedSizeAvailable()); | 452 ASSERT(isDecodedSizeAvailable()); |
| 459 | 453 |
| 460 ASSERT(m_frameBufferCache.size() > frameIndex); | 454 ASSERT(m_frameBufferCache.size() > frameIndex); |
| 461 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 455 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 462 ASSERT(buffer.getStatus() != ImageFrame::FrameComplete); | 456 ASSERT(buffer.getStatus() != ImageFrame::FrameComplete); |
| 463 | 457 |
| 464 if (buffer.getStatus() == ImageFrame::FrameEmpty) { | 458 if (buffer.getStatus() == ImageFrame::FrameEmpty) { |
| 465 if (!buffer.setSize(size().width(), size().height())) | 459 if (!buffer.setSizeAndColorProfile(size().width(), size().height(), colo
rProfile())) |
| 466 return setFailed(); | 460 return setFailed(); |
| 467 buffer.setStatus(ImageFrame::FramePartial); | 461 buffer.setStatus(ImageFrame::FramePartial); |
| 468 // The buffer is transparent outside the decoded area while the image is
loading. | 462 // The buffer is transparent outside the decoded area while the image is
loading. |
| 469 // The correct value of 'hasAlpha' for the frame will be set when it is
fully decoded. | 463 // The correct value of 'hasAlpha' for the frame will be set when it is
fully decoded. |
| 470 buffer.setHasAlpha(true); | 464 buffer.setHasAlpha(true); |
| 471 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); | 465 buffer.setOriginalFrameRect(IntRect(IntPoint(), size())); |
| 472 } | 466 } |
| 473 | 467 |
| 474 const IntRect& frameRect = buffer.originalFrameRect(); | 468 const IntRect& frameRect = buffer.originalFrameRect(); |
| 475 if (!m_decoder) { | 469 if (!m_decoder) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 505 return false; | 499 return false; |
| 506 } | 500 } |
| 507 // FALLTHROUGH | 501 // FALLTHROUGH |
| 508 default: | 502 default: |
| 509 clear(); | 503 clear(); |
| 510 return setFailed(); | 504 return setFailed(); |
| 511 } | 505 } |
| 512 } | 506 } |
| 513 | 507 |
| 514 } // namespace blink | 508 } // namespace blink |
| OLD | NEW |