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