< prev index next >

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

Print this page




   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*****************************************************************************
  26  *   "Gif-Lib" - Yet another gif library.
  27  *
  28  * Written by:  Gershon Elber                Ver 0.1, Jun. 1989
  29  * Extensively hacked by: Eric S. Raymond        Ver 1.?, Sep 1992
  30  *****************************************************************************
  31  * GIF construction tools
  32  *****************************************************************************
  33  * History:
  34  * 15 Sep 92 - Version 1.0 by Eric Raymond.
  35  ****************************************************************************/
  36 
  37 #ifdef HAVE_CONFIG_H
  38 #include <config.h>
  39 #endif
  40 
  41 #include <stdlib.h>
  42 #include <stdio.h>
  43 #include <string.h>

  44 #include "gif_lib.h"
  45 
  46 #define MAX(x, y)    (((x) > (y)) ? (x) : (y))
  47 
  48 /******************************************************************************
  49  * Miscellaneous utility functions
  50  *****************************************************************************/
  51 
  52 /* return smallest bitfield size n will fit in */
  53 int
  54 BitSize(int n) {
  55 
  56     register int i;
  57 
  58     for (i = 1; i <= 8; i++)
  59         if ((1 << i) >= n)
  60             break;
  61     return (i);
  62 }
  63 
  64 /******************************************************************************
  65  * Color map object functions
  66  *****************************************************************************/
  67 
  68 /*
  69  * Allocate a color map of given size; initialize with contents of
  70  * ColorMap if that pointer is non-NULL.
  71  */
  72 ColorMapObject *
  73 MakeMapObject(int ColorCount,
  74               const GifColorType * ColorMap) {
  75 
  76     ColorMapObject *Object;
  77 
  78     /*** FIXME: Our ColorCount has to be a power of two.  Is it necessary to
  79      * make the user know that or should we automatically round up instead? */
  80     if (ColorCount != (1 << BitSize(ColorCount))) {
  81         return ((ColorMapObject *) NULL);
  82     }
  83 
  84     Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
  85     if (Object == (ColorMapObject *) NULL) {
  86         return ((ColorMapObject *) NULL);
  87     }
  88 
  89     Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
  90     if (Object->Colors == (GifColorType *) NULL) {
  91         free(Object);
  92         return ((ColorMapObject *) NULL);
  93     }
  94 
  95     Object->ColorCount = ColorCount;
  96     Object->BitsPerPixel = BitSize(ColorCount);

  97 
  98     if (ColorMap) {
  99         memcpy((char *)Object->Colors,
 100                (char *)ColorMap, ColorCount * sizeof(GifColorType));
 101     }
 102 
 103     return (Object);
 104 }
 105 
 106 /*
 107  * Free a color map object
 108  */
 109 void
 110 FreeMapObject(ColorMapObject * Object) {
 111 
 112     if (Object != NULL) {
 113         free(Object->Colors);
 114         free(Object);
 115         Object = NULL;
 116     }
 117 }
 118 
 119 #ifdef DEBUG
 120 void
 121 DumpColorMap(ColorMapObject * Object,
 122              FILE * fp) {
 123 
 124     if (Object) {
 125         int i, j, Len = Object->ColorCount;
 126 
 127         for (i = 0; i < Len; i += 4) {
 128             for (j = 0; j < 4 && j < Len; j++) {
 129                 fprintf(fp, "%3d: %02x %02x %02x   ", i + j,
 130                         Object->Colors[i + j].Red,
 131                         Object->Colors[i + j].Green,
 132                         Object->Colors[i + j].Blue);
 133             }
 134             fprintf(fp, "\n");
 135         }
 136     }
 137 }
 138 #endif /* DEBUG */
 139 
 140 /******************************************************************************
 141  * Extension record functions
 142  *****************************************************************************/











 143 
 144 void
 145 MakeExtension(SavedImage * New,
 146               int Function) {









 147 
 148     New->Function = Function;
 149     /*** FIXME:
 150      * Someday we might have to deal with multiple extensions.
 151      * ??? Was this a note from Gershon or from me?  Does the multiple
 152      * extension blocks solve this or do we need multiple Functions?  Or is
 153      * this an obsolete function?  (People should use AddExtensionBlock
 154      * instead?)
 155      * Looks like AddExtensionBlock needs to take the int Function argument
 156      * then it can take the place of this function.  Right now people have to
 157      * use both.  Fix AddExtensionBlock and add this to the deprecation list.



 158      */

























































 159 }
 160 
 161 int
 162 AddExtensionBlock(SavedImage * New,
 163                   int Len,
 164                   unsigned char ExtData[]) {








 165 










 166     ExtensionBlock *ep;
 167 
 168     if (New->ExtensionBlocks == NULL)
 169         New->ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
 170     else
 171         New->ExtensionBlocks = (ExtensionBlock *)realloc(New->ExtensionBlocks,
 172                                       sizeof(ExtensionBlock) *
 173                                       (New->ExtensionBlockCount + 1));




 174 
 175     if (New->ExtensionBlocks == NULL)
 176         return (GIF_ERROR);
 177 
 178     ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
 179 

 180     ep->ByteCount=Len;
 181     ep->Bytes = (char *)malloc(ep->ByteCount);
 182     if (ep->Bytes == NULL)
 183         return (GIF_ERROR);
 184 
 185     if (ExtData) {
 186         memcpy(ep->Bytes, ExtData, Len);
 187         ep->Function = New->Function;
 188     }
 189 
 190     return (GIF_OK);
 191 }
 192 
 193 void
 194 FreeExtension(SavedImage * Image)

 195 {
 196     ExtensionBlock *ep;
 197 
 198     if ((Image == NULL) || (Image->ExtensionBlocks == NULL)) {
 199         return;
 200     }
 201     for (ep = Image->ExtensionBlocks;
 202          ep < (Image->ExtensionBlocks + Image->ExtensionBlockCount); ep++)

 203         (void)free((char *)ep->Bytes);
 204     free((char *)Image->ExtensionBlocks);
 205     Image->ExtensionBlocks = NULL;

 206 }
 207 
 208 /******************************************************************************
 209  * Image block allocation functions
 210 ******************************************************************************/
 211 
 212 /* Private Function:
 213  * Frees the last image in the GifFile->SavedImages array
 214  */
 215 void
 216 FreeLastSavedImage(GifFileType *GifFile) {
 217 
 218     SavedImage *sp;
 219 
 220     if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
 221         return;
 222 
 223     /* Remove one SavedImage from the GifFile */
 224     GifFile->ImageCount--;
 225     sp = &GifFile->SavedImages[GifFile->ImageCount];
 226 
 227     /* Deallocate its Colormap */
 228     if (sp->ImageDesc.ColorMap)
 229         FreeMapObject(sp->ImageDesc.ColorMap);


 230 
 231     /* Deallocate the image data */
 232     if (sp->RasterBits)
 233         free((char *)sp->RasterBits);
 234 
 235     /* Deallocate any extensions */
 236     if (sp->ExtensionBlocks)
 237         FreeExtension(sp);
 238 
 239     /*** FIXME: We could realloc the GifFile->SavedImages structure but is
 240      * there a point to it? Saves some memory but we'd have to do it every
 241      * time.  If this is used in FreeSavedImages then it would be inefficient
 242      * (The whole array is going to be deallocated.)  If we just use it when
 243      * we want to free the last Image it's convenient to do it here.
 244      */
 245 }
 246 
 247 /*
 248  * Append an image block to the SavedImages array
 249  */
 250 SavedImage *
 251 MakeSavedImage(GifFileType * GifFile,
 252                const SavedImage * CopyFrom) {
 253 
 254     SavedImage *sp;
 255 
 256     if (GifFile->SavedImages == NULL)
 257         GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
 258     else
 259         GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
 260                                sizeof(SavedImage) * (GifFile->ImageCount + 1));
 261 
 262     if (GifFile->SavedImages == NULL)
 263         return ((SavedImage *)NULL);
 264     else {
 265         sp = &GifFile->SavedImages[GifFile->ImageCount++];
 266         memset((char *)sp, '\0', sizeof(SavedImage));
 267 
 268         if (CopyFrom) {
 269             memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
 270 
 271             /*
 272              * Make our own allocated copies of the heap fields in the
 273              * copied record.  This guards against potential aliasing
 274              * problems.
 275              */
 276 
 277             /* first, the local color map */
 278             if (sp->ImageDesc.ColorMap) {
 279                 sp->ImageDesc.ColorMap = MakeMapObject(
 280                                          CopyFrom->ImageDesc.ColorMap->ColorCount,
 281                                          CopyFrom->ImageDesc.ColorMap->Colors);
 282                 if (sp->ImageDesc.ColorMap == NULL) {
 283                     FreeLastSavedImage(GifFile);
 284                     return (SavedImage *)(NULL);
 285                 }
 286             }
 287 
 288             /* next, the raster */
 289             sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
 290                                                    CopyFrom->ImageDesc.Height *
 291                                                    CopyFrom->ImageDesc.Width);
 292             if (sp->RasterBits == NULL) {
 293                 FreeLastSavedImage(GifFile);
 294                 return (SavedImage *)(NULL);
 295             }
 296             memcpy(sp->RasterBits, CopyFrom->RasterBits,
 297                    sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
 298                    CopyFrom->ImageDesc.Width);
 299 
 300             /* finally, the extension blocks */
 301             if (sp->ExtensionBlocks) {
 302                 sp->ExtensionBlocks = (ExtensionBlock *)malloc(
 303                                       sizeof(ExtensionBlock) *
 304                                       CopyFrom->ExtensionBlockCount);
 305                 if (sp->ExtensionBlocks == NULL) {
 306                     FreeLastSavedImage(GifFile);
 307                     return (SavedImage *)(NULL);
 308                 }
 309                 memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
 310                        sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);
 311 
 312                 /*
 313                  * For the moment, the actual blocks can take their
 314                  * chances with free().  We'll fix this later.
 315                  *** FIXME: [Better check this out... Toshio]
 316                  * 2004 May 27: Looks like this was an ESR note.
 317                  * It means the blocks are shallow copied from InFile to
 318                  * OutFile.  However, I don't see that in this code....
 319                  * Did ESR fix it but never remove this note (And other notes
 320                  * in gifspnge?)
 321                  */
 322             }
 323         }
 324 
 325         return (sp);
 326     }
 327 }
 328 
 329 void
 330 FreeSavedImages(GifFileType * GifFile) {
 331 
 332     SavedImage *sp;
 333 
 334     if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
 335         return;
 336     }
 337     for (sp = GifFile->SavedImages;
 338          sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
 339         if (sp->ImageDesc.ColorMap)
 340             FreeMapObject(sp->ImageDesc.ColorMap);


 341 
 342         if (sp->RasterBits)
 343             free((char *)sp->RasterBits);
 344 
 345         if (sp->ExtensionBlocks)
 346             FreeExtension(sp);
 347     }
 348     free((char *)GifFile->SavedImages);
 349     GifFile->SavedImages=NULL;
 350 }




   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*****************************************************************************
  26 
  27  GIF construction tools
  28 
  29 ****************************************************************************/










  30 
  31 #include <stdlib.h>
  32 #include <stdio.h>
  33 #include <string.h>
  34 
  35 #include "gif_lib.h"
  36 
  37 #define MAX(x, y)    (((x) > (y)) ? (x) : (y))
  38 
  39 /******************************************************************************
  40  Miscellaneous utility functions                          
  41 ******************************************************************************/
  42 
  43 /* return smallest bitfield size n will fit in */
  44 int
  45 GifBitSize(int n)
  46 {
  47     register int i;
  48 
  49     for (i = 1; i <= 8; i++)
  50         if ((1 << i) >= n)
  51             break;
  52     return (i);
  53 }
  54 
  55 /******************************************************************************
  56   Color map object functions                              
  57 ******************************************************************************/
  58 
  59 /*
  60  * Allocate a color map of given size; initialize with contents of
  61  * ColorMap if that pointer is non-NULL.
  62  */
  63 ColorMapObject *
  64 GifMakeMapObject(int ColorCount, const GifColorType *ColorMap)
  65 {

  66     ColorMapObject *Object;
  67 
  68     /*** FIXME: Our ColorCount has to be a power of two.  Is it necessary to
  69      * make the user know that or should we automatically round up instead? */
  70     if (ColorCount != (1 << GifBitSize(ColorCount))) {
  71         return ((ColorMapObject *) NULL);
  72     }
  73     
  74     Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
  75     if (Object == (ColorMapObject *) NULL) {
  76         return ((ColorMapObject *) NULL);
  77     }
  78 
  79     Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
  80     if (Object->Colors == (GifColorType *) NULL) {
  81         free(Object);
  82         return ((ColorMapObject *) NULL);
  83     }
  84 
  85     Object->ColorCount = ColorCount;
  86     Object->BitsPerPixel = GifBitSize(ColorCount);
  87     Object->SortFlag = false;
  88 
  89     if (ColorMap != NULL) {
  90         memcpy((char *)Object->Colors,
  91                (char *)ColorMap, ColorCount * sizeof(GifColorType));
  92     }
  93 
  94     return (Object);
  95 }
  96 
  97 /*******************************************************************************
  98 Free a color map object
  99 *******************************************************************************/
 100 void
 101 GifFreeMapObject(ColorMapObject *Object)
 102 {
 103     if (Object != NULL) {
 104         (void)free(Object->Colors);
 105         (void)free(Object);

 106     }
 107 }
 108 
 109 #ifdef DEBUG
 110 void
 111 DumpColorMap(ColorMapObject *Object,
 112              FILE * fp)
 113 {
 114     if (Object != NULL) {
 115         int i, j, Len = Object->ColorCount;
 116 
 117         for (i = 0; i < Len; i += 4) {
 118             for (j = 0; j < 4 && j < Len; j++) {
 119                 (void)fprintf(fp, "%3d: %02x %02x %02x   ", i + j,
 120                               Object->Colors[i + j].Red,
 121                               Object->Colors[i + j].Green,
 122                               Object->Colors[i + j].Blue);
 123             }
 124             (void)fprintf(fp, "\n");
 125         }
 126     }
 127 }
 128 #endif /* DEBUG */
 129 
 130 /*******************************************************************************
 131  Compute the union of two given color maps and return it.  If result can't 
 132  fit into 256 colors, NULL is returned, the allocated union otherwise.
 133  ColorIn1 is copied as is to ColorUnion, while colors from ColorIn2 are
 134  copied iff they didn't exist before.  ColorTransIn2 maps the old
 135  ColorIn2 into the ColorUnion color map table./
 136 *******************************************************************************/
 137 ColorMapObject *
 138 GifUnionColorMap(const ColorMapObject *ColorIn1,
 139               const ColorMapObject *ColorIn2,
 140               GifPixelType ColorTransIn2[])
 141 {
 142     int i, j, CrntSlot, RoundUpTo, NewGifBitSize;
 143     ColorMapObject *ColorUnion;
 144 
 145     /*
 146      * We don't worry about duplicates within either color map; if
 147      * the caller wants to resolve those, he can perform unions
 148      * with an empty color map.
 149      */
 150 
 151     /* Allocate table which will hold the result for sure. */
 152     ColorUnion = GifMakeMapObject(MAX(ColorIn1->ColorCount,
 153                                ColorIn2->ColorCount) * 2, NULL);
 154 
 155     if (ColorUnion == NULL)
 156         return (NULL);
 157 
 158     /* 
 159      * Copy ColorIn1 to ColorUnion.
 160      */
 161     for (i = 0; i < ColorIn1->ColorCount; i++)
 162         ColorUnion->Colors[i] = ColorIn1->Colors[i];
 163     CrntSlot = ColorIn1->ColorCount;
 164 
 165     /* 
 166      * Potentially obnoxious hack:
 167      *
 168      * Back CrntSlot down past all contiguous {0, 0, 0} slots at the end
 169      * of table 1.  This is very useful if your display is limited to
 170      * 16 colors.
 171      */
 172     while (ColorIn1->Colors[CrntSlot - 1].Red == 0
 173            && ColorIn1->Colors[CrntSlot - 1].Green == 0
 174            && ColorIn1->Colors[CrntSlot - 1].Blue == 0)
 175         CrntSlot--;
 176 
 177     /* Copy ColorIn2 to ColorUnion (use old colors if they exist): */
 178     for (i = 0; i < ColorIn2->ColorCount && CrntSlot <= 256; i++) {
 179         /* Let's see if this color already exists: */
 180         for (j = 0; j < ColorIn1->ColorCount; j++)
 181             if (memcmp (&ColorIn1->Colors[j], &ColorIn2->Colors[i], 
 182                         sizeof(GifColorType)) == 0)
 183                 break;
 184 
 185         if (j < ColorIn1->ColorCount)
 186             ColorTransIn2[i] = j;    /* color exists in Color1 */
 187         else {
 188             /* Color is new - copy it to a new slot: */
 189             ColorUnion->Colors[CrntSlot] = ColorIn2->Colors[i];
 190             ColorTransIn2[i] = CrntSlot++;
 191         }
 192     }
 193 
 194     if (CrntSlot > 256) {
 195         GifFreeMapObject(ColorUnion);
 196         return ((ColorMapObject *) NULL);
 197     }
 198 
 199     NewGifBitSize = GifBitSize(CrntSlot);
 200     RoundUpTo = (1 << NewGifBitSize);
 201 
 202     if (RoundUpTo != ColorUnion->ColorCount) {
 203         register GifColorType *Map = ColorUnion->Colors;
 204 
 205         /* 
 206          * Zero out slots up to next power of 2.
 207          * We know these slots exist because of the way ColorUnion's
 208          * start dimension was computed.
 209          */
 210         for (j = CrntSlot; j < RoundUpTo; j++)
 211             Map[j].Red = Map[j].Green = Map[j].Blue = 0;
 212 
 213         /* perhaps we can shrink the map? */
 214         if (RoundUpTo < ColorUnion->ColorCount) {
 215             GifColorType *new_map = (GifColorType *)realloc(Map,
 216                                  sizeof(GifColorType) * RoundUpTo);
 217             if( new_map == NULL ) {
 218                 GifFreeMapObject(ColorUnion);
 219                 return ((ColorMapObject *) NULL);
 220             }
 221             ColorUnion->Colors = new_map;
 222         }
 223     }
 224 
 225     ColorUnion->ColorCount = RoundUpTo;
 226     ColorUnion->BitsPerPixel = NewGifBitSize;
 227 
 228     return (ColorUnion);
 229 }
 230 
 231 /*******************************************************************************
 232  Apply a given color translation to the raster bits of an image
 233 *******************************************************************************/
 234 void
 235 GifApplyTranslation(SavedImage *Image, GifPixelType Translation[])
 236 {
 237     register int i;
 238     register int RasterSize = Image->ImageDesc.Height * Image->ImageDesc.Width;
 239 
 240     for (i = 0; i < RasterSize; i++)
 241         Image->RasterBits[i] = Translation[Image->RasterBits[i]];
 242 }
 243 
 244 /******************************************************************************
 245  Extension record functions                              
 246 ******************************************************************************/
 247 int
 248 GifAddExtensionBlock(int *ExtensionBlockCount,
 249                      ExtensionBlock **ExtensionBlocks,
 250                      int Function,
 251                      unsigned int Len,
 252                      unsigned char ExtData[])
 253 {
 254     ExtensionBlock *ep;
 255 
 256     if (*ExtensionBlocks == NULL)
 257         *ExtensionBlocks=(ExtensionBlock *)malloc(sizeof(ExtensionBlock));
 258     else {
 259         ExtensionBlock* ep_new = (ExtensionBlock *)realloc(*ExtensionBlocks,
 260                                       sizeof(ExtensionBlock) *
 261                                       (*ExtensionBlockCount + 1));
 262         if( ep_new == NULL )
 263             return (GIF_ERROR);
 264         *ExtensionBlocks = ep_new;
 265     }
 266 
 267     if (*ExtensionBlocks == NULL)
 268         return (GIF_ERROR);
 269 
 270     ep = &(*ExtensionBlocks)[(*ExtensionBlockCount)++];
 271 
 272     ep->Function = Function;
 273     ep->ByteCount=Len;
 274     ep->Bytes = (GifByteType *)malloc(ep->ByteCount);
 275     if (ep->Bytes == NULL)
 276         return (GIF_ERROR);
 277 
 278     if (ExtData != NULL) {
 279         memcpy(ep->Bytes, ExtData, Len);

 280     }
 281 
 282     return (GIF_OK);
 283 }
 284 
 285 void
 286 GifFreeExtensions(int *ExtensionBlockCount,
 287                   ExtensionBlock **ExtensionBlocks)
 288 {
 289     ExtensionBlock *ep;
 290 
 291     if (*ExtensionBlocks == NULL)
 292         return;
 293 
 294     for (ep = *ExtensionBlocks;
 295          ep < (*ExtensionBlocks + *ExtensionBlockCount); 
 296          ep++)
 297         (void)free((char *)ep->Bytes);
 298     (void)free((char *)*ExtensionBlocks);
 299     *ExtensionBlocks = NULL;
 300     *ExtensionBlockCount = 0;
 301 }
 302 
 303 /******************************************************************************
 304  Image block allocation functions                          
 305 ******************************************************************************/
 306 
 307 /* Private Function:
 308  * Frees the last image in the GifFile->SavedImages array
 309  */
 310 void
 311 FreeLastSavedImage(GifFileType *GifFile)
 312 {
 313     SavedImage *sp;
 314     
 315     if ((GifFile == NULL) || (GifFile->SavedImages == NULL))
 316         return;
 317 
 318     /* Remove one SavedImage from the GifFile */
 319     GifFile->ImageCount--;
 320     sp = &GifFile->SavedImages[GifFile->ImageCount];
 321 
 322     /* Deallocate its Colormap */
 323     if (sp->ImageDesc.ColorMap != NULL) {
 324         GifFreeMapObject(sp->ImageDesc.ColorMap);
 325         sp->ImageDesc.ColorMap = NULL;
 326     }
 327 
 328     /* Deallocate the image data */
 329     if (sp->RasterBits != NULL)
 330         free((char *)sp->RasterBits);
 331 
 332     /* Deallocate any extensions */
 333     GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);

 334 
 335     /*** FIXME: We could realloc the GifFile->SavedImages structure but is
 336      * there a point to it? Saves some memory but we'd have to do it every
 337      * time.  If this is used in GifFreeSavedImages then it would be inefficient
 338      * (The whole array is going to be deallocated.)  If we just use it when
 339      * we want to free the last Image it's convenient to do it here.
 340      */
 341 }
 342 
 343 /*
 344  * Append an image block to the SavedImages array  
 345  */
 346 SavedImage *
 347 GifMakeSavedImage(GifFileType *GifFile, const SavedImage *CopyFrom)
 348 {



 349     if (GifFile->SavedImages == NULL)
 350         GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
 351     else
 352         GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
 353                                sizeof(SavedImage) * (GifFile->ImageCount + 1));
 354 
 355     if (GifFile->SavedImages == NULL)
 356         return ((SavedImage *)NULL);
 357     else {
 358         SavedImage *sp = &GifFile->SavedImages[GifFile->ImageCount++];
 359         memset((char *)sp, '\0', sizeof(SavedImage));
 360 
 361         if (CopyFrom != NULL) {
 362             memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
 363 
 364             /* 
 365              * Make our own allocated copies of the heap fields in the
 366              * copied record.  This guards against potential aliasing
 367              * problems.
 368              */
 369 
 370             /* first, the local color map */
 371             if (sp->ImageDesc.ColorMap != NULL) {
 372                 sp->ImageDesc.ColorMap = GifMakeMapObject(
 373                                          CopyFrom->ImageDesc.ColorMap->ColorCount,
 374                                          CopyFrom->ImageDesc.ColorMap->Colors);
 375                 if (sp->ImageDesc.ColorMap == NULL) {
 376                     FreeLastSavedImage(GifFile);
 377                     return (SavedImage *)(NULL);
 378                 }
 379             }
 380 
 381             /* next, the raster */
 382             sp->RasterBits = (unsigned char *)malloc(sizeof(GifPixelType) *
 383                                                    CopyFrom->ImageDesc.Height *
 384                                                    CopyFrom->ImageDesc.Width);
 385             if (sp->RasterBits == NULL) {
 386                 FreeLastSavedImage(GifFile);
 387                 return (SavedImage *)(NULL);
 388             }
 389             memcpy(sp->RasterBits, CopyFrom->RasterBits,
 390                    sizeof(GifPixelType) * CopyFrom->ImageDesc.Height *
 391                    CopyFrom->ImageDesc.Width);
 392 
 393             /* finally, the extension blocks */
 394             if (sp->ExtensionBlocks != NULL) {
 395                 sp->ExtensionBlocks = (ExtensionBlock *)malloc(
 396                                       sizeof(ExtensionBlock) *
 397                                       CopyFrom->ExtensionBlockCount);
 398                 if (sp->ExtensionBlocks == NULL) {
 399                     FreeLastSavedImage(GifFile);
 400                     return (SavedImage *)(NULL);
 401                 }
 402                 memcpy(sp->ExtensionBlocks, CopyFrom->ExtensionBlocks,
 403                        sizeof(ExtensionBlock) * CopyFrom->ExtensionBlockCount);











 404             }
 405         }
 406 
 407         return (sp);
 408     }
 409 }
 410 
 411 void
 412 GifFreeSavedImages(GifFileType *GifFile)
 413 {
 414     SavedImage *sp;
 415 
 416     if ((GifFile == NULL) || (GifFile->SavedImages == NULL)) {
 417         return;
 418     }
 419     for (sp = GifFile->SavedImages;
 420          sp < GifFile->SavedImages + GifFile->ImageCount; sp++) {
 421         if (sp->ImageDesc.ColorMap != NULL) {
 422             GifFreeMapObject(sp->ImageDesc.ColorMap);
 423             sp->ImageDesc.ColorMap = NULL;
 424         }
 425 
 426         if (sp->RasterBits != NULL)
 427             free((char *)sp->RasterBits);
 428         
 429         GifFreeExtensions(&sp->ExtensionBlockCount, &sp->ExtensionBlocks);

 430     }
 431     free((char *)GifFile->SavedImages);
 432     GifFile->SavedImages = NULL;
 433 }
 434 
 435 /* end */
< prev index next >