Line | Count | Source |
1 | | /* libwmf (bbuf.c): library for wmf conversion |
2 | | Copyright (C) 2000,2001 Francis James Franklin |
3 | | |
4 | | The libwmf Library is free software; you can redistribute it and/or |
5 | | modify it under the terms of the GNU Library General Public License as |
6 | | published by the Free Software Foundation; either version 2 of the |
7 | | License, or (at your option) any later version. |
8 | | |
9 | | The libwmf Library is distributed in the hope that it will be useful, |
10 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | | Library General Public License for more details. |
13 | | |
14 | | You should have received a copy of the GNU Library General Public |
15 | | License along with the libwmf Library; see the file COPYING. If not, |
16 | | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
17 | | Boston, MA 02111-1307, USA. */ |
18 | | |
19 | | |
20 | | #ifdef HAVE_CONFIG_H |
21 | | #include "wmfconfig.h" |
22 | | #endif |
23 | | |
24 | | #include <stdio.h> |
25 | | |
26 | | #include "wmfdefs.h" |
27 | | |
28 | | #include "bbuf.h" |
29 | | |
30 | | /** |
31 | | * Set custom metafile input-stream handler functions. |
32 | | * |
33 | | * @param API the API handle |
34 | | * @param fp_read function to read a byte |
35 | | * @param fp_seek function to set position |
36 | | * @param fp_tell function to get position |
37 | | * @param user_data handle for user data |
38 | | * |
39 | | * \b libwmf has simple methods for reading either from file or from memory, but many applications will want |
40 | | * to use customized variants of these. wmf_bbuf_input() enables this. |
41 | | * |
42 | | * @verbatim |
43 | | typedef int (*wmfRead) (void* user_data); |
44 | | typedef int (*wmfSeek) (void* user_data,long position); |
45 | | typedef long (*wmfTell) (void* user_data); |
46 | | @endverbatim |
47 | | * |
48 | | * \b wmfRead returns unsigned char cast to int, or EOF (cf. fgetc()) |
49 | | * |
50 | | * \b wmfSeek returns (-1) on error, otherwise 0 (cf. fseek()) |
51 | | * |
52 | | * \b wmfTell returns (-1) on error, otherwise current position (cf. ftell()) |
53 | | * |
54 | | * @return Returns the library error state (\b wmf_E_None on success). |
55 | | * Possible library error state of \b wmf_E_Glitch, if any of the three functions is zero. |
56 | | */ |
57 | | wmf_error_t wmf_bbuf_input (wmfAPI* API,wmfRead fp_read,wmfSeek fp_seek,wmfTell fp_tell,void* user_data) |
58 | 11.9k | { if (ERR (API)) return (API->err); |
59 | | |
60 | 11.9k | if ((fp_read == 0) || (fp_seek == 0) || (fp_tell == 0)) |
61 | 0 | { WMF_ERROR (API,"wmf_bbuf_input: null arg. given unexpectedly!"); |
62 | 0 | API->err = wmf_E_Glitch; |
63 | 0 | } |
64 | 11.9k | else |
65 | 11.9k | { API->buffer_data = user_data; |
66 | | |
67 | 11.9k | API->bbuf.read = fp_read; |
68 | 11.9k | API->bbuf.seek = fp_seek; |
69 | 11.9k | API->bbuf.tell = fp_tell; |
70 | 11.9k | } |
71 | | |
72 | 11.9k | return (API->err); |
73 | 11.9k | } |
74 | | |
75 | | /** |
76 | | * Open file as metafile. |
77 | | * |
78 | | * @param API the API handle |
79 | | * @param file file name |
80 | | * |
81 | | * Simple method for reading from file. |
82 | | * |
83 | | * @return Returns the library error state (\b wmf_E_None on success). |
84 | | * Possible library error states of \b wmf_E_Glitch or \b wmf_E_BadFile. |
85 | | */ |
86 | | wmf_error_t wmf_file_open (wmfAPI* API,const char* file) |
87 | 0 | { wmfBBufFileInfo* file_info = 0; |
88 | |
|
89 | 0 | if (ERR (API)) return (API->err); |
90 | | |
91 | 0 | if (API->buffer_data) |
92 | 0 | { WMF_ERROR (API,"wmf_file_open: input stream already open!"); |
93 | 0 | API->err = wmf_E_Glitch; |
94 | 0 | return (API->err); |
95 | 0 | } |
96 | | |
97 | 0 | file_info = (wmfBBufFileInfo*) wmf_malloc (API,sizeof (wmfBBufFileInfo)); |
98 | |
|
99 | 0 | if (ERR (API)) return (API->err); |
100 | | |
101 | 0 | if ((file_info->file = fopen (file,"rb")) == 0) |
102 | 0 | { WMF_ERROR (API,"wmf_file_open: unable to open file for reading."); |
103 | 0 | wmf_free (API,file_info); |
104 | 0 | API->err = wmf_E_BadFile; |
105 | 0 | return (API->err); |
106 | 0 | } |
107 | | |
108 | 0 | wmf_bbuf_input (API,wmf_file_read,wmf_file_seek,wmf_file_tell,(void*) file_info); |
109 | |
|
110 | 0 | if (ERR (API)) |
111 | 0 | { wmf_file_close (API); |
112 | 0 | return (API->err); |
113 | 0 | } |
114 | | |
115 | 0 | API->flags |= API_FILE_OPEN; |
116 | |
|
117 | 0 | return (API->err); |
118 | 0 | } |
119 | | |
120 | | /** |
121 | | * Close metafile input file stream. |
122 | | * |
123 | | * @param API the API handle |
124 | | * |
125 | | * @return Returns the library error state (\b wmf_E_None on success). |
126 | | * Possible library error state of \b wmf_E_Glitch. |
127 | | */ |
128 | | wmf_error_t wmf_file_close (wmfAPI* API) |
129 | 0 | { wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) (API->buffer_data); |
130 | |
|
131 | 0 | if ((API->buffer_data == 0) || ((API->flags & API_FILE_OPEN) == 0)) |
132 | 0 | { WMF_ERROR (API,"wmf_file_close: attempt to close unopened stream!"); |
133 | 0 | API->err = wmf_E_Glitch; |
134 | 0 | return (API->err); |
135 | 0 | } |
136 | | |
137 | 0 | fclose (file_info->file); |
138 | |
|
139 | 0 | API->flags &= ~API_FILE_OPEN; |
140 | |
|
141 | 0 | wmf_free (API,API->buffer_data); |
142 | |
|
143 | 0 | API->buffer_data = 0; |
144 | |
|
145 | 0 | API->bbuf.read = 0; |
146 | 0 | API->bbuf.seek = 0; |
147 | 0 | API->bbuf.tell = 0; |
148 | |
|
149 | 0 | return (API->err); |
150 | 0 | } |
151 | | |
152 | | /** |
153 | | * @internal |
154 | | */ |
155 | | int wmf_file_read (void* user_data) |
156 | 0 | { wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data; |
157 | |
|
158 | 0 | return (fgetc (file_info->file)); |
159 | 0 | } |
160 | | |
161 | | /** |
162 | | * @internal |
163 | | */ |
164 | | int wmf_file_seek (void* user_data,long pos) |
165 | 0 | { wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data; |
166 | |
|
167 | 0 | return (fseek (file_info->file,pos,SEEK_SET)); |
168 | 0 | } |
169 | | |
170 | | /** |
171 | | * @internal |
172 | | */ |
173 | | long wmf_file_tell (void* user_data) |
174 | 0 | { wmfBBufFileInfo* file_info = (wmfBBufFileInfo*) user_data; |
175 | |
|
176 | 0 | return (ftell (file_info->file)); |
177 | 0 | } |
178 | | |
179 | | /** |
180 | | * Open metafile in memory. |
181 | | * |
182 | | * @param API the API handle |
183 | | * @param mem the metafile in memory |
184 | | * @param length the length in bytes of metafile data |
185 | | * |
186 | | * Simple method for reading from memory as array of unsigned char. |
187 | | * |
188 | | * @return Returns the library error state (\b wmf_E_None on success). |
189 | | * Possible library error state of \b wmf_E_Glitch. |
190 | | */ |
191 | | wmf_error_t wmf_mem_open (wmfAPI* API,unsigned char* mem,long length) |
192 | 0 | { wmfBBufMemInfo* mem_info = 0; |
193 | |
|
194 | 0 | if (ERR (API)) return (API->err); |
195 | | |
196 | 0 | if (API->buffer_data) |
197 | 0 | { WMF_ERROR (API,"wmf_mem_open: input stream already open!"); |
198 | 0 | API->err = wmf_E_Glitch; |
199 | 0 | return (API->err); |
200 | 0 | } |
201 | | |
202 | 0 | if ((mem == 0) || (length <= 0)) |
203 | 0 | { WMF_ERROR (API,"wmf_mem_open: null or improper buffer!"); |
204 | 0 | API->err = wmf_E_Glitch; |
205 | 0 | return (API->err); |
206 | 0 | } |
207 | | |
208 | 0 | mem_info = (wmfBBufMemInfo*) wmf_malloc (API,sizeof (wmfBBufMemInfo)); |
209 | |
|
210 | 0 | if (ERR (API)) return (API->err); |
211 | | |
212 | 0 | mem_info->mem = mem; |
213 | 0 | mem_info->ptr = mem; |
214 | |
|
215 | 0 | mem_info->pos = 0; |
216 | 0 | mem_info->length = length; |
217 | |
|
218 | 0 | wmf_bbuf_input (API,wmf_mem_read,wmf_mem_seek,wmf_mem_tell,(void*) mem_info); |
219 | |
|
220 | 0 | if (ERR (API)) |
221 | 0 | { wmf_mem_close (API); |
222 | 0 | return (API->err); |
223 | 0 | } |
224 | | |
225 | 0 | return (API->err); |
226 | 0 | } |
227 | | |
228 | | /** |
229 | | * Close metafile input memory stream. |
230 | | * |
231 | | * @param API the API handle |
232 | | * |
233 | | * @return Returns the library error state (\b wmf_E_None on success). |
234 | | */ |
235 | | wmf_error_t wmf_mem_close (wmfAPI* API) |
236 | 0 | { wmf_free (API,API->buffer_data); |
237 | |
|
238 | 0 | API->buffer_data = 0; |
239 | |
|
240 | 0 | API->bbuf.read = 0; |
241 | 0 | API->bbuf.seek = 0; |
242 | 0 | API->bbuf.tell = 0; |
243 | |
|
244 | 0 | return (API->err); |
245 | 0 | } |
246 | | |
247 | | /** |
248 | | * @internal |
249 | | */ |
250 | | int wmf_mem_read (void* user_data) |
251 | 0 | { int byte = EOF; |
252 | |
|
253 | 0 | wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data; |
254 | |
|
255 | 0 | if (mem_info->pos < mem_info->length) |
256 | 0 | { byte = (int) (*(mem_info->ptr)); |
257 | |
|
258 | 0 | mem_info->ptr++; |
259 | 0 | mem_info->pos++; |
260 | 0 | } |
261 | |
|
262 | 0 | return (byte); |
263 | 0 | } |
264 | | |
265 | | /** |
266 | | * @internal |
267 | | */ |
268 | | int wmf_mem_seek (void* user_data,long pos) |
269 | 0 | { wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data; |
270 | |
|
271 | 0 | if ((pos < 0) || (pos >= mem_info->length)) return (-1); |
272 | | |
273 | 0 | mem_info->ptr = mem_info->mem + pos; |
274 | 0 | mem_info->pos = pos; |
275 | |
|
276 | 0 | return (0); |
277 | 0 | } |
278 | | |
279 | | /** |
280 | | * @internal |
281 | | */ |
282 | | long wmf_mem_tell (void* user_data) |
283 | 0 | { wmfBBufMemInfo* mem_info = (wmfBBufMemInfo*) user_data; |
284 | |
|
285 | 0 | return (mem_info->pos); |
286 | 0 | } |