/****************************************************************************** * This routine should be called last, to close the GIF file. *****************************************************************************/ int DGifCloseFile(GifFileType * GifFile) { GifFilePrivateType *Private; if (GifFile == NULL) return GIF_ERROR; Private = GifFile->Private; if (GifFile->Image.ColorMap) { FreeMapObject(GifFile->Image.ColorMap); GifFile->Image.ColorMap = NULL; } if (GifFile->SColorMap) { FreeMapObject(GifFile->SColorMap); GifFile->SColorMap = NULL; } ungif_free(Private); Private = NULL; if (GifFile->SavedImages) { FreeSavedImages(GifFile); GifFile->SavedImages = NULL; } FreeExtension(&GifFile->Extensions); ungif_free(GifFile); return GIF_OK; }
/* Private Function: * Frees the last image in the GifFile->SavedImages array */ void FreeLastSavedImage(GifFileType *GifFile) { SavedImage *sp; if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) return; /* Remove one SavedImage from the GifFile */ GifFile->ImageCount--; sp = &GifFile->SavedImages[GifFile->ImageCount]; /* Deallocate its Colormap */ if (sp->ImageDesc.ColorMap) FreeMapObject(sp->ImageDesc.ColorMap); /* Deallocate the image data */ if (sp->RasterBits) free((char *)sp->RasterBits); /* Deallocate any extensions */ if (sp->ExtensionBlocks) FreeExtension(sp); /*** FIXME: We could realloc the GifFile->SavedImages structure but is * there a point to it? Saves some memory but we'd have to do it every * time. If this is used in FreeSavedImages then it would be inefficient * (The whole array is going to be deallocated.) If we just use it when * we want to free the last Image it's convenient to do it here. */ }
/* * This function free extension data that has been saved to assist the image * decoder */ void SkGifCodec::FreeExtension(SavedImage* image) { if (NULL != image->ExtensionBlocks) { #if GIFLIB_MAJOR < 5 FreeExtension(image); #else GifFreeExtensions(&image->ExtensionBlockCount, &image->ExtensionBlocks); #endif } }
void free_gif_saved_image( SavedImage *sp, Bool reusable ) { if( sp ) { if (sp->ImageDesc.ColorMap) FreeMapObject(sp->ImageDesc.ColorMap); if (sp->RasterBits) free((char *)sp->RasterBits); if (sp->ExtensionBlocks) FreeExtension(sp); if( !reusable ) free( sp ); } }
void FreeSavedImages(GifFileType *GifFile) { SavedImage *sp; for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { if (sp->ImageDesc.ColorMap) FreeMapObject(sp->ImageDesc.ColorMap); if (sp->RasterBits) free((char *)sp->RasterBits); if (sp->ExtensionBlocks) FreeExtension(sp); } free((char *) GifFile->SavedImages); }
static void FreeSavedImages(GifFileType * GifFile) { SavedImage *sp; if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) { return; } for (sp = GifFile->SavedImages; sp < GifFile->SavedImages + GifFile->ImageCount; sp++) { if (sp->ImageDesc.ColorMap) { FreeMapObject(sp->ImageDesc.ColorMap); sp->ImageDesc.ColorMap = NULL; } ungif_free(sp->RasterBits); if (sp->Extensions.ExtensionBlocks) FreeExtension(&sp->Extensions); } ungif_free(GifFile->SavedImages); GifFile->SavedImages=NULL; }
/****************************************************************************** * This routine reads an entire GIF into core, hanging all its state info off * * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() * * first to initialize I/O. Its inverse is EGifSpew(). * * ******************************************************************************/ int DGifSlurp(GifFileType *GifFile) { int i, j, Error, ImageSize; GifRecordType RecordType; SavedImage *sp; GifByteType *ExtData; SavedImage temp_save; temp_save.ExtensionBlocks=NULL; temp_save.ExtensionBlockCount=0; do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) return(GIF_ERROR); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) return(GIF_ERROR); sp = &GifFile->SavedImages[GifFile->ImageCount-1]; ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; sp->RasterBits = (char *) malloc(ImageSize * sizeof(GifPixelType)); if (DGifGetLine(GifFile, (GifByteType*)sp->RasterBits, ImageSize) == GIF_ERROR) return(GIF_ERROR); if (temp_save.ExtensionBlocks) { sp->ExtensionBlocks = temp_save.ExtensionBlocks; sp->ExtensionBlockCount = temp_save.ExtensionBlockCount; temp_save.ExtensionBlocks = NULL; temp_save.ExtensionBlockCount=0; /* FIXME: The following is wrong. It is left in only for backwards * compatibility. Someday it should go away. Use the * sp->ExtensionBlocks->Function variable instead. */ sp->Function = sp->ExtensionBlocks[0].Function; } break; case EXTENSION_RECORD_TYPE: if (DGifGetExtension(GifFile,&temp_save.Function,&ExtData)==GIF_ERROR) return(GIF_ERROR); while (ExtData != NULL) { /* Create an extension block with our data */ if (AddExtensionBlock(&temp_save, ExtData[0], (char*)&ExtData[1]) == GIF_ERROR) return (GIF_ERROR); if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) return(GIF_ERROR); temp_save.Function = 0; } break; case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Just in case the Gif has an extension block without an associated * image... (Should we save this into a savefile structure with no image * instead? Have to check if the present writing code can handle that as * well.... */ if (temp_save.ExtensionBlocks) FreeExtension(&temp_save); return(GIF_OK); }
/****************************************************************************** * This routine reads an entire GIF into core, hanging all its state info off * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() * first to initialize I/O. Its inverse is EGifSpew(). ******************************************************************************/ int DGifSlurp(GifFileType * GifFile) { int ImageSize; GifRecordType RecordType; SavedImage *sp; GifByteType *ExtData; Extensions temp_save; temp_save.ExtensionBlocks = NULL; temp_save.ExtensionBlockCount = 0; do { if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR) return (GIF_ERROR); switch (RecordType) { case IMAGE_DESC_RECORD_TYPE: if (DGifGetImageDesc(GifFile) == GIF_ERROR) return (GIF_ERROR); sp = &GifFile->SavedImages[GifFile->ImageCount - 1]; ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height; sp->RasterBits = ungif_alloc(ImageSize * sizeof(GifPixelType)); if (sp->RasterBits == NULL) { return GIF_ERROR; } if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) == GIF_ERROR) return (GIF_ERROR); if (temp_save.ExtensionBlocks) { sp->Extensions.ExtensionBlocks = temp_save.ExtensionBlocks; sp->Extensions.ExtensionBlockCount = temp_save.ExtensionBlockCount; temp_save.ExtensionBlocks = NULL; temp_save.ExtensionBlockCount = 0; /* FIXME: The following is wrong. It is left in only for * backwards compatibility. Someday it should go away. Use * the sp->ExtensionBlocks->Function variable instead. */ sp->Extensions.Function = sp->Extensions.ExtensionBlocks[0].Function; } break; case EXTENSION_RECORD_TYPE: { int Function; Extensions *Extensions; if (DGifGetExtension(GifFile, &Function, &ExtData) == GIF_ERROR) return (GIF_ERROR); if (GifFile->ImageCount || Function == GRAPHICS_EXT_FUNC_CODE) Extensions = &temp_save; else Extensions = &GifFile->Extensions; Extensions->Function = Function; /* Create an extension block with our data */ if (AddExtensionBlock(Extensions, ExtData[0], &ExtData[1]) == GIF_ERROR) return (GIF_ERROR); while (ExtData != NULL) { int Len; GifByteType *Data; if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR) return (GIF_ERROR); if (ExtData) { Len = ExtData[0]; Data = &ExtData[1]; } else { Len = 0; Data = NULL; } if (AppendExtensionBlock(Extensions, Len, Data) == GIF_ERROR) return (GIF_ERROR); } break; } case TERMINATE_RECORD_TYPE: break; default: /* Should be trapped by DGifGetRecordType */ break; } } while (RecordType != TERMINATE_RECORD_TYPE); /* Just in case the Gif has an extension block without an associated * image... (Should we save this into a savefile structure with no image * instead? Have to check if the present writing code can handle that as * well.... */ if (temp_save.ExtensionBlocks) FreeExtension(&temp_save); return (GIF_OK); }