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