dgif_lib.c revision 9aef3ea079a57c98a9207f8c3b95a5dc08ee74b5
1/******************************************************************************
2
3dgif_lib.c - GIF decoding
4
5The functions here and in egif_lib.c are partitioned carefully so that
6if you only require one of read and write capability, only one of these
7two 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
35static int DGifGetWord(GifFileType *GifFile, GifWord *Word);
36static int DGifSetupDecompress(GifFileType *GifFile);
37static int DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
38                              int LineLen);
39static int DGifGetPrefixChar(GifPrefixType *Prefix, int Code, int ClearCode);
40static int DGifDecompressInput(GifFileType *GifFile, int *Code);
41static 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******************************************************************************/
49GifFileType *
50DGifOpenFileName(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******************************************************************************/
71GifFileType *
72DGifOpenFileHandle(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******************************************************************************/
155GifFileType *
156DGifOpen(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******************************************************************************/
228int
229DGifGetScreenDesc(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******************************************************************************/
290int
291DGifGetRecordType(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******************************************************************************/
330int
331DGifGetImageDesc(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******************************************************************************/
431int
432DGifGetLine(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******************************************************************************/
471int
472DGifGetPixel(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******************************************************************************/
512int
513DGifGetExtension(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******************************************************************************/
538int
539DGifGetExtensionNext(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
566int 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
589int 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******************************************************************************/
614int
615DGifCloseFile(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******************************************************************************/
668static int
669DGifGetWord(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******************************************************************************/
689int
690DGifGetCode(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******************************************************************************/
710int
711DGifGetCodeNext(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******************************************************************************/
743static int
744DGifSetupDecompress(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******************************************************************************/
779static int
780DGifDecompressLine(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******************************************************************************/
905static int
906DGifGetPrefixChar(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******************************************************************************/
923int
924DGifGetLZCodes(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******************************************************************************/
962static int
963DGifDecompressInput(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******************************************************************************/
1016static int
1017DGifBufferedInput(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*******************************************************************************/
1061int
1062DGifSlurp(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 (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1138				       &GifFile->ExtensionBlocks,
1139				       ExtFunction, ExtData[0], &ExtData[1])
1140		  == GIF_ERROR)
1141		  return (GIF_ERROR);
1142              while (ExtData != NULL) {
1143                  if (DGifGetExtensionNext(GifFile, &ExtData) == GIF_ERROR)
1144                      return (GIF_ERROR);
1145                  /* Continue the extension block */
1146		  if (ExtData != NULL)
1147		      if (GifAddExtensionBlock(&GifFile->ExtensionBlockCount,
1148					       &GifFile->ExtensionBlocks,
1149					       CONTINUE_EXT_FUNC_CODE,
1150					       ExtData[0], &ExtData[1]) == GIF_ERROR)
1151                      return (GIF_ERROR);
1152              }
1153              break;
1154
1155          case TERMINATE_RECORD_TYPE:
1156              break;
1157
1158          default:    /* Should be trapped by DGifGetRecordType */
1159              break;
1160        }
1161    } while (RecordType != TERMINATE_RECORD_TYPE);
1162
1163    return (GIF_OK);
1164}
1165
1166/* end */
1167