| 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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 | 119 |
| 120 const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefin
ed() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table(
); | 120 const GIFColorMap::Table& colorTable = frameContext->localColorMap().isDefin
ed() ? frameContext->localColorMap().table() : m_reader->globalColorMap().table(
); |
| 121 | 121 |
| 122 if (colorTable.isEmpty()) | 122 if (colorTable.isEmpty()) |
| 123 return true; | 123 return true; |
| 124 | 124 |
| 125 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin(); | 125 GIFColorMap::Table::const_iterator colorTableIter = colorTable.begin(); |
| 126 | 126 |
| 127 // Initialize the frame if necessary. | 127 // Initialize the frame if necessary. |
| 128 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 128 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 129 if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameInd
ex)) | 129 if ((buffer.getStatus() == ImageFrame::FrameEmpty) && !initFrameBuffer(frame
Index)) |
| 130 return false; | 130 return false; |
| 131 | 131 |
| 132 const size_t transparentPixel = frameContext->transparentPixel(); | 132 const size_t transparentPixel = frameContext->transparentPixel(); |
| 133 GIFRow::const_iterator rowEnd = rowBegin + (xEnd - xBegin); | 133 GIFRow::const_iterator rowEnd = rowBegin + (xEnd - xBegin); |
| 134 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin); | 134 ImageFrame::PixelData* currentAddress = buffer.getAddr(xBegin, yBegin); |
| 135 | 135 |
| 136 // We may or may not need to write transparent pixels to the buffer. | 136 // We may or may not need to write transparent pixels to the buffer. |
| 137 // If we're compositing against a previous image, it's wrong, and if | 137 // If we're compositing against a previous image, it's wrong, and if |
| 138 // we're writing atop a cleared, fully transparent buffer, it's | 138 // we're writing atop a cleared, fully transparent buffer, it's |
| 139 // unnecessary; but if we're decoding an interlaced gif and | 139 // unnecessary; but if we're decoding an interlaced gif and |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 bool GIFImageDecoder::parseCompleted() const | 176 bool GIFImageDecoder::parseCompleted() const |
| 177 { | 177 { |
| 178 return m_reader && m_reader->parseCompleted(); | 178 return m_reader && m_reader->parseCompleted(); |
| 179 } | 179 } |
| 180 | 180 |
| 181 bool GIFImageDecoder::frameComplete(size_t frameIndex) | 181 bool GIFImageDecoder::frameComplete(size_t frameIndex) |
| 182 { | 182 { |
| 183 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, | 183 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, |
| 184 // in which case we never reach haveDecodedRow() before getting here. | 184 // in which case we never reach haveDecodedRow() before getting here. |
| 185 ImageFrame& buffer = m_frameBufferCache[frameIndex]; | 185 ImageFrame& buffer = m_frameBufferCache[frameIndex]; |
| 186 if ((buffer.status() == ImageFrame::FrameEmpty) && !initFrameBuffer(frameInd
ex)) | 186 if ((buffer.getStatus() == ImageFrame::FrameEmpty) && !initFrameBuffer(frame
Index)) |
| 187 return false; // initFrameBuffer() has already called setFailed(). | 187 return false; // initFrameBuffer() has already called setFailed(). |
| 188 | 188 |
| 189 buffer.setStatus(ImageFrame::FrameComplete); | 189 buffer.setStatus(ImageFrame::FrameComplete); |
| 190 | 190 |
| 191 if (!m_currentBufferSawAlpha) { | 191 if (!m_currentBufferSawAlpha) { |
| 192 // The whole frame was non-transparent, so it's possible that the entire | 192 // The whole frame was non-transparent, so it's possible that the entire |
| 193 // resulting buffer was non-transparent, and we can setHasAlpha(false). | 193 // resulting buffer was non-transparent, and we can setHasAlpha(false). |
| 194 if (buffer.originalFrameRect().contains(IntRect(IntPoint(), size()))) { | 194 if (buffer.originalFrameRect().contains(IntRect(IntPoint(), size()))) { |
| 195 buffer.setHasAlpha(false); | 195 buffer.setHasAlpha(false); |
| 196 buffer.setRequiredPreviousFrameIndex(kNotFound); | 196 buffer.setRequiredPreviousFrameIndex(kNotFound); |
| 197 } else if (buffer.requiredPreviousFrameIndex() != kNotFound) { | 197 } else if (buffer.requiredPreviousFrameIndex() != kNotFound) { |
| 198 // Tricky case. This frame does not have alpha only if everywhere | 198 // Tricky case. This frame does not have alpha only if everywhere |
| 199 // outside its rect doesn't have alpha. To know whether this is | 199 // outside its rect doesn't have alpha. To know whether this is |
| 200 // true, we check the start state of the frame -- if it doesn't have | 200 // true, we check the start state of the frame -- if it doesn't have |
| 201 // alpha, we're safe. | 201 // alpha, we're safe. |
| 202 const ImageFrame* prevBuffer = &m_frameBufferCache[buffer.requiredPr
eviousFrameIndex()]; | 202 const ImageFrame* prevBuffer = &m_frameBufferCache[buffer.requiredPr
eviousFrameIndex()]; |
| 203 ASSERT(prevBuffer->disposalMethod() != ImageFrame::DisposeOverwriteP
revious); | 203 ASSERT(prevBuffer->getDisposalMethod() != ImageFrame::DisposeOverwri
tePrevious); |
| 204 | 204 |
| 205 // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then | 205 // Now, if we're at a DisposeNotSpecified or DisposeKeep frame, then |
| 206 // we can say we have no alpha if that frame had no alpha. But | 206 // we can say we have no alpha if that frame had no alpha. But |
| 207 // since in initFrameBuffer() we already copied that frame's alpha | 207 // since in initFrameBuffer() we already copied that frame's alpha |
| 208 // state into the current frame's, we need do nothing at all here. | 208 // state into the current frame's, we need do nothing at all here. |
| 209 // | 209 // |
| 210 // The only remaining case is a DisposeOverwriteBgcolor frame. If | 210 // The only remaining case is a DisposeOverwriteBgcolor frame. If |
| 211 // it had no alpha, and its rect is contained in the current frame's | 211 // it had no alpha, and its rect is contained in the current frame's |
| 212 // rect, we know the current frame has no alpha. | 212 // rect, we know the current frame has no alpha. |
| 213 if ((prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgc
olor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevBuff
er->originalFrameRect())) | 213 if ((prevBuffer->getDisposalMethod() == ImageFrame::DisposeOverwrite
Bgcolor) && !prevBuffer->hasAlpha() && buffer.originalFrameRect().contains(prevB
uffer->originalFrameRect())) |
| 214 buffer.setHasAlpha(false); | 214 buffer.setHasAlpha(false); |
| 215 } | 215 } |
| 216 } | 216 } |
| 217 | 217 |
| 218 return true; | 218 return true; |
| 219 } | 219 } |
| 220 | 220 |
| 221 size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) | 221 size_t GIFImageDecoder::clearCacheExceptFrame(size_t clearExceptFrame) |
| 222 { | 222 { |
| 223 // We expect that after this call, we'll be asked to decode frames after | 223 // We expect that after this call, we'll be asked to decode frames after |
| 224 // this one. So we want to avoid clearing frames such that those requests | 224 // this one. So we want to avoid clearing frames such that those requests |
| 225 // would force re-decoding from the beginning of the image. | 225 // would force re-decoding from the beginning of the image. |
| 226 // | 226 // |
| 227 // When |clearExceptFrame| is e.g. DisposeKeep, simply not clearing that | 227 // When |clearExceptFrame| is e.g. DisposeKeep, simply not clearing that |
| 228 // frame is sufficient, as the next frame will be based on it, and in | 228 // frame is sufficient, as the next frame will be based on it, and in |
| 229 // general future frames can't be based on anything previous. | 229 // general future frames can't be based on anything previous. |
| 230 // | 230 // |
| 231 // However, if this frame is DisposeOverwritePrevious, then subsequent | 231 // However, if this frame is DisposeOverwritePrevious, then subsequent |
| 232 // frames will depend on this frame's required previous frame. In this | 232 // frames will depend on this frame's required previous frame. In this |
| 233 // case, we need to preserve both this frame and that one. | 233 // case, we need to preserve both this frame and that one. |
| 234 size_t clearExceptFrame2 = kNotFound; | 234 size_t clearExceptFrame2 = kNotFound; |
| 235 if (clearExceptFrame < m_frameBufferCache.size()) { | 235 if (clearExceptFrame < m_frameBufferCache.size()) { |
| 236 const ImageFrame& frame = m_frameBufferCache[clearExceptFrame]; | 236 const ImageFrame& frame = m_frameBufferCache[clearExceptFrame]; |
| 237 if ((frame.status() != ImageFrame::FrameEmpty) && (frame.disposalMethod(
) == ImageFrame::DisposeOverwritePrevious)) { | 237 if ((frame.getStatus() != ImageFrame::FrameEmpty) && (frame.getDisposalM
ethod() == ImageFrame::DisposeOverwritePrevious)) { |
| 238 clearExceptFrame2 = clearExceptFrame; | 238 clearExceptFrame2 = clearExceptFrame; |
| 239 clearExceptFrame = frame.requiredPreviousFrameIndex(); | 239 clearExceptFrame = frame.requiredPreviousFrameIndex(); |
| 240 } | 240 } |
| 241 } | 241 } |
| 242 | 242 |
| 243 // Now |clearExceptFrame| indicates the frame that future frames will | 243 // Now |clearExceptFrame| indicates the frame that future frames will |
| 244 // depend on. But if decoding is skipping forward past intermediate frames, | 244 // depend on. But if decoding is skipping forward past intermediate frames, |
| 245 // this frame may be FrameEmpty. So we need to keep traversing back through | 245 // this frame may be FrameEmpty. So we need to keep traversing back through |
| 246 // the required previous frames until we find the nearest non-empty | 246 // the required previous frames until we find the nearest non-empty |
| 247 // ancestor. Preserving that will minimize the amount of future decoding | 247 // ancestor. Preserving that will minimize the amount of future decoding |
| 248 // needed. | 248 // needed. |
| 249 while ((clearExceptFrame < m_frameBufferCache.size()) && (m_frameBufferCache
[clearExceptFrame].status() == ImageFrame::FrameEmpty)) | 249 while ((clearExceptFrame < m_frameBufferCache.size()) && (m_frameBufferCache
[clearExceptFrame].getStatus() == ImageFrame::FrameEmpty)) |
| 250 clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPrevious
FrameIndex(); | 250 clearExceptFrame = m_frameBufferCache[clearExceptFrame].requiredPrevious
FrameIndex(); |
| 251 return clearCacheExceptTwoFrames(clearExceptFrame, clearExceptFrame2); | 251 return clearCacheExceptTwoFrames(clearExceptFrame, clearExceptFrame2); |
| 252 } | 252 } |
| 253 | 253 |
| 254 | 254 |
| 255 size_t GIFImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1, size
_t clearExceptFrame2) | 255 size_t GIFImageDecoder::clearCacheExceptTwoFrames(size_t clearExceptFrame1, size
_t clearExceptFrame2) |
| 256 { | 256 { |
| 257 size_t frameBytesCleared = 0; | 257 size_t frameBytesCleared = 0; |
| 258 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { | 258 for (size_t i = 0; i < m_frameBufferCache.size(); ++i) { |
| 259 if (m_frameBufferCache[i].status() != ImageFrame::FrameEmpty && i != cle
arExceptFrame1 && i != clearExceptFrame2) { | 259 if (m_frameBufferCache[i].getStatus() != ImageFrame::FrameEmpty && i !=
clearExceptFrame1 && i != clearExceptFrame2) { |
| 260 frameBytesCleared += frameBytesAtIndex(i); | 260 frameBytesCleared += frameBytesAtIndex(i); |
| 261 clearFrameBuffer(i); | 261 clearFrameBuffer(i); |
| 262 } | 262 } |
| 263 } | 263 } |
| 264 return frameBytesCleared; | 264 return frameBytesCleared; |
| 265 } | 265 } |
| 266 | 266 |
| 267 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) | 267 void GIFImageDecoder::clearFrameBuffer(size_t frameIndex) |
| 268 { | 268 { |
| 269 if (m_reader && m_frameBufferCache[frameIndex].status() == ImageFrame::Frame
Partial) { | 269 if (m_reader && m_frameBufferCache[frameIndex].getStatus() == ImageFrame::Fr
amePartial) { |
| 270 // Reset the state of the partial frame in the reader so that the frame | 270 // Reset the state of the partial frame in the reader so that the frame |
| 271 // can be decoded again when requested. | 271 // can be decoded again when requested. |
| 272 m_reader->clearDecodeState(frameIndex); | 272 m_reader->clearDecodeState(frameIndex); |
| 273 } | 273 } |
| 274 ImageDecoder::clearFrameBuffer(frameIndex); | 274 ImageDecoder::clearFrameBuffer(frameIndex); |
| 275 } | 275 } |
| 276 | 276 |
| 277 size_t GIFImageDecoder::decodeFrameCount() | 277 size_t GIFImageDecoder::decodeFrameCount() |
| 278 { | 278 { |
| 279 parse(GIFFrameCountQuery); | 279 parse(GIFFrameCountQuery); |
| 280 // If decoding fails, |m_reader| will have been destroyed. Instead of | 280 // If decoding fails, |m_reader| will have been destroyed. Instead of |
| 281 // returning 0 in this case, return the existing number of frames. This way | 281 // returning 0 in this case, return the existing number of frames. This way |
| 282 // if we get halfway through the image before decoding fails, we won't | 282 // if we get halfway through the image before decoding fails, we won't |
| 283 // suddenly start reporting that the image has zero frames. | 283 // suddenly start reporting that the image has zero frames. |
| 284 return failed() ? m_frameBufferCache.size() : m_reader->imagesCount(); | 284 return failed() ? m_frameBufferCache.size() : m_reader->imagesCount(); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void GIFImageDecoder::initializeNewFrame(size_t index) | 287 void GIFImageDecoder::initializeNewFrame(size_t index) |
| 288 { | 288 { |
| 289 ImageFrame* buffer = &m_frameBufferCache[index]; | 289 ImageFrame* buffer = &m_frameBufferCache[index]; |
| 290 const GIFFrameContext* frameContext = m_reader->frameContext(index); | 290 const GIFFrameContext* frameContext = m_reader->frameContext(index); |
| 291 buffer->setOriginalFrameRect(intersection(frameContext->frameRect(), IntRect
(IntPoint(), size()))); | 291 buffer->setOriginalFrameRect(intersection(frameContext->frameRect(), IntRect
(IntPoint(), size()))); |
| 292 buffer->setDuration(frameContext->delayTime()); | 292 buffer->setDuration(frameContext->delayTime()); |
| 293 buffer->setDisposalMethod(frameContext->disposalMethod()); | 293 buffer->setDisposalMethod(frameContext->getDisposalMethod()); |
| 294 buffer->setRequiredPreviousFrameIndex(findRequiredPreviousFrame(index, false
)); | 294 buffer->setRequiredPreviousFrameIndex(findRequiredPreviousFrame(index, false
)); |
| 295 } | 295 } |
| 296 | 296 |
| 297 void GIFImageDecoder::decode(size_t index) | 297 void GIFImageDecoder::decode(size_t index) |
| 298 { | 298 { |
| 299 parse(GIFFrameCountQuery); | 299 parse(GIFFrameCountQuery); |
| 300 | 300 |
| 301 if (failed()) | 301 if (failed()) |
| 302 return; | 302 return; |
| 303 | 303 |
| 304 Vector<size_t> framesToDecode; | 304 Vector<size_t> framesToDecode; |
| 305 size_t frameToDecode = index; | 305 size_t frameToDecode = index; |
| 306 do { | 306 do { |
| 307 framesToDecode.append(frameToDecode); | 307 framesToDecode.append(frameToDecode); |
| 308 frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFrameI
ndex(); | 308 frameToDecode = m_frameBufferCache[frameToDecode].requiredPreviousFrameI
ndex(); |
| 309 } while (frameToDecode != kNotFound && m_frameBufferCache[frameToDecode].sta
tus() != ImageFrame::FrameComplete); | 309 } while (frameToDecode != kNotFound && m_frameBufferCache[frameToDecode].get
Status() != ImageFrame::FrameComplete); |
| 310 | 310 |
| 311 for (auto i = framesToDecode.rbegin(); i != framesToDecode.rend(); ++i) { | 311 for (auto i = framesToDecode.rbegin(); i != framesToDecode.rend(); ++i) { |
| 312 if (!m_reader->decode(*i)) { | 312 if (!m_reader->decode(*i)) { |
| 313 setFailed(); | 313 setFailed(); |
| 314 return; | 314 return; |
| 315 } | 315 } |
| 316 | 316 |
| 317 // We need more data to continue decoding. | 317 // We need more data to continue decoding. |
| 318 if (m_frameBufferCache[*i].status() != ImageFrame::FrameComplete) | 318 if (m_frameBufferCache[*i].getStatus() != ImageFrame::FrameComplete) |
| 319 break; | 319 break; |
| 320 } | 320 } |
| 321 | 321 |
| 322 // It is also a fatal error if all data is received and we have decoded all | 322 // It is also a fatal error if all data is received and we have decoded all |
| 323 // frames available but the file is truncated. | 323 // frames available but the file is truncated. |
| 324 if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() && m_reade
r && !m_reader->parseCompleted()) | 324 if (index >= m_frameBufferCache.size() - 1 && isAllDataReceived() && m_reade
r && !m_reader->parseCompleted()) |
| 325 setFailed(); | 325 setFailed(); |
| 326 } | 326 } |
| 327 | 327 |
| 328 void GIFImageDecoder::parse(GIFParseQuery query) | 328 void GIFImageDecoder::parse(GIFParseQuery query) |
| (...skipping 15 matching lines...) Expand all Loading... |
| 344 // Initialize the frame rect in our buffer. | 344 // Initialize the frame rect in our buffer. |
| 345 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; | 345 ImageFrame* const buffer = &m_frameBufferCache[frameIndex]; |
| 346 | 346 |
| 347 size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); | 347 size_t requiredPreviousFrameIndex = buffer->requiredPreviousFrameIndex(); |
| 348 if (requiredPreviousFrameIndex == kNotFound) { | 348 if (requiredPreviousFrameIndex == kNotFound) { |
| 349 // This frame doesn't rely on any previous data. | 349 // This frame doesn't rely on any previous data. |
| 350 if (!buffer->setSize(size().width(), size().height())) | 350 if (!buffer->setSize(size().width(), size().height())) |
| 351 return setFailed(); | 351 return setFailed(); |
| 352 } else { | 352 } else { |
| 353 const ImageFrame* prevBuffer = &m_frameBufferCache[requiredPreviousFrame
Index]; | 353 const ImageFrame* prevBuffer = &m_frameBufferCache[requiredPreviousFrame
Index]; |
| 354 ASSERT(prevBuffer->status() == ImageFrame::FrameComplete); | 354 ASSERT(prevBuffer->getStatus() == ImageFrame::FrameComplete); |
| 355 | 355 |
| 356 // Preserve the last frame as the starting state for this frame. | 356 // Preserve the last frame as the starting state for this frame. |
| 357 if (!buffer->copyBitmapData(*prevBuffer)) | 357 if (!buffer->copyBitmapData(*prevBuffer)) |
| 358 return setFailed(); | 358 return setFailed(); |
| 359 | 359 |
| 360 if (prevBuffer->disposalMethod() == ImageFrame::DisposeOverwriteBgcolor)
{ | 360 if (prevBuffer->getDisposalMethod() == ImageFrame::DisposeOverwriteBgcol
or) { |
| 361 // We want to clear the previous frame to transparent, without | 361 // We want to clear the previous frame to transparent, without |
| 362 // affecting pixels in the image outside of the frame. | 362 // affecting pixels in the image outside of the frame. |
| 363 const IntRect& prevRect = prevBuffer->originalFrameRect(); | 363 const IntRect& prevRect = prevBuffer->originalFrameRect(); |
| 364 ASSERT(!prevRect.contains(IntRect(IntPoint(), size()))); | 364 ASSERT(!prevRect.contains(IntRect(IntPoint(), size()))); |
| 365 buffer->zeroFillFrameRect(prevRect); | 365 buffer->zeroFillFrameRect(prevRect); |
| 366 } | 366 } |
| 367 } | 367 } |
| 368 | 368 |
| 369 // Update our status to be partially complete. | 369 // Update our status to be partially complete. |
| 370 buffer->setStatus(ImageFrame::FramePartial); | 370 buffer->setStatus(ImageFrame::FramePartial); |
| 371 | 371 |
| 372 // Reset the alpha pixel tracker for this frame. | 372 // Reset the alpha pixel tracker for this frame. |
| 373 m_currentBufferSawAlpha = false; | 373 m_currentBufferSawAlpha = false; |
| 374 return true; | 374 return true; |
| 375 } | 375 } |
| 376 | 376 |
| 377 } // namespace blink | 377 } // namespace blink |
| OLD | NEW |