Mercurial > hg > xemacs-beta
comparison src/gif_io.c @ 308:33bdb3d4b97f r21-0b52
Import from CVS: tag r21-0b52
author | cvs |
---|---|
date | Mon, 13 Aug 2007 10:42:44 +0200 |
parents | |
children | 74fd4e045ea6 |
comparison
equal
deleted
inserted
replaced
307:42d630fd9bd8 | 308:33bdb3d4b97f |
---|---|
1 #include <stdio.h> | |
2 #include <stdlib.h> | |
3 #include <string.h> | |
4 #include <unistd.h> | |
5 #include "gifrlib.h" | |
6 | |
7 /****************************************************************************** | |
8 * Set up the GifFileType structure for use. This must be called first in any * | |
9 * client program. Then, if custom IO or Error functions are desired, call * | |
10 * GifSetIOFunc/GifSetErrorFunc, then call EGifInitWrite. Else call * | |
11 * EGifOpenFileName or EGifOpenFileHandle for standard IO functions. * | |
12 * If setup fails, a NULL pointer is returned. * | |
13 ******************************************************************************/ | |
14 GifFileType *GifSetup(void) | |
15 { | |
16 GifIODataType *GifIO; | |
17 GifFileType *GifFile; | |
18 | |
19 if ((GifFile = (GifFileType *) malloc(sizeof(GifFileType))) == NULL) | |
20 return NULL; | |
21 memset(GifFile, '\0', sizeof(GifFileType)); | |
22 if ((GifIO = (GifIODataType *) malloc(sizeof(GifIODataType))) == NULL) { | |
23 free((char *) GifFile); | |
24 return NULL; | |
25 } | |
26 memset(GifIO, '\0', sizeof(GifIODataType)); | |
27 GifFile->GifIO = GifIO; | |
28 return GifFile; | |
29 } | |
30 | |
31 void GifFree(GifFileType *GifFile) | |
32 { | |
33 GifFilePrivateType *Private; | |
34 | |
35 if (GifFile == NULL) return; | |
36 | |
37 Private = (GifFilePrivateType *) GifFile->Private; | |
38 | |
39 if (GifFile->SavedImages) | |
40 FreeSavedImages(GifFile); | |
41 if (GifFile->Image.ColorMap) | |
42 FreeMapObject(GifFile->Image.ColorMap); | |
43 if (GifFile->SColorMap) | |
44 FreeMapObject(GifFile->SColorMap); | |
45 if (Private) | |
46 { | |
47 free(Private); | |
48 } | |
49 if (GifFile->GifIO) | |
50 free(GifFile->GifIO); | |
51 free(GifFile); | |
52 } | |
53 | |
54 /**************************************************************************** | |
55 * Install the specified ReadFunction into the GifFile specified. * | |
56 ****************************************************************************/ | |
57 void GifSetReadFunc(GifFileType *GifFile, Gif_rw_func ReadFunc, VoidPtr data) | |
58 { | |
59 GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO; | |
60 GifIO->ReadFunc = ReadFunc; | |
61 GifIO->ReadFunc_data = data; | |
62 } | |
63 | |
64 /**************************************************************************** | |
65 * Install the specified WriteFunction into the GifFile specified. * | |
66 ****************************************************************************/ | |
67 void GifSetWriteFunc(GifFileType *GifFile, Gif_rw_func WriteFunc, VoidPtr data) | |
68 { | |
69 GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO; | |
70 GifIO->WriteFunc = WriteFunc; | |
71 GifIO->WriteFunc_data = data; | |
72 } | |
73 | |
74 /**************************************************************************** | |
75 * Install the specified CloseFunction into the GifFile specified. * | |
76 ****************************************************************************/ | |
77 void GifSetCloseFunc(GifFileType *GifFile, Gif_close_func CloseFunc, VoidPtr data) | |
78 { | |
79 GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO; | |
80 GifIO->CloseFunc = CloseFunc; | |
81 GifIO->CloseFunc_data = data; | |
82 } | |
83 | |
84 /**************************************************************************** | |
85 * Install the standard IO funcs into the GifFile, including the FILE info * | |
86 ****************************************************************************/ | |
87 void GifStdIOInit(GifFileType *GifFile, FILE *file, int filehandle) | |
88 { | |
89 GifStdIODataType *IOData; | |
90 | |
91 if ((IOData = (GifStdIODataType*)malloc(sizeof(GifStdIODataType))) == NULL) | |
92 GifInternError(GifFile, GIF_ERR_NOT_ENOUGH_MEM); | |
93 IOData->File = file; | |
94 IOData->FileHandle = filehandle; | |
95 GifSetReadFunc(GifFile, GifStdRead, IOData); | |
96 GifSetWriteFunc(GifFile, GifStdWrite, IOData); | |
97 GifSetCloseFunc(GifFile, GifStdFileClose, IOData); | |
98 } | |
99 | |
100 size_t GifStdRead(GifByteType *buf, size_t size, VoidPtr method_data) | |
101 { | |
102 GifStdIODataType *IOtype = (GifStdIODataType*)method_data; | |
103 return (fread(buf, 1, size, IOtype->File)); | |
104 } | |
105 | |
106 size_t GifStdWrite(GifByteType *buf, size_t size, VoidPtr method_data) | |
107 { | |
108 GifStdIODataType *IOtype = (GifStdIODataType*)method_data; | |
109 return (fwrite(buf, 1, size, IOtype->File)); | |
110 } | |
111 | |
112 int GifStdFileClose(VoidPtr method_data) | |
113 { | |
114 int ret; | |
115 GifStdIODataType *IOtype = (GifStdIODataType*)method_data; | |
116 ret = fclose(IOtype->File); | |
117 if (ret == 0 && IOtype->FileHandle != -1) | |
118 ret = close(IOtype->FileHandle); | |
119 return ret; | |
120 } | |
121 | |
122 void GifRead(GifByteType *buf, size_t size, GifFileType *GifFile) | |
123 { | |
124 GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO; | |
125 if ((*(GifIO->ReadFunc))(buf, size, GifIO->ReadFunc_data) != size) | |
126 GifError(GifFile, "Read error!"); | |
127 } | |
128 | |
129 void GifWrite(GifByteType *buf, size_t size, GifFileType *GifFile) | |
130 { | |
131 GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO; | |
132 if ((*(GifIO->WriteFunc))(buf, size, GifIO->WriteFunc_data) != size) | |
133 GifError(GifFile, "Write error!"); | |
134 } | |
135 | |
136 int GifClose(GifFileType *GifFile) | |
137 { | |
138 GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO; | |
139 return ((*(GifIO->CloseFunc))(GifIO->CloseFunc_data)); | |
140 } | |
141 | |
142 static char *GifErrorString[14] = { | |
143 "Failed to open given file", /* D_GIF_ERR_OPEN_FAILED */ | |
144 "Failed to read from given file", /* D_GIF_ERR_READ_FAILED */ | |
145 "Given file is NOT a GIF file", /* D_GIF_ERR_NOT_GIF_FILE */ | |
146 "No Screen Descriptor detected", /* D_GIF_ERR_NO_SCRN_DSCR */ | |
147 "No Image Descriptor detected", /* D_GIF_ERR_NO_IMAG_DSCR */ | |
148 "No global or local color map", /* D_GIF_ERR_NO_COLOR_MAP */ | |
149 "Wrong record type detected", /* D_GIF_ERR_WRONG_RECORD */ | |
150 "#Pixels bigger than Width * Height", /* D_GIF_ERR_DATA_TOO_BIG */ | |
151 "Fail to allocate required memory", /* D_GIF_ERR_NOT_ENOUGH_MEM */ | |
152 "Failed to close given file", /* D_GIF_ERR_CLOSE_FAILED */ | |
153 "Given file was not opened for read", /* D_GIF_ERR_CLOSE_FAILED */ | |
154 "Image is defective, decoding aborted", /* D_GIF_ERR_IMAGE_DEFECT */ | |
155 "Image EOF detected before image complete", /* D_GIF_ERR_EOF_TOO_SOON */ | |
156 "Undefined error!", | |
157 }; | |
158 | |
159 const char *GetGifError(int error); | |
160 | |
161 /***************************************************************************** | |
162 * Get the last GIF error in human-readable form. * | |
163 *****************************************************************************/ | |
164 const char *GetGifError(int error) | |
165 { | |
166 char *Err; | |
167 | |
168 switch(error) { | |
169 case D_GIF_ERR_OPEN_FAILED: | |
170 Err = GifErrorString[0]; | |
171 break; | |
172 case D_GIF_ERR_READ_FAILED: | |
173 Err = GifErrorString[1]; | |
174 break; | |
175 case D_GIF_ERR_NOT_GIF_FILE: | |
176 Err = GifErrorString[2]; | |
177 break; | |
178 case D_GIF_ERR_NO_SCRN_DSCR: | |
179 Err = GifErrorString[3]; | |
180 break; | |
181 case D_GIF_ERR_NO_IMAG_DSCR: | |
182 Err = GifErrorString[4]; | |
183 break; | |
184 case D_GIF_ERR_NO_COLOR_MAP: | |
185 Err = GifErrorString[5]; | |
186 break; | |
187 case D_GIF_ERR_WRONG_RECORD: | |
188 Err = GifErrorString[6]; | |
189 break; | |
190 case D_GIF_ERR_DATA_TOO_BIG: | |
191 Err = GifErrorString[7]; | |
192 break; | |
193 case D_GIF_ERR_NOT_ENOUGH_MEM: | |
194 Err = GifErrorString[8]; | |
195 break; | |
196 case D_GIF_ERR_CLOSE_FAILED: | |
197 Err = GifErrorString[9]; | |
198 break; | |
199 case D_GIF_ERR_NOT_READABLE: | |
200 Err = GifErrorString[10]; | |
201 break; | |
202 case D_GIF_ERR_IMAGE_DEFECT: | |
203 Err = GifErrorString[11]; | |
204 break; | |
205 case D_GIF_ERR_EOF_TOO_SOON: | |
206 Err = GifErrorString[12]; | |
207 break; | |
208 default: | |
209 Err = GifErrorString[13]; | |
210 break; | |
211 } | |
212 return Err; | |
213 } | |
214 | |
215 /****************************** | |
216 * These are called internally * | |
217 ******************************/ | |
218 void GifError(GifFileType *GifFile, const char *err_str) | |
219 { | |
220 GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO; | |
221 if (GifIO->ErrorFunc) | |
222 (*(GifIO->ErrorFunc))(err_str, GifIO->ErrorFunc_data); | |
223 else | |
224 fprintf(stderr, "GIF FATAL ERROR: %s", err_str); | |
225 exit(-10); | |
226 } | |
227 | |
228 void GifWarning(GifFileType *GifFile, const char *err_str) | |
229 { | |
230 GifIODataType *GifIO = (GifIODataType*)GifFile->GifIO; | |
231 if (GifIO->WarningFunc) | |
232 (*(GifIO->WarningFunc))(err_str, GifIO->WarningFunc_data); | |
233 } | |
234 | |
235 void GifInternError(GifFileType *GifFile, int error_num) | |
236 { | |
237 const char *ErrStr = GetGifError(error_num); | |
238 GifError(GifFile, ErrStr); | |
239 } | |
240 | |
241 void GifInternWarning(GifFileType *GifFile, int error_num) | |
242 { | |
243 const char *ErrStr = GetGifError(error_num); | |
244 GifWarning(GifFile, ErrStr); | |
245 } | |
246 | |
247 void GifSetErrorFunc(GifFileType *GifFile, Gif_error_func ErrorFunc, VoidPtr data) | |
248 { | |
249 GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO; | |
250 GifIO->ErrorFunc = ErrorFunc; | |
251 GifIO->ErrorFunc_data = data; | |
252 } | |
253 | |
254 void GifSetWarningFunc(GifFileType *GifFile, Gif_error_func WarningFunc, VoidPtr data) | |
255 { | |
256 GifIODataType *GifIO = (GifIODataType *)GifFile->GifIO; | |
257 GifIO->WarningFunc = WarningFunc; | |
258 GifIO->WarningFunc_data = data; | |
259 } |