Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. | 2 * Copyright (C) 2006 Apple Computer, 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 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
| 8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
| 9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
| 10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 120 | 120 |
| 121 ImageFrame& frame = m_frameBufferCache[index]; | 121 ImageFrame& frame = m_frameBufferCache[index]; |
| 122 if (frame.status() != ImageFrame::FrameComplete) { | 122 if (frame.status() != ImageFrame::FrameComplete) { |
| 123 PlatformInstrumentation::willDecodeImage("GIF"); | 123 PlatformInstrumentation::willDecodeImage("GIF"); |
| 124 decode(index + 1, GIFFullQuery); | 124 decode(index + 1, GIFFullQuery); |
| 125 PlatformInstrumentation::didDecodeImage(); | 125 PlatformInstrumentation::didDecodeImage(); |
| 126 } | 126 } |
| 127 return &frame; | 127 return &frame; |
| 128 } | 128 } |
| 129 | 129 |
| 130 bool GIFImageDecoder::frameIsCompleteAtIndex(size_t index) const | |
| 131 { | |
| 132 if (!m_reader) | |
| 133 return false; | |
| 134 if (index >= m_reader->imagesCount()) | |
| 135 return false; | |
| 136 return m_reader->frameContext(index)->isComplete(); | |
|
Peter Kasting
2013/04/23 21:43:20
Nit: Simpler:
return m_reader && (index < m_r
Alpha Left Google
2013/04/25 23:02:44
Done.
| |
| 137 } | |
| 138 | |
| 139 float GIFImageDecoder::frameDurationAtIndex(size_t index) const | |
| 140 { | |
| 141 if (!m_reader) | |
| 142 return 0; | |
| 143 if (index >= m_reader->imagesCount()) | |
| 144 return 0; | |
| 145 if (m_reader->frameContext(index)->isHeaderDefined()) | |
| 146 return m_reader->frameContext(index)->delayTime; | |
| 147 return 0; | |
|
Peter Kasting
2013/04/23 21:43:20
Nit: Simpler:
return (m_reader && (index < m_re
Alpha Left Google
2013/04/25 23:02:44
Done.
| |
| 148 } | |
| 149 | |
| 130 bool GIFImageDecoder::setFailed() | 150 bool GIFImageDecoder::setFailed() |
| 131 { | 151 { |
| 132 m_reader.clear(); | 152 m_reader.clear(); |
| 133 return ImageDecoder::setFailed(); | 153 return ImageDecoder::setFailed(); |
| 134 } | 154 } |
| 135 | 155 |
| 136 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) | 156 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) |
| 137 { | 157 { |
| 138 // In some cases, like if the decoder was destroyed while animating, we | 158 // In some cases, like if the decoder was destroyed while animating, we |
| 139 // can be asked to clear more frames than we currently have. | 159 // can be asked to clear more frames than we currently have. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 // Now |i| holds the last frame we need to preserve; clear prior frames. | 198 // Now |i| holds the last frame we need to preserve; clear prior frames. |
| 179 for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j ) { | 199 for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j ) { |
| 180 ASSERT(j->status() != ImageFrame::FramePartial); | 200 ASSERT(j->status() != ImageFrame::FramePartial); |
| 181 if (j->status() != ImageFrame::FrameEmpty) | 201 if (j->status() != ImageFrame::FrameEmpty) |
| 182 j->clearPixelData(); | 202 j->clearPixelData(); |
| 183 } | 203 } |
| 184 } | 204 } |
| 185 | 205 |
| 186 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, const Vector<unsigned char>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool wri teTransparentPixels) | 206 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, const Vector<unsigned char>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool wri teTransparentPixels) |
| 187 { | 207 { |
| 188 const GIFFrameContext* frameContext = m_reader->frameContext(); | 208 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
| 189 // The pixel data and coordinates supplied to us are relative to the frame's | 209 // The pixel data and coordinates supplied to us are relative to the frame's |
| 190 // origin within the entire image size, i.e. | 210 // origin within the entire image size, i.e. |
| 191 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee | 211 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee |
| 192 // that width == (size().width() - frameContext->xOffset), so | 212 // that width == (size().width() - frameContext->xOffset), so |
| 193 // we must ensure we don't run off the end of either the source data or the | 213 // we must ensure we don't run off the end of either the source data or the |
| 194 // row's X-coordinates. | 214 // row's X-coordinates. |
| 195 int xBegin = upperBoundScaledX(frameContext->xOffset); | 215 int xBegin = upperBoundScaledX(frameContext->xOffset); |
| 196 int yBegin = upperBoundScaledY(frameContext->yOffset + rowNumber); | 216 int yBegin = upperBoundScaledY(frameContext->yOffset + rowNumber); |
| 197 int xEnd = lowerBoundScaledX(std::min(static_cast<int>(frameContext->xOffset + width), size().width()) - 1, xBegin + 1) + 1; | 217 int xEnd = lowerBoundScaledX(std::min(static_cast<int>(frameContext->xOffset + width), size().width()) - 1, xBegin + 1) + 1; |
| 198 int yEnd = lowerBoundScaledY(std::min(static_cast<int>(frameContext->yOffset + rowNumber + repeatCount), size().height()) - 1, yBegin + 1) + 1; | 218 int yEnd = lowerBoundScaledY(std::min(static_cast<int>(frameContext->yOffset + rowNumber + repeatCount), size().height()) - 1, yBegin + 1) + 1; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 } | 310 } |
| 291 | 311 |
| 292 return true; | 312 return true; |
| 293 } | 313 } |
| 294 | 314 |
| 295 void GIFImageDecoder::gifComplete() | 315 void GIFImageDecoder::gifComplete() |
| 296 { | 316 { |
| 297 // Cache the repetition count, which is now as authoritative as it's ever | 317 // Cache the repetition count, which is now as authoritative as it's ever |
| 298 // going to be. | 318 // going to be. |
| 299 repetitionCount(); | 319 repetitionCount(); |
| 300 | |
| 301 m_reader.clear(); | |
| 302 } | 320 } |
| 303 | 321 |
| 304 void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query) | 322 void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query) |
| 305 { | 323 { |
| 306 if (failed()) | 324 if (failed()) |
| 307 return; | 325 return; |
| 308 | 326 |
| 309 if (!m_reader) { | 327 if (!m_reader) { |
| 310 m_reader = adoptPtr(new GIFImageReader(this)); | 328 m_reader = adoptPtr(new GIFImageReader(this)); |
| 311 m_reader->setData(m_data); | 329 m_reader->setData(m_data); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 328 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); | 346 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); |
| 329 | 347 |
| 330 if (query == GIFFrameCountQuery) | 348 if (query == GIFFrameCountQuery) |
| 331 return; | 349 return; |
| 332 | 350 |
| 333 if (!m_reader->decode(GIFFullQuery, haltAtFrame)) { | 351 if (!m_reader->decode(GIFFullQuery, haltAtFrame)) { |
| 334 setFailed(); | 352 setFailed(); |
| 335 return; | 353 return; |
| 336 } | 354 } |
| 337 | 355 |
| 338 // It is also a fatal error if all data is received but we failed to decode | 356 // It is also a fatal error if all data is received and we have decoded all |
| 339 // all frames completely. | 357 // frames available but the file is truncated. |
|
Peter Kasting
2013/04/23 21:43:20
The old comment seemed better, honestly, but this
| |
| 340 if (isAllDataReceived() && haltAtFrame >= m_frameBufferCache.size() && m_rea der) | 358 if (isAllDataReceived() && haltAtFrame >= m_frameBufferCache.size() && !m_re ader->parseCompleted()) |
|
Peter Kasting
2013/04/23 21:43:20
Doesn't this check now only test parsing the GIF,
Alpha Left Google
2013/04/25 23:02:44
If it is parse only we'd return at line 349. The i
Peter Kasting
2013/04/25 23:22:32
I understand what is going on now. My main proble
| |
| 341 setFailed(); | 359 setFailed(); |
| 342 } | 360 } |
| 343 | 361 |
| 344 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) | 362 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) |
| 345 { | 363 { |
| 346 // Initialize the frame rect in our buffer. | 364 // Initialize the frame rect in our buffer. |
| 347 const GIFFrameContext* frameContext = m_reader->frameContext(); | 365 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
| 348 IntRect frameRect(frameContext->xOffset, frameContext->yOffset, frameContext ->width, frameContext->height); | 366 IntRect frameRect(frameContext->xOffset, frameContext->yOffset, frameContext ->width, frameContext->height); |
| 349 | 367 |
| 350 // Make sure the frameRect doesn't extend outside the buffer. | 368 // Make sure the frameRect doesn't extend outside the buffer. |
| 351 if (frameRect.maxX() > size().width()) | 369 if (frameRect.maxX() > size().width()) |
| 352 frameRect.setWidth(size().width() - frameContext->xOffset); | 370 frameRect.setWidth(size().width() - frameContext->xOffset); |
| 353 if (frameRect.maxY() > size().height()) | 371 if (frameRect.maxY() > size().height()) |
| 354 frameRect.setHeight(size().height() - frameContext->yOffset); | 372 frameRect.setHeight(size().height() - frameContext->yOffset); |
| 355 | 373 |
| 356 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; | 374 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; |
| 357 int left = upperBoundScaledX(frameRect.x()); | 375 int left = upperBoundScaledX(frameRect.x()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 411 | 429 |
| 412 // Update our status to be partially complete. | 430 // Update our status to be partially complete. |
| 413 buffer->setStatus(ImageFrame::FramePartial); | 431 buffer->setStatus(ImageFrame::FramePartial); |
| 414 | 432 |
| 415 // Reset the alpha pixel tracker for this frame. | 433 // Reset the alpha pixel tracker for this frame. |
| 416 m_currentBufferSawAlpha = false; | 434 m_currentBufferSawAlpha = false; |
| 417 return true; | 435 return true; |
| 418 } | 436 } |
| 419 | 437 |
| 420 } // namespace WebCore | 438 } // namespace WebCore |
| OLD | NEW |