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) | 234 if ((m_formatFlags & ICCP_FLAG)) |
235 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 |