< prev index next >

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

Print this page




  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;


 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) {


 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);


 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 


 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)


 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 


 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. */


 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;


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


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...


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) {


  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;


 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) {


 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);


 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 


 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)


 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 


 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. */


 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;


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


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...


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) {
< prev index next >