| 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 return m_reader && (index < m_reader->imagesCount()) && m_reader->frameConte
xt(index)->isComplete(); |
| 133 } |
| 134 |
| 135 float GIFImageDecoder::frameDurationAtIndex(size_t index) const |
| 136 { |
| 137 return (m_reader && (index < m_reader->imagesCount()) && |
| 138 m_reader->frameContext(index)->isHeaderDefined()) ? |
| 139 m_reader->frameContext(index)->delayTime : 0; |
| 140 } |
| 141 |
| 130 bool GIFImageDecoder::setFailed() | 142 bool GIFImageDecoder::setFailed() |
| 131 { | 143 { |
| 132 m_reader.clear(); | 144 m_reader.clear(); |
| 133 return ImageDecoder::setFailed(); | 145 return ImageDecoder::setFailed(); |
| 134 } | 146 } |
| 135 | 147 |
| 136 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) | 148 void GIFImageDecoder::clearFrameBufferCache(size_t clearBeforeFrame) |
| 137 { | 149 { |
| 138 // In some cases, like if the decoder was destroyed while animating, we | 150 // In some cases, like if the decoder was destroyed while animating, we |
| 139 // can be asked to clear more frames than we currently have. | 151 // 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. | 190 // 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
) { | 191 for (Vector<ImageFrame>::iterator j(m_frameBufferCache.begin()); j != i; ++j
) { |
| 180 ASSERT(j->status() != ImageFrame::FramePartial); | 192 ASSERT(j->status() != ImageFrame::FramePartial); |
| 181 if (j->status() != ImageFrame::FrameEmpty) | 193 if (j->status() != ImageFrame::FrameEmpty) |
| 182 j->clearPixelData(); | 194 j->clearPixelData(); |
| 183 } | 195 } |
| 184 } | 196 } |
| 185 | 197 |
| 186 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, const Vector<unsigned
char>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool wri
teTransparentPixels) | 198 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, const Vector<unsigned
char>& rowBuffer, size_t width, size_t rowNumber, unsigned repeatCount, bool wri
teTransparentPixels) |
| 187 { | 199 { |
| 188 const GIFFrameContext* frameContext = m_reader->frameContext(); | 200 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
| 189 // The pixel data and coordinates supplied to us are relative to the frame's | 201 // The pixel data and coordinates supplied to us are relative to the frame's |
| 190 // origin within the entire image size, i.e. | 202 // origin within the entire image size, i.e. |
| 191 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee | 203 // (frameContext->xOffset, frameContext->yOffset). There is no guarantee |
| 192 // that width == (size().width() - frameContext->xOffset), so | 204 // 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 | 205 // we must ensure we don't run off the end of either the source data or the |
| 194 // row's X-coordinates. | 206 // row's X-coordinates. |
| 195 int xBegin = upperBoundScaledX(frameContext->xOffset); | 207 int xBegin = upperBoundScaledX(frameContext->xOffset); |
| 196 int yBegin = upperBoundScaledY(frameContext->yOffset + rowNumber); | 208 int yBegin = upperBoundScaledY(frameContext->yOffset + rowNumber); |
| 197 int xEnd = lowerBoundScaledX(std::min(static_cast<int>(frameContext->xOffset
+ width), size().width()) - 1, xBegin + 1) + 1; | 209 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; | 210 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 } | 302 } |
| 291 | 303 |
| 292 return true; | 304 return true; |
| 293 } | 305 } |
| 294 | 306 |
| 295 void GIFImageDecoder::gifComplete() | 307 void GIFImageDecoder::gifComplete() |
| 296 { | 308 { |
| 297 // Cache the repetition count, which is now as authoritative as it's ever | 309 // Cache the repetition count, which is now as authoritative as it's ever |
| 298 // going to be. | 310 // going to be. |
| 299 repetitionCount(); | 311 repetitionCount(); |
| 300 | |
| 301 m_reader.clear(); | |
| 302 } | 312 } |
| 303 | 313 |
| 304 void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query) | 314 void GIFImageDecoder::decode(unsigned haltAtFrame, GIFQuery query) |
| 305 { | 315 { |
| 306 if (failed()) | 316 if (failed()) |
| 307 return; | 317 return; |
| 308 | 318 |
| 309 if (!m_reader) { | 319 if (!m_reader) { |
| 310 m_reader = adoptPtr(new GIFImageReader(this)); | 320 m_reader = adoptPtr(new GIFImageReader(this)); |
| 311 m_reader->setData(m_data); | 321 m_reader->setData(m_data); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 328 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); | 338 m_frameBufferCache[i].setPremultiplyAlpha(m_premultiplyAlpha); |
| 329 | 339 |
| 330 if (query == GIFFrameCountQuery) | 340 if (query == GIFFrameCountQuery) |
| 331 return; | 341 return; |
| 332 | 342 |
| 333 if (!m_reader->decode(GIFFullQuery, haltAtFrame)) { | 343 if (!m_reader->decode(GIFFullQuery, haltAtFrame)) { |
| 334 setFailed(); | 344 setFailed(); |
| 335 return; | 345 return; |
| 336 } | 346 } |
| 337 | 347 |
| 338 // It is also a fatal error if all data is received but we failed to decode | 348 // It is also a fatal error if all data is received and we have decoded all |
| 339 // all frames completely. | 349 // frames available but the file is truncated. |
| 340 if (isAllDataReceived() && haltAtFrame >= m_frameBufferCache.size() && m_rea
der) | 350 if (haltAtFrame >= m_frameBufferCache.size() && isAllDataReceived() && m_rea
der && !m_reader->parseCompleted()) |
| 341 setFailed(); | 351 setFailed(); |
| 342 } | 352 } |
| 343 | 353 |
| 344 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) | 354 bool GIFImageDecoder::initFrameBuffer(unsigned frameIndex) |
| 345 { | 355 { |
| 346 // Initialize the frame rect in our buffer. | 356 // Initialize the frame rect in our buffer. |
| 347 const GIFFrameContext* frameContext = m_reader->frameContext(); | 357 const GIFFrameContext* frameContext = m_reader->frameContext(frameIndex); |
| 348 IntRect frameRect(frameContext->xOffset, frameContext->yOffset, frameContext
->width, frameContext->height); | 358 IntRect frameRect(frameContext->xOffset, frameContext->yOffset, frameContext
->width, frameContext->height); |
| 349 | 359 |
| 350 // Make sure the frameRect doesn't extend outside the buffer. | 360 // Make sure the frameRect doesn't extend outside the buffer. |
| 351 if (frameRect.maxX() > size().width()) | 361 if (frameRect.maxX() > size().width()) |
| 352 frameRect.setWidth(size().width() - frameContext->xOffset); | 362 frameRect.setWidth(size().width() - frameContext->xOffset); |
| 353 if (frameRect.maxY() > size().height()) | 363 if (frameRect.maxY() > size().height()) |
| 354 frameRect.setHeight(size().height() - frameContext->yOffset); | 364 frameRect.setHeight(size().height() - frameContext->yOffset); |
| 355 | 365 |
| 356 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; | 366 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; |
| 357 int left = upperBoundScaledX(frameRect.x()); | 367 int left = upperBoundScaledX(frameRect.x()); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 | 421 |
| 412 // Update our status to be partially complete. | 422 // Update our status to be partially complete. |
| 413 buffer->setStatus(ImageFrame::FramePartial); | 423 buffer->setStatus(ImageFrame::FramePartial); |
| 414 | 424 |
| 415 // Reset the alpha pixel tracker for this frame. | 425 // Reset the alpha pixel tracker for this frame. |
| 416 m_currentBufferSawAlpha = false; | 426 m_currentBufferSawAlpha = false; |
| 417 return true; | 427 return true; |
| 418 } | 428 } |
| 419 | 429 |
| 420 } // namespace WebCore | 430 } // namespace WebCore |
| OLD | NEW |