| 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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 } | 324 } |
| 325 | 325 |
| 326 // Update our status to be partially complete. | 326 // Update our status to be partially complete. |
| 327 buffer->setStatus(RGBA32Buffer::FramePartial); | 327 buffer->setStatus(RGBA32Buffer::FramePartial); |
| 328 | 328 |
| 329 // Reset the alpha pixel tracker for this frame. | 329 // Reset the alpha pixel tracker for this frame. |
| 330 m_currentBufferSawAlpha = false; | 330 m_currentBufferSawAlpha = false; |
| 331 return true; | 331 return true; |
| 332 } | 332 } |
| 333 | 333 |
| 334 void GIFImageDecoder::haveDecodedRow(unsigned frameIndex, | 334 bool GIFImageDecoder::haveDecodedRow(unsigned frameIndex, |
| 335 unsigned char* rowBuffer, | 335 unsigned char* rowBuffer, |
| 336 unsigned char* rowEnd, | 336 unsigned char* rowEnd, |
| 337 unsigned rowNumber, | 337 unsigned rowNumber, |
| 338 unsigned repeatCount, | 338 unsigned repeatCount, |
| 339 bool writeTransparentPixels) | 339 bool writeTransparentPixels) |
| 340 { | 340 { |
| 341 // The pixel data and coordinates supplied to us are relative to the frame's | 341 // The pixel data and coordinates supplied to us are relative to the frame's |
| 342 // origin within the entire image size, i.e. | 342 // origin within the entire image size, i.e. |
| 343 // (m_reader->frameXOffset(), m_reader->frameYOffset()). | 343 // (m_reader->frameXOffset(), m_reader->frameYOffset()). |
| 344 int x = m_reader->frameXOffset(); | 344 int x = m_reader->frameXOffset(); |
| 345 const int y = m_reader->frameYOffset() + rowNumber; | 345 const int y = m_reader->frameYOffset() + rowNumber; |
| 346 | 346 |
| 347 // Sanity-check the arguments. | 347 // Sanity-check the arguments. |
| 348 if ((rowBuffer == 0) || (y >= size().height())) | 348 if ((rowBuffer == 0) || (y >= size().height())) |
| 349 return; | 349 return true; |
| 350 | 350 |
| 351 // Get the colormap. | 351 // Get the colormap. |
| 352 unsigned colorMapSize; | 352 unsigned colorMapSize; |
| 353 unsigned char* colorMap; | 353 unsigned char* colorMap; |
| 354 m_reader->getColorMap(colorMap, colorMapSize); | 354 m_reader->getColorMap(colorMap, colorMapSize); |
| 355 if (!colorMap) | 355 if (!colorMap) |
| 356 return; | 356 return true; |
| 357 | 357 |
| 358 // Initialize the frame if necessary. | 358 // Initialize the frame if necessary. |
| 359 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; | 359 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; |
| 360 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameI
ndex)) | 360 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameI
ndex)) |
| 361 return; | 361 return false; |
| 362 | 362 |
| 363 // Write one row's worth of data into the frame. There is no guarantee that | 363 // Write one row's worth of data into the frame. There is no guarantee that |
| 364 // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so | 364 // (rowEnd - rowBuffer) == (size().width() - m_reader->frameXOffset()), so |
| 365 // we must ensure we don't run off the end of either the source data or the | 365 // we must ensure we don't run off the end of either the source data or the |
| 366 // row's X-coordinates. | 366 // row's X-coordinates. |
| 367 for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < s
ize().width()); ++sourceAddr, ++x) { | 367 for (unsigned char* sourceAddr = rowBuffer; (sourceAddr != rowEnd) && (x < s
ize().width()); ++sourceAddr, ++x) { |
| 368 const unsigned char sourceValue = *sourceAddr; | 368 const unsigned char sourceValue = *sourceAddr; |
| 369 if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparent
Pixel())) && (sourceValue < colorMapSize)) { | 369 if ((!m_reader->isTransparent() || (sourceValue != m_reader->transparent
Pixel())) && (sourceValue < colorMapSize)) { |
| 370 const size_t colorIndex = static_cast<size_t>(sourceValue) * 3; | 370 const size_t colorIndex = static_cast<size_t>(sourceValue) * 3; |
| 371 buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1],
colorMap[colorIndex + 2], 255); | 371 buffer.setRGBA(x, y, colorMap[colorIndex], colorMap[colorIndex + 1],
colorMap[colorIndex + 2], 255); |
| 372 } else { | 372 } else { |
| 373 m_currentBufferSawAlpha = true; | 373 m_currentBufferSawAlpha = true; |
| 374 // We may or may not need to write transparent pixels to the buffer. | 374 // We may or may not need to write transparent pixels to the buffer. |
| 375 // If we're compositing against a previous image, it's wrong, and if | 375 // If we're compositing against a previous image, it's wrong, and if |
| 376 // we're writing atop a cleared, fully transparent buffer, it's | 376 // we're writing atop a cleared, fully transparent buffer, it's |
| 377 // unnecessary; but if we're decoding an interlaced gif and | 377 // unnecessary; but if we're decoding an interlaced gif and |
| 378 // displaying it "Haeberli"-style, we must write these for passes | 378 // displaying it "Haeberli"-style, we must write these for passes |
| 379 // beyond the first, or the initial passes will "show through" the | 379 // beyond the first, or the initial passes will "show through" the |
| 380 // later ones. | 380 // later ones. |
| 381 if (writeTransparentPixels) | 381 if (writeTransparentPixels) |
| 382 buffer.setRGBA(x, y, 0, 0, 0, 0); | 382 buffer.setRGBA(x, y, 0, 0, 0, 0); |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 | 385 |
| 386 // Tell the frame to copy the row data if need be. | 386 // Tell the frame to copy the row data if need be. |
| 387 if (repeatCount > 1) | 387 if (repeatCount > 1) |
| 388 buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static
_cast<int>(repeatCount), size().height())); | 388 buffer.copyRowNTimes(m_reader->frameXOffset(), x, y, std::min(y + static
_cast<int>(repeatCount), size().height())); |
| 389 |
| 390 return true; |
| 389 } | 391 } |
| 390 | 392 |
| 391 void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
RGBA32Buffer::FrameDisposalMethod disposalMethod) | 393 void GIFImageDecoder::frameComplete(unsigned frameIndex, unsigned frameDuration,
RGBA32Buffer::FrameDisposalMethod disposalMethod) |
| 392 { | 394 { |
| 393 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, | 395 // Initialize the frame if necessary. Some GIFs insert do-nothing frames, |
| 394 // in which case we never reach haveDecodedRow() before getting here. | 396 // in which case we never reach haveDecodedRow() before getting here. |
| 395 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; | 397 RGBA32Buffer& buffer = m_frameBufferCache[frameIndex]; |
| 396 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameI
ndex)) | 398 if ((buffer.status() == RGBA32Buffer::FrameEmpty) && !initFrameBuffer(frameI
ndex)) |
| 397 return; | 399 return; |
| 398 | 400 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 | 438 |
| 437 void GIFImageDecoder::gifComplete() | 439 void GIFImageDecoder::gifComplete() |
| 438 { | 440 { |
| 439 if (m_reader) | 441 if (m_reader) |
| 440 m_repetitionCount = m_reader->repetitionCount(); | 442 m_repetitionCount = m_reader->repetitionCount(); |
| 441 delete m_reader; | 443 delete m_reader; |
| 442 m_reader = 0; | 444 m_reader = 0; |
| 443 } | 445 } |
| 444 | 446 |
| 445 } // namespace WebCore | 447 } // namespace WebCore |
| OLD | NEW |