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