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