annotate src/dgif_lib.c @ 4594:2986723ac32d

Update comment.
author Stephen J. Turnbull <stephen@xemacs.org>
date Mon, 02 Feb 2009 23:31:09 +0900
parents 6c7605dfcf07
children
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 {
3462
6c7605dfcf07 [xemacs-hg @ 2006-06-19 18:19:33 by james]
james
parents: 2062
diff changeset
369 GifFilePrivateType *Private;
428
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
3462
6c7605dfcf07 [xemacs-hg @ 2006-06-19 18:19:33 by james]
james
parents: 2062
diff changeset
373 Private = (GifFilePrivateType *)GifFile->Private;
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
374 if (!IS_READABLE(Private))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
375 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
376 /* This file was NOT open for reading: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
377 GifInternError(GifFile, D_GIF_ERR_NOT_READABLE);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
380 if (GifClose (GifFile))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
381 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
382 GifInternError(GifFile, D_GIF_ERR_CLOSE_FAILED);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
383 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
384 return 0;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
388 * Get 2 bytes (word) from the given file: *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
389 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
390 static void DGifGetWord(GifFileType *GifFile, int *Word)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
391 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
392 unsigned char c[2];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
393
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
394 GifRead(c, 2, GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
395
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
396 *Word = (((unsigned int) c[1]) << 8) + c[0];
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
400 * 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
401 * 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
402 * than decoding and encoding again. This routine should be followed by calls *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
403 * to DGifGetCodeNext, until NULL block is returned. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
404 * The block should NOT be freed by the user (not dynamically allocated). *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
405 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
406 void DGifGetCode(GifFileType *GifFile, int *CodeSize, GifByteType **CodeBlock)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
407 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
408 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
409
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
410 if (!IS_READABLE(Private)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
411 /* This file was NOT open for reading: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
412 GifInternError(GifFile, D_GIF_ERR_NOT_READABLE);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
415 *CodeSize = Private->BitsPerPixel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
416
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
417 DGifGetCodeNext(GifFile, CodeBlock);
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
421 * 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
422 * called until NULL block is returned. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
423 * The block should NOT be freed by the user (not dynamically allocated). *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
424 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
425 void DGifGetCodeNext(GifFileType *GifFile, GifByteType **CodeBlock)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
426 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
427 GifByteType Buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
428 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
429
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
430 GifRead(&Buf, 1, GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
431
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
432 if (Buf > 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
433 *CodeBlock = Private->Buf; /* Use private unused buffer. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
434 (*CodeBlock)[0] = Buf; /* Pascal strings notation (pos. 0 is len.). */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
435 GifRead(&((*CodeBlock)[1]), Buf, GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
436 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
437 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
438 *CodeBlock = NULL;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
439 Private->Buf[0] = 0; /* Make sure the buffer is empty! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
440 Private->PixelCount = 0; /* And local info. indicate image read. */
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
446 * Setup the LZ decompression for this image: *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
447 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
448 static void DGifSetupDecompress(GifFileType *GifFile)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
449 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
450 int i, BitsPerPixel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
451 GifByteType CodeSize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
452 unsigned int *Prefix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
453 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
454
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
455 GifRead(&CodeSize, 1, GifFile); /* Read Code size from file. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
456 BitsPerPixel = CodeSize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
457
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
458 Private->Buf[0] = 0; /* Input Buffer empty. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
459 Private->BitsPerPixel = BitsPerPixel;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
460 Private->ClearCode = (1 << BitsPerPixel);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
461 Private->EOFCode = Private->ClearCode + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
462 Private->RunningCode = Private->EOFCode + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
463 Private->RunningBits = BitsPerPixel + 1; /* Number of bits per code. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
464 Private->MaxCode1 = 1 << Private->RunningBits; /* Max. code + 1. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
465 Private->StackPtr = 0; /* No pixels on the pixel stack. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
466 Private->LastCode = NO_SUCH_CODE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
467 Private->CrntShiftState = 0; /* No information in CrntShiftDWord. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
468 Private->CrntShiftDWord = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
469
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
470 Prefix = Private->Prefix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
471 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
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
475 * The LZ decompression routine: *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
476 * This version decompress the given gif file into Line of length LineLen. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
477 * 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
478 * order the complete the whole image. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
479 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
480 static void DGifDecompressLine(GifFileType *GifFile, GifPixelType *Line,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
481 int LineLen)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
482 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
483 int i = 0, j, CrntCode, EOFCode, ClearCode, CrntPrefix, LastCode, StackPtr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
484 GifByteType *Stack, *Suffix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
485 unsigned int *Prefix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
486 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
487
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
488 StackPtr = Private->StackPtr;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
489 Prefix = Private->Prefix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
490 Suffix = Private->Suffix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
491 Stack = Private->Stack;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
492 EOFCode = Private->EOFCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
493 ClearCode = Private->ClearCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
494 LastCode = Private->LastCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
495
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
496 CrntPrefix = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
497 if (StackPtr != 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
498 /* Let pop the stack off before continueing to read the gif file: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
499 while (StackPtr != 0 && i < LineLen) Line[i++] = Stack[--StackPtr];
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
502 while (i < LineLen) { /* Decode LineLen items. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
503 DGifDecompressInput(GifFile, &CrntCode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
504
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
505 if (CrntCode == EOFCode) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
506 /* 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
507 /* 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
508 /* not be read at all, and DGifGetLine/Pixel clean everything. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
509 if (i != LineLen - 1 || Private->PixelCount != 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
510 GifInternError(GifFile, D_GIF_ERR_EOF_TOO_SOON);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
511 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
512 i++;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
513 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
514 else if (CrntCode == ClearCode) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
515 /* We need to start over again: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
516 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
517 Private->RunningCode = Private->EOFCode + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
518 Private->RunningBits = Private->BitsPerPixel + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
519 Private->MaxCode1 = 1 << Private->RunningBits;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
520 LastCode = Private->LastCode = NO_SUCH_CODE;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
521 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
522 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
523 /* Its regular code - if in pixel range simply add it to output */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
524 /* stream, otherwise trace to codes linked list until the prefix */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
525 /* is in pixel range: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
526 if (CrntCode < ClearCode) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
527 /* This is simple - its pixel scalar, so add it to output: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
528 Line[i++] = CrntCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
529 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
530 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
531 /* Its a code to needed to be traced: trace the linked list */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
532 /* until the prefix is a pixel, while pushing the suffix */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
533 /* pixels on our stack. If we done, pop the stack in reverse */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
534 /* (thats what stack is good for!) order to output. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
535 if (Prefix[CrntCode] == NO_SUCH_CODE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
536 /* Only allowed if CrntCode is exactly the running code: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
537 /* In that case CrntCode = XXXCode, CrntCode or the */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
538 /* prefix code is last code and the suffix char is */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
539 /* exactly the prefix of last code! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
540 if (CrntCode == Private->RunningCode - 2) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
541 CrntPrefix = LastCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
542 Suffix[Private->RunningCode - 2] =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
543 Stack[StackPtr++] = DGifGetPrefixChar(Prefix,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
544 LastCode, ClearCode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
545 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
546 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
547 GifInternError(GifFile, D_GIF_ERR_IMAGE_DEFECT);
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
550 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
551 CrntPrefix = CrntCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
552
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
553 /* 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
554 /* During the trace. As we might loop forever, in case of */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
555 /* defective image, we count the number of loops we trace */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
556 /* and stop if we got LZ_MAX_CODE. obviously we can not */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
557 /* loop more than that. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
558 j = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
559 while (j++ <= LZ_MAX_CODE &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
560 CrntPrefix > ClearCode &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
561 CrntPrefix <= LZ_MAX_CODE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
562 Stack[StackPtr++] = Suffix[CrntPrefix];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
563 CrntPrefix = Prefix[CrntPrefix];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
564 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
565 if (j >= LZ_MAX_CODE || CrntPrefix > LZ_MAX_CODE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
566 GifInternError(GifFile, D_GIF_ERR_IMAGE_DEFECT);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
567 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
568 /* Push the last character on stack: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
569 Stack[StackPtr++] = CrntPrefix;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
570
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
571 /* Now lets pop all the stack into output: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
572 while (StackPtr != 0 && i < LineLen)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
573 Line[i++] = Stack[--StackPtr];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
574 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
575 if (LastCode != NO_SUCH_CODE) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
576 Prefix[Private->RunningCode - 2] = LastCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
577
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
578 if (CrntCode == Private->RunningCode - 2) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
579 /* Only allowed if CrntCode is exactly the running code: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
580 /* In that case CrntCode = XXXCode, CrntCode or the */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
581 /* prefix code is last code and the suffix char is */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
582 /* exactly the prefix of last code! */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
583 Suffix[Private->RunningCode - 2] =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
584 DGifGetPrefixChar(Prefix, LastCode, ClearCode);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
585 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
586 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
587 Suffix[Private->RunningCode - 2] =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
588 DGifGetPrefixChar(Prefix, CrntCode, ClearCode);
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 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
591 LastCode = CrntCode;
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
595 Private->LastCode = LastCode;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
596 Private->StackPtr = StackPtr;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
600 * 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
601 * 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
602 * 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
603 * the maximum possible if image O.k. - LZ_MAX_CODE times. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
604 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
605 static int DGifGetPrefixChar(unsigned int *Prefix, int Code, int ClearCode)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
606 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
607 int i = 0;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
608
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
609 while (Code > ClearCode && i++ <= LZ_MAX_CODE) Code = Prefix[Code];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
610 return Code;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
614 * 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
615 * (12bits), or to -1 if EOF code is returned. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
616 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
617 void DGifGetLZCodes(GifFileType *GifFile, int *Code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
618 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
619 GifByteType *CodeBlock;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
620 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
621
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
622 if (!IS_READABLE(Private)) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
623 /* This file was NOT open for reading: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
624 GifInternError(GifFile, D_GIF_ERR_NOT_READABLE);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
627 DGifDecompressInput(GifFile, Code);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
628
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
629 if (*Code == Private->EOFCode) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
630 /* Skip rest of codes (hopefully only NULL terminating block): */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
631 do
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
632 DGifGetCodeNext(GifFile, &CodeBlock);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
633 while (CodeBlock != NULL);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
634
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
635 *Code = -1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
636 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
637 else if (*Code == Private->ClearCode) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
638 /* We need to start over again: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
639 Private->RunningCode = Private->EOFCode + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
640 Private->RunningBits = Private->BitsPerPixel + 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
641 Private->MaxCode1 = 1 << Private->RunningBits;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
646 * The LZ decompression input routine: *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
647 * This routine is responsable for the decompression of the bit stream from *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
648 * 8 bits (bytes) packets, into the real codes. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
649 * Returns GIF_OK if read succesfully. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
650 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
651 static void DGifDecompressInput(GifFileType *GifFile, int *Code)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
652 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
653 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
654 GifByteType NextByte;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
655 static unsigned int CodeMasks[] = {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
656 0x0000, 0x0001, 0x0003, 0x0007,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
657 0x000f, 0x001f, 0x003f, 0x007f,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
658 0x00ff, 0x01ff, 0x03ff, 0x07ff,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
659 0x0fff
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
662 while (Private->CrntShiftState < Private->RunningBits) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
663 /* Needs to get more bytes from input stream for next code: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
664 DGifBufferedInput(GifFile, &NextByte);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
665 Private->CrntShiftDWord |=
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
666 ((unsigned long) NextByte) << Private->CrntShiftState;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
667 Private->CrntShiftState += 8;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
668 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
669 *Code = Private->CrntShiftDWord & CodeMasks[Private->RunningBits];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
670
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
671 Private->CrntShiftDWord >>= Private->RunningBits;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
672 Private->CrntShiftState -= Private->RunningBits;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
673
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
674 /* If code cannt fit into RunningBits bits, must raise its size. Note */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
675 /* however that codes above 4095 are used for special signaling. */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
676 if (++Private->RunningCode > Private->MaxCode1 &&
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
677 Private->RunningBits < LZ_BITS) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
678 Private->MaxCode1 <<= 1;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
679 Private->RunningBits++;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
684 * 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
685 * so that the decompression routine could access it. *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
686 * 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
687 * block in if buffer empty) *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
688 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
689 static void DGifBufferedInput(GifFileType *GifFile, GifByteType *NextByte)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
690 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
691 GifFilePrivateType *Private = (GifFilePrivateType *) GifFile->Private;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
692 GifByteType *Buf = Private->Buf;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
693
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
694 if (Buf[0] == 0) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
695 /* Needs to read the next buffer - this one is empty: */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
696 GifRead(Buf, 1, GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
697 GifRead((Buf + 1), Buf[0], GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
698 *NextByte = Buf[1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
699 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
700 Buf[0]--;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
701 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
702 else {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
703 *NextByte = Buf[Buf[1]++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
704 Buf[0]--;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
709 * 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
710 * the GifFileType pointer. Call DGifOpenFileName() or DGifOpenFileHandle() *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
711 * first to initialize I/O. Its inverse is EGifSpew(). *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
712 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
713 void DGifSlurp(GifFileType *GifFile)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
714 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
715 int ImageSize;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
716 GifRecordType RecordType;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
717 SavedImage *sp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
718 GifByteType *ExtData;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
719
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
720 /* Some versions of malloc dislike 0-length requests */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
721 GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
722 memset(GifFile->SavedImages, 0, sizeof(SavedImage));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
723 sp = &GifFile->SavedImages[0];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
724
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
725 do {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
726 DGifGetRecordType(GifFile, &RecordType);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
727
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
728 switch (RecordType) {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
729 case IMAGE_DESC_RECORD_TYPE:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
730 DGifGetImageDesc(GifFile);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
731
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
732 sp = &GifFile->SavedImages[GifFile->ImageCount-1];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
733 ImageSize = sp->ImageDesc.Width * sp->ImageDesc.Height;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
734
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
735 sp->RasterBits
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
736 = (GifPixelType*) malloc (ImageSize * sizeof(GifPixelType));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
737
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
738 DGifGetLine(GifFile, sp->RasterBits, ImageSize);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
739 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
740
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
741 case EXTENSION_RECORD_TYPE:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
742 DGifGetExtension(GifFile,&sp->Function,&ExtData);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
743
2062
00f374c78661 [xemacs-hg @ 2004-05-06 12:12:12 by malcolmp]
malcolmp
parents: 442
diff changeset
744 while (ExtData != NULL) {
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
745 if (AddExtensionBlock(sp, ExtData[0], ExtData+1) == GIF_ERROR)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
746 GifInternError(GifFile, D_GIF_ERR_NOT_ENOUGH_MEM);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
747 DGifGetExtensionNext(GifFile, &ExtData);
2062
00f374c78661 [xemacs-hg @ 2004-05-06 12:12:12 by malcolmp]
malcolmp
parents: 442
diff changeset
748 }
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
749 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
750
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
751 case TERMINATE_RECORD_TYPE:
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
752 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
753
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
754 default: /* Should be trapped by DGifGetRecordType */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
755 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
756 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
757 } while (RecordType != TERMINATE_RECORD_TYPE);
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
761 * Extension record functions *
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
764 void MakeExtension(SavedImage *New, int Function)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
765 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
766 New->Function = Function;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
767 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
768 * Someday we might have to deal with multiple extensions.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
772 int AddExtensionBlock(SavedImage *New, int Len, GifByteType *data)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
773 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
774 int size;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
775 ExtensionBlock *ep;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
776
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
777 if (New->ExtensionBlocks == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
778 New->ExtensionBlocks = (ExtensionBlock *)malloc(sizeof(ExtensionBlock));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
779 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
780 New->ExtensionBlocks =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
781 (ExtensionBlock *)realloc(New->ExtensionBlocks,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
782 sizeof(ExtensionBlock) * (New->ExtensionBlockCount + 1));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
783
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
784 if (New->ExtensionBlocks == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
785 return(GIF_ERROR);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
786
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
787 ep = &New->ExtensionBlocks[New->ExtensionBlockCount++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
788 ep->ByteCount = Len;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
789 size = Len * sizeof(GifByteType);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
790 ep->Bytes = (GifByteType *)malloc(size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
791 memcpy(ep->Bytes, data, size);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
792 return(GIF_OK);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
795 void FreeExtension(SavedImage *Image)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
796 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
797 ExtensionBlock *ep;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
798
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
799 for (ep = Image->ExtensionBlocks;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
800 ep < Image->ExtensionBlocks + Image->ExtensionBlockCount;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
801 ep++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
802 (void) free((char *)ep->Bytes);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
803 free((char *)Image->ExtensionBlocks);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
804 Image->ExtensionBlocks = NULL;
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
808 * Image block allocation functions *
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
809 ******************************************************************************/
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
810 SavedImage *MakeSavedImage(GifFileType *GifFile, SavedImage *CopyFrom)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
811 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
812 * Append an image block to the SavedImages array
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 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
815 SavedImage *sp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
816
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
817 if (GifFile->SavedImages == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
818 GifFile->SavedImages = (SavedImage *)malloc(sizeof(SavedImage));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
819 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
820 GifFile->SavedImages = (SavedImage *)realloc(GifFile->SavedImages,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
821 sizeof(SavedImage) * (GifFile->ImageCount+1));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
822
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
823 if (GifFile->SavedImages == NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
824 return((SavedImage *)NULL);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
825 else
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
826 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
827 sp = &GifFile->SavedImages[GifFile->ImageCount++];
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
828 memset((char *)sp, '\0', sizeof(SavedImage));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
829
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
830 if (CopyFrom)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
831 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
832 memcpy((char *)sp, CopyFrom, sizeof(SavedImage));
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 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
835 * Make our own allocated copies of the heap fields in the
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
836 * copied record. This guards against potential aliasing
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
837 * problems.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
840 /* first, the local color map */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
841 if (sp->ImageDesc.ColorMap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
842 sp->ImageDesc.ColorMap =
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
843 MakeMapObject(CopyFrom->ImageDesc.ColorMap->ColorCount,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
844 CopyFrom->ImageDesc.ColorMap->Colors);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
845
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
846 /* next, the raster */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
847 sp->RasterBits = (GifPixelType *) malloc(sizeof(GifPixelType)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
848 * CopyFrom->ImageDesc.Height
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
849 * CopyFrom->ImageDesc.Width);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
850 memcpy(sp->RasterBits,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
851 CopyFrom->RasterBits,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
852 sizeof(GifPixelType)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
853 * CopyFrom->ImageDesc.Height
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
854 * CopyFrom->ImageDesc.Width);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
855
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
856 /* finally, the extension blocks */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
857 if (sp->ExtensionBlocks)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
858 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
859 sp->ExtensionBlocks
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
860 = (ExtensionBlock*)malloc(sizeof(ExtensionBlock)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
861 * CopyFrom->ExtensionBlockCount);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
862 memcpy(sp->ExtensionBlocks,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
863 CopyFrom->ExtensionBlocks,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
864 sizeof(ExtensionBlock)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
865 * CopyFrom->ExtensionBlockCount);
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 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
868 * For the moment, the actual blocks can take their
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
869 * chances with free(). We'll fix this later.
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
874 return(sp);
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
878 void FreeSavedImages(GifFileType *GifFile)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
879 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
880 SavedImage *sp;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
881
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
882 for (sp = GifFile->SavedImages;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
883 sp < GifFile->SavedImages + GifFile->ImageCount;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
884 sp++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
885 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
886 if (sp->ImageDesc.ColorMap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
887 FreeMapObject(sp->ImageDesc.ColorMap);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
888
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
889 if (sp->RasterBits)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
890 free((char *)sp->RasterBits);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
891
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
892 if (sp->ExtensionBlocks)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
893 FreeExtension(sp);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
894 }
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
895 free((char *) GifFile->SavedImages);
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
899 * Miscellaneous utility functions *
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
902 static int BitSize(int n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
903 /* return smallest bitfield size n will fit in */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
904 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
905 register int i;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
906
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
907 for (i = 1; i <= 8; i++)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
908 if ((1 << i) >= n)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
909 break;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
910 return(i);
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 /******************************************************************************
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
914 * Color map object functions *
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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
917 ColorMapObject *MakeMapObject(int ColorCount, GifColorType *ColorMap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
918 /*
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
919 * Allocate a color map of given size; initialize with contents of
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
920 * ColorMap if that pointer is non-NULL.
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 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
923 ColorMapObject *Object;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
924
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
925 if (ColorCount != (1 << BitSize(ColorCount)))
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
926 return((ColorMapObject *)NULL);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
927
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
928 Object = (ColorMapObject *)malloc(sizeof(ColorMapObject));
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
929 if (Object == (ColorMapObject *)NULL)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
930 return((ColorMapObject *)NULL);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
931
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
932 Object->Colors = (GifColorType *)calloc(ColorCount, sizeof(GifColorType));
3462
6c7605dfcf07 [xemacs-hg @ 2006-06-19 18:19:33 by james]
james
parents: 2062
diff changeset
933 if (Object->Colors == (GifColorType *)NULL) {
6c7605dfcf07 [xemacs-hg @ 2006-06-19 18:19:33 by james]
james
parents: 2062
diff changeset
934 free(Object);
428
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
935 return((ColorMapObject *)NULL);
3462
6c7605dfcf07 [xemacs-hg @ 2006-06-19 18:19:33 by james]
james
parents: 2062
diff changeset
936 }
428
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 Object->ColorCount = ColorCount;
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
939 Object->BitsPerPixel = BitSize(ColorCount);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
940
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
941 if (ColorMap)
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
942 memcpy((char *)Object->Colors,
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
943 (char *)ColorMap, ColorCount * sizeof(GifColorType));
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 return(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
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
948 void FreeMapObject(ColorMapObject *Object)
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 a color map object
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
951 */
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
952 {
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
953 free(Object->Colors);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
954 free(Object);
3ecd8885ac67 Import from CVS: tag r21-2-22
cvs
parents:
diff changeset
955 }