in imagecore/formats/internal/gif.cpp [228:281]
bool ImageReaderGIF::readImage(Image* dest)
{
if( !supportsOutputColorModel(dest->getColorModel()) ) {
return false;
}
ImageRGBA* destImage = dest->asRGBA();
if( m_Gif == NULL || (unsigned int)m_Gif->ImageCount <= m_CurrentFrame) {
return false;
}
SavedImage* prevFrame = m_CurrentFrame > 0 ? &m_Gif->SavedImages[m_CurrentFrame - 1] : NULL;
SavedImage* currentFrame = &m_Gif->SavedImages[m_CurrentFrame];
int prevDisposalMode = prevFrame != NULL ? getDisposalMode(prevFrame) : DISPOSAL_UNSPECIFIED;
int currDisposalMode = getDisposalMode(currentFrame);
// if this is the 1st frame and it is not equal to the full image size, perform a clear
if((m_CurrentFrame == 0) && ((currentFrame->ImageDesc.Left != 0) || (currentFrame->ImageDesc.Top != 0) || (currentFrame->ImageDesc.Width != m_Width) || (currentFrame->ImageDesc.Height != m_Height))) {
destImage->clear(0, 0, 0, 0);
}
// If consecutive frames use DISPOSE_PREVIOUS, it means keep using the original frame.
// Otherwise, copy the current frame to copy back later.
if( currDisposalMode == DISPOSE_PREVIOUS && prevDisposalMode != DISPOSE_PREVIOUS && prevFrame != NULL ) {
if( m_PrevFrameCopy == NULL ) {
m_PrevFrameCopy = ImageRGBA::create(destImage->getWidth(), destImage->getHeight(), destImage->getColorModel() == kColorModel_RGBA);
if( m_PrevFrameCopy == NULL ) {
return false;
}
}
destImage->copy(m_PrevFrameCopy);
}
// Previous frame asked for it to be cleared by copying back the original frame.
if( prevDisposalMode == DISPOSE_PREVIOUS && prevFrame != NULL && m_PrevFrameCopy != NULL ) {
m_PrevFrameCopy->copy(destImage);
const GifImageDesc& desc = prevFrame->ImageDesc;
int left, top, width, height;
getValidRegion(left, top, width, height, desc, m_Width, m_Height);
destImage->copyRect(m_PrevFrameCopy, left, top, left, top, width, height);
}
// Previous frame specified a background clear, so clear the region covered by that frame.
if( prevDisposalMode == DISPOSE_BACKGROUND && prevFrame != NULL ) {
const GifImageDesc& desc = prevFrame->ImageDesc;
int left, top, width, height;
getValidRegion(left, top, width, height, desc, m_Width, m_Height);
destImage->clearRect(left, top, width, height, 255, 255, 255, 0);
m_HasAlpha = true;
}
return copyFrameRegion(m_CurrentFrame, destImage, m_CurrentFrame == 0);
}