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