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 |