< prev index next >

src/java.desktop/share/native/libsplashscreen/giflib/gifalloc.c

Print this page

        

*** 21,85 **** * or visit www.oracle.com if you need additional information or have any * questions. */ /***************************************************************************** ! * "Gif-Lib" - Yet another gif library. ! * ! * Written by: Gershon Elber Ver 0.1, Jun. 1989 ! * Extensively hacked by: Eric S. Raymond Ver 1.?, Sep 1992 ! ***************************************************************************** ! * GIF construction tools ! ***************************************************************************** ! * History: ! * 15 Sep 92 - Version 1.0 by Eric Raymond. ! ****************************************************************************/ ! ! #ifdef HAVE_CONFIG_H ! #include <config.h> ! #endif #include <stdlib.h> #include <stdio.h> #include <string.h> #include "gif_lib.h" #define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** ! * Miscellaneous utility functions ! *****************************************************************************/ /* return smallest bitfield size n will fit in */ int ! BitSize(int n) { ! register int i; for (i = 1; i <= 8; i++) if ((1 << i) >= n) break; return (i); } /****************************************************************************** ! * Color map object functions ! *****************************************************************************/ /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ ColorMapObject * ! MakeMapObject(int ColorCount, ! const GifColorType * ColorMap) { ! ColorMapObject *Object; /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to * make the user know that or should we automatically round up instead? */ ! if (ColorCount != (1 << BitSize(ColorCount))) { return ((ColorMapObject *) NULL); } Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); if (Object == (ColorMapObject *) NULL) { --- 21,75 ---- * or visit www.oracle.com if you need additional information or have any * questions. */ /***************************************************************************** ! ! GIF construction tools ! ! ****************************************************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> + #include "gif_lib.h" #define MAX(x, y) (((x) > (y)) ? (x) : (y)) /****************************************************************************** ! Miscellaneous utility functions ! ******************************************************************************/ /* return smallest bitfield size n will fit in */ int ! GifBitSize(int n) ! { register int i; for (i = 1; i <= 8; i++) if ((1 << i) >= n) break; return (i); } /****************************************************************************** ! Color map object functions ! ******************************************************************************/ /* * Allocate a color map of given size; initialize with contents of * ColorMap if that pointer is non-NULL. */ ColorMapObject * ! GifMakeMapObject(int ColorCount, const GifColorType *ColorMap) ! { ColorMapObject *Object; /*** FIXME: Our ColorCount has to be a power of two. Is it necessary to * make the user know that or should we automatically round up instead? */ ! if (ColorCount != (1 << GifBitSize(ColorCount))) { return ((ColorMapObject *) NULL); } Object = (ColorMapObject *)malloc(sizeof(ColorMapObject)); if (Object == (ColorMapObject *) NULL) {
*** 91,284 **** free(Object); return ((ColorMapObject *) NULL); } Object->ColorCount = ColorCount; ! Object->BitsPerPixel = BitSize(ColorCount); ! if (ColorMap) { memcpy((char *)Object->Colors, (char *)ColorMap, ColorCount * sizeof(GifColorType)); } return (Object); } ! /* ! * Free a color map object ! */ void ! FreeMapObject(ColorMapObject * Object) { ! if (Object != NULL) { ! free(Object->Colors); ! free(Object); ! Object = NULL; } } #ifdef DEBUG void ! DumpColorMap(ColorMapObject * Object, ! FILE * fp) { ! ! if (Object) { int i, j, Len = Object->ColorCount; for (i = 0; i < Len; i += 4) { for (j = 0; j < 4 && j < Len; j++) { ! fprintf(fp, "%3d: %02x %02x %02x ", i + j, Object->Colors[i + j].Red, Object->Colors[i + j].Green, Object->Colors[i + j].Blue); } ! fprintf(fp, "\n"); } } } #endif /* DEBUG */ ! /****************************************************************************** ! * Extension record functions ! *****************************************************************************/ ! void ! MakeExtension(SavedImage * New, ! int Function) { ! New->Function = Function; ! /*** FIXME: ! * Someday we might have to deal with multiple extensions. ! * ??? Was this a note from Gershon or from me? Does the multiple ! * extension blocks solve this or do we need multiple Functions? Or is ! * this an obsolete function? (People should use AddExtensionBlock ! * instead?) ! * Looks like AddExtensionBlock needs to take the int Function argument ! * then it can take the place of this function. Right now people have to ! * use both. Fix AddExtensionBlock and add this to the deprecation list. */ } ! int ! AddExtensionBlock(SavedImage * New, ! int Len, ! unsigned char ExtData[]) { ExtensionBlock *ep; ! if (New->ExtensionBlocks == NULL) ! New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); ! else ! New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks, sizeof(ExtensionBlock) * ! (New->ExtensionBlockCount + 1)); ! if (New->ExtensionBlocks == NULL) return (GIF_ERROR); ! ep = &New->ExtensionBlocks[New->ExtensionBlockCount++]; ep->ByteCount=Len; ! ep->Bytes = (char *)malloc(ep->ByteCount); if (ep->Bytes == NULL) return (GIF_ERROR); ! if (ExtData) { memcpy(ep->Bytes, ExtData, Len); - ep->Function = New->Function; } return (GIF_OK); } void ! FreeExtension(SavedImage * Image) { ExtensionBlock *ep; ! if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) { return; ! } ! for (ep = Image->ExtensionBlocks; ! ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++) (void)free((char *)ep->Bytes); ! free((char *)Image->ExtensionBlocks); ! Image->ExtensionBlocks = NULL; } /****************************************************************************** ! * Image block allocation functions ******************************************************************************/ /* 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. */ } /* * Append an image block to the SavedImages array */ SavedImage * ! MakeSavedImage(GifFileType * GifFile, ! const SavedImage * CopyFrom) { ! ! SavedImage *sp; ! if (GifFile->SavedImages == NULL) GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); else GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1)); if (GifFile->SavedImages == NULL) return ((SavedImage *)NULL); else { ! sp = &GifFile->SavedImages[GifFile->ImageCount++]; memset((char *)sp, '\0', sizeof(SavedImage)); ! if (CopyFrom) { memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); /* * Make our own allocated copies of the heap fields in the * copied record. This guards against potential aliasing * problems. */ /* first, the local color map */ ! if (sp->ImageDesc.ColorMap) { ! sp->ImageDesc.ColorMap = MakeMapObject( CopyFrom->ImageDesc.ColorMap->ColorCount, CopyFrom->ImageDesc.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); --- 81,377 ---- free(Object); return ((ColorMapObject *) NULL); } Object->ColorCount = ColorCount; ! Object->BitsPerPixel = GifBitSize(ColorCount); ! Object->SortFlag = false; ! if (ColorMap != NULL) { memcpy((char *)Object->Colors, (char *)ColorMap, ColorCount * sizeof(GifColorType)); } return (Object); } ! /******************************************************************************* ! Free a color map object ! *******************************************************************************/ void ! GifFreeMapObject(ColorMapObject *Object) ! { if (Object != NULL) { ! (void)free(Object->Colors); ! (void)free(Object); } } #ifdef DEBUG void ! DumpColorMap(ColorMapObject *Object, ! FILE * fp) ! { ! if (Object != NULL) { int i, j, Len = Object->ColorCount; for (i = 0; i < Len; i += 4) { for (j = 0; j < 4 && j < Len; j++) { ! (void)fprintf(fp, "%3d: %02x %02x %02x ", i + j, Object->Colors[i + j].Red, Object->Colors[i + j].Green, Object->Colors[i + j].Blue); } ! (void)fprintf(fp, "\n"); } } } #endif /* DEBUG */ ! /******************************************************************************* ! Compute the union of two given color maps and return it. If result can't ! fit into 256 colors, NULL is returned, the allocated union otherwise. ! ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are ! copied iff they didn't exist before. ColorTransIn2 maps the old ! ColorIn2 into the ColorUnion color map table./ ! *******************************************************************************/ ! ColorMapObject * ! GifUnionColorMap(const ColorMapObject *ColorIn1, ! const ColorMapObject *ColorIn2, ! GifPixelType ColorTransIn2[]) ! { ! int i, j, CrntSlot, RoundUpTo, NewGifBitSize; ! ColorMapObject *ColorUnion; ! /* ! * We don't worry about duplicates within either color map; if ! * the caller wants to resolve those, he can perform unions ! * with an empty color map. ! */ ! ! /* Allocate table which will hold the result for sure. */ ! ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount, ! ColorIn2->ColorCount) * 2, NULL); ! ! if (ColorUnion == NULL) ! return (NULL); ! /* ! * Copy ColorIn1 to ColorUnion. ! */ ! for (i = 0; i < ColorIn1->ColorCount; i++) ! ColorUnion->Colors[i] = ColorIn1->Colors[i]; ! CrntSlot = ColorIn1->ColorCount; ! ! /* ! * Potentially obnoxious hack: ! * ! * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end ! * of table 1. This is very useful if your display is limited to ! * 16 colors. */ + while (ColorIn1->Colors[CrntSlot - 1].Red == 0 + && ColorIn1->Colors[CrntSlot - 1].Green == 0 + && ColorIn1->Colors[CrntSlot - 1].Blue == 0) + CrntSlot--; + + /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */ + for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) { + /* Let's see if this color already exists: */ + for (j = 0; j < ColorIn1->ColorCount; j++) + if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], + sizeof(GifColorType)) == 0) + break; + + if (j < ColorIn1->ColorCount) + ColorTransIn2[i] = j; /* color exists in Color1 */ + else { + /* Color is new - copy it to a new slot: */ + ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i]; + ColorTransIn2[i] = CrntSlot++; + } + } + + if (CrntSlot > 256) { + GifFreeMapObject(ColorUnion); + return ((ColorMapObject *) NULL); + } + + NewGifBitSize = GifBitSize(CrntSlot); + RoundUpTo = (1 << NewGifBitSize); + + if (RoundUpTo != ColorUnion->ColorCount) { + register GifColorType *Map = ColorUnion->Colors; + + /* + * Zero out slots up to next power of 2. + * We know these slots exist because of the way ColorUnion's + * start dimension was computed. + */ + for (j = CrntSlot; j < RoundUpTo; j++) + Map[j].Red = Map[j].Green = Map[j].Blue = 0; + + /* perhaps we can shrink the map? */ + if (RoundUpTo < ColorUnion->ColorCount) { + GifColorType *new_map = (GifColorType *)realloc(Map, + sizeof(GifColorType) * RoundUpTo); + if( new_map == NULL ) { + GifFreeMapObject(ColorUnion); + return ((ColorMapObject *) NULL); + } + ColorUnion->Colors = new_map; + } + } + + ColorUnion->ColorCount = RoundUpTo; + ColorUnion->BitsPerPixel = NewGifBitSize; + + return (ColorUnion); } ! /******************************************************************************* ! Apply a given color translation to the raster bits of an image ! *******************************************************************************/ ! void ! GifApplyTranslation(SavedImage *Image, GifPixelType Translation[]) ! { ! register int i; ! register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width; ! ! for (i = 0; i < RasterSize; i++) ! Image->RasterBits[i] = Translation[Image->RasterBits[i]]; ! } + /****************************************************************************** + Extension record functions + ******************************************************************************/ + int + GifAddExtensionBlock(int *ExtensionBlockCount, + ExtensionBlock **ExtensionBlocks, + int Function, + unsigned int Len, + unsigned char ExtData[]) + { ExtensionBlock *ep; ! if (*ExtensionBlocks == NULL) ! *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock)); ! else { ! ExtensionBlock* ep_new = (ExtensionBlock *)realloc(*ExtensionBlocks, sizeof(ExtensionBlock) * ! (*ExtensionBlockCount + 1)); ! if( ep_new == NULL ) ! return (GIF_ERROR); ! *ExtensionBlocks = ep_new; ! } ! if (*ExtensionBlocks == NULL) return (GIF_ERROR); ! ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++]; + ep->Function = Function; ep->ByteCount=Len; ! ep->Bytes = (GifByteType *)malloc(ep->ByteCount); if (ep->Bytes == NULL) return (GIF_ERROR); ! if (ExtData != NULL) { memcpy(ep->Bytes, ExtData, Len); } return (GIF_OK); } void ! GifFreeExtensions(int *ExtensionBlockCount, ! ExtensionBlock **ExtensionBlocks) { ExtensionBlock *ep; ! if (*ExtensionBlocks == NULL) return; ! ! for (ep = *ExtensionBlocks; ! ep < (*ExtensionBlocks + *ExtensionBlockCount); ! ep++) (void)free((char *)ep->Bytes); ! (void)free((char *)*ExtensionBlocks); ! *ExtensionBlocks = NULL; ! *ExtensionBlockCount = 0; } /****************************************************************************** ! Image block allocation functions ******************************************************************************/ /* 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 != NULL) { ! GifFreeMapObject(sp->ImageDesc.ColorMap); ! sp->ImageDesc.ColorMap = NULL; ! } /* Deallocate the image data */ ! if (sp->RasterBits != NULL) free((char *)sp->RasterBits); /* Deallocate any extensions */ ! GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks); /*** 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 GifFreeSavedImages 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. */ } /* * Append an image block to the SavedImages array */ SavedImage * ! GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom) ! { if (GifFile->SavedImages == NULL) GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage)); else GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages, sizeof(SavedImage) * (GifFile->ImageCount + 1)); if (GifFile->SavedImages == NULL) return ((SavedImage *)NULL); else { ! SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++]; memset((char *)sp, '\0', sizeof(SavedImage)); ! if (CopyFrom != NULL) { memcpy((char *)sp, CopyFrom, sizeof(SavedImage)); /* * Make our own allocated copies of the heap fields in the * copied record. This guards against potential aliasing * problems. */ /* first, the local color map */ ! if (sp->ImageDesc.ColorMap != NULL) { ! sp->ImageDesc.ColorMap = GifMakeMapObject( CopyFrom->ImageDesc.ColorMap->ColorCount, CopyFrom->ImageDesc.ColorMap->Colors); if (sp->ImageDesc.ColorMap == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL);
*** 296,350 **** memcpy(sp->RasterBits, CopyFrom->RasterBits, sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width); /* finally, the extension blocks */ ! if (sp->ExtensionBlocks) { sp->ExtensionBlocks = (ExtensionBlock *)malloc( sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); if (sp->ExtensionBlocks == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); } memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); - - /* - * For the moment, the actual blocks can take their - * chances with free(). We'll fix this later. - *** FIXME: [Better check this out... Toshio] - * 2004 May 27: Looks like this was an ESR note. - * It means the blocks are shallow copied from InFile to - * OutFile. However, I don't see that in this code.... - * Did ESR fix it but never remove this note (And other notes - * in gifspnge?) - */ } } return (sp); } } 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); ! if (sp->RasterBits) free((char *)sp->RasterBits); ! if (sp->ExtensionBlocks) ! FreeExtension(sp); } free((char *)GifFile->SavedImages); ! GifFile->SavedImages=NULL; } --- 389,435 ---- memcpy(sp->RasterBits, CopyFrom->RasterBits, sizeof(GifPixelType) * CopyFrom->ImageDesc.Height * CopyFrom->ImageDesc.Width); /* finally, the extension blocks */ ! if (sp->ExtensionBlocks != NULL) { sp->ExtensionBlocks = (ExtensionBlock *)malloc( sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); if (sp->ExtensionBlocks == NULL) { FreeLastSavedImage(GifFile); return (SavedImage *)(NULL); } memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks, sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount); } } return (sp); } } void ! GifFreeSavedImages(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 != NULL) { ! GifFreeMapObject(sp->ImageDesc.ColorMap); ! sp->ImageDesc.ColorMap = NULL; ! } ! if (sp->RasterBits != NULL) free((char *)sp->RasterBits); ! GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks); } free((char *)GifFile->SavedImages); ! GifFile->SavedImages = NULL; } + + /* end */
< prev index next >