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