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