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