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