Home | History | Annotate | Download | only in giflib
      1 /******************************************************************************
      2 
      3 dgif_lib.c - GIF decoding
      4 
      5 The functions here and in egif_lib.c are partitioned carefully so that
      6 if you only require one of read and write capability, only one of these
      7 two modules will be linked.  Preserve this property!
      8 
      9 *****************************************************************************/
     10 
     11 #include <stdlib.h>
     12 #include <limits.h>
     13 #include <stdint.h>
     14 #include <fcntl.h>
     15 #include <unistd.h>
     16 #include <stdio.h>
     17 #include <string.h>
     18 
     19 #ifdef _WIN32
     20 #include <io.h>
     21 #endif /* _WIN32 */
     22 
     23 #include "gif_lib.h"
     24 #include "gif_lib_private.h"
     25 
     26 /* compose unsigned little endian value */
     27 #define UNSIGNED_LITTLE_ENDIAN(lo, hi)	((lo) | ((hi) << 8))
     28 
     29 /* avoid extra function call in case we use fread (TVT) */
     30 #define READ(_gif,_buf,_len)                                     \
     31   (((GifFilePrivateType*)_gif->Private)->Read ?                   \
     32     ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
     33     fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
     34 
     35 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
     36 static int DGifSetupDecompress(GifFileType *GifFile);
     37 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
     38                               int LineLen);
     39 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
     40 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
     41 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
     42                              GifByteType *NextByte);
     43 
     44 /******************************************************************************
     45  Open a new GIF file for read, given by its name.
     46  Returns dynamically allocated GifFileType pointer which serves as the GIF
     47  info record.
     48 ******************************************************************************/
     49 GifFileType *
     50 DGifOpenFileName(const char *FileName, int *Error)
     51 {
     52     int FileHandle;
     53     GifFileType *GifFile;
     54 
     55     if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
     56 	if (Error != NULL)
     57 	    *Error = D_GIF_ERR_OPEN_FAILED;
     58         return NULL;
     59     }
     60 
     61     GifFile = DGifOpenFileHandle(FileHandle, Error);
     62     return GifFile;
     63 }
     64 
     65 /******************************************************************************
     66  Update a new GIF file, given its file handle.
     67  Returns dynamically allocated GifFileType pointer which serves as the GIF
     68  info record.
     69 ******************************************************************************/
     70 GifFileType *
     71 DGifOpenFileHandle(int FileHandle, int *Error)
     72 {
     73     char Buf[GIF_STAMP_LEN + 1];
     74     GifFileType *GifFile;
     75     GifFilePrivateType *Private;
     76     FILE *f;
     77 
     78     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
     79     if (GifFile == NULL) {
     80         if (Error != NULL)
     81 	    *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
     82         (void)close(FileHandle);
     83         return NULL;
     84     }
     85 
     86     /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
     87 
     88     /* Belt and suspenders, in case the null pointer isn't zero */
     89     GifFile->SavedImages = NULL;
     90     GifFile->SColorMap = NULL;
     91 
     92     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
     93     if (Private == NULL) {
     94         if (Error != NULL)
     95 	    *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
     96         (void)close(FileHandle);
     97         free((char *)GifFile);
     98         return NULL;
     99     }
    100 #ifdef _WIN32
    101     _setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */
    102 #endif /* _WIN32 */
    103 
    104     f = fdopen(FileHandle, "rb");    /* Make it into a stream: */
    105 
    106     /*@-mustfreeonly@*/
    107     GifFile->Private = (void *)Private;
    108     Private->FileHandle = FileHandle;
    109     Private->File = f;
    110     Private->FileState = FILE_STATE_READ;
    111     Private->Read = NULL;        /* don't use alternate input method (TVT) */
    112     GifFile->UserData = NULL;    /* TVT */
    113     /*@=mustfreeonly@*/
    114 
    115     /* Let's see if this is a GIF file: */
    116     /* coverity[check_return] */
    117     if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    118         if (Error != NULL)
    119 	    *Error = D_GIF_ERR_READ_FAILED;
    120         (void)fclose(f);
    121         free((char *)Private);
    122         free((char *)GifFile);
    123         return NULL;
    124     }
    125 
    126     /* Check for GIF prefix at start of file */
    127     Buf[GIF_STAMP_LEN] = 0;
    128     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    129         if (Error != NULL)
    130 	    *Error = D_GIF_ERR_NOT_GIF_FILE;
    131         (void)fclose(f);
    132         free((char *)Private);
    133         free((char *)GifFile);
    134         return NULL;
    135     }
    136 
    137     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    138         (void)fclose(f);
    139         free((char *)Private);
    140         free((char *)GifFile);
    141         return NULL;
    142     }
    143 
    144     GifFile->Error = 0;
    145 
    146     /* What version of GIF? */
    147     Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
    148 
    149     return GifFile;
    150 }
    151 
    152 /******************************************************************************
    153  GifFileType constructor with user supplied input function (TVT)
    154 ******************************************************************************/
    155 GifFileType *
    156 DGifOpen(void *userData, InputFunc readFunc, int *Error)
    157 {
    158     char Buf[GIF_STAMP_LEN + 1];
    159     GifFileType *GifFile;
    160     GifFilePrivateType *Private;
    161 
    162     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
    163     if (GifFile == NULL) {
    164         if (Error != NULL)
    165 	    *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    166         return NULL;
    167     }
    168 
    169     memset(GifFile, '\0', sizeof(GifFileType));
    170 
    171     /* Belt and suspenders, in case the null pointer isn't zero */
    172     GifFile->SavedImages = NULL;
    173     GifFile->SColorMap = NULL;
    174 
    175     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
    176     if (!Private) {
    177         if (Error != NULL)
    178 	    *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    179         free((char *)GifFile);
    180         return NULL;
    181     }
    182 
    183     GifFile->Private = (void *)Private;
    184     Private->FileHandle = 0;
    185     Private->File = NULL;
    186     Private->FileState = FILE_STATE_READ;
    187 
    188     Private->Read = readFunc;    /* TVT */
    189     GifFile->UserData = userData;    /* TVT */
    190 
    191     /* Lets see if this is a GIF file: */
    192     /* coverity[check_return] */
    193     if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    194         if (Error != NULL)
    195 	    *Error = D_GIF_ERR_READ_FAILED;
    196         free((char *)Private);
    197         free((char *)GifFile);
    198         return NULL;
    199     }
    200 
    201     /* Check for GIF prefix at start of file */
    202     Buf[GIF_STAMP_LEN] = '\0';
    203     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    204         if (Error != NULL)
    205 	    *Error = D_GIF_ERR_NOT_GIF_FILE;
    206         free((char *)Private);
    207         free((char *)GifFile);
    208         return NULL;
    209     }
    210 
    211     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    212         free((char *)Private);
    213         free((char *)GifFile);
    214         if (Error != NULL)
    215 	    *Error = D_GIF_ERR_NO_SCRN_DSCR;
    216         return NULL;
    217     }
    218 
    219     GifFile->Error = 0;
    220 
    221     /* What version of GIF? */
    222     Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
    223 
    224     return GifFile;
    225 }
    226 
    227 /******************************************************************************
    228  This routine should be called before any other DGif calls. Note that
    229  this routine is called automatically from DGif file open routines.
    230 ******************************************************************************/
    231 int
    232 DGifGetScreenDesc(GifFileType *GifFile)
    233 {
    234     int BitsPerPixel;
    235     bool SortFlag;
    236     GifByteType Buf[3];
    237     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    238 
    239     if (!IS_READABLE(Private)) {
    240         /* This file was NOT open for reading: */
    241         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    242         return GIF_ERROR;
    243     }
    244 
    245     /* Put the screen descriptor into the file: */
    246     if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
    247         DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
    248         return GIF_ERROR;
    249 
    250     if (READ(GifFile, Buf, 3) != 3) {
    251         GifFile->Error = D_GIF_ERR_READ_FAILED;
    252 	GifFreeMapObject(GifFile->SColorMap);
    253 	GifFile->SColorMap = NULL;
    254         return GIF_ERROR;
    255     }
    256     GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
    257     SortFlag = (Buf[0] & 0x08) != 0;
    258     BitsPerPixel = (Buf[0] & 0x07) + 1;
    259     GifFile->SBackGroundColor = Buf[1];
    260     GifFile->AspectByte = Buf[2];
    261     if (Buf[0] & 0x80) {    /* Do we have global color map? */
    262 	int i;
    263 
    264         GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
    265         if (GifFile->SColorMap == NULL) {
    266             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    267             return GIF_ERROR;
    268         }
    269 
    270         /* Get the global color map: */
    271 	GifFile->SColorMap->SortFlag = SortFlag;
    272         for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
    273 	    /* coverity[check_return] */
    274             if (READ(GifFile, Buf, 3) != 3) {
    275                 GifFreeMapObject(GifFile->SColorMap);
    276                 GifFile->SColorMap = NULL;
    277                 GifFile->Error = D_GIF_ERR_READ_FAILED;
    278                 return GIF_ERROR;
    279             }
    280             GifFile->SColorMap->Colors[i].Red = Buf[0];
    281             GifFile->SColorMap->Colors[i].Green = Buf[1];
    282             GifFile->SColorMap->Colors[i].Blue = Buf[2];
    283         }
    284     } else {
    285         GifFile->SColorMap = NULL;
    286     }
    287 
    288     return GIF_OK;
    289 }
    290 
    291 /******************************************************************************
    292  This routine should be called before any attempt to read an image.
    293 ******************************************************************************/
    294 int
    295 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
    296 {
    297     GifByteType Buf;
    298     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    299 
    300     if (!IS_READABLE(Private)) {
    301         /* This file was NOT open for reading: */
    302         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    303         return GIF_ERROR;
    304     }
    305 
    306     /* coverity[check_return] */
    307     if (READ(GifFile, &Buf, 1) != 1) {
    308         GifFile->Error = D_GIF_ERR_READ_FAILED;
    309         return GIF_ERROR;
    310     }
    311 
    312     switch (Buf) {
    313       case DESCRIPTOR_INTRODUCER:
    314           *Type = IMAGE_DESC_RECORD_TYPE;
    315           break;
    316       case EXTENSION_INTRODUCER:
    317           *Type = EXTENSION_RECORD_TYPE;
    318           break;
    319       case TERMINATOR_INTRODUCER:
    320           *Type = TERMINATE_RECORD_TYPE;
    321           break;
    322       default:
    323           *Type = UNDEFINED_RECORD_TYPE;
    324           GifFile->Error = D_GIF_ERR_WRONG_RECORD;
    325           return GIF_ERROR;
    326     }
    327 
    328     return GIF_OK;
    329 }
    330 
    331 /******************************************************************************
    332  This routine should be called before any attempt to read an image.
    333  Note it is assumed the Image desc. header has been read.
    334 ******************************************************************************/
    335 int
    336 DGifGetImageDesc(GifFileType *GifFile)
    337 {
    338     unsigned int BitsPerPixel;
    339     GifByteType Buf[3];
    340     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    341     SavedImage *sp;
    342 
    343     if (!IS_READABLE(Private)) {
    344         /* This file was NOT open for reading: */
    345         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    346         return GIF_ERROR;
    347     }
    348 
    349     if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
    350         DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
    351         DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
    352         DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
    353         return GIF_ERROR;
    354     if (READ(GifFile, Buf, 1) != 1) {
    355         GifFile->Error = D_GIF_ERR_READ_FAILED;
    356 	GifFreeMapObject(GifFile->Image.ColorMap);
    357 	GifFile->Image.ColorMap = NULL;
    358         return GIF_ERROR;
    359     }
    360     BitsPerPixel = (Buf[0] & 0x07) + 1;
    361     GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;
    362 
    363     /* Setup the colormap */
    364     if (GifFile->Image.ColorMap) {
    365         GifFreeMapObject(GifFile->Image.ColorMap);
    366         GifFile->Image.ColorMap = NULL;
    367     }
    368     /* Does this image have local color map? */
    369     if (Buf[0] & 0x80) {
    370 	unsigned int i;
    371 
    372         GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
    373         if (GifFile->Image.ColorMap == NULL) {
    374             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    375             return GIF_ERROR;
    376         }
    377 
    378         /* Get the image local color map: */
    379         for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
    380 	    /* coverity[check_return] */
    381             if (READ(GifFile, Buf, 3) != 3) {
    382                 GifFreeMapObject(GifFile->Image.ColorMap);
    383                 GifFile->Error = D_GIF_ERR_READ_FAILED;
    384                 GifFile->Image.ColorMap = NULL;
    385                 return GIF_ERROR;
    386             }
    387             GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
    388             GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
    389             GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
    390         }
    391     }
    392 
    393     if (GifFile->SavedImages) {
    394         SavedImage* new_saved_images =
    395             (SavedImage *)realloc(GifFile->SavedImages,
    396                             sizeof(SavedImage) * (GifFile->ImageCount + 1));
    397         if (new_saved_images == NULL) {
    398             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    399             return GIF_ERROR;
    400         }
    401         GifFile->SavedImages = new_saved_images;
    402     } else {
    403         if ((GifFile->SavedImages =
    404              (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
    405             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    406             return GIF_ERROR;
    407         }
    408     }
    409 
    410     sp = &GifFile->SavedImages[GifFile->ImageCount];
    411     memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
    412     if (GifFile->Image.ColorMap != NULL) {
    413         sp->ImageDesc.ColorMap = GifMakeMapObject(
    414                                  GifFile->Image.ColorMap->ColorCount,
    415                                  GifFile->Image.ColorMap->Colors);
    416         if (sp->ImageDesc.ColorMap == NULL) {
    417             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
    418             return GIF_ERROR;
    419         }
    420     }
    421     sp->RasterBits = (unsigned char *)NULL;
    422     sp->ExtensionBlockCount = 0;
    423     sp->ExtensionBlocks = (ExtensionBlock *) NULL;
    424 
    425     GifFile->ImageCount++;
    426 
    427     Private->PixelCount = (long)GifFile->Image.Width *
    428        (long)GifFile->Image.Height;
    429 
    430     /* Reset decompress algorithm parameters. */
    431     return DGifSetupDecompress(GifFile);
    432 }
    433 
    434 /******************************************************************************
    435  Get one full scanned line (Line) of length LineLen from GIF file.
    436 ******************************************************************************/
    437 int
    438 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
    439 {
    440     GifByteType *Dummy;
    441     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    442 
    443     if (!IS_READABLE(Private)) {
    444         /* This file was NOT open for reading: */
    445         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    446         return GIF_ERROR;
    447     }
    448 
    449     if (!LineLen)
    450         LineLen = GifFile->Image.Width;
    451 
    452     if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
    453         GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
    454         return GIF_ERROR;
    455     }
    456 
    457     if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
    458         if (Private->PixelCount == 0) {
    459             /* We probably won't be called any more, so let's clean up
    460              * everything before we return: need to flush out all the
    461              * rest of image until an empty block (size 0)
    462              * detected. We use GetCodeNext.
    463 	     */
    464             do
    465                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    466                     return GIF_ERROR;
    467             while (Dummy != NULL) ;
    468         }
    469         return GIF_OK;
    470     } else
    471         return GIF_ERROR;
    472 }
    473 
    474 /******************************************************************************
    475  Put one pixel (Pixel) into GIF file.
    476 ******************************************************************************/
    477 int
    478 DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
    479 {
    480     GifByteType *Dummy;
    481     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    482 
    483     if (!IS_READABLE(Private)) {
    484         /* This file was NOT open for reading: */
    485         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    486         return GIF_ERROR;
    487     }
    488     if (--Private->PixelCount > 0xffff0000UL)
    489     {
    490         GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
    491         return GIF_ERROR;
    492     }
    493 
    494     if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
    495         if (Private->PixelCount == 0) {
    496             /* We probably won't be called any more, so let's clean up
    497              * everything before we return: need to flush out all the
    498              * rest of image until an empty block (size 0)
    499              * detected. We use GetCodeNext.
    500 	     */
    501             do
    502                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    503                     return GIF_ERROR;
    504             while (Dummy != NULL) ;
    505         }
    506         return GIF_OK;
    507     } else
    508         return GIF_ERROR;
    509 }
    510 
    511 /******************************************************************************
    512  Get an extension block (see GIF manual) from GIF file. This routine only
    513  returns the first data block, and DGifGetExtensionNext should be called
    514  after this one until NULL extension is returned.
    515  The Extension should NOT be freed by the user (not dynamically allocated).
    516  Note it is assumed the Extension description header has been read.
    517 ******************************************************************************/
    518 int
    519 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
    520 {
    521     GifByteType Buf;
    522     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    523 
    524     if (!IS_READABLE(Private)) {
    525         /* This file was NOT open for reading: */
    526         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    527         return GIF_ERROR;
    528     }
    529 
    530     /* coverity[check_return] */
    531     if (READ(GifFile, &Buf, 1) != 1) {
    532         GifFile->Error = D_GIF_ERR_READ_FAILED;
    533         return GIF_ERROR;
    534     }
    535     *ExtCode = Buf;
    536 
    537     return DGifGetExtensionNext(GifFile, Extension);
    538 }
    539 
    540 /******************************************************************************
    541  Get a following extension block (see GIF manual) from GIF file. This
    542  routine should be called until NULL Extension is returned.
    543  The Extension should NOT be freed by the user (not dynamically allocated).
    544 ******************************************************************************/
    545 int
    546 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
    547 {
    548     GifByteType Buf;
    549     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    550 
    551     if (READ(GifFile, &Buf, 1) != 1) {
    552         GifFile->Error = D_GIF_ERR_READ_FAILED;
    553         return GIF_ERROR;
    554     }
    555     if (Buf > 0) {
    556         *Extension = Private->Buf;    /* Use private unused buffer. */
    557         (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    558 	/* coverity[tainted_data,check_return] */
    559         if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
    560             GifFile->Error = D_GIF_ERR_READ_FAILED;
    561             return GIF_ERROR;
    562         }
    563     } else
    564         *Extension = NULL;
    565 
    566     return GIF_OK;
    567 }
    568 
    569 /******************************************************************************
    570  Extract a Graphics Control Block from raw extension data
    571 ******************************************************************************/
    572 
    573 int DGifExtensionToGCB(const size_t GifExtensionLength,
    574 		       const GifByteType *GifExtension,
    575 		       GraphicsControlBlock *GCB)
    576 {
    577     if (GifExtensionLength != 4) {
    578 	return GIF_ERROR;
    579     }
    580 
    581     GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
    582     GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
    583     GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
    584     if (GifExtension[0] & 0x01)
    585 	GCB->TransparentColor = (int)GifExtension[3];
    586     else
    587 	GCB->TransparentColor = NO_TRANSPARENT_COLOR;
    588 
    589     return GIF_OK;
    590 }
    591 
    592 /******************************************************************************
    593  Extract the Graphics Control Block for a saved image, if it exists.
    594 ******************************************************************************/
    595 
    596 int DGifSavedExtensionToGCB(GifFileType *GifFile,
    597 			    int ImageIndex, GraphicsControlBlock *GCB)
    598 {
    599     int i;
    600 
    601     if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
    602 	return GIF_ERROR;
    603 
    604     GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
    605     GCB->UserInputFlag = false;
    606     GCB->DelayTime = 0;
    607     GCB->TransparentColor = NO_TRANSPARENT_COLOR;
    608 
    609     for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
    610 	ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
    611 	if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
    612 	    return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
    613     }
    614 
    615     return GIF_ERROR;
    616 }
    617 
    618 /******************************************************************************
    619  This routine should be called last, to close the GIF file.
    620 ******************************************************************************/
    621 int
    622 DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
    623 {
    624     GifFilePrivateType *Private;
    625 
    626     if (GifFile == NULL || GifFile->Private == NULL)
    627         return GIF_ERROR;
    628 
    629     if (GifFile->Image.ColorMap) {
    630         GifFreeMapObject(GifFile->Image.ColorMap);
    631         GifFile->Image.ColorMap = NULL;
    632     }
    633 
    634     if (GifFile->SColorMap) {
    635         GifFreeMapObject(GifFile->SColorMap);
    636         GifFile->SColorMap = NULL;
    637     }
    638 
    639     if (GifFile->SavedImages) {
    640         GifFreeSavedImages(GifFile);
    641         GifFile->SavedImages = NULL;
    642     }
    643 
    644     GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
    645 
    646     Private = (GifFilePrivateType *) GifFile->Private;
    647 
    648     if (!IS_READABLE(Private)) {
    649         /* This file was NOT open for reading: */
    650 	if (ErrorCode != NULL)
    651 	    *ErrorCode = D_GIF_ERR_NOT_READABLE;
    652 	free((char *)GifFile->Private);
    653 	free(GifFile);
    654         return GIF_ERROR;
    655     }
    656 
    657     if (Private->File && (fclose(Private->File) != 0)) {
    658 	if (ErrorCode != NULL)
    659 	    *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
    660 	free((char *)GifFile->Private);
    661 	free(GifFile);
    662         return GIF_ERROR;
    663     }
    664 
    665     free((char *)GifFile->Private);
    666     free(GifFile);
    667     if (ErrorCode != NULL)
    668 	*ErrorCode = D_GIF_SUCCEEDED;
    669     return GIF_OK;
    670 }
    671 
    672 /******************************************************************************
    673  Get 2 bytes (word) from the given file:
    674 ******************************************************************************/
    675 static int
    676 DGifGetWord(GifFileType *GifFile, GifWord *Word)
    677 {
    678     unsigned char c[2];
    679 
    680     /* coverity[check_return] */
    681     if (READ(GifFile, c, 2) != 2) {
    682         GifFile->Error = D_GIF_ERR_READ_FAILED;
    683         return GIF_ERROR;
    684     }
    685 
    686     *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
    687     return GIF_OK;
    688 }
    689 
    690 /******************************************************************************
    691  Get the image code in compressed form.  This routine can be called if the
    692  information needed to be piped out as is. Obviously this is much faster
    693  than decoding and encoding again. This routine should be followed by calls
    694  to DGifGetCodeNext, until NULL block is returned.
    695  The block should NOT be freed by the user (not dynamically allocated).
    696 ******************************************************************************/
    697 int
    698 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
    699 {
    700     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    701 
    702     if (!IS_READABLE(Private)) {
    703         /* This file was NOT open for reading: */
    704         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    705         return GIF_ERROR;
    706     }
    707 
    708     *CodeSize = Private->BitsPerPixel;
    709 
    710     return DGifGetCodeNext(GifFile, CodeBlock);
    711 }
    712 
    713 /******************************************************************************
    714  Continue to get the image code in compressed form. This routine should be
    715  called until NULL block is returned.
    716  The block should NOT be freed by the user (not dynamically allocated).
    717 ******************************************************************************/
    718 int
    719 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
    720 {
    721     GifByteType Buf;
    722     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    723 
    724     /* coverity[tainted_data_argument] */
    725     /* coverity[check_return] */
    726     if (READ(GifFile, &Buf, 1) != 1) {
    727         GifFile->Error = D_GIF_ERR_READ_FAILED;
    728         return GIF_ERROR;
    729     }
    730 
    731     /* coverity[lower_bounds] */
    732     if (Buf > 0) {
    733         *CodeBlock = Private->Buf;    /* Use private unused buffer. */
    734         (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    735 	/* coverity[tainted_data] */
    736         if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
    737             GifFile->Error = D_GIF_ERR_READ_FAILED;
    738             return GIF_ERROR;
    739         }
    740     } else {
    741         *CodeBlock = NULL;
    742         Private->Buf[0] = 0;    /* Make sure the buffer is empty! */
    743         Private->PixelCount = 0;    /* And local info. indicate image read. */
    744     }
    745 
    746     return GIF_OK;
    747 }
    748 
    749 /******************************************************************************
    750  Setup the LZ decompression for this image:
    751 ******************************************************************************/
    752 static int
    753 DGifSetupDecompress(GifFileType *GifFile)
    754 {
    755     int i, BitsPerPixel;
    756     GifByteType CodeSize;
    757     GifPrefixType *Prefix;
    758     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    759 
    760     /* coverity[check_return] */
    761     if (READ(GifFile, &CodeSize, 1) < 1) {    /* Read Code size from file. */
    762 	return GIF_ERROR;    /* Failed to read Code size. */
    763     }
    764     BitsPerPixel = CodeSize;
    765 
    766     Private->Buf[0] = 0;    /* Input Buffer empty. */
    767     Private->BitsPerPixel = BitsPerPixel;
    768     Private->ClearCode = (1 << BitsPerPixel);
    769     Private->EOFCode = Private->ClearCode + 1;
    770     Private->RunningCode = Private->EOFCode + 1;
    771     Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */
    772     Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */
    773     Private->StackPtr = 0;    /* No pixels on the pixel stack. */
    774     Private->LastCode = NO_SUCH_CODE;
    775     Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */
    776     Private->CrntShiftDWord = 0;
    777 
    778     Prefix = Private->Prefix;
    779     for (i = 0; i <= LZ_MAX_CODE; i++)
    780         Prefix[i] = NO_SUCH_CODE;
    781 
    782     return GIF_OK;
    783 }
    784 
    785 /******************************************************************************
    786  The LZ decompression routine:
    787  This version decompress the given GIF file into Line of length LineLen.
    788  This routine can be called few times (one per scan line, for example), in
    789  order the complete the whole image.
    790 ******************************************************************************/
    791 static int
    792 DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
    793 {
    794     int i = 0;
    795     int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
    796     GifByteType *Stack, *Suffix;
    797     GifPrefixType *Prefix;
    798     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    799 
    800     StackPtr = Private->StackPtr;
    801     Prefix = Private->Prefix;
    802     Suffix = Private->Suffix;
    803     Stack = Private->Stack;
    804     EOFCode = Private->EOFCode;
    805     ClearCode = Private->ClearCode;
    806     LastCode = Private->LastCode;
    807 
    808     if (StackPtr > LZ_MAX_CODE) {
    809         return GIF_ERROR;
    810     }
    811 
    812     if (StackPtr != 0) {
    813         /* Let pop the stack off before continueing to read the GIF file: */
    814         while (StackPtr != 0 && i < LineLen)
    815             Line[i++] = Stack[--StackPtr];
    816     }
    817 
    818     while (i < LineLen) {    /* Decode LineLen items. */
    819         if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
    820             return GIF_ERROR;
    821 
    822         if (CrntCode == EOFCode) {
    823             /* Note however that usually we will not be here as we will stop
    824              * decoding as soon as we got all the pixel, or EOF code will
    825              * not be read at all, and DGifGetLine/Pixel clean everything.  */
    826 	    GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;
    827 	    return GIF_ERROR;
    828         } else if (CrntCode == ClearCode) {
    829             /* We need to start over again: */
    830             for (j = 0; j <= LZ_MAX_CODE; j++)
    831                 Prefix[j] = NO_SUCH_CODE;
    832             Private->RunningCode = Private->EOFCode + 1;
    833             Private->RunningBits = Private->BitsPerPixel + 1;
    834             Private->MaxCode1 = 1 << Private->RunningBits;
    835             LastCode = Private->LastCode = NO_SUCH_CODE;
    836         } else {
    837             /* Its regular code - if in pixel range simply add it to output
    838              * stream, otherwise trace to codes linked list until the prefix
    839              * is in pixel range: */
    840             if (CrntCode < ClearCode) {
    841                 /* This is simple - its pixel scalar, so add it to output: */
    842                 Line[i++] = CrntCode;
    843             } else {
    844                 /* Its a code to needed to be traced: trace the linked list
    845                  * until the prefix is a pixel, while pushing the suffix
    846                  * pixels on our stack. If we done, pop the stack in reverse
    847                  * (thats what stack is good for!) order to output.  */
    848                 if (Prefix[CrntCode] == NO_SUCH_CODE) {
    849                     CrntPrefix = LastCode;
    850 
    851                     /* Only allowed if CrntCode is exactly the running code:
    852                      * In that case CrntCode = XXXCode, CrntCode or the
    853                      * prefix code is last code and the suffix char is
    854                      * exactly the prefix of last code! */
    855                     if (CrntCode == Private->RunningCode - 2) {
    856                         Suffix[Private->RunningCode - 2] =
    857                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
    858                                                                  LastCode,
    859                                                                  ClearCode);
    860                     } else {
    861                         Suffix[Private->RunningCode - 2] =
    862                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
    863                                                                  CrntCode,
    864                                                                  ClearCode);
    865                     }
    866                 } else
    867                     CrntPrefix = CrntCode;
    868 
    869                 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
    870                  * during the trace. As we might loop forever, in case of
    871                  * defective image, we use StackPtr as loop counter and stop
    872                  * before overflowing Stack[]. */
    873                 while (StackPtr < LZ_MAX_CODE &&
    874                        CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
    875                     Stack[StackPtr++] = Suffix[CrntPrefix];
    876                     CrntPrefix = Prefix[CrntPrefix];
    877                 }
    878                 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
    879                     GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
    880                     return GIF_ERROR;
    881                 }
    882                 /* Push the last character on stack: */
    883                 Stack[StackPtr++] = CrntPrefix;
    884 
    885                 /* Now lets pop all the stack into output: */
    886                 while (StackPtr != 0 && i < LineLen)
    887                     Line[i++] = Stack[--StackPtr];
    888             }
    889             if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
    890                 Prefix[Private->RunningCode - 2] = LastCode;
    891 
    892                 if (CrntCode == Private->RunningCode - 2) {
    893                     /* Only allowed if CrntCode is exactly the running code:
    894                      * In that case CrntCode = XXXCode, CrntCode or the
    895                      * prefix code is last code and the suffix char is
    896                      * exactly the prefix of last code! */
    897                     Suffix[Private->RunningCode - 2] =
    898                        DGifGetPrefixChar(Prefix, LastCode, ClearCode);
    899                 } else {
    900                     Suffix[Private->RunningCode - 2] =
    901                        DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
    902                 }
    903             }
    904             LastCode = CrntCode;
    905         }
    906     }
    907 
    908     Private->LastCode = LastCode;
    909     Private->StackPtr = StackPtr;
    910 
    911     return GIF_OK;
    912 }
    913 
    914 /******************************************************************************
    915  Routine to trace the Prefixes linked list until we get a prefix which is
    916  not code, but a pixel value (less than ClearCode). Returns that pixel value.
    917  If image is defective, we might loop here forever, so we limit the loops to
    918  the maximum possible if image O.k. - LZ_MAX_CODE times.
    919 ******************************************************************************/
    920 static int
    921 DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
    922 {
    923     int i = 0;
    924 
    925     while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
    926         if (Code > LZ_MAX_CODE) {
    927             return NO_SUCH_CODE;
    928         }
    929         Code = Prefix[Code];
    930     }
    931     return Code;
    932 }
    933 
    934 /******************************************************************************
    935  Interface for accessing the LZ codes directly. Set Code to the real code
    936  (12bits), or to -1 if EOF code is returned.
    937 ******************************************************************************/
    938 int
    939 DGifGetLZCodes(GifFileType *GifFile, int *Code)
    940 {
    941     GifByteType *CodeBlock;
    942     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    943 
    944     if (!IS_READABLE(Private)) {
    945         /* This file was NOT open for reading: */
    946         GifFile->Error = D_GIF_ERR_NOT_READABLE;
    947         return GIF_ERROR;
    948     }
    949 
    950     if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
    951         return GIF_ERROR;
    952 
    953     if (*Code == Private->EOFCode) {
    954         /* Skip rest of codes (hopefully only NULL terminating block): */
    955         do {
    956             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
    957                 return GIF_ERROR;
    958         } while (CodeBlock != NULL) ;
    959 
    960         *Code = -1;
    961     } else if (*Code == Private->ClearCode) {
    962         /* We need to start over again: */
    963         Private->RunningCode = Private->EOFCode + 1;
    964         Private->RunningBits = Private->BitsPerPixel + 1;
    965         Private->MaxCode1 = 1 << Private->RunningBits;
    966     }
    967 
    968     return GIF_OK;
    969 }
    970 
    971 /******************************************************************************
    972  The LZ decompression input routine:
    973  This routine is responsable for the decompression of the bit stream from
    974  8 bits (bytes) packets, into the real codes.
    975  Returns GIF_OK if read successfully.
    976 ******************************************************************************/
    977 static int
    978 DGifDecompressInput(GifFileType *GifFile, int *Code)
    979 {
    980     static const unsigned short CodeMasks[] = {
    981 	0x0000, 0x0001, 0x0003, 0x0007,
    982 	0x000f, 0x001f, 0x003f, 0x007f,
    983 	0x00ff, 0x01ff, 0x03ff, 0x07ff,
    984 	0x0fff
    985     };
    986 
    987     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    988 
    989     GifByteType NextByte;
    990 
    991     /* The image can't contain more than LZ_BITS per code. */
    992     if (Private->RunningBits > LZ_BITS) {
    993         GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
    994         return GIF_ERROR;
    995     }
    996 
    997     while (Private->CrntShiftState < Private->RunningBits) {
    998         /* Needs to get more bytes from input stream for next code: */
    999         if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
   1000             return GIF_ERROR;
   1001         }
   1002         Private->CrntShiftDWord |=
   1003 	    ((unsigned long)NextByte) << Private->CrntShiftState;
   1004         Private->CrntShiftState += 8;
   1005     }
   1006     *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
   1007 
   1008     Private->CrntShiftDWord >>= Private->RunningBits;
   1009     Private->CrntShiftState -= Private->RunningBits;
   1010 
   1011     /* If code cannot fit into RunningBits bits, must raise its size. Note
   1012      * however that codes above 4095 are used for special signaling.
   1013      * If we're using LZ_BITS bits already and we're at the max code, just
   1014      * keep using the table as it is, don't increment Private->RunningCode.
   1015      */
   1016     if (Private->RunningCode < LZ_MAX_CODE + 2 &&
   1017 	++Private->RunningCode > Private->MaxCode1 &&
   1018 	Private->RunningBits < LZ_BITS) {
   1019         Private->MaxCode1 <<= 1;
   1020         Private->RunningBits++;
   1021     }
   1022     return GIF_OK;
   1023 }
   1024 
   1025 /******************************************************************************
   1026  This routines read one GIF data block at a time and buffers it internally
   1027  so that the decompression routine could access it.
   1028  The routine returns the next byte from its internal buffer (or read next
   1029  block in if buffer empty) and returns GIF_OK if succesful.
   1030 ******************************************************************************/
   1031 static int
   1032 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
   1033 {
   1034     if (Buf[0] == 0) {
   1035         /* Needs to read the next buffer - this one is empty: */
   1036 	/* coverity[check_return] */
   1037         if (READ(GifFile, Buf, 1) != 1) {
   1038             GifFile->Error = D_GIF_ERR_READ_FAILED;
   1039             return GIF_ERROR;
   1040         }
   1041         /* There shouldn't be any empty data blocks here as the LZW spec
   1042          * says the LZW termination code should come first.  Therefore we
   1043          * shouldn't be inside this routine at that point.
   1044          */
   1045         if (Buf[0] == 0) {
   1046             GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
   1047             return GIF_ERROR;
   1048         }
   1049         if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
   1050             GifFile->Error = D_GIF_ERR_READ_FAILED;
   1051             return GIF_ERROR;
   1052         }
   1053         *NextByte = Buf[1];
   1054         Buf[1] = 2;    /* We use now the second place as last char read! */
   1055         Buf[0]--;
   1056     } else {
   1057         *NextByte = Buf[Buf[1]++];
   1058         Buf[0]--;
   1059     }
   1060 
   1061     return GIF_OK;
   1062 }
   1063 
   1064 /******************************************************************************
   1065  This routine reads an entire GIF into core, hanging all its state info off
   1066  the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
   1067  first to initialize I/O.  Its inverse is EGifSpew().
   1068 *******************************************************************************/
   1069 int
   1070 DGifSlurp(GifFileType *GifFile)
   1071 {
   1072     size_t ImageSize;
   1073     GifRecordType RecordType;
   1074     SavedImage *sp;
   1075     GifByteType *ExtData;
   1076     int ExtFunction;
   1077 
   1078     GifFile->ExtensionBlocks = NULL;
   1079     GifFile->ExtensionBlockCount = 0;
   1080 
   1081     do {
   1082         if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
   1083             return (GIF_ERROR);
   1084 
   1085         switch (RecordType) {
   1086           case IMAGE_DESC_RECORD_TYPE:
   1087               if (DGifGetImageDesc(GifFile) == GIF_ERROR)
   1088                   return (GIF_ERROR);
   1089 
   1090               sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
   1091               /* Allocate memory for the image */
   1092               if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
   1093                       sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
   1094                   return GIF_ERROR;
   1095               }
   1096               ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
   1097 
   1098               if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
   1099                   return GIF_ERROR;
   1100               }
   1101               sp->RasterBits = (unsigned char *)malloc(ImageSize *
   1102                       sizeof(GifPixelType));
   1103 
   1104               if (sp->RasterBits == NULL) {
   1105                   return GIF_ERROR;
   1106               }
   1107 
   1108 	      if (sp->ImageDesc.Interlace) {
   1109 		  int i, j;
   1110 		   /*
   1111 		    * The way an interlaced image should be read -
   1112 		    * offsets and jumps...
   1113 		    */
   1114 		  int InterlacedOffset[] = { 0, 4, 2, 1 };
   1115 		  int InterlacedJumps[] = { 8, 8, 4, 2 };
   1116 		  /* Need to perform 4 passes on the image */
   1117 		  for (i = 0; i < 4; i++)
   1118 		      for (j = InterlacedOffset[i];
   1119 			   j < sp->ImageDesc.Height;
   1120 			   j += InterlacedJumps[i]) {
   1121 			  if (DGifGetLine(GifFile,
   1122 					  sp->RasterBits+j*sp->ImageDesc.Width,
   1123 					  sp->ImageDesc.Width) == GIF_ERROR)
   1124 			      return GIF_ERROR;
   1125 		      }
   1126 	      }
   1127 	      else {
   1128 		  if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
   1129 		      return (GIF_ERROR);
   1130 	      }
   1131 
   1132               if (GifFile->ExtensionBlocks) {
   1133                   sp->ExtensionBlocks = GifFile->ExtensionBlocks;
   1134                   sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
   1135 
   1136                   GifFile->ExtensionBlocks = NULL;
   1137                   GifFile->ExtensionBlockCount = 0;
   1138               }
   1139               break;
   1140 
   1141           case EXTENSION_RECORD_TYPE:
   1142               if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)
   1143                   return (GIF_ERROR);
   1144 	      /* Create an extension block with our data */
   1145               if (ExtData != NULL) {
   1146 		  if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
   1147 					   &GifFile->ExtensionBlocks,
   1148 					   ExtFunction, ExtData[0], &ExtData[1])
   1149 		      == GIF_ERROR)
   1150 		      return (GIF_ERROR);
   1151 	      }
   1152               while (ExtData != NULL) {
   1153                   if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
   1154                       return (GIF_ERROR);
   1155                   /* Continue the extension block */
   1156 		  if (ExtData != NULL)
   1157 		      if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
   1158 					       &GifFile->ExtensionBlocks,
   1159 					       CONTINUE_EXT_FUNC_CODE,
   1160 					       ExtData[0], &ExtData[1]) == GIF_ERROR)
   1161                       return (GIF_ERROR);
   1162               }
   1163               break;
   1164 
   1165           case TERMINATE_RECORD_TYPE:
   1166               break;
   1167 
   1168           default:    /* Should be trapped by DGifGetRecordType */
   1169               break;
   1170         }
   1171     } while (RecordType != TERMINATE_RECORD_TYPE);
   1172 
   1173     return (GIF_OK);
   1174 }
   1175 
   1176 /* end */
   1177