in animated-gif/src/main/jni/gifimage/gif.cpp [609:671]
int modifiedDGifSlurp(GifWrapper* pGifWrapper, int maxDimension, bool forceStatic) {
GifFileType* pGifFile = pGifWrapper->get();
GifRecordType recordType;
pGifFile->ExtensionBlocks = NULL;
pGifFile->ExtensionBlockCount = 0;
bool isStop = false;
do {
if (DGifGetRecordType(pGifFile, &recordType) == GIF_ERROR) {
break;
}
switch (recordType) {
case IMAGE_DESC_RECORD_TYPE:
// Set the flag whether gif is animated, but give up slurping after the first frame,
// when static image is requested.
if (pGifFile->ImageCount >= 1) {
pGifWrapper->setAnimated(true);
if (forceStatic) {
isStop = true;
break;
}
}
// We save the byte offset where each frame begins. This allows us to avoid storing
// the pixel data for each frame and instead decode it on the fly.
pGifWrapper->addFrameByteOffset(pGifWrapper->getData()->getPosition());
if (readSingleFrame(
pGifWrapper,
false, // Don't decode frame pixels
true, // Add to saved images
maxDimension // Max dimension
) == GIF_ERROR) {
isStop = true;
}
break;
case EXTENSION_RECORD_TYPE:
if (decodeExtension(pGifFile) == GIF_ERROR) {
isStop = true;
}
break;
case TERMINATE_RECORD_TYPE:
isStop = true;
break;
default: // Should be trapped by DGifGetRecordType.
break;
}
} while (!isStop);
isStop = false;
// parse application extensions
const int imageCount = pGifFile->ImageCount;
ReaderLock rlock_{pGifWrapper->getSavedImagesRWLock()};
for (int i = 0; i < imageCount; i++) {
parseApplicationExtensions(&pGifFile->SavedImages[i], pGifWrapper);
}
return pGifWrapper->getFrameSize() > 0 ? GIF_OK : GIF_ERROR;
}