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