in imagecore/formats/internal/gif.cpp [159:226]
bool ImageReaderGIF::copyFrameRegion(unsigned int frameIndex, ImageRGBA* destImage, bool writeBackground)
{
if( m_Gif == NULL || (unsigned int)m_Gif->ImageCount <= frameIndex ) {
return false;
}
SavedImage* savedImage = &m_Gif->SavedImages[frameIndex];
if( savedImage->RasterBits == NULL ) {
if( DGifDecodeFrame(m_Gif, frameIndex) != GIF_OK || savedImage->RasterBits == NULL ) {
return false;
}
}
GifImageDesc& imageDesc = savedImage->ImageDesc;
int transparentIndex = getTransparentIndex(savedImage);
uint8_t* regionImage = savedImage->RasterBits;
if( regionImage == NULL ) {
return false;
}
ColorMapObject* colorMap = imageDesc.ColorMap ? imageDesc.ColorMap : m_Gif->SColorMap;
if( colorMap == NULL ) {
return false;
}
int regionX;
int regionY;
int regionWidth;
int regionHeight;
getValidRegion(regionX, regionY, regionWidth, regionHeight, imageDesc, m_Width, m_Height);
unsigned int destPitch = 0;
uint8_t* destBuffer = destImage->lockRect(regionX, regionY, regionWidth, regionHeight, destPitch);
bool hadAlpha = false;
for( unsigned int y = 0; y < regionHeight; y++ ) {
for( unsigned int x = 0; x < regionWidth; x++ ) {
unsigned char paletteIndex = regionImage[y * imageDesc.Width + x];
unsigned int outIndex = y * destPitch + x * 4U;
bool isAlpha = transparentIndex == paletteIndex;
if( !isAlpha ) {
GifColorType* color = &colorMap->Colors[paletteIndex];
destBuffer[outIndex + 0] = color->Red;
destBuffer[outIndex + 1] = color->Green;
destBuffer[outIndex + 2] = color->Blue;
destBuffer[outIndex + 3] = 255;
} else {
if( writeBackground ) {
destBuffer[outIndex + 0] = 255;
destBuffer[outIndex + 1] = 255;
destBuffer[outIndex + 2] = 255;
destBuffer[outIndex + 3] = 0;
}
if( !hadAlpha ) {
hadAlpha = true;
}
}
}
}
// If we previously had a transparent frame, but just wrote a full frame over it, then it no longer has alpha.
if( m_HasAlpha && !hadAlpha && regionWidth == m_Width && regionHeight == m_Height) {
m_HasAlpha = false;
}
destImage->unlockRect();
return true;
}