< prev index next >

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

Print this page




   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  *   "Gif-Lib" - Yet another gif library.
  27  *
  28  * Written by:  Gershon Elber            IBM PC Ver 1.1,    Aug. 1990
  29  ******************************************************************************
  30  * The kernel of the GIF Decoding process can be found here.
  31  ******************************************************************************
  32  * History:
  33  * 16 Jun 89 - Version 1.0 by Gershon Elber.
  34  *  3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
  35  *****************************************************************************/
  36 
  37 /* !!!! */
  38 
  39 #ifdef HAVE_CONFIG_H
  40 #include <config.h>
  41 #endif
  42 
  43 #include <stdlib.h>
  44 #if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__)
  45 #include <io.h>
  46 #include <alloc.h>
  47 #include <sys\stat.h>
  48 #else
  49 #include <sys/types.h>
  50 #include <sys/stat.h>
  51 #endif /* __MSDOS__ */
  52 
  53 #ifdef _WIN32
  54 #include <io.h>
  55 #define _OPEN_BINARY
  56 #else
  57 #include <unistd.h>
  58 #endif
  59 
  60 #include <fcntl.h>
  61 
  62 #include <stdio.h>
  63 #include <string.h>
  64 #include "gif_lib.h"
  65 #include "gif_lib_private.h"
  66 
  67 #define COMMENT_EXT_FUNC_CODE 0xfe  /* Extension function code for
  68                                        comment. */
  69 
  70 /* avoid extra function call in case we use fread (TVT) */
  71 #define READ(_gif,_buf,_len)                                     \
  72   (((GifFilePrivateType*)_gif->Private)->Read ?                   \
  73     (size_t)((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
  74     fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
  75 
  76 static int DGifGetWord(GifFileType *GifFile, int *Word);
  77 static int DGifSetupDecompress(GifFileType *GifFile);
  78 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
  79                               int LineLen);
  80 static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode);
  81 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
  82 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
  83                              GifByteType *NextByte);
  84 
  85 /******************************************************************************
  86  * Open a new gif file for read, given by its name.
  87  * Returns GifFileType pointer dynamically allocated which serves as the gif
  88  * info record. _GifError is cleared if succesfull.
  89  *****************************************************************************/
  90 GifFileType *
  91 DGifOpenFileName(const char *FileName) {

  92     int FileHandle;
  93     GifFileType *GifFile;
  94 
  95     if ((FileHandle = open(FileName, O_RDONLY
  96 #if defined(__MSDOS__) || defined(_OPEN_BINARY)
  97                            | O_BINARY
  98 #endif /* __MSDOS__ || _OPEN_BINARY */
  99          )) == -1) {
 100         _GifError = D_GIF_ERR_OPEN_FAILED;
 101         return NULL;
 102     }
 103 
 104     GifFile = DGifOpenFileHandle(FileHandle);
 105     if (GifFile == (GifFileType *)NULL)
 106         close(FileHandle);
 107     return GifFile;
 108 }
 109 
 110 /******************************************************************************
 111  * Update a new gif file, given its file handle.
 112  * Returns GifFileType pointer dynamically allocated which serves as the gif
 113  * info record. _GifError is cleared if succesfull.
 114  *****************************************************************************/
 115 GifFileType *
 116 DGifOpenFileHandle(int FileHandle) {
 117 
 118     unsigned char Buf[GIF_STAMP_LEN + 1];
 119     GifFileType *GifFile;
 120     GifFilePrivateType *Private;
 121     FILE *f;
 122 
 123     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
 124     if (GifFile == NULL) {
 125         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;


 126         return NULL;
 127     }
 128 
 129     memset(GifFile, '\0', sizeof(GifFileType));




 130 
 131     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
 132     if (Private == NULL) {
 133         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;


 134         free((char *)GifFile);
 135         return NULL;
 136     }
 137 #ifdef __MSDOS__
 138     setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */
 139 #endif /* __MSDOS__ */
 140 
 141     f = fdopen(FileHandle, "rb");    /* Make it into a stream: */
 142 
 143 #ifdef __MSDOS__
 144     setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);    /* And inc. stream
 145                                                           buffer. */
 146 #endif /* __MSDOS__ */
 147 
 148     GifFile->Private = (VoidPtr)Private;
 149     Private->FileHandle = FileHandle;
 150     Private->File = f;
 151     Private->FileState = FILE_STATE_READ;
 152     Private->Read = 0;    /* don't use alternate input method (TVT) */
 153     GifFile->UserData = 0;    /* TVT */
 154 
 155     /* Lets see if this is a GIF file: */
 156     if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
 157         _GifError = D_GIF_ERR_READ_FAILED;
 158         fclose(f);



 159         free((char *)Private);
 160         free((char *)GifFile);
 161         return NULL;
 162     }
 163 
 164     /* The GIF Version number is ignored at this time. Maybe we should do
 165      * something more useful with it.  */
 166     Buf[GIF_STAMP_LEN] = 0;
 167     if (strncmp(GIF_STAMP, (const char*)Buf, GIF_VERSION_POS) != 0) {
 168         _GifError = D_GIF_ERR_NOT_GIF_FILE;
 169         fclose(f);

 170         free((char *)Private);
 171         free((char *)GifFile);
 172         return NULL;
 173     }
 174 
 175     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
 176         fclose(f);
 177         free((char *)Private);
 178         free((char *)GifFile);
 179         return NULL;
 180     }
 181 
 182     _GifError = 0;



 183 
 184     return GifFile;
 185 }
 186 
 187 /******************************************************************************
 188  * GifFileType constructor with user supplied input function (TVT)
 189  *****************************************************************************/
 190 GifFileType *
 191 DGifOpen(void *userData,
 192          InputFunc readFunc) {
 193 
 194     unsigned char Buf[GIF_STAMP_LEN + 1];
 195     GifFileType *GifFile;
 196     GifFilePrivateType *Private;
 197 
 198     if (!readFunc) {
 199         _GifError = D_GIF_ERR_READ_FAILED;
 200         return NULL;
 201     }
 202 
 203     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
 204     if (GifFile == NULL) {
 205         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;

 206         return NULL;
 207     }
 208 
 209     memset(GifFile, '\0', sizeof(GifFileType));
 210 




 211     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
 212     if (!Private) {
 213         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;

 214         free((char *)GifFile);
 215         return NULL;
 216     }
 217 
 218     GifFile->Private = (VoidPtr)Private;
 219     Private->FileHandle = 0;
 220     Private->File = 0;
 221     Private->FileState = FILE_STATE_READ;
 222 
 223     Private->Read = readFunc;    /* TVT */
 224     GifFile->UserData = userData;    /* TVT */
 225 
 226     /* Lets see if this is a GIF file: */
 227     if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
 228         _GifError = D_GIF_ERR_READ_FAILED;


 229         free((char *)Private);
 230         free((char *)GifFile);
 231         return NULL;
 232     }
 233 
 234     /* The GIF Version number is ignored at this time. Maybe we should do
 235      * something more useful with it. */
 236     Buf[GIF_STAMP_LEN] = 0;
 237     if (strncmp(GIF_STAMP, (const char*)Buf, GIF_VERSION_POS) != 0) {
 238         _GifError = D_GIF_ERR_NOT_GIF_FILE;
 239         free((char *)Private);
 240         free((char *)GifFile);
 241         return NULL;
 242     }
 243 
 244     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
 245         free((char *)Private);
 246         free((char *)GifFile);


 247         return NULL;
 248     }
 249 
 250     _GifError = 0;



 251 
 252     return GifFile;
 253 }
 254 
 255 /******************************************************************************
 256  * This routine should be called before any other DGif calls. Note that
 257  * this routine is called automatically from DGif file open routines.
 258  *****************************************************************************/
 259 int
 260 DGifGetScreenDesc(GifFileType * GifFile) {
 261 
 262     int i, BitsPerPixel;

 263     GifByteType Buf[3];
 264     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 265 
 266     if (!IS_READABLE(Private)) {
 267         /* This file was NOT open for reading: */
 268         _GifError = D_GIF_ERR_NOT_READABLE;
 269         return GIF_ERROR;
 270     }
 271 
 272     /* Put the screen descriptor into the file: */
 273     if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
 274         DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
 275         return GIF_ERROR;
 276 
 277     if (READ(GifFile, Buf, 3) != 3) {
 278         _GifError = D_GIF_ERR_READ_FAILED;


 279         return GIF_ERROR;
 280     }
 281     GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;

 282     BitsPerPixel = (Buf[0] & 0x07) + 1;
 283     GifFile->SBackGroundColor = Buf[1];

 284     if (Buf[0] & 0x80) {    /* Do we have global color map? */

 285 
 286         GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
 287         if (GifFile->SColorMap == NULL) {
 288             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
 289             return GIF_ERROR;
 290         }
 291 
 292         /* Get the global color map: */

 293         for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {

 294             if (READ(GifFile, Buf, 3) != 3) {
 295                 FreeMapObject(GifFile->SColorMap);
 296                 _GifError = D_GIF_ERR_READ_FAILED;

 297                 return GIF_ERROR;
 298             }
 299             GifFile->SColorMap->Colors[i].Red = Buf[0];
 300             GifFile->SColorMap->Colors[i].Green = Buf[1];
 301             GifFile->SColorMap->Colors[i].Blue = Buf[2];
 302         }
 303     } else {
 304         GifFile->SColorMap = NULL;
 305     }
 306 
 307     return GIF_OK;
 308 }
 309 
 310 /******************************************************************************
 311  * This routine should be called before any attempt to read an image.
 312  *****************************************************************************/
 313 int
 314 DGifGetRecordType(GifFileType * GifFile,
 315                   GifRecordType * Type) {
 316 
 317     GifByteType Buf;
 318     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 319 
 320     if (!IS_READABLE(Private)) {
 321         /* This file was NOT open for reading: */
 322         _GifError = D_GIF_ERR_NOT_READABLE;
 323         return GIF_ERROR;
 324     }
 325 

 326     if (READ(GifFile, &Buf, 1) != 1) {
 327         _GifError = D_GIF_ERR_READ_FAILED;
 328         return GIF_ERROR;
 329     }
 330 
 331     switch (Buf) {
 332       case ',':
 333           *Type = IMAGE_DESC_RECORD_TYPE;
 334           break;
 335       case '!':
 336           *Type = EXTENSION_RECORD_TYPE;
 337           break;
 338       case ';':
 339           *Type = TERMINATE_RECORD_TYPE;
 340           break;
 341       default:
 342           *Type = UNDEFINED_RECORD_TYPE;
 343           _GifError = D_GIF_ERR_WRONG_RECORD;
 344           return GIF_ERROR;
 345     }
 346 
 347     return GIF_OK;
 348 }
 349 
 350 /******************************************************************************
 351  * This routine should be called before any attempt to read an image.
 352  * Note it is assumed the Image desc. header (',') has been read.
 353  *****************************************************************************/
 354 int
 355 DGifGetImageDesc(GifFileType * GifFile) {
 356 
 357     int i, BitsPerPixel;
 358     GifByteType Buf[3];
 359     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 360     SavedImage *sp;
 361 
 362     if (!IS_READABLE(Private)) {
 363         /* This file was NOT open for reading: */
 364         _GifError = D_GIF_ERR_NOT_READABLE;
 365         return GIF_ERROR;
 366     }
 367 
 368     if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
 369         DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
 370         DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
 371         DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
 372         return GIF_ERROR;
 373     if (READ(GifFile, Buf, 1) != 1) {
 374         _GifError = D_GIF_ERR_READ_FAILED;


 375         return GIF_ERROR;
 376     }
 377     BitsPerPixel = (Buf[0] & 0x07) + 1;
 378     GifFile->Image.Interlace = (Buf[0] & 0x40);
 379     if (Buf[0] & 0x80) {    /* Does this image have local color map? */
 380 
 381         /*** FIXME: Why do we check both of these in order to do this?
 382          * Why do we have both Image and SavedImages? */
 383         if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
 384             FreeMapObject(GifFile->Image.ColorMap);




 385 
 386         GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
 387         if (GifFile->Image.ColorMap == NULL) {
 388             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
 389             return GIF_ERROR;
 390         }
 391 
 392         /* Get the image local color map: */
 393         for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {

 394             if (READ(GifFile, Buf, 3) != 3) {
 395                 FreeMapObject(GifFile->Image.ColorMap);
 396                 _GifError = D_GIF_ERR_READ_FAILED;

 397                 return GIF_ERROR;
 398             }
 399             GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
 400             GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
 401             GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
 402         }
 403     } else if (GifFile->Image.ColorMap) {
 404         FreeMapObject(GifFile->Image.ColorMap);
 405         GifFile->Image.ColorMap = NULL;
 406     }
 407 
 408     if (GifFile->SavedImages) {
 409         if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
 410                                       sizeof(SavedImage) *
 411                                       (GifFile->ImageCount + 1))) == NULL) {
 412             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;

 413             return GIF_ERROR;
 414         }

 415     } else {
 416         if ((GifFile->SavedImages =
 417              (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
 418             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
 419             return GIF_ERROR;
 420         }
 421     }
 422 
 423     sp = &GifFile->SavedImages[GifFile->ImageCount];
 424     memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
 425     if (GifFile->Image.ColorMap != NULL) {
 426         sp->ImageDesc.ColorMap = MakeMapObject(
 427                                  GifFile->Image.ColorMap->ColorCount,
 428                                  GifFile->Image.ColorMap->Colors);
 429         if (sp->ImageDesc.ColorMap == NULL) {
 430             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
 431             return GIF_ERROR;
 432         }
 433     }
 434     sp->RasterBits = (unsigned char *)NULL;
 435     sp->ExtensionBlockCount = 0;
 436     sp->ExtensionBlocks = (ExtensionBlock *) NULL;
 437 
 438     GifFile->ImageCount++;
 439 
 440     Private->PixelCount = (long)GifFile->Image.Width *
 441        (long)GifFile->Image.Height;
 442 
 443     return DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */

 444 }
 445 
 446 /******************************************************************************
 447  * Get one full scanned line (Line) of length LineLen from GIF file.
 448  *****************************************************************************/
 449 int
 450 DGifGetLine(GifFileType * GifFile,
 451             GifPixelType * Line,
 452             int LineLen) {
 453 
 454     GifByteType *Dummy;
 455     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 456 
 457     if (!IS_READABLE(Private)) {
 458         /* This file was NOT open for reading: */
 459         _GifError = D_GIF_ERR_NOT_READABLE;
 460         return GIF_ERROR;
 461     }
 462 
 463     if (!LineLen)
 464         LineLen = GifFile->Image.Width;
 465 
 466 #if defined(__MSDOS__) || defined(__GNUC__)
 467     if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
 468 #else
 469     if ((Private->PixelCount -= LineLen) > 0xffff0000) {
 470 #endif /* __MSDOS__ */
 471         _GifError = D_GIF_ERR_DATA_TOO_BIG;
 472         return GIF_ERROR;
 473     }
 474 
 475     if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
 476         if (Private->PixelCount == 0) {
 477             /* We probably would not be called any more, so lets clean
 478              * everything before we return: need to flush out all rest of
 479              * image until empty block (size 0) detected. We use GetCodeNext. */


 480             do
 481                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
 482                     return GIF_ERROR;
 483             while (Dummy != NULL) ;
 484         }
 485         return GIF_OK;
 486     } else
 487         return GIF_ERROR;
 488 }
 489 
 490 /******************************************************************************
 491  * Put one pixel (Pixel) into GIF file.
 492  *****************************************************************************/
 493 int
 494 DGifGetPixel(GifFileType * GifFile,
 495              GifPixelType Pixel) {
 496 
 497     GifByteType *Dummy;
 498     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 499 
 500     if (!IS_READABLE(Private)) {
 501         /* This file was NOT open for reading: */
 502         _GifError = D_GIF_ERR_NOT_READABLE;
 503         return GIF_ERROR;
 504     }
 505 #if defined(__MSDOS__) || defined(__GNUC__)
 506     if (--Private->PixelCount > 0xffff0000UL)
 507 #else
 508     if (--Private->PixelCount > 0xffff0000)
 509 #endif /* __MSDOS__ */
 510     {
 511         _GifError = D_GIF_ERR_DATA_TOO_BIG;
 512         return GIF_ERROR;
 513     }
 514 
 515     if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
 516         if (Private->PixelCount == 0) {
 517             /* We probably would not be called any more, so lets clean
 518              * everything before we return: need to flush out all rest of
 519              * image until empty block (size 0) detected. We use GetCodeNext. */


 520             do
 521                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
 522                     return GIF_ERROR;
 523             while (Dummy != NULL) ;
 524         }
 525         return GIF_OK;
 526     } else
 527         return GIF_ERROR;
 528 }
 529 
 530 /******************************************************************************
 531  * Get an extension block (see GIF manual) from gif file. This routine only
 532  * returns the first data block, and DGifGetExtensionNext should be called
 533  * after this one until NULL extension is returned.
 534  * The Extension should NOT be freed by the user (not dynamically allocated).
 535  * Note it is assumed the Extension desc. header ('!') has been read.
 536  *****************************************************************************/
 537 int
 538 DGifGetExtension(GifFileType * GifFile,
 539                  int *ExtCode,
 540                  GifByteType ** Extension) {
 541 
 542     GifByteType Buf;
 543     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 544 
 545     if (!IS_READABLE(Private)) {
 546         /* This file was NOT open for reading: */
 547         _GifError = D_GIF_ERR_NOT_READABLE;
 548         return GIF_ERROR;
 549     }
 550 

 551     if (READ(GifFile, &Buf, 1) != 1) {
 552         _GifError = D_GIF_ERR_READ_FAILED;
 553         return GIF_ERROR;
 554     }
 555     *ExtCode = Buf;
 556 
 557     return DGifGetExtensionNext(GifFile, Extension);
 558 }
 559 
 560 /******************************************************************************
 561  * Get a following extension block (see GIF manual) from gif file. This
 562  * routine should be called until NULL Extension is returned.
 563  * The Extension should NOT be freed by the user (not dynamically allocated).
 564  *****************************************************************************/
 565 int
 566 DGifGetExtensionNext(GifFileType * GifFile,
 567                      GifByteType ** Extension) {
 568 
 569     GifByteType Buf;
 570     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 571 
 572     if (READ(GifFile, &Buf, 1) != 1) {
 573         _GifError = D_GIF_ERR_READ_FAILED;
 574         return GIF_ERROR;
 575     }
 576     if (Buf > 0) {
 577         *Extension = Private->Buf;    /* Use private unused buffer. */
 578         (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */

 579         if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
 580             _GifError = D_GIF_ERR_READ_FAILED;
 581             return GIF_ERROR;
 582         }
 583     } else
 584         *Extension = NULL;
 585 
 586     return GIF_OK;
 587 }
 588 
 589 /******************************************************************************
 590  * This routine should be called last, to close the GIF file.
 591  *****************************************************************************/
 592 int
 593 DGifCloseFile(GifFileType * GifFile) {
 594 
 595     GifFilePrivateType *Private;
 596     FILE *File;
 597 
 598     if (GifFile == NULL)

 599         return GIF_ERROR;

 600 
 601     Private = (GifFilePrivateType *) GifFile->Private;






 602 
 603     if (!IS_READABLE(Private)) {
 604         /* This file was NOT open for reading: */
 605         _GifError = D_GIF_ERR_NOT_READABLE;










 606         return GIF_ERROR;










 607     }
 608 
 609     File = Private->File;












 610 
 611     if (GifFile->Image.ColorMap) {
 612         FreeMapObject(GifFile->Image.ColorMap);
 613         GifFile->Image.ColorMap = NULL;
 614     }
 615 
 616     if (GifFile->SColorMap) {
 617         FreeMapObject(GifFile->SColorMap);
 618         GifFile->SColorMap = NULL;
 619     }
 620 
 621     if (Private) {
 622         free((char *)Private);
 623         Private = NULL;
 624     }
 625 
 626     if (GifFile->SavedImages) {
 627         FreeSavedImages(GifFile);
 628         GifFile->SavedImages = NULL;
 629     }
 630 









 631     free(GifFile);


 632 
 633     if (File && (fclose(File) != 0)) {
 634         _GifError = D_GIF_ERR_CLOSE_FAILED;



 635         return GIF_ERROR;
 636     }





 637     return GIF_OK;
 638 }
 639 
 640 /******************************************************************************
 641  * Get 2 bytes (word) from the given file:
 642  *****************************************************************************/
 643 static int
 644 DGifGetWord(GifFileType * GifFile,
 645             int *Word) {
 646 
 647     unsigned char c[2];
 648 

 649     if (READ(GifFile, c, 2) != 2) {
 650         _GifError = D_GIF_ERR_READ_FAILED;
 651         return GIF_ERROR;
 652     }
 653 
 654     *Word = (((unsigned int)c[1]) << 8) + c[0];
 655     return GIF_OK;
 656 }
 657 
 658 /******************************************************************************
 659  * Get the image code in compressed form.  This routine can be called if the
 660  * information needed to be piped out as is. Obviously this is much faster
 661  * than decoding and encoding again. This routine should be followed by calls
 662  * to DGifGetCodeNext, until NULL block is returned.
 663  * The block should NOT be freed by the user (not dynamically allocated).
 664  *****************************************************************************/
 665 int
 666 DGifGetCode(GifFileType * GifFile,
 667             int *CodeSize,
 668             GifByteType ** CodeBlock) {
 669 
 670     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 671 
 672     if (!IS_READABLE(Private)) {
 673         /* This file was NOT open for reading: */
 674         _GifError = D_GIF_ERR_NOT_READABLE;
 675         return GIF_ERROR;
 676     }
 677 
 678     *CodeSize = Private->BitsPerPixel;
 679 
 680     return DGifGetCodeNext(GifFile, CodeBlock);
 681 }
 682 
 683 /******************************************************************************
 684  * Continue to get the image code in compressed form. This routine should be
 685  * called until NULL block is returned.
 686  * The block should NOT be freed by the user (not dynamically allocated).
 687  *****************************************************************************/
 688 int
 689 DGifGetCodeNext(GifFileType * GifFile,
 690                 GifByteType ** CodeBlock) {
 691 
 692     GifByteType Buf;
 693     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 694 


 695     if (READ(GifFile, &Buf, 1) != 1) {
 696         _GifError = D_GIF_ERR_READ_FAILED;
 697         return GIF_ERROR;
 698     }
 699 

 700     if (Buf > 0) {
 701         *CodeBlock = Private->Buf;    /* Use private unused buffer. */
 702         (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */

 703         if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
 704             _GifError = D_GIF_ERR_READ_FAILED;
 705             return GIF_ERROR;
 706         }
 707     } else {
 708         *CodeBlock = NULL;
 709         Private->Buf[0] = 0;    /* Make sure the buffer is empty! */
 710         Private->PixelCount = 0;    /* And local info. indicate image read. */
 711     }
 712 
 713     return GIF_OK;
 714 }
 715 
 716 /******************************************************************************
 717  * Setup the LZ decompression for this image:
 718  *****************************************************************************/
 719 static int
 720 DGifSetupDecompress(GifFileType * GifFile) {
 721 
 722     int i, BitsPerPixel;
 723     GifByteType CodeSize;
 724     unsigned int *Prefix;
 725     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 726 
 727     READ(GifFile, &CodeSize, 1);    /* Read Code size from file. */
 728     if (CodeSize >= 12) {
 729         /* Invalid initial code size: report failure */
 730         return GIF_ERROR;
 731     }
 732     BitsPerPixel = CodeSize;
 733 
 734     Private->Buf[0] = 0;    /* Input Buffer empty. */
 735     Private->BitsPerPixel = BitsPerPixel;
 736     Private->ClearCode = (1 << BitsPerPixel);
 737     Private->EOFCode = Private->ClearCode + 1;
 738     Private->RunningCode = Private->EOFCode + 1;
 739     Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */
 740     Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */
 741     Private->StackPtr = 0;    /* No pixels on the pixel stack. */
 742     Private->LastCode = NO_SUCH_CODE;
 743     Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */
 744     Private->CrntShiftDWord = 0;
 745 
 746     Prefix = Private->Prefix;
 747     for (i = 0; i <= LZ_MAX_CODE; i++)
 748         Prefix[i] = NO_SUCH_CODE;
 749 
 750     return GIF_OK;
 751 }
 752 
 753 /******************************************************************************
 754  * The LZ decompression routine:
 755  * This version decompress the given gif file into Line of length LineLen.
 756  * This routine can be called few times (one per scan line, for example), in
 757  * order the complete the whole image.
 758  *****************************************************************************/
 759 static int
 760 DGifDecompressLine(GifFileType * GifFile,
 761                    GifPixelType * Line,
 762                    int LineLen) {
 763 
 764     int i = 0;
 765     int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
 766     GifByteType *Stack, *Suffix;
 767     unsigned int *Prefix;
 768     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 769 
 770     StackPtr = Private->StackPtr;
 771     Prefix = Private->Prefix;
 772     Suffix = Private->Suffix;
 773     Stack = Private->Stack;
 774     EOFCode = Private->EOFCode;
 775     ClearCode = Private->ClearCode;
 776     LastCode = Private->LastCode;
 777 




 778     if (StackPtr != 0) {
 779         /* Let pop the stack off before continueing to read the gif file: */
 780         while (StackPtr != 0 && i < LineLen)
 781             Line[i++] = Stack[--StackPtr];
 782     }
 783 
 784     while (i < LineLen) {    /* Decode LineLen items. */
 785         if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
 786             return GIF_ERROR;
 787 
 788         if (CrntCode == EOFCode) {
 789             /* Note however that usually we will not be here as we will stop
 790              * decoding as soon as we got all the pixel, or EOF code will
 791              * not be read at all, and DGifGetLine/Pixel clean everything.  */
 792             if (i != LineLen - 1 || Private->PixelCount != 0) {
 793                 _GifError = D_GIF_ERR_EOF_TOO_SOON;
 794                 return GIF_ERROR;
 795             }
 796             i++;
 797         } else if (CrntCode == ClearCode) {
 798             /* We need to start over again: */
 799             for (j = 0; j <= LZ_MAX_CODE; j++)
 800                 Prefix[j] = NO_SUCH_CODE;
 801             Private->RunningCode = Private->EOFCode + 1;
 802             Private->RunningBits = Private->BitsPerPixel + 1;
 803             Private->MaxCode1 = 1 << Private->RunningBits;
 804             LastCode = Private->LastCode = NO_SUCH_CODE;
 805         } else {
 806             /* Its regular code - if in pixel range simply add it to output
 807              * stream, otherwise trace to codes linked list until the prefix
 808              * is in pixel range: */
 809             if (CrntCode < ClearCode) {
 810                 /* This is simple - its pixel scalar, so add it to output: */
 811                 Line[i++] = CrntCode;
 812             } else {
 813                 /* Its a code to needed to be traced: trace the linked list
 814                  * until the prefix is a pixel, while pushing the suffix
 815                  * pixels on our stack. If we done, pop the stack in reverse
 816                  * (thats what stack is good for!) order to output.  */
 817                 if (Prefix[CrntCode] == NO_SUCH_CODE) {


 818                     /* Only allowed if CrntCode is exactly the running code:
 819                      * In that case CrntCode = XXXCode, CrntCode or the
 820                      * prefix code is last code and the suffix char is
 821                      * exactly the prefix of last code! */
 822                     if (CrntCode == Private->RunningCode - 2) {
 823                         CrntPrefix = LastCode;
 824                         Suffix[Private->RunningCode - 2] =
 825                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
 826                                                                  LastCode,
 827                                                                  ClearCode);
 828                     } else {
 829                         _GifError = D_GIF_ERR_IMAGE_DEFECT;
 830                         return GIF_ERROR;


 831                     }
 832                 } else
 833                     CrntPrefix = CrntCode;
 834 
 835                 /* Now (if image is O.K.) we should not get an NO_SUCH_CODE
 836                  * During the trace. As we might loop forever, in case of
 837                  * defective image, we count the number of loops we trace
 838                  * and stop if we got LZ_MAX_CODE. obviously we can not
 839                  * loop more than that.  */
 840                 j = 0;
 841                 while (j++ <= LZ_MAX_CODE &&
 842                        CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
 843                     Stack[StackPtr++] = Suffix[CrntPrefix];
 844                     CrntPrefix = Prefix[CrntPrefix];
 845                 }
 846                 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
 847                     _GifError = D_GIF_ERR_IMAGE_DEFECT;
 848                     return GIF_ERROR;
 849                 }
 850                 /* Push the last character on stack: */
 851                 Stack[StackPtr++] = CrntPrefix;
 852 
 853                 /* Now lets pop all the stack into output: */
 854                 while (StackPtr != 0 && i < LineLen)
 855                     Line[i++] = Stack[--StackPtr];
 856             }
 857             if (LastCode != NO_SUCH_CODE) {
 858                 Prefix[Private->RunningCode - 2] = LastCode;
 859 
 860                 if (CrntCode == Private->RunningCode - 2) {
 861                     /* Only allowed if CrntCode is exactly the running code:
 862                      * In that case CrntCode = XXXCode, CrntCode or the
 863                      * prefix code is last code and the suffix char is
 864                      * exactly the prefix of last code! */
 865                     Suffix[Private->RunningCode - 2] =
 866                        DGifGetPrefixChar(Prefix, LastCode, ClearCode);
 867                 } else {
 868                     Suffix[Private->RunningCode - 2] =
 869                        DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
 870                 }
 871             }
 872             LastCode = CrntCode;
 873         }
 874     }
 875 
 876     Private->LastCode = LastCode;
 877     Private->StackPtr = StackPtr;
 878 
 879     return GIF_OK;
 880 }
 881 
 882 /******************************************************************************
 883  * Routine to trace the Prefixes linked list until we get a prefix which is
 884  * not code, but a pixel value (less than ClearCode). Returns that pixel value.
 885  * If image is defective, we might loop here forever, so we limit the loops to
 886  * the maximum possible if image O.k. - LZ_MAX_CODE times.
 887  *****************************************************************************/
 888 static int
 889 DGifGetPrefixChar(unsigned int *Prefix,
 890                   int Code,
 891                   int ClearCode) {
 892 
 893     int i = 0;
 894 
 895     while (Code > ClearCode && i++ <= LZ_MAX_CODE)



 896         Code = Prefix[Code];

 897     return Code;
 898 }
 899 
 900 /******************************************************************************
 901  * Interface for accessing the LZ codes directly. Set Code to the real code
 902  * (12bits), or to -1 if EOF code is returned.
 903  *****************************************************************************/
 904 int
 905 DGifGetLZCodes(GifFileType * GifFile,
 906                int *Code) {
 907 
 908     GifByteType *CodeBlock;
 909     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 910 
 911     if (!IS_READABLE(Private)) {
 912         /* This file was NOT open for reading: */
 913         _GifError = D_GIF_ERR_NOT_READABLE;
 914         return GIF_ERROR;
 915     }
 916 
 917     if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
 918         return GIF_ERROR;
 919 
 920     if (*Code == Private->EOFCode) {
 921         /* Skip rest of codes (hopefully only NULL terminating block): */
 922         do {
 923             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
 924                 return GIF_ERROR;
 925         } while (CodeBlock != NULL) ;
 926 
 927         *Code = -1;
 928     } else if (*Code == Private->ClearCode) {
 929         /* We need to start over again: */
 930         Private->RunningCode = Private->EOFCode + 1;
 931         Private->RunningBits = Private->BitsPerPixel + 1;
 932         Private->MaxCode1 = 1 << Private->RunningBits;
 933     }
 934 
 935     return GIF_OK;
 936 }
 937 
 938 /******************************************************************************
 939  * The LZ decompression input routine:
 940  * This routine is responsable for the decompression of the bit stream from
 941  * 8 bits (bytes) packets, into the real codes.
 942  * Returns GIF_OK if read succesfully.
 943  *****************************************************************************/
 944 static int
 945 DGifDecompressInput(GifFileType * GifFile,
 946                     int *Code) {
 947 
 948     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 949 
 950     GifByteType NextByte;
 951     static unsigned int CodeMasks[] = {
 952         0x0000, 0x0001, 0x0003, 0x0007,
 953         0x000f, 0x001f, 0x003f, 0x007f,
 954         0x00ff, 0x01ff, 0x03ff, 0x07ff,
 955         0x0fff
 956     };
 957 










 958     while (Private->CrntShiftState < Private->RunningBits) {
 959         /* Needs to get more bytes from input stream for next code: */
 960         if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
 961             return GIF_ERROR;
 962         }
 963         Private->CrntShiftDWord |=
 964            ((unsigned long)NextByte) << Private->CrntShiftState;
 965         Private->CrntShiftState += 8;
 966     }
 967     *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
 968 
 969     Private->CrntShiftDWord >>= Private->RunningBits;
 970     Private->CrntShiftState -= Private->RunningBits;
 971 
 972     /* If code cannot fit into RunningBits bits, must raise its size. Note
 973      * however that codes above 4095 are used for special signaling.  */
 974     if (++Private->RunningCode > Private->MaxCode1) {
 975         if (Private->RunningBits < LZ_BITS) {




 976             Private->MaxCode1 <<= 1;
 977             Private->RunningBits++;
 978         } else {
 979             Private->RunningCode = Private->MaxCode1;
 980         }
 981     }
 982     return GIF_OK;
 983 }
 984 
 985 /******************************************************************************
 986  * This routines read one gif data block at a time and buffers it internally
 987  * so that the decompression routine could access it.
 988  * The routine returns the next byte from its internal buffer (or read next
 989  * block in if buffer empty) and returns GIF_OK if succesful.
 990  *****************************************************************************/
 991 static int
 992 DGifBufferedInput(GifFileType * GifFile,
 993                   GifByteType * Buf,
 994                   GifByteType * NextByte) {
 995 
 996     if (Buf[0] == 0) {
 997         /* Needs to read the next buffer - this one is empty: */

 998         if (READ(GifFile, Buf, 1) != 1) {
 999             _GifError = D_GIF_ERR_READ_FAILED;








1000             return GIF_ERROR;
1001         }
1002         if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1003             _GifError = D_GIF_ERR_READ_FAILED;
1004             return GIF_ERROR;
1005         }
1006         *NextByte = Buf[1];
1007         Buf[1] = 2;    /* We use now the second place as last char read! */
1008         Buf[0]--;
1009     } else {
1010         *NextByte = Buf[Buf[1]++];
1011         Buf[0]--;
1012     }
1013 
1014     return GIF_OK;
1015 }
1016 
1017 /******************************************************************************
1018  * This routine reads an entire GIF into core, hanging all its state info off
1019  * the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
1020  * first to initialize I/O.  Its inverse is EGifSpew().
1021  ******************************************************************************/
1022 int
1023 DGifSlurp(GifFileType * GifFile) {
1024 
1025     int ImageSize;
1026     GifRecordType RecordType;
1027     SavedImage *sp;
1028     GifByteType *ExtData;
1029     SavedImage temp_save;
1030 
1031     temp_save.ExtensionBlocks = NULL;
1032     temp_save.ExtensionBlockCount = 0;
1033 
1034     do {
1035         if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1036             return (GIF_ERROR);
1037 
1038         switch (RecordType) {
1039           case IMAGE_DESC_RECORD_TYPE:
1040               if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1041                   return (GIF_ERROR);
1042 
1043               sp = &GifFile->SavedImages[GifFile->ImageCount - 1];





1044               ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1045 



1046               sp->RasterBits = (unsigned char *)malloc(ImageSize *
1047                                                        sizeof(GifPixelType));

1048               if (sp->RasterBits == NULL) {
1049                   return GIF_ERROR;
1050               }
1051               if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
1052                   GIF_ERROR)




















1053                   return (GIF_ERROR);
1054               if (temp_save.ExtensionBlocks) {
1055                   sp->ExtensionBlocks = temp_save.ExtensionBlocks;
1056                   sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
1057 
1058                   temp_save.ExtensionBlocks = NULL;
1059                   temp_save.ExtensionBlockCount = 0;
1060 
1061                   /* FIXME: The following is wrong.  It is left in only for
1062                    * backwards compatibility.  Someday it should go away. Use
1063                    * the sp->ExtensionBlocks->Function variable instead. */
1064                   sp->Function = sp->ExtensionBlocks[0].Function;
1065               }
1066               break;
1067 
1068           case EXTENSION_RECORD_TYPE:
1069               if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
1070                   GIF_ERROR)
1071                   return (GIF_ERROR);
1072               while (ExtData != NULL) {
1073 
1074                   /* Create an extension block with our data */
1075                   if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])



1076                       == GIF_ERROR)
1077                       return (GIF_ERROR);
1078 

1079                   if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1080                       return (GIF_ERROR);
1081                   temp_save.Function = 0;






1082               }
1083               break;
1084 
1085           case TERMINATE_RECORD_TYPE:
1086               break;
1087 
1088           default:    /* Should be trapped by DGifGetRecordType */
1089               break;
1090         }
1091     } while (RecordType != TERMINATE_RECORD_TYPE);
1092 
1093     /* Just in case the Gif has an extension block without an associated
1094      * image... (Should we save this into a savefile structure with no image
1095      * instead? Have to check if the present writing code can handle that as
1096      * well.... */
1097     if (temp_save.ExtensionBlocks)
1098         FreeExtension(&temp_save);
1099 
1100     return (GIF_OK);
1101 }




   6  * published by the Free Software Foundation.  Oracle designates this
   7  * particular file as subject to the "Classpath" exception as provided
   8  * by Oracle in the LICENSE file that accompanied this code.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /******************************************************************************
  26 
  27 dgif_lib.c - GIF decoding
  28 
  29 The functions here and in egif_lib.c are partitioned carefully so that
  30 if you only require one of read and write capability, only one of these
  31 two modules will be linked.  Preserve this property!
  32 
  33 *****************************************************************************/








  34 
  35 #include <stdlib.h>
  36 #include <limits.h>
  37 #include <stdint.h>
  38 #include <fcntl.h>
  39 #include <stdio.h>
  40 #include <string.h>



  41 
  42 #ifdef _WIN32
  43 #include <io.h>

  44 #else
  45 #include <unistd.h>
  46 #endif /* _WIN32 */


  47 


  48 #include "gif_lib.h"
  49 #include "gif_lib_private.h"
  50 
  51 /* compose unsigned little endian value */
  52 #define UNSIGNED_LITTLE_ENDIAN(lo, hi)  ((lo) | ((hi) << 8))
  53 
  54 /* avoid extra function call in case we use fread (TVT) */
  55 #define READ(_gif,_buf,_len)                                     \
  56   (((GifFilePrivateType*)_gif->Private)->Read ?                   \
  57     ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
  58     fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
  59 
  60 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
  61 static int DGifSetupDecompress(GifFileType *GifFile);
  62 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
  63                               int LineLen);
  64 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
  65 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
  66 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
  67                              GifByteType *NextByte);
  68 
  69 /******************************************************************************
  70  Open a new GIF file for read, given by its name.
  71  Returns dynamically allocated GifFileType pointer which serves as the GIF
  72  info record.
  73 ******************************************************************************/
  74 GifFileType *
  75 DGifOpenFileName(const char *FileName, int *Error)
  76 {
  77     int FileHandle;
  78     GifFileType *GifFile;
  79 
  80     if ((FileHandle = open(FileName, O_RDONLY)) == -1) {
  81         if (Error != NULL)
  82             *Error = D_GIF_ERR_OPEN_FAILED;



  83         return NULL;
  84     }
  85 
  86     GifFile = DGifOpenFileHandle(FileHandle, Error);


  87     return GifFile;
  88 }
  89 
  90 /******************************************************************************
  91  Update a new GIF file, given its file handle.
  92  Returns dynamically allocated GifFileType pointer which serves as the GIF
  93  info record.
  94 ******************************************************************************/
  95 GifFileType *
  96 DGifOpenFileHandle(int FileHandle, int *Error)
  97 {
  98     char Buf[GIF_STAMP_LEN + 1];
  99     GifFileType *GifFile;
 100     GifFilePrivateType *Private;
 101     FILE *f;
 102 
 103     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
 104     if (GifFile == NULL) {
 105         if (Error != NULL)
 106             *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 107         (void)close(FileHandle);
 108         return NULL;
 109     }
 110 
 111     /*@i1@*/memset(GifFile, '\0', sizeof(GifFileType));
 112 
 113     /* Belt and suspenders, in case the null pointer isn't zero */
 114     GifFile->SavedImages = NULL;
 115     GifFile->SColorMap = NULL;
 116 
 117     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
 118     if (Private == NULL) {
 119         if (Error != NULL)
 120             *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 121         (void)close(FileHandle);
 122         free((char *)GifFile);
 123         return NULL;
 124     }
 125 #ifdef _WIN32
 126     _setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */
 127 #endif /* _WIN32 */
 128 
 129     f = fdopen(FileHandle, "rb");    /* Make it into a stream: */
 130 
 131     /*@-mustfreeonly@*/
 132     GifFile->Private = (void *)Private;




 133     Private->FileHandle = FileHandle;
 134     Private->File = f;
 135     Private->FileState = FILE_STATE_READ;
 136     Private->Read = NULL;        /* don't use alternate input method (TVT) */
 137     GifFile->UserData = NULL;    /* TVT */
 138     /*@=mustfreeonly@*/
 139 
 140     /* Let's see if this is a GIF file: */
 141     /* coverity[check_return] */
 142     if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
 143         if (Error != NULL)
 144             *Error = D_GIF_ERR_READ_FAILED;
 145         (void)fclose(f);
 146         free((char *)Private);
 147         free((char *)GifFile);
 148         return NULL;
 149     }
 150 
 151     /* Check for GIF prefix at start of file */

 152     Buf[GIF_STAMP_LEN] = 0;
 153     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
 154         if (Error != NULL)
 155             *Error = D_GIF_ERR_NOT_GIF_FILE;
 156         (void)fclose(f);
 157         free((char *)Private);
 158         free((char *)GifFile);
 159         return NULL;
 160     }
 161 
 162     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
 163         (void)fclose(f);
 164         free((char *)Private);
 165         free((char *)GifFile);
 166         return NULL;
 167     }
 168 
 169     GifFile->Error = 0;
 170 
 171     /* What version of GIF? */
 172     Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
 173 
 174     return GifFile;
 175 }
 176 
 177 /******************************************************************************
 178  GifFileType constructor with user supplied input function (TVT)
 179 ******************************************************************************/
 180 GifFileType *
 181 DGifOpen(void *userData, InputFunc readFunc, int *Error)
 182 {
 183     char Buf[GIF_STAMP_LEN + 1];

 184     GifFileType *GifFile;
 185     GifFilePrivateType *Private;
 186 





 187     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
 188     if (GifFile == NULL) {
 189         if (Error != NULL)
 190             *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 191         return NULL;
 192     }
 193 
 194     memset(GifFile, '\0', sizeof(GifFileType));
 195 
 196     /* Belt and suspenders, in case the null pointer isn't zero */
 197     GifFile->SavedImages = NULL;
 198     GifFile->SColorMap = NULL;
 199 
 200     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
 201     if (!Private) {
 202         if (Error != NULL)
 203             *Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 204         free((char *)GifFile);
 205         return NULL;
 206     }
 207 
 208     GifFile->Private = (void *)Private;
 209     Private->FileHandle = 0;
 210     Private->File = NULL;
 211     Private->FileState = FILE_STATE_READ;
 212 
 213     Private->Read = readFunc;    /* TVT */
 214     GifFile->UserData = userData;    /* TVT */
 215 
 216     /* Lets see if this is a GIF file: */
 217     /* coverity[check_return] */
 218     if (READ(GifFile, (unsigned char *)Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
 219         if (Error != NULL)
 220             *Error = D_GIF_ERR_READ_FAILED;
 221         free((char *)Private);
 222         free((char *)GifFile);
 223         return NULL;
 224     }
 225 
 226     /* Check for GIF prefix at start of file */
 227     Buf[GIF_STAMP_LEN] = '\0';
 228     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
 229         if (Error != NULL)
 230             *Error = D_GIF_ERR_NOT_GIF_FILE;
 231         free((char *)Private);
 232         free((char *)GifFile);
 233         return NULL;
 234     }
 235 
 236     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
 237         free((char *)Private);
 238         free((char *)GifFile);
 239         if (Error != NULL)
 240             *Error = D_GIF_ERR_NO_SCRN_DSCR;
 241         return NULL;
 242     }
 243 
 244     GifFile->Error = 0;
 245 
 246     /* What version of GIF? */
 247     Private->gif89 = (Buf[GIF_VERSION_POS] == '9');
 248 
 249     return GifFile;
 250 }
 251 
 252 /******************************************************************************
 253  This routine should be called before any other DGif calls. Note that
 254  this routine is called automatically from DGif file open routines.
 255 ******************************************************************************/
 256 int
 257 DGifGetScreenDesc(GifFileType *GifFile)
 258 {
 259     int BitsPerPixel;
 260     bool SortFlag;
 261     GifByteType Buf[3];
 262     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 263 
 264     if (!IS_READABLE(Private)) {
 265         /* This file was NOT open for reading: */
 266         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 267         return GIF_ERROR;
 268     }
 269 
 270     /* Put the screen descriptor into the file: */
 271     if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
 272         DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
 273         return GIF_ERROR;
 274 
 275     if (READ(GifFile, Buf, 3) != 3) {
 276         GifFile->Error = D_GIF_ERR_READ_FAILED;
 277         GifFreeMapObject(GifFile->SColorMap);
 278         GifFile->SColorMap = NULL;
 279         return GIF_ERROR;
 280     }
 281     GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
 282     SortFlag = (Buf[0] & 0x08) != 0;
 283     BitsPerPixel = (Buf[0] & 0x07) + 1;
 284     GifFile->SBackGroundColor = Buf[1];
 285     GifFile->AspectByte = Buf[2]; 
 286     if (Buf[0] & 0x80) {    /* Do we have global color map? */
 287         int i;
 288 
 289         GifFile->SColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
 290         if (GifFile->SColorMap == NULL) {
 291             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 292             return GIF_ERROR;
 293         }
 294 
 295         /* Get the global color map: */
 296         GifFile->SColorMap->SortFlag = SortFlag;
 297         for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
 298             /* coverity[check_return] */
 299             if (READ(GifFile, Buf, 3) != 3) {
 300                 GifFreeMapObject(GifFile->SColorMap);
 301                 GifFile->SColorMap = NULL;
 302                 GifFile->Error = D_GIF_ERR_READ_FAILED;
 303                 return GIF_ERROR;
 304             }
 305             GifFile->SColorMap->Colors[i].Red = Buf[0];
 306             GifFile->SColorMap->Colors[i].Green = Buf[1];
 307             GifFile->SColorMap->Colors[i].Blue = Buf[2];
 308         }
 309     } else {
 310         GifFile->SColorMap = NULL;
 311     }
 312 
 313     return GIF_OK;
 314 }
 315 
 316 /******************************************************************************
 317  This routine should be called before any attempt to read an image.
 318 ******************************************************************************/
 319 int
 320 DGifGetRecordType(GifFileType *GifFile, GifRecordType* Type)
 321 {

 322     GifByteType Buf;
 323     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 324 
 325     if (!IS_READABLE(Private)) {
 326         /* This file was NOT open for reading: */
 327         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 328         return GIF_ERROR;
 329     }
 330 
 331     /* coverity[check_return] */
 332     if (READ(GifFile, &Buf, 1) != 1) {
 333         GifFile->Error = D_GIF_ERR_READ_FAILED;
 334         return GIF_ERROR;
 335     }
 336 
 337     switch (Buf) {
 338       case DESCRIPTOR_INTRODUCER:
 339           *Type = IMAGE_DESC_RECORD_TYPE;
 340           break;
 341       case EXTENSION_INTRODUCER:
 342           *Type = EXTENSION_RECORD_TYPE;
 343           break;
 344       case TERMINATOR_INTRODUCER:
 345           *Type = TERMINATE_RECORD_TYPE;
 346           break;
 347       default:
 348           *Type = UNDEFINED_RECORD_TYPE;
 349           GifFile->Error = D_GIF_ERR_WRONG_RECORD;
 350           return GIF_ERROR;
 351     }
 352 
 353     return GIF_OK;
 354 }
 355 
 356 /******************************************************************************
 357  This routine should be called before any attempt to read an image.
 358  Note it is assumed the Image desc. header has been read.
 359 ******************************************************************************/
 360 int
 361 DGifGetImageDesc(GifFileType *GifFile)
 362 {
 363     unsigned int BitsPerPixel;
 364     GifByteType Buf[3];
 365     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 366     SavedImage *sp;
 367 
 368     if (!IS_READABLE(Private)) {
 369         /* This file was NOT open for reading: */
 370         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 371         return GIF_ERROR;
 372     }
 373 
 374     if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
 375         DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
 376         DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
 377         DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
 378         return GIF_ERROR;
 379     if (READ(GifFile, Buf, 1) != 1) {
 380         GifFile->Error = D_GIF_ERR_READ_FAILED;
 381         GifFreeMapObject(GifFile->Image.ColorMap);
 382         GifFile->Image.ColorMap = NULL;
 383         return GIF_ERROR;
 384     }
 385     BitsPerPixel = (Buf[0] & 0x07) + 1;
 386     GifFile->Image.Interlace = (Buf[0] & 0x40) ? true : false;

 387 
 388     /* Setup the colormap */
 389     if (GifFile->Image.ColorMap) {
 390         GifFreeMapObject(GifFile->Image.ColorMap);
 391         GifFile->Image.ColorMap = NULL;
 392     }
 393     /* Does this image have local color map? */
 394     if (Buf[0] & 0x80) {
 395         unsigned int i;
 396 
 397         GifFile->Image.ColorMap = GifMakeMapObject(1 << BitsPerPixel, NULL);
 398         if (GifFile->Image.ColorMap == NULL) {
 399             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 400             return GIF_ERROR;
 401         }
 402 
 403         /* Get the image local color map: */
 404         for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
 405             /* coverity[check_return] */
 406             if (READ(GifFile, Buf, 3) != 3) {
 407                 GifFreeMapObject(GifFile->Image.ColorMap);
 408                 GifFile->Error = D_GIF_ERR_READ_FAILED;
 409                 GifFile->Image.ColorMap = NULL;
 410                 return GIF_ERROR;
 411             }
 412             GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
 413             GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
 414             GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
 415         }



 416     }
 417 
 418     if (GifFile->SavedImages) {
 419         SavedImage* new_saved_images =
 420             (SavedImage *)realloc(GifFile->SavedImages,
 421                             sizeof(SavedImage) * (GifFile->ImageCount + 1));
 422         if (new_saved_images == NULL) {
 423             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 424             return GIF_ERROR;
 425         }
 426         GifFile->SavedImages = new_saved_images;
 427     } else {
 428         if ((GifFile->SavedImages =
 429              (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
 430             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 431             return GIF_ERROR;
 432         }
 433     }
 434 
 435     sp = &GifFile->SavedImages[GifFile->ImageCount];
 436     memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
 437     if (GifFile->Image.ColorMap != NULL) {
 438         sp->ImageDesc.ColorMap = GifMakeMapObject(
 439                                  GifFile->Image.ColorMap->ColorCount,
 440                                  GifFile->Image.ColorMap->Colors);
 441         if (sp->ImageDesc.ColorMap == NULL) {
 442             GifFile->Error = D_GIF_ERR_NOT_ENOUGH_MEM;
 443             return GIF_ERROR;
 444         }
 445     }
 446     sp->RasterBits = (unsigned char *)NULL;
 447     sp->ExtensionBlockCount = 0;
 448     sp->ExtensionBlocks = (ExtensionBlock *) NULL;
 449 
 450     GifFile->ImageCount++;
 451 
 452     Private->PixelCount = (long)GifFile->Image.Width *
 453        (long)GifFile->Image.Height;
 454 
 455     /* Reset decompress algorithm parameters. */
 456     return DGifSetupDecompress(GifFile);
 457 }
 458 
 459 /******************************************************************************
 460  Get one full scanned line (Line) of length LineLen from GIF file.
 461 ******************************************************************************/
 462 int
 463 DGifGetLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
 464 {


 465     GifByteType *Dummy;
 466     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 467 
 468     if (!IS_READABLE(Private)) {
 469         /* This file was NOT open for reading: */
 470         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 471         return GIF_ERROR;
 472     }
 473 
 474     if (!LineLen)
 475         LineLen = GifFile->Image.Width;
 476 

 477     if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
 478         GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;



 479         return GIF_ERROR;
 480     }
 481 
 482     if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
 483         if (Private->PixelCount == 0) {
 484             /* We probably won't be called any more, so let's clean up
 485              * everything before we return: need to flush out all the
 486              * rest of image until an empty block (size 0)
 487              * detected. We use GetCodeNext.
 488              */
 489             do
 490                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
 491                     return GIF_ERROR;
 492             while (Dummy != NULL) ;
 493         }
 494         return GIF_OK;
 495     } else
 496         return GIF_ERROR;
 497 }
 498 
 499 /******************************************************************************
 500  Put one pixel (Pixel) into GIF file.
 501 ******************************************************************************/
 502 int
 503 DGifGetPixel(GifFileType *GifFile, GifPixelType Pixel)
 504 {

 505     GifByteType *Dummy;
 506     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 507 
 508     if (!IS_READABLE(Private)) {
 509         /* This file was NOT open for reading: */
 510         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 511         return GIF_ERROR;
 512     }

 513     if (--Private->PixelCount > 0xffff0000UL)



 514     {
 515         GifFile->Error = D_GIF_ERR_DATA_TOO_BIG;
 516         return GIF_ERROR;
 517     }
 518 
 519     if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
 520         if (Private->PixelCount == 0) {
 521             /* We probably won't be called any more, so let's clean up
 522              * everything before we return: need to flush out all the
 523              * rest of image until an empty block (size 0)
 524              * detected. We use GetCodeNext.
 525              */
 526             do
 527                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
 528                     return GIF_ERROR;
 529             while (Dummy != NULL) ;
 530         }
 531         return GIF_OK;
 532     } else
 533         return GIF_ERROR;
 534 }
 535 
 536 /******************************************************************************
 537  Get an extension block (see GIF manual) from GIF file. This routine only
 538  returns the first data block, and DGifGetExtensionNext should be called
 539  after this one until NULL extension is returned.
 540  The Extension should NOT be freed by the user (not dynamically allocated).
 541  Note it is assumed the Extension description header has been read.
 542 ******************************************************************************/
 543 int
 544 DGifGetExtension(GifFileType *GifFile, int *ExtCode, GifByteType **Extension)
 545 {


 546     GifByteType Buf;
 547     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 548 
 549     if (!IS_READABLE(Private)) {
 550         /* This file was NOT open for reading: */
 551         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 552         return GIF_ERROR;
 553     }
 554 
 555     /* coverity[check_return] */
 556     if (READ(GifFile, &Buf, 1) != 1) {
 557         GifFile->Error = D_GIF_ERR_READ_FAILED;
 558         return GIF_ERROR;
 559     }
 560     *ExtCode = Buf;
 561 
 562     return DGifGetExtensionNext(GifFile, Extension);
 563 }
 564 
 565 /******************************************************************************
 566  Get a following extension block (see GIF manual) from GIF file. This
 567  routine should be called until NULL Extension is returned.
 568  The Extension should NOT be freed by the user (not dynamically allocated).
 569 ******************************************************************************/
 570 int
 571 DGifGetExtensionNext(GifFileType *GifFile, GifByteType ** Extension)
 572 {

 573     GifByteType Buf;
 574     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 575 
 576     if (READ(GifFile, &Buf, 1) != 1) {
 577         GifFile->Error = D_GIF_ERR_READ_FAILED;
 578         return GIF_ERROR;
 579     }
 580     if (Buf > 0) {
 581         *Extension = Private->Buf;    /* Use private unused buffer. */
 582         (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
 583         /* coverity[tainted_data,check_return] */
 584         if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
 585             GifFile->Error = D_GIF_ERR_READ_FAILED;
 586             return GIF_ERROR;
 587         }
 588     } else
 589         *Extension = NULL;
 590 
 591     return GIF_OK;
 592 }
 593 
 594 /******************************************************************************
 595  Extract a Graphics Control Block from raw extension data
 596 ******************************************************************************/


 597 
 598 int DGifExtensionToGCB(const size_t GifExtensionLength,
 599                        const GifByteType *GifExtension,
 600                        GraphicsControlBlock *GCB)
 601 {
 602     if (GifExtensionLength != 4) {
 603         return GIF_ERROR;
 604     }
 605 
 606     GCB->DisposalMode = (GifExtension[0] >> 2) & 0x07;
 607     GCB->UserInputFlag = (GifExtension[0] & 0x02) != 0;
 608     GCB->DelayTime = UNSIGNED_LITTLE_ENDIAN(GifExtension[1], GifExtension[2]);
 609     if (GifExtension[0] & 0x01)
 610         GCB->TransparentColor = (int)GifExtension[3];
 611     else
 612         GCB->TransparentColor = NO_TRANSPARENT_COLOR;
 613 
 614     return GIF_OK;
 615 }
 616 
 617 /******************************************************************************
 618  Extract the Graphics Control Block for a saved image, if it exists.
 619 ******************************************************************************/
 620 
 621 int DGifSavedExtensionToGCB(GifFileType *GifFile,
 622                             int ImageIndex, GraphicsControlBlock *GCB)
 623 {
 624     int i;
 625 
 626     if (ImageIndex < 0 || ImageIndex > GifFile->ImageCount - 1)
 627         return GIF_ERROR;
 628 
 629     GCB->DisposalMode = DISPOSAL_UNSPECIFIED;
 630     GCB->UserInputFlag = false;
 631     GCB->DelayTime = 0;
 632     GCB->TransparentColor = NO_TRANSPARENT_COLOR;
 633 
 634     for (i = 0; i < GifFile->SavedImages[ImageIndex].ExtensionBlockCount; i++) {
 635         ExtensionBlock *ep = &GifFile->SavedImages[ImageIndex].ExtensionBlocks[i];
 636         if (ep->Function == GRAPHICS_EXT_FUNC_CODE)
 637             return DGifExtensionToGCB(ep->ByteCount, ep->Bytes, GCB);
 638     }
 639 
 640     return GIF_ERROR;
 641 }
 642 
 643 /******************************************************************************
 644  This routine should be called last, to close the GIF file.
 645 ******************************************************************************/
 646 int
 647 DGifCloseFile(GifFileType *GifFile, int *ErrorCode)
 648 {
 649     GifFilePrivateType *Private;
 650 
 651     if (GifFile == NULL || GifFile->Private == NULL)
 652         return GIF_ERROR;
 653 
 654     if (GifFile->Image.ColorMap) {
 655         GifFreeMapObject(GifFile->Image.ColorMap);
 656         GifFile->Image.ColorMap = NULL;
 657     }
 658 
 659     if (GifFile->SColorMap) {
 660         GifFreeMapObject(GifFile->SColorMap);
 661         GifFile->SColorMap = NULL;
 662     }
 663 





 664     if (GifFile->SavedImages) {
 665         GifFreeSavedImages(GifFile);
 666         GifFile->SavedImages = NULL;
 667     }
 668 
 669     GifFreeExtensions(&GifFile->ExtensionBlockCount, &GifFile->ExtensionBlocks);
 670 
 671     Private = (GifFilePrivateType *) GifFile->Private;
 672 
 673     if (!IS_READABLE(Private)) {
 674         /* This file was NOT open for reading: */
 675         if (ErrorCode != NULL)
 676             *ErrorCode = D_GIF_ERR_NOT_READABLE;
 677         free((char *)GifFile->Private);
 678         free(GifFile);
 679         return GIF_ERROR;
 680     }
 681 
 682     if (Private->File && (fclose(Private->File) != 0)) {
 683         if (ErrorCode != NULL)
 684             *ErrorCode = D_GIF_ERR_CLOSE_FAILED;
 685         free((char *)GifFile->Private);
 686         free(GifFile);
 687         return GIF_ERROR;
 688     }
 689 
 690     free((char *)GifFile->Private);
 691     free(GifFile);
 692     if (ErrorCode != NULL)
 693         *ErrorCode = D_GIF_SUCCEEDED;
 694     return GIF_OK;
 695 }
 696 
 697 /******************************************************************************
 698  Get 2 bytes (word) from the given file:
 699 ******************************************************************************/
 700 static int
 701 DGifGetWord(GifFileType *GifFile, GifWord *Word)
 702 {

 703     unsigned char c[2];
 704 
 705     /* coverity[check_return] */
 706     if (READ(GifFile, c, 2) != 2) {
 707         GifFile->Error = D_GIF_ERR_READ_FAILED;
 708         return GIF_ERROR;
 709     }
 710 
 711     *Word = (GifWord)UNSIGNED_LITTLE_ENDIAN(c[0], c[1]);
 712     return GIF_OK;
 713 }
 714 
 715 /******************************************************************************
 716  Get the image code in compressed form.  This routine can be called if the
 717  information needed to be piped out as is. Obviously this is much faster
 718  than decoding and encoding again. This routine should be followed by calls
 719  to DGifGetCodeNext, until NULL block is returned.
 720  The block should NOT be freed by the user (not dynamically allocated).
 721 ******************************************************************************/
 722 int
 723 DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
 724 {


 725     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 726 
 727     if (!IS_READABLE(Private)) {
 728         /* This file was NOT open for reading: */
 729         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 730         return GIF_ERROR;
 731     }
 732 
 733     *CodeSize = Private->BitsPerPixel;
 734 
 735     return DGifGetCodeNext(GifFile, CodeBlock);
 736 }
 737 
 738 /******************************************************************************
 739  Continue to get the image code in compressed form. This routine should be
 740  called until NULL block is returned.
 741  The block should NOT be freed by the user (not dynamically allocated).
 742 ******************************************************************************/
 743 int
 744 DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
 745 {

 746     GifByteType Buf;
 747     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 748 
 749     /* coverity[tainted_data_argument] */
 750     /* coverity[check_return] */
 751     if (READ(GifFile, &Buf, 1) != 1) {
 752         GifFile->Error = D_GIF_ERR_READ_FAILED;
 753         return GIF_ERROR;
 754     }
 755 
 756     /* coverity[lower_bounds] */
 757     if (Buf > 0) {
 758         *CodeBlock = Private->Buf;    /* Use private unused buffer. */
 759         (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
 760         /* coverity[tainted_data] */
 761         if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
 762             GifFile->Error = D_GIF_ERR_READ_FAILED;
 763             return GIF_ERROR;
 764         }
 765     } else {
 766         *CodeBlock = NULL;
 767         Private->Buf[0] = 0;    /* Make sure the buffer is empty! */
 768         Private->PixelCount = 0;    /* And local info. indicate image read. */
 769     }
 770 
 771     return GIF_OK;
 772 }
 773 
 774 /******************************************************************************
 775  Setup the LZ decompression for this image:
 776 ******************************************************************************/
 777 static int
 778 DGifSetupDecompress(GifFileType *GifFile)
 779 {
 780     int i, BitsPerPixel;
 781     GifByteType CodeSize;
 782     GifPrefixType *Prefix;
 783     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 784 
 785     /* coverity[check_return] */
 786     if (READ(GifFile, &CodeSize, 1) < 1) {    /* Read Code size from file. */
 787         return GIF_ERROR;    /* Failed to read Code size. */

 788     }
 789     BitsPerPixel = CodeSize;
 790 
 791     Private->Buf[0] = 0;    /* Input Buffer empty. */
 792     Private->BitsPerPixel = BitsPerPixel;
 793     Private->ClearCode = (1 << BitsPerPixel);
 794     Private->EOFCode = Private->ClearCode + 1;
 795     Private->RunningCode = Private->EOFCode + 1;
 796     Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */
 797     Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */
 798     Private->StackPtr = 0;    /* No pixels on the pixel stack. */
 799     Private->LastCode = NO_SUCH_CODE;
 800     Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */
 801     Private->CrntShiftDWord = 0;
 802 
 803     Prefix = Private->Prefix;
 804     for (i = 0; i <= LZ_MAX_CODE; i++)
 805         Prefix[i] = NO_SUCH_CODE;
 806 
 807     return GIF_OK;
 808 }
 809 
 810 /******************************************************************************
 811  The LZ decompression routine:
 812  This version decompress the given GIF file into Line of length LineLen.
 813  This routine can be called few times (one per scan line, for example), in
 814  order the complete the whole image.
 815 ******************************************************************************/
 816 static int
 817 DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line, int LineLen)
 818 {


 819     int i = 0;
 820     int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
 821     GifByteType *Stack, *Suffix;
 822     GifPrefixType *Prefix;
 823     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
 824 
 825     StackPtr = Private->StackPtr;
 826     Prefix = Private->Prefix;
 827     Suffix = Private->Suffix;
 828     Stack = Private->Stack;
 829     EOFCode = Private->EOFCode;
 830     ClearCode = Private->ClearCode;
 831     LastCode = Private->LastCode;
 832 
 833     if (StackPtr > LZ_MAX_CODE) {
 834         return GIF_ERROR;
 835     }
 836 
 837     if (StackPtr != 0) {
 838         /* Let pop the stack off before continueing to read the GIF file: */
 839         while (StackPtr != 0 && i < LineLen)
 840             Line[i++] = Stack[--StackPtr];
 841     }
 842 
 843     while (i < LineLen) {    /* Decode LineLen items. */
 844         if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
 845             return GIF_ERROR;
 846 
 847         if (CrntCode == EOFCode) {
 848             /* Note however that usually we will not be here as we will stop
 849              * decoding as soon as we got all the pixel, or EOF code will
 850              * not be read at all, and DGifGetLine/Pixel clean everything.  */
 851             GifFile->Error = D_GIF_ERR_EOF_TOO_SOON;

 852             return GIF_ERROR;


 853         } else if (CrntCode == ClearCode) {
 854             /* We need to start over again: */
 855             for (j = 0; j <= LZ_MAX_CODE; j++)
 856                 Prefix[j] = NO_SUCH_CODE;
 857             Private->RunningCode = Private->EOFCode + 1;
 858             Private->RunningBits = Private->BitsPerPixel + 1;
 859             Private->MaxCode1 = 1 << Private->RunningBits;
 860             LastCode = Private->LastCode = NO_SUCH_CODE;
 861         } else {
 862             /* Its regular code - if in pixel range simply add it to output
 863              * stream, otherwise trace to codes linked list until the prefix
 864              * is in pixel range: */
 865             if (CrntCode < ClearCode) {
 866                 /* This is simple - its pixel scalar, so add it to output: */
 867                 Line[i++] = CrntCode;
 868             } else {
 869                 /* Its a code to needed to be traced: trace the linked list
 870                  * until the prefix is a pixel, while pushing the suffix
 871                  * pixels on our stack. If we done, pop the stack in reverse
 872                  * (thats what stack is good for!) order to output.  */
 873                 if (Prefix[CrntCode] == NO_SUCH_CODE) {
 874                     CrntPrefix = LastCode;
 875 
 876                     /* Only allowed if CrntCode is exactly the running code:
 877                      * In that case CrntCode = XXXCode, CrntCode or the
 878                      * prefix code is last code and the suffix char is
 879                      * exactly the prefix of last code! */
 880                     if (CrntCode == Private->RunningCode - 2) {

 881                         Suffix[Private->RunningCode - 2] =
 882                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
 883                                                                  LastCode,
 884                                                                  ClearCode);
 885                     } else {
 886                         Suffix[Private->RunningCode - 2] =
 887                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
 888                                                                  CrntCode,
 889                                                                  ClearCode);
 890                     }
 891                 } else
 892                     CrntPrefix = CrntCode;
 893 
 894                 /* Now (if image is O.K.) we should not get a NO_SUCH_CODE
 895                  * during the trace. As we might loop forever, in case of
 896                  * defective image, we use StackPtr as loop counter and stop
 897                  * before overflowing Stack[]. */
 898                 while (StackPtr < LZ_MAX_CODE &&


 899                        CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
 900                     Stack[StackPtr++] = Suffix[CrntPrefix];
 901                     CrntPrefix = Prefix[CrntPrefix];
 902                 }
 903                 if (StackPtr >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
 904                     GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
 905                     return GIF_ERROR;
 906                 }
 907                 /* Push the last character on stack: */
 908                 Stack[StackPtr++] = CrntPrefix;
 909 
 910                 /* Now lets pop all the stack into output: */
 911                 while (StackPtr != 0 && i < LineLen)
 912                     Line[i++] = Stack[--StackPtr];
 913             }
 914             if (LastCode != NO_SUCH_CODE && Prefix[Private->RunningCode - 2] == NO_SUCH_CODE) {
 915                 Prefix[Private->RunningCode - 2] = LastCode;
 916 
 917                 if (CrntCode == Private->RunningCode - 2) {
 918                     /* Only allowed if CrntCode is exactly the running code:
 919                      * In that case CrntCode = XXXCode, CrntCode or the
 920                      * prefix code is last code and the suffix char is
 921                      * exactly the prefix of last code! */
 922                     Suffix[Private->RunningCode - 2] =
 923                        DGifGetPrefixChar(Prefix, LastCode, ClearCode);
 924                 } else {
 925                     Suffix[Private->RunningCode - 2] =
 926                        DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
 927                 }
 928             }
 929             LastCode = CrntCode;
 930         }
 931     }
 932 
 933     Private->LastCode = LastCode;
 934     Private->StackPtr = StackPtr;
 935 
 936     return GIF_OK;
 937 }
 938 
 939 /******************************************************************************
 940  Routine to trace the Prefixes linked list until we get a prefix which is
 941  not code, but a pixel value (less than ClearCode). Returns that pixel value.
 942  If image is defective, we might loop here forever, so we limit the loops to
 943  the maximum possible if image O.k. - LZ_MAX_CODE times.
 944 ******************************************************************************/
 945 static int
 946 DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode)
 947 {


 948     int i = 0;
 949 
 950     while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
 951         if (Code > LZ_MAX_CODE) {
 952             return NO_SUCH_CODE;
 953         }
 954         Code = Prefix[Code];
 955     }
 956     return Code;
 957 }
 958 
 959 /******************************************************************************
 960  Interface for accessing the LZ codes directly. Set Code to the real code
 961  (12bits), or to -1 if EOF code is returned.
 962 ******************************************************************************/
 963 int
 964 DGifGetLZCodes(GifFileType *GifFile, int *Code)
 965 {

 966     GifByteType *CodeBlock;
 967     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
 968 
 969     if (!IS_READABLE(Private)) {
 970         /* This file was NOT open for reading: */
 971         GifFile->Error = D_GIF_ERR_NOT_READABLE;
 972         return GIF_ERROR;
 973     }
 974 
 975     if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
 976         return GIF_ERROR;
 977 
 978     if (*Code == Private->EOFCode) {
 979         /* Skip rest of codes (hopefully only NULL terminating block): */
 980         do {
 981             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
 982                 return GIF_ERROR;
 983         } while (CodeBlock != NULL) ;
 984 
 985         *Code = -1;
 986     } else if (*Code == Private->ClearCode) {
 987         /* We need to start over again: */
 988         Private->RunningCode = Private->EOFCode + 1;
 989         Private->RunningBits = Private->BitsPerPixel + 1;
 990         Private->MaxCode1 = 1 << Private->RunningBits;
 991     }
 992 
 993     return GIF_OK;
 994 }
 995 
 996 /******************************************************************************
 997  The LZ decompression input routine:
 998  This routine is responsable for the decompression of the bit stream from
 999  8 bits (bytes) packets, into the real codes.
1000  Returns GIF_OK if read successfully.
1001 ******************************************************************************/
1002 static int
1003 DGifDecompressInput(GifFileType *GifFile, int *Code)
1004 {
1005     static const unsigned short CodeMasks[] = {




1006         0x0000, 0x0001, 0x0003, 0x0007,
1007         0x000f, 0x001f, 0x003f, 0x007f,
1008         0x00ff, 0x01ff, 0x03ff, 0x07ff,
1009         0x0fff
1010     };
1011 
1012     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
1013 
1014     GifByteType NextByte;
1015 
1016     /* The image can't contain more than LZ_BITS per code. */
1017     if (Private->RunningBits > LZ_BITS) {
1018         GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1019         return GIF_ERROR;
1020     }
1021     
1022     while (Private->CrntShiftState < Private->RunningBits) {
1023         /* Needs to get more bytes from input stream for next code: */
1024         if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
1025             return GIF_ERROR;
1026         }
1027         Private->CrntShiftDWord |=
1028             ((unsigned long)NextByte) << Private->CrntShiftState;
1029         Private->CrntShiftState += 8;
1030     }
1031     *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
1032 
1033     Private->CrntShiftDWord >>= Private->RunningBits;
1034     Private->CrntShiftState -= Private->RunningBits;
1035 
1036     /* If code cannot fit into RunningBits bits, must raise its size. Note
1037      * however that codes above 4095 are used for special signaling.
1038      * If we're using LZ_BITS bits already and we're at the max code, just
1039      * keep using the table as it is, don't increment Private->RunningCode.
1040      */
1041     if (Private->RunningCode < LZ_MAX_CODE + 2 &&
1042         ++Private->RunningCode > Private->MaxCode1 &&
1043         Private->RunningBits < LZ_BITS) {
1044         Private->MaxCode1 <<= 1;
1045         Private->RunningBits++;



1046     }
1047     return GIF_OK;
1048 }
1049 
1050 /******************************************************************************
1051  This routines read one GIF data block at a time and buffers it internally
1052  so that the decompression routine could access it.
1053  The routine returns the next byte from its internal buffer (or read next
1054  block in if buffer empty) and returns GIF_OK if succesful.
1055 ******************************************************************************/
1056 static int
1057 DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf, GifByteType *NextByte)
1058 {


1059     if (Buf[0] == 0) {
1060         /* Needs to read the next buffer - this one is empty: */
1061         /* coverity[check_return] */
1062         if (READ(GifFile, Buf, 1) != 1) {
1063             GifFile->Error = D_GIF_ERR_READ_FAILED;
1064             return GIF_ERROR;
1065         }
1066         /* There shouldn't be any empty data blocks here as the LZW spec
1067          * says the LZW termination code should come first.  Therefore we
1068          * shouldn't be inside this routine at that point.
1069          */
1070         if (Buf[0] == 0) {
1071             GifFile->Error = D_GIF_ERR_IMAGE_DEFECT;
1072             return GIF_ERROR;
1073         }
1074         if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
1075             GifFile->Error = D_GIF_ERR_READ_FAILED;
1076             return GIF_ERROR;
1077         }
1078         *NextByte = Buf[1];
1079         Buf[1] = 2;    /* We use now the second place as last char read! */
1080         Buf[0]--;
1081     } else {
1082         *NextByte = Buf[Buf[1]++];
1083         Buf[0]--;
1084     }
1085 
1086     return GIF_OK;
1087 }
1088 
1089 /******************************************************************************
1090  This routine reads an entire GIF into core, hanging all its state info off
1091  the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
1092  first to initialize I/O.  Its inverse is EGifSpew().
1093 *******************************************************************************/
1094 int
1095 DGifSlurp(GifFileType *GifFile)
1096 {
1097     size_t ImageSize;
1098     GifRecordType RecordType;
1099     SavedImage *sp;
1100     GifByteType *ExtData;
1101     int ExtFunction;
1102 
1103     GifFile->ExtensionBlocks = NULL;
1104     GifFile->ExtensionBlockCount = 0;
1105 
1106     do {
1107         if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
1108             return (GIF_ERROR);
1109 
1110         switch (RecordType) {
1111           case IMAGE_DESC_RECORD_TYPE:
1112               if (DGifGetImageDesc(GifFile) == GIF_ERROR)
1113                   return (GIF_ERROR);
1114 
1115               sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
1116               /* Allocate memory for the image */
1117               if (sp->ImageDesc.Width < 0 && sp->ImageDesc.Height < 0 &&
1118                       sp->ImageDesc.Width > (INT_MAX / sp->ImageDesc.Height)) {
1119                   return GIF_ERROR;
1120               }
1121               ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
1122 
1123               if (ImageSize > (SIZE_MAX / sizeof(GifPixelType))) {
1124                   return GIF_ERROR;
1125               }
1126               sp->RasterBits = (unsigned char *)malloc(ImageSize *
1127                       sizeof(GifPixelType));
1128 
1129               if (sp->RasterBits == NULL) {
1130                   return GIF_ERROR;
1131               }
1132 
1133               if (sp->ImageDesc.Interlace) {
1134                   int i, j;
1135                    /* 
1136                     * The way an interlaced image should be read - 
1137                     * offsets and jumps...
1138                     */
1139                   int InterlacedOffset[] = { 0, 4, 2, 1 };
1140                   int InterlacedJumps[] = { 8, 8, 4, 2 };
1141                   /* Need to perform 4 passes on the image */
1142                   for (i = 0; i < 4; i++)
1143                       for (j = InterlacedOffset[i]; 
1144                            j < sp->ImageDesc.Height;
1145                            j += InterlacedJumps[i]) {
1146                           if (DGifGetLine(GifFile, 
1147                                           sp->RasterBits+j*sp->ImageDesc.Width, 
1148                                           sp->ImageDesc.Width) == GIF_ERROR)
1149                               return GIF_ERROR;
1150                       }
1151               }
1152               else {
1153                   if (DGifGetLine(GifFile,sp->RasterBits,ImageSize)==GIF_ERROR)
1154                       return (GIF_ERROR);
1155               }
1156 
1157               if (GifFile->ExtensionBlocks) {
1158                   sp->ExtensionBlocks = GifFile->ExtensionBlocks;
1159                   sp->ExtensionBlockCount = GifFile->ExtensionBlockCount;
1160 
1161                   GifFile->ExtensionBlocks = NULL;
1162                   GifFile->ExtensionBlockCount = 0;



1163               }
1164               break;
1165 
1166           case EXTENSION_RECORD_TYPE:
1167               if (DGifGetExtension(GifFile,&ExtFunction,&ExtData) == GIF_ERROR)

1168                   return (GIF_ERROR);


1169               /* Create an extension block with our data */
1170               if (ExtData != NULL) {
1171                   if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1172                                            &GifFile->ExtensionBlocks, 
1173                                            ExtFunction, ExtData[0], &ExtData[1])
1174                       == GIF_ERROR)
1175                       return (GIF_ERROR);
1176               }
1177               while (ExtData != NULL) {
1178                   if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1179                       return (GIF_ERROR);
1180                   /* Continue the extension block */
1181                   if (ExtData != NULL)
1182                       if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1183                                                &GifFile->ExtensionBlocks,
1184                                                CONTINUE_EXT_FUNC_CODE, 
1185                                                ExtData[0], &ExtData[1]) == GIF_ERROR)
1186                       return (GIF_ERROR);
1187               }
1188               break;
1189 
1190           case TERMINATE_RECORD_TYPE:
1191               break;
1192 
1193           default:    /* Should be trapped by DGifGetRecordType */
1194               break;
1195         }
1196     } while (RecordType != TERMINATE_RECORD_TYPE);
1197 
1198     /* Sanity check for corrupted file */
1199     if (GifFile->ImageCount == 0) {
1200         GifFile->Error = D_GIF_ERR_NO_IMAG_DSCR;
1201         return(GIF_ERROR);
1202     }

1203 
1204     return (GIF_OK);
1205 }
1206 
1207 /* end */
< prev index next >