annotate src/dgif_lib.c @ 771:943eaba38521

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