Home | History | Annotate | Download | only in giflib
      1 /******************************************************************************
      2  *   "Gif-Lib" - Yet another gif library.
      3  *
      4  * Written by:  Gershon Elber            IBM PC Ver 1.1,    Aug. 1990
      5  ******************************************************************************
      6  * The kernel of the GIF Decoding process can be found here.
      7  ******************************************************************************
      8  * History:
      9  * 16 Jun 89 - Version 1.0 by Gershon Elber.
     10  *  3 Sep 90 - Version 1.1 by Gershon Elber (Support for Gif89, Unique names).
     11  *****************************************************************************/
     12 
     13 #ifdef HAVE_CONFIG_H
     14 #include <config.h>
     15 #endif
     16 
     17 #include <stdlib.h>
     18 #if defined (__MSDOS__) && !defined(__DJGPP__) && !defined(__GNUC__)
     19 #include <io.h>
     20 #include <alloc.h>
     21 #include <sys\stat.h>
     22 #else
     23 #include <sys/types.h>
     24 #include <sys/stat.h>
     25 #endif /* __MSDOS__ */
     26 
     27 #ifdef HAVE_IO_H
     28 #include <io.h>
     29 #endif
     30 
     31 #ifdef HAVE_FCNTL_H
     32 #include <fcntl.h>
     33 #endif /* HAVE_FCNTL_H */
     34 #ifdef HAVE_UNISTD_H
     35 #include <unistd.h>
     36 #endif /* HAVE_UNISTD_H */
     37 #include <stdio.h>
     38 #include <string.h>
     39 #include "gif_lib.h"
     40 #include "gif_lib_private.h"
     41 
     42 #define COMMENT_EXT_FUNC_CODE 0xfe  /* Extension function code for
     43                                        comment. */
     44 
     45 /* avoid extra function call in case we use fread (TVT) */
     46 #define READ(_gif,_buf,_len)                                     \
     47   (((GifFilePrivateType*)_gif->Private)->Read ?                   \
     48     ((GifFilePrivateType*)_gif->Private)->Read(_gif,_buf,_len) : \
     49     fread(_buf,1,_len,((GifFilePrivateType*)_gif->Private)->File))
     50 
     51 static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
     52 static int DGifSetupDecompress(GifFileType *GifFile);
     53 static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
     54                               int LineLen);
     55 static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
     56 static int DGifDecompressInput(GifFileType *GifFile, int *Code);
     57 static int DGifBufferedInput(GifFileType *GifFile, GifByteType *Buf,
     58                              GifByteType *NextByte);
     59 #ifndef _GBA_NO_FILEIO
     60 
     61 /******************************************************************************
     62  * Open a new gif file for read, given by its name.
     63  * Returns GifFileType pointer dynamically allocated which serves as the gif
     64  * info record. _GifError is cleared if succesfull.
     65  *****************************************************************************/
     66 GifFileType *
     67 DGifOpenFileName(const char *FileName) {
     68     int FileHandle;
     69     GifFileType *GifFile;
     70 
     71     if ((FileHandle = open(FileName, O_RDONLY
     72 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)
     73                            | O_BINARY
     74 #endif /* __MSDOS__ || _OPEN_BINARY */
     75          )) == -1) {
     76         _GifError = D_GIF_ERR_OPEN_FAILED;
     77         return NULL;
     78     }
     79 
     80     GifFile = DGifOpenFileHandle(FileHandle);
     81     return GifFile;
     82 }
     83 
     84 /******************************************************************************
     85  * Update a new gif file, given its file handle.
     86  * Returns GifFileType pointer dynamically allocated which serves as the gif
     87  * info record. _GifError is cleared if succesfull.
     88  *****************************************************************************/
     89 GifFileType *
     90 DGifOpenFileHandle(int FileHandle) {
     91 
     92     unsigned char Buf[GIF_STAMP_LEN + 1];
     93     GifFileType *GifFile;
     94     GifFilePrivateType *Private;
     95     FILE *f;
     96 
     97     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
     98     if (GifFile == NULL) {
     99         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    100         close(FileHandle);
    101         return NULL;
    102     }
    103 
    104     memset(GifFile, '\0', sizeof(GifFileType));
    105 
    106     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
    107     if (Private == NULL) {
    108         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    109         close(FileHandle);
    110         free((char *)GifFile);
    111         return NULL;
    112     }
    113 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(_OPEN_BINARY)
    114     setmode(FileHandle, O_BINARY);    /* Make sure it is in binary mode. */
    115 #endif /* __MSDOS__ */
    116 
    117     f = fdopen(FileHandle, "rb");    /* Make it into a stream: */
    118 
    119 #if defined(__MSDOS__) || defined(WINDOWS32)
    120     setvbuf(f, NULL, _IOFBF, GIF_FILE_BUFFER_SIZE);    /* And inc. stream
    121                                                           buffer. */
    122 #endif /* __MSDOS__ */
    123 
    124     GifFile->Private = (VoidPtr)Private;
    125     Private->FileHandle = FileHandle;
    126     Private->File = f;
    127     Private->FileState = FILE_STATE_READ;
    128     Private->Read = 0;    /* don't use alternate input method (TVT) */
    129     GifFile->UserData = 0;    /* TVT */
    130 
    131     /* Lets see if this is a GIF file: */
    132     if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    133         _GifError = D_GIF_ERR_READ_FAILED;
    134         fclose(f);
    135         free((char *)Private);
    136         free((char *)GifFile);
    137         return NULL;
    138     }
    139 
    140     /* The GIF Version number is ignored at this time. Maybe we should do
    141      * something more useful with it.  */
    142     Buf[GIF_STAMP_LEN] = 0;
    143     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    144         _GifError = D_GIF_ERR_NOT_GIF_FILE;
    145         fclose(f);
    146         free((char *)Private);
    147         free((char *)GifFile);
    148         return NULL;
    149     }
    150 
    151     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    152         fclose(f);
    153         free((char *)Private);
    154         free((char *)GifFile);
    155         return NULL;
    156     }
    157 
    158     _GifError = 0;
    159 
    160     return GifFile;
    161 }
    162 
    163 #endif /* _GBA_NO_FILEIO */
    164 
    165 /******************************************************************************
    166  * GifFileType constructor with user supplied input function (TVT)
    167  *****************************************************************************/
    168 GifFileType *
    169 DGifOpen(void *userData,
    170          InputFunc readFunc) {
    171 
    172     unsigned char Buf[GIF_STAMP_LEN + 1];
    173     GifFileType *GifFile;
    174     GifFilePrivateType *Private;
    175 
    176     GifFile = (GifFileType *)malloc(sizeof(GifFileType));
    177     if (GifFile == NULL) {
    178         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    179         return NULL;
    180     }
    181 
    182     memset(GifFile, '\0', sizeof(GifFileType));
    183 
    184     Private = (GifFilePrivateType *)malloc(sizeof(GifFilePrivateType));
    185     if (!Private) {
    186         _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    187         free((char *)GifFile);
    188         return NULL;
    189     }
    190 
    191     GifFile->Private = (VoidPtr)Private;
    192     Private->FileHandle = 0;
    193     Private->File = 0;
    194     Private->FileState = FILE_STATE_READ;
    195 
    196     Private->Read = readFunc;    /* TVT */
    197     GifFile->UserData = userData;    /* TVT */
    198 
    199     /* Lets see if this is a GIF file: */
    200     if (READ(GifFile, Buf, GIF_STAMP_LEN) != GIF_STAMP_LEN) {
    201         _GifError = D_GIF_ERR_READ_FAILED;
    202         free((char *)Private);
    203         free((char *)GifFile);
    204         return NULL;
    205     }
    206 
    207     /* The GIF Version number is ignored at this time. Maybe we should do
    208      * something more useful with it. */
    209     Buf[GIF_STAMP_LEN] = 0;
    210     if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) {
    211         _GifError = D_GIF_ERR_NOT_GIF_FILE;
    212         free((char *)Private);
    213         free((char *)GifFile);
    214         return NULL;
    215     }
    216 
    217     if (DGifGetScreenDesc(GifFile) == GIF_ERROR) {
    218         free((char *)Private);
    219         free((char *)GifFile);
    220         return NULL;
    221     }
    222 
    223     _GifError = 0;
    224 
    225     return GifFile;
    226 }
    227 
    228 /******************************************************************************
    229  * This routine should be called before any other DGif calls. Note that
    230  * this routine is called automatically from DGif file open routines.
    231  *****************************************************************************/
    232 int
    233 DGifGetScreenDesc(GifFileType * GifFile) {
    234 
    235     int i, BitsPerPixel;
    236     GifByteType Buf[3];
    237     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    238 
    239     if (!IS_READABLE(Private)) {
    240         /* This file was NOT open for reading: */
    241         _GifError = D_GIF_ERR_NOT_READABLE;
    242         return GIF_ERROR;
    243     }
    244 
    245     /* Put the screen descriptor into the file: */
    246     if (DGifGetWord(GifFile, &GifFile->SWidth) == GIF_ERROR ||
    247         DGifGetWord(GifFile, &GifFile->SHeight) == GIF_ERROR)
    248         return GIF_ERROR;
    249 
    250     if (READ(GifFile, Buf, 3) != 3) {
    251         _GifError = D_GIF_ERR_READ_FAILED;
    252         return GIF_ERROR;
    253     }
    254     GifFile->SColorResolution = (((Buf[0] & 0x70) + 1) >> 4) + 1;
    255     BitsPerPixel = (Buf[0] & 0x07) + 1;
    256     GifFile->SBackGroundColor = Buf[1];
    257     if (Buf[0] & 0x80) {    /* Do we have global color map? */
    258 
    259         GifFile->SColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
    260         if (GifFile->SColorMap == NULL) {
    261             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    262             return GIF_ERROR;
    263         }
    264 
    265         /* Get the global color map: */
    266         for (i = 0; i < GifFile->SColorMap->ColorCount; i++) {
    267             if (READ(GifFile, Buf, 3) != 3) {
    268                 FreeMapObject(GifFile->SColorMap);
    269                 GifFile->SColorMap = NULL;
    270                 _GifError = D_GIF_ERR_READ_FAILED;
    271                 return GIF_ERROR;
    272             }
    273             GifFile->SColorMap->Colors[i].Red = Buf[0];
    274             GifFile->SColorMap->Colors[i].Green = Buf[1];
    275             GifFile->SColorMap->Colors[i].Blue = Buf[2];
    276         }
    277     } else {
    278         GifFile->SColorMap = NULL;
    279     }
    280 
    281     return GIF_OK;
    282 }
    283 
    284 /******************************************************************************
    285  * This routine should be called before any attempt to read an image.
    286  *****************************************************************************/
    287 int
    288 DGifGetRecordType(GifFileType * GifFile,
    289                   GifRecordType * Type) {
    290 
    291     GifByteType Buf;
    292     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    293 
    294     if (!IS_READABLE(Private)) {
    295         /* This file was NOT open for reading: */
    296         _GifError = D_GIF_ERR_NOT_READABLE;
    297         return GIF_ERROR;
    298     }
    299 
    300     if (READ(GifFile, &Buf, 1) != 1) {
    301         _GifError = D_GIF_ERR_READ_FAILED;
    302         return GIF_ERROR;
    303     }
    304 
    305     switch (Buf) {
    306       case ',':
    307           *Type = IMAGE_DESC_RECORD_TYPE;
    308           break;
    309       case '!':
    310           *Type = EXTENSION_RECORD_TYPE;
    311           break;
    312       case ';':
    313           *Type = TERMINATE_RECORD_TYPE;
    314           break;
    315       default:
    316           *Type = UNDEFINED_RECORD_TYPE;
    317           _GifError = D_GIF_ERR_WRONG_RECORD;
    318           return GIF_ERROR;
    319     }
    320 
    321     return GIF_OK;
    322 }
    323 
    324 /******************************************************************************
    325  * This routine should be called before any attempt to read an image.
    326  * Note it is assumed the Image desc. header (',') has been read.
    327  *****************************************************************************/
    328 int
    329 DGifGetImageDesc(GifFileType * GifFile) {
    330 
    331     int i, BitsPerPixel;
    332     GifByteType Buf[3];
    333     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    334     SavedImage *sp;
    335 
    336     if (!IS_READABLE(Private)) {
    337         /* This file was NOT open for reading: */
    338         _GifError = D_GIF_ERR_NOT_READABLE;
    339         return GIF_ERROR;
    340     }
    341 
    342     if (DGifGetWord(GifFile, &GifFile->Image.Left) == GIF_ERROR ||
    343         DGifGetWord(GifFile, &GifFile->Image.Top) == GIF_ERROR ||
    344         DGifGetWord(GifFile, &GifFile->Image.Width) == GIF_ERROR ||
    345         DGifGetWord(GifFile, &GifFile->Image.Height) == GIF_ERROR)
    346         return GIF_ERROR;
    347     if (READ(GifFile, Buf, 1) != 1) {
    348         _GifError = D_GIF_ERR_READ_FAILED;
    349         return GIF_ERROR;
    350     }
    351     BitsPerPixel = (Buf[0] & 0x07) + 1;
    352     GifFile->Image.Interlace = (Buf[0] & 0x40);
    353     if (Buf[0] & 0x80) {    /* Does this image have local color map? */
    354 
    355         /*** FIXME: Why do we check both of these in order to do this?
    356          * Why do we have both Image and SavedImages? */
    357         if (GifFile->Image.ColorMap && GifFile->SavedImages == NULL)
    358             FreeMapObject(GifFile->Image.ColorMap);
    359 
    360         GifFile->Image.ColorMap = MakeMapObject(1 << BitsPerPixel, NULL);
    361         if (GifFile->Image.ColorMap == NULL) {
    362             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    363             return GIF_ERROR;
    364         }
    365 
    366         /* Get the image local color map: */
    367         for (i = 0; i < GifFile->Image.ColorMap->ColorCount; i++) {
    368             if (READ(GifFile, Buf, 3) != 3) {
    369                 FreeMapObject(GifFile->Image.ColorMap);
    370                 _GifError = D_GIF_ERR_READ_FAILED;
    371                 GifFile->Image.ColorMap = NULL;
    372                 return GIF_ERROR;
    373             }
    374             GifFile->Image.ColorMap->Colors[i].Red = Buf[0];
    375             GifFile->Image.ColorMap->Colors[i].Green = Buf[1];
    376             GifFile->Image.ColorMap->Colors[i].Blue = Buf[2];
    377         }
    378     } else if (GifFile->Image.ColorMap) {
    379         FreeMapObject(GifFile->Image.ColorMap);
    380         GifFile->Image.ColorMap = NULL;
    381     }
    382 
    383     if (GifFile->SavedImages) {
    384         if ((GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
    385                                       sizeof(SavedImage) *
    386                                       (GifFile->ImageCount + 1))) == NULL) {
    387             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    388             return GIF_ERROR;
    389         }
    390     } else {
    391         if ((GifFile->SavedImages =
    392              (SavedImage *) malloc(sizeof(SavedImage))) == NULL) {
    393             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    394             return GIF_ERROR;
    395         }
    396     }
    397 
    398     sp = &GifFile->SavedImages[GifFile->ImageCount];
    399     memcpy(&sp->ImageDesc, &GifFile->Image, sizeof(GifImageDesc));
    400     if (GifFile->Image.ColorMap != NULL) {
    401         sp->ImageDesc.ColorMap = MakeMapObject(
    402                                  GifFile->Image.ColorMap->ColorCount,
    403                                  GifFile->Image.ColorMap->Colors);
    404         if (sp->ImageDesc.ColorMap == NULL) {
    405             _GifError = D_GIF_ERR_NOT_ENOUGH_MEM;
    406             return GIF_ERROR;
    407         }
    408     }
    409     sp->RasterBits = (unsigned char *)NULL;
    410     sp->ExtensionBlockCount = 0;
    411     sp->ExtensionBlocks = (ExtensionBlock *) NULL;
    412 
    413     GifFile->ImageCount++;
    414 
    415     Private->PixelCount = (long)GifFile->Image.Width *
    416        (long)GifFile->Image.Height;
    417 
    418     DGifSetupDecompress(GifFile);  /* Reset decompress algorithm parameters. */
    419 
    420     return GIF_OK;
    421 }
    422 
    423 /******************************************************************************
    424  * Get one full scanned line (Line) of length LineLen from GIF file.
    425  *****************************************************************************/
    426 int
    427 DGifGetLine(GifFileType * GifFile,
    428             GifPixelType * Line,
    429             int LineLen) {
    430 
    431     GifByteType *Dummy;
    432     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    433 
    434     if (!IS_READABLE(Private)) {
    435         /* This file was NOT open for reading: */
    436         _GifError = D_GIF_ERR_NOT_READABLE;
    437         return GIF_ERROR;
    438     }
    439 
    440     if (!LineLen)
    441         LineLen = GifFile->Image.Width;
    442 
    443 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__)
    444     if ((Private->PixelCount -= LineLen) > 0xffff0000UL) {
    445 #else
    446     if ((Private->PixelCount -= LineLen) > 0xffff0000) {
    447 #endif /* __MSDOS__ */
    448         _GifError = D_GIF_ERR_DATA_TOO_BIG;
    449         return GIF_ERROR;
    450     }
    451 
    452     if (DGifDecompressLine(GifFile, Line, LineLen) == GIF_OK) {
    453         if (Private->PixelCount == 0) {
    454             /* We probably would not be called any more, so lets clean
    455              * everything before we return: need to flush out all rest of
    456              * image until empty block (size 0) detected. We use GetCodeNext. */
    457             do
    458                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    459                     return GIF_ERROR;
    460             while (Dummy != NULL) ;
    461         }
    462         return GIF_OK;
    463     } else
    464         return GIF_ERROR;
    465 }
    466 
    467 /******************************************************************************
    468  * Put one pixel (Pixel) into GIF file.
    469  *****************************************************************************/
    470 int
    471 DGifGetPixel(GifFileType * GifFile,
    472              GifPixelType Pixel) {
    473 
    474     GifByteType *Dummy;
    475     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    476 
    477     if (!IS_READABLE(Private)) {
    478         /* This file was NOT open for reading: */
    479         _GifError = D_GIF_ERR_NOT_READABLE;
    480         return GIF_ERROR;
    481     }
    482 #if defined(__MSDOS__) || defined(WINDOWS32) || defined(__GNUC__)
    483     if (--Private->PixelCount > 0xffff0000UL)
    484 #else
    485     if (--Private->PixelCount > 0xffff0000)
    486 #endif /* __MSDOS__ */
    487     {
    488         _GifError = D_GIF_ERR_DATA_TOO_BIG;
    489         return GIF_ERROR;
    490     }
    491 
    492     if (DGifDecompressLine(GifFile, &Pixel, 1) == GIF_OK) {
    493         if (Private->PixelCount == 0) {
    494             /* We probably would not be called any more, so lets clean
    495              * everything before we return: need to flush out all rest of
    496              * image until empty block (size 0) detected. We use GetCodeNext. */
    497             do
    498                 if (DGifGetCodeNext(GifFile, &Dummy) == GIF_ERROR)
    499                     return GIF_ERROR;
    500             while (Dummy != NULL) ;
    501         }
    502         return GIF_OK;
    503     } else
    504         return GIF_ERROR;
    505 }
    506 
    507 /******************************************************************************
    508  * Get an extension block (see GIF manual) from gif file. This routine only
    509  * returns the first data block, and DGifGetExtensionNext should be called
    510  * after this one until NULL extension is returned.
    511  * The Extension should NOT be freed by the user (not dynamically allocated).
    512  * Note it is assumed the Extension desc. header ('!') has been read.
    513  *****************************************************************************/
    514 int
    515 DGifGetExtension(GifFileType * GifFile,
    516                  int *ExtCode,
    517                  GifByteType ** Extension) {
    518 
    519     GifByteType Buf;
    520     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    521 
    522     if (!IS_READABLE(Private)) {
    523         /* This file was NOT open for reading: */
    524         _GifError = D_GIF_ERR_NOT_READABLE;
    525         return GIF_ERROR;
    526     }
    527 
    528     if (READ(GifFile, &Buf, 1) != 1) {
    529         _GifError = D_GIF_ERR_READ_FAILED;
    530         return GIF_ERROR;
    531     }
    532     *ExtCode = Buf;
    533 
    534     return DGifGetExtensionNext(GifFile, Extension);
    535 }
    536 
    537 /******************************************************************************
    538  * Get a following extension block (see GIF manual) from gif file. This
    539  * routine should be called until NULL Extension is returned.
    540  * The Extension should NOT be freed by the user (not dynamically allocated).
    541  *****************************************************************************/
    542 int
    543 DGifGetExtensionNext(GifFileType * GifFile,
    544                      GifByteType ** Extension) {
    545 
    546     GifByteType Buf;
    547     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    548 
    549     if (READ(GifFile, &Buf, 1) != 1) {
    550         _GifError = D_GIF_ERR_READ_FAILED;
    551         return GIF_ERROR;
    552     }
    553     if (Buf > 0) {
    554         *Extension = Private->Buf;    /* Use private unused buffer. */
    555         (*Extension)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    556         if (READ(GifFile, &((*Extension)[1]), Buf) != Buf) {
    557             _GifError = D_GIF_ERR_READ_FAILED;
    558             return GIF_ERROR;
    559         }
    560     } else
    561         *Extension = NULL;
    562 
    563     return GIF_OK;
    564 }
    565 
    566 /******************************************************************************
    567  * This routine should be called last, to close the GIF file.
    568  *****************************************************************************/
    569 int
    570 DGifCloseFile(GifFileType * GifFile) {
    571 
    572     GifFilePrivateType *Private;
    573     FILE *File;
    574 
    575     if (GifFile == NULL)
    576         return GIF_ERROR;
    577 
    578     Private = (GifFilePrivateType *) GifFile->Private;
    579 
    580     if (!IS_READABLE(Private)) {
    581         /* This file was NOT open for reading: */
    582         _GifError = D_GIF_ERR_NOT_READABLE;
    583         return GIF_ERROR;
    584     }
    585 
    586     File = Private->File;
    587 
    588     if (GifFile->Image.ColorMap) {
    589         FreeMapObject(GifFile->Image.ColorMap);
    590         GifFile->Image.ColorMap = NULL;
    591     }
    592 
    593     if (GifFile->SColorMap) {
    594         FreeMapObject(GifFile->SColorMap);
    595         GifFile->SColorMap = NULL;
    596     }
    597 
    598     if (Private) {
    599         free((char *)Private);
    600         Private = NULL;
    601     }
    602 
    603     if (GifFile->SavedImages) {
    604         FreeSavedImages(GifFile);
    605         GifFile->SavedImages = NULL;
    606     }
    607 
    608     free(GifFile);
    609 
    610     if (File && (fclose(File) != 0)) {
    611         _GifError = D_GIF_ERR_CLOSE_FAILED;
    612         return GIF_ERROR;
    613     }
    614     return GIF_OK;
    615 }
    616 
    617 /******************************************************************************
    618  * Get 2 bytes (word) from the given file:
    619  *****************************************************************************/
    620 static int
    621 DGifGetWord(GifFileType * GifFile,
    622             GifWord *Word) {
    623 
    624     unsigned char c[2];
    625 
    626     if (READ(GifFile, c, 2) != 2) {
    627         _GifError = D_GIF_ERR_READ_FAILED;
    628         return GIF_ERROR;
    629     }
    630 
    631     *Word = (((unsigned int)c[1]) << 8) + c[0];
    632     return GIF_OK;
    633 }
    634 
    635 /******************************************************************************
    636  * Get the image code in compressed form.  This routine can be called if the
    637  * information needed to be piped out as is. Obviously this is much faster
    638  * than decoding and encoding again. This routine should be followed by calls
    639  * to DGifGetCodeNext, until NULL block is returned.
    640  * The block should NOT be freed by the user (not dynamically allocated).
    641  *****************************************************************************/
    642 int
    643 DGifGetCode(GifFileType * GifFile,
    644             int *CodeSize,
    645             GifByteType ** CodeBlock) {
    646 
    647     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    648 
    649     if (!IS_READABLE(Private)) {
    650         /* This file was NOT open for reading: */
    651         _GifError = D_GIF_ERR_NOT_READABLE;
    652         return GIF_ERROR;
    653     }
    654 
    655     *CodeSize = Private->BitsPerPixel;
    656 
    657     return DGifGetCodeNext(GifFile, CodeBlock);
    658 }
    659 
    660 /******************************************************************************
    661  * Continue to get the image code in compressed form. This routine should be
    662  * called until NULL block is returned.
    663  * The block should NOT be freed by the user (not dynamically allocated).
    664  *****************************************************************************/
    665 int
    666 DGifGetCodeNext(GifFileType * GifFile,
    667                 GifByteType ** CodeBlock) {
    668 
    669     GifByteType Buf;
    670     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    671 
    672     if (READ(GifFile, &Buf, 1) != 1) {
    673         _GifError = D_GIF_ERR_READ_FAILED;
    674         return GIF_ERROR;
    675     }
    676 
    677     if (Buf > 0) {
    678         *CodeBlock = Private->Buf;    /* Use private unused buffer. */
    679         (*CodeBlock)[0] = Buf;  /* Pascal strings notation (pos. 0 is len.). */
    680         if (READ(GifFile, &((*CodeBlock)[1]), Buf) != Buf) {
    681             _GifError = D_GIF_ERR_READ_FAILED;
    682             return GIF_ERROR;
    683         }
    684     } else {
    685         *CodeBlock = NULL;
    686         Private->Buf[0] = 0;    /* Make sure the buffer is empty! */
    687         Private->PixelCount = 0;    /* And local info. indicate image read. */
    688     }
    689 
    690     return GIF_OK;
    691 }
    692 
    693 /******************************************************************************
    694  * Setup the LZ decompression for this image:
    695  *****************************************************************************/
    696 static int
    697 DGifSetupDecompress(GifFileType * GifFile) {
    698 
    699     int i, BitsPerPixel;
    700     GifByteType CodeSize;
    701     GifPrefixType *Prefix;
    702     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    703 
    704     READ(GifFile, &CodeSize, 1);    /* Read Code size from file. */
    705     BitsPerPixel = CodeSize;
    706 
    707     Private->Buf[0] = 0;    /* Input Buffer empty. */
    708     Private->BitsPerPixel = BitsPerPixel;
    709     Private->ClearCode = (1 << BitsPerPixel);
    710     Private->EOFCode = Private->ClearCode + 1;
    711     Private->RunningCode = Private->EOFCode + 1;
    712     Private->RunningBits = BitsPerPixel + 1;    /* Number of bits per code. */
    713     Private->MaxCode1 = 1 << Private->RunningBits;    /* Max. code + 1. */
    714     Private->StackPtr = 0;    /* No pixels on the pixel stack. */
    715     Private->LastCode = NO_SUCH_CODE;
    716     Private->CrntShiftState = 0;    /* No information in CrntShiftDWord. */
    717     Private->CrntShiftDWord = 0;
    718 
    719     Prefix = Private->Prefix;
    720     for (i = 0; i <= LZ_MAX_CODE; i++)
    721         Prefix[i] = NO_SUCH_CODE;
    722 
    723     return GIF_OK;
    724 }
    725 
    726 /******************************************************************************
    727  * The LZ decompression routine:
    728  * This version decompress the given gif file into Line of length LineLen.
    729  * This routine can be called few times (one per scan line, for example), in
    730  * order the complete the whole image.
    731  *****************************************************************************/
    732 static int
    733 DGifDecompressLine(GifFileType * GifFile,
    734                    GifPixelType * Line,
    735                    int LineLen) {
    736 
    737     int i = 0;
    738     int j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
    739     GifByteType *Stack, *Suffix;
    740     GifPrefixType *Prefix;
    741     GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
    742 
    743     StackPtr = Private->StackPtr;
    744     Prefix = Private->Prefix;
    745     Suffix = Private->Suffix;
    746     Stack = Private->Stack;
    747     EOFCode = Private->EOFCode;
    748     ClearCode = Private->ClearCode;
    749     LastCode = Private->LastCode;
    750 
    751     if (StackPtr > LZ_MAX_CODE) {
    752         return GIF_ERROR;
    753     }
    754 
    755     if (StackPtr != 0) {
    756         /* Let pop the stack off before continueing to read the gif file: */
    757         while (StackPtr != 0 && i < LineLen)
    758             Line[i++] = Stack[--StackPtr];
    759     }
    760 
    761     while (i < LineLen) {    /* Decode LineLen items. */
    762         if (DGifDecompressInput(GifFile, &CrntCode) == GIF_ERROR)
    763             return GIF_ERROR;
    764 
    765         if (CrntCode == EOFCode) {
    766             /* Note however that usually we will not be here as we will stop
    767              * decoding as soon as we got all the pixel, or EOF code will
    768              * not be read at all, and DGifGetLine/Pixel clean everything.  */
    769             if (i != LineLen - 1 || Private->PixelCount != 0) {
    770                 _GifError = D_GIF_ERR_EOF_TOO_SOON;
    771                 return GIF_ERROR;
    772             }
    773             i++;
    774         } else if (CrntCode == ClearCode) {
    775             /* We need to start over again: */
    776             for (j = 0; j <= LZ_MAX_CODE; j++)
    777                 Prefix[j] = NO_SUCH_CODE;
    778             Private->RunningCode = Private->EOFCode + 1;
    779             Private->RunningBits = Private->BitsPerPixel + 1;
    780             Private->MaxCode1 = 1 << Private->RunningBits;
    781             LastCode = Private->LastCode = NO_SUCH_CODE;
    782         } else {
    783             /* Its regular code - if in pixel range simply add it to output
    784              * stream, otherwise trace to codes linked list until the prefix
    785              * is in pixel range: */
    786             if (CrntCode < ClearCode) {
    787                 /* This is simple - its pixel scalar, so add it to output: */
    788                 Line[i++] = CrntCode;
    789             } else {
    790                 /* Its a code to needed to be traced: trace the linked list
    791                  * until the prefix is a pixel, while pushing the suffix
    792                  * pixels on our stack. If we done, pop the stack in reverse
    793                  * (thats what stack is good for!) order to output.  */
    794                 if (Prefix[CrntCode] == NO_SUCH_CODE) {
    795                     /* Only allowed if CrntCode is exactly the running code:
    796                      * In that case CrntCode = XXXCode, CrntCode or the
    797                      * prefix code is last code and the suffix char is
    798                      * exactly the prefix of last code! */
    799                     if (CrntCode == Private->RunningCode - 2) {
    800                         CrntPrefix = LastCode;
    801                         Suffix[Private->RunningCode - 2] =
    802                            Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
    803                                                                  LastCode,
    804                                                                  ClearCode);
    805                     } else {
    806                         _GifError = D_GIF_ERR_IMAGE_DEFECT;
    807                         return GIF_ERROR;
    808                     }
    809                 } else
    810                     CrntPrefix = CrntCode;
    811 
    812                 /* Now (if image is O.K.) we should not get an NO_SUCH_CODE
    813                  * During the trace. As we might loop forever, in case of
    814                  * defective image, we count the number of loops we trace
    815                  * and stop if we got LZ_MAX_CODE. obviously we can not
    816                  * loop more than that.  */
    817                 j = 0;
    818                 while (j++ <= LZ_MAX_CODE &&
    819                        CrntPrefix > ClearCode && CrntPrefix <= LZ_MAX_CODE) {
    820                     Stack[StackPtr++] = Suffix[CrntPrefix];
    821                     CrntPrefix = Prefix[CrntPrefix];
    822                 }
    823                 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
    824                     _GifError = D_GIF_ERR_IMAGE_DEFECT;
    825                     return GIF_ERROR;
    826                 }
    827                 /* Push the last character on stack: */
    828                 Stack[StackPtr++] = CrntPrefix;
    829 
    830                 /* Now lets pop all the stack into output: */
    831                 while (StackPtr != 0 && i < LineLen)
    832                     Line[i++] = Stack[--StackPtr];
    833             }
    834             if (LastCode != NO_SUCH_CODE) {
    835                 Prefix[Private->RunningCode - 2] = LastCode;
    836 
    837                 if (CrntCode == Private->RunningCode - 2) {
    838                     /* Only allowed if CrntCode is exactly the running code:
    839                      * In that case CrntCode = XXXCode, CrntCode or the
    840                      * prefix code is last code and the suffix char is
    841                      * exactly the prefix of last code! */
    842                     Suffix[Private->RunningCode - 2] =
    843                        DGifGetPrefixChar(Prefix, LastCode, ClearCode);
    844                 } else {
    845                     Suffix[Private->RunningCode - 2] =
    846                        DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
    847                 }
    848             }
    849             LastCode = CrntCode;
    850         }
    851     }
    852 
    853     Private->LastCode = LastCode;
    854     Private->StackPtr = StackPtr;
    855 
    856     return GIF_OK;
    857 }
    858 
    859 /******************************************************************************
    860  * Routine to trace the Prefixes linked list until we get a prefix which is
    861  * not code, but a pixel value (less than ClearCode). Returns that pixel value.
    862  * If image is defective, we might loop here forever, so we limit the loops to
    863  * the maximum possible if image O.k. - LZ_MAX_CODE times.
    864  *****************************************************************************/
    865 static int
    866 DGifGetPrefixChar(GifPrefixType *Prefix,
    867                   int Code,
    868                   int ClearCode) {
    869 
    870     int i = 0;
    871 
    872     while (Code > ClearCode && i++ <= LZ_MAX_CODE) {
    873         if (Code > LZ_MAX_CODE) {
    874             return NO_SUCH_CODE;
    875         }
    876         Code = Prefix[Code];
    877     }
    878     return Code;
    879 }
    880 
    881 /******************************************************************************
    882  * Interface for accessing the LZ codes directly. Set Code to the real code
    883  * (12bits), or to -1 if EOF code is returned.
    884  *****************************************************************************/
    885 int
    886 DGifGetLZCodes(GifFileType * GifFile,
    887                int *Code) {
    888 
    889     GifByteType *CodeBlock;
    890     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    891 
    892     if (!IS_READABLE(Private)) {
    893         /* This file was NOT open for reading: */
    894         _GifError = D_GIF_ERR_NOT_READABLE;
    895         return GIF_ERROR;
    896     }
    897 
    898     if (DGifDecompressInput(GifFile, Code) == GIF_ERROR)
    899         return GIF_ERROR;
    900 
    901     if (*Code == Private->EOFCode) {
    902         /* Skip rest of codes (hopefully only NULL terminating block): */
    903         do {
    904             if (DGifGetCodeNext(GifFile, &CodeBlock) == GIF_ERROR)
    905                 return GIF_ERROR;
    906         } while (CodeBlock != NULL) ;
    907 
    908         *Code = -1;
    909     } else if (*Code == Private->ClearCode) {
    910         /* We need to start over again: */
    911         Private->RunningCode = Private->EOFCode + 1;
    912         Private->RunningBits = Private->BitsPerPixel + 1;
    913         Private->MaxCode1 = 1 << Private->RunningBits;
    914     }
    915 
    916     return GIF_OK;
    917 }
    918 
    919 /******************************************************************************
    920  * The LZ decompression input routine:
    921  * This routine is responsable for the decompression of the bit stream from
    922  * 8 bits (bytes) packets, into the real codes.
    923  * Returns GIF_OK if read succesfully.
    924  *****************************************************************************/
    925 static int
    926 DGifDecompressInput(GifFileType * GifFile,
    927                     int *Code) {
    928 
    929     GifFilePrivateType *Private = (GifFilePrivateType *)GifFile->Private;
    930 
    931     GifByteType NextByte;
    932     static unsigned short CodeMasks[] = {
    933         0x0000, 0x0001, 0x0003, 0x0007,
    934         0x000f, 0x001f, 0x003f, 0x007f,
    935         0x00ff, 0x01ff, 0x03ff, 0x07ff,
    936         0x0fff
    937     };
    938     /* The image can't contain more than LZ_BITS per code. */
    939     if (Private->RunningBits > LZ_BITS) {
    940         _GifError = D_GIF_ERR_IMAGE_DEFECT;
    941         return GIF_ERROR;
    942     }
    943 
    944     while (Private->CrntShiftState < Private->RunningBits) {
    945         /* Needs to get more bytes from input stream for next code: */
    946         if (DGifBufferedInput(GifFile, Private->Buf, &NextByte) == GIF_ERROR) {
    947             return GIF_ERROR;
    948         }
    949         Private->CrntShiftDWord |=
    950            ((unsigned long)NextByte) << Private->CrntShiftState;
    951         Private->CrntShiftState += 8;
    952     }
    953     *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
    954 
    955     Private->CrntShiftDWord >>= Private->RunningBits;
    956     Private->CrntShiftState -= Private->RunningBits;
    957 
    958     /* If code cannot fit into RunningBits bits, must raise its size. Note
    959      * however that codes above 4095 are used for special signaling.
    960      * If we're using LZ_BITS bits already and we're at the max code, just
    961      * keep using the table as it is, don't increment Private->RunningCode.
    962      */
    963     if (Private->RunningCode < LZ_MAX_CODE + 2 &&
    964             ++Private->RunningCode > Private->MaxCode1 &&
    965             Private->RunningBits < LZ_BITS) {
    966         Private->MaxCode1 <<= 1;
    967         Private->RunningBits++;
    968     }
    969     return GIF_OK;
    970 }
    971 
    972 /******************************************************************************
    973  * This routines read one gif data block at a time and buffers it internally
    974  * so that the decompression routine could access it.
    975  * The routine returns the next byte from its internal buffer (or read next
    976  * block in if buffer empty) and returns GIF_OK if succesful.
    977  *****************************************************************************/
    978 static int
    979 DGifBufferedInput(GifFileType * GifFile,
    980                   GifByteType * Buf,
    981                   GifByteType * NextByte) {
    982 
    983     if (Buf[0] == 0) {
    984         /* Needs to read the next buffer - this one is empty: */
    985         if (READ(GifFile, Buf, 1) != 1) {
    986             _GifError = D_GIF_ERR_READ_FAILED;
    987             return GIF_ERROR;
    988         }
    989         /* There shouldn't be any empty data blocks here as the LZW spec
    990          * says the LZW termination code should come first.  Therefore we
    991          * shouldn't be inside this routine at that point.
    992          */
    993         if (Buf[0] == 0) {
    994             _GifError = D_GIF_ERR_IMAGE_DEFECT;
    995             return GIF_ERROR;
    996         }
    997         if (READ(GifFile, &Buf[1], Buf[0]) != Buf[0]) {
    998             _GifError = D_GIF_ERR_READ_FAILED;
    999             return GIF_ERROR;
   1000         }
   1001         *NextByte = Buf[1];
   1002         Buf[1] = 2;    /* We use now the second place as last char read! */
   1003         Buf[0]--;
   1004     } else {
   1005         *NextByte = Buf[Buf[1]++];
   1006         Buf[0]--;
   1007     }
   1008 
   1009     return GIF_OK;
   1010 }
   1011 #ifndef _GBA_NO_FILEIO
   1012 
   1013 /******************************************************************************
   1014  * This routine reads an entire GIF into core, hanging all its state info off
   1015  * the GifFileType pointer.  Call DGifOpenFileName() or DGifOpenFileHandle()
   1016  * first to initialize I/O.  Its inverse is EGifSpew().
   1017  ******************************************************************************/
   1018 int
   1019 DGifSlurp(GifFileType * GifFile) {
   1020 
   1021     int ImageSize;
   1022     GifRecordType RecordType;
   1023     SavedImage *sp;
   1024     GifByteType *ExtData;
   1025     SavedImage temp_save;
   1026 
   1027     temp_save.ExtensionBlocks = NULL;
   1028     temp_save.ExtensionBlockCount = 0;
   1029 
   1030     do {
   1031         if (DGifGetRecordType(GifFile, &RecordType) == GIF_ERROR)
   1032             return (GIF_ERROR);
   1033 
   1034         switch (RecordType) {
   1035           case IMAGE_DESC_RECORD_TYPE:
   1036               if (DGifGetImageDesc(GifFile) == GIF_ERROR)
   1037                   return (GIF_ERROR);
   1038 
   1039               sp = &GifFile->SavedImages[GifFile->ImageCount - 1];
   1040               ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
   1041 
   1042               sp->RasterBits = (unsigned char *)malloc(ImageSize *
   1043                                                        sizeof(GifPixelType));
   1044               if (sp->RasterBits == NULL) {
   1045                   return GIF_ERROR;
   1046               }
   1047               if (DGifGetLine(GifFile, sp->RasterBits, ImageSize) ==
   1048                   GIF_ERROR)
   1049                   return (GIF_ERROR);
   1050               if (temp_save.ExtensionBlocks) {
   1051                   sp->ExtensionBlocks = temp_save.ExtensionBlocks;
   1052                   sp->ExtensionBlockCount = temp_save.ExtensionBlockCount;
   1053 
   1054                   temp_save.ExtensionBlocks = NULL;
   1055                   temp_save.ExtensionBlockCount = 0;
   1056 
   1057                   /* FIXME: The following is wrong.  It is left in only for
   1058                    * backwards compatibility.  Someday it should go away. Use
   1059                    * the sp->ExtensionBlocks->Function variable instead. */
   1060                   sp->Function = sp->ExtensionBlocks[0].Function;
   1061               }
   1062               break;
   1063 
   1064           case EXTENSION_RECORD_TYPE:
   1065               if (DGifGetExtension(GifFile, &temp_save.Function, &ExtData) ==
   1066                   GIF_ERROR)
   1067                   return (GIF_ERROR);
   1068               while (ExtData != NULL) {
   1069 
   1070                   /* Create an extension block with our data */
   1071                   if (AddExtensionBlock(&temp_save, ExtData[0], &ExtData[1])
   1072                       == GIF_ERROR)
   1073                       return (GIF_ERROR);
   1074 
   1075                   if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
   1076                       return (GIF_ERROR);
   1077                   temp_save.Function = 0;
   1078               }
   1079               break;
   1080 
   1081           case TERMINATE_RECORD_TYPE:
   1082               break;
   1083 
   1084           default:    /* Should be trapped by DGifGetRecordType */
   1085               break;
   1086         }
   1087     } while (RecordType != TERMINATE_RECORD_TYPE);
   1088 
   1089     /* Just in case the Gif has an extension block without an associated
   1090      * image... (Should we save this into a savefile structure with no image
   1091      * instead? Have to check if the present writing code can handle that as
   1092      * well.... */
   1093     if (temp_save.ExtensionBlocks)
   1094         FreeExtension(&temp_save);
   1095 
   1096     return (GIF_OK);
   1097 }
   1098 #endif /* _GBA_NO_FILEIO */
   1099