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