]>
Commit | Line | Data |
---|---|---|
1 | /* $Header$ */ | |
2 | ||
3 | /* | |
4 | * Copyright (c) 1988-1997 Sam Leffler | |
5 | * Copyright (c) 1991-1997 Silicon Graphics, Inc. | |
6 | * | |
7 | * Permission to use, copy, modify, distribute, and sell this software and | |
8 | * its documentation for any purpose is hereby granted without fee, provided | |
9 | * that (i) the above copyright notices and this permission notice appear in | |
10 | * all copies of the software and related documentation, and (ii) the names of | |
11 | * Sam Leffler and Silicon Graphics may not be used in any advertising or | |
12 | * publicity relating to the software without the specific, prior written | |
13 | * permission of Sam Leffler and Silicon Graphics. | |
14 | * | |
15 | * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, | |
16 | * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY | |
17 | * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. | |
18 | * | |
19 | * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR | |
20 | * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, | |
21 | * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
22 | * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF | |
23 | * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE | |
24 | * OF THIS SOFTWARE. | |
25 | */ | |
26 | ||
27 | /* | |
28 | * TIFF Library RISC OS specific Routines. | |
29 | * Developed out of the Unix version. | |
30 | * Peter Greenham, May 1995 | |
31 | */ | |
32 | #include "tiffiop.h" | |
33 | #include <stdio.h> | |
34 | #include <stdlib.h> | |
35 | ||
36 | /* | |
37 | Low-level file handling | |
38 | ~~~~~~~~~~~~~~~~~~~~~~~ | |
39 | The functions in osfcn.h are unavailable when compiling under C, as it's a | |
40 | C++ header. Therefore they have been implemented here. | |
41 | ||
42 | Now, why have I done it this way? | |
43 | ||
44 | The definitive API library for RISC OS is Jonathan Coxhead's OSLib, which | |
45 | uses heavily optimised ARM assembler or even plain inline SWI calls for | |
46 | maximum performance and minimum runtime size. However, I don't want to make | |
47 | LIBTIFF need that to survive. Therefore I have also emulated the functions | |
48 | using macros to _swi() and _swix() defined in the swis.h header, and | |
49 | borrowing types from kernel.h, which is less efficient but doesn't need any | |
50 | third-party libraries. | |
51 | */ | |
52 | ||
53 | #ifdef INCLUDE_OSLIB | |
54 | ||
55 | #include "osfile.h" | |
56 | #include "osgbpb.h" | |
57 | #include "osargs.h" | |
58 | #include "osfind.h" | |
59 | ||
60 | #else | |
61 | ||
62 | /* OSLIB EMULATION STARTS */ | |
63 | ||
64 | #include "kernel.h" | |
65 | #include "swis.h" | |
66 | ||
67 | /* From oslib:types.h */ | |
68 | typedef unsigned int bits; | |
69 | typedef unsigned char byte; | |
70 | #ifndef TRUE | |
71 | #define TRUE 1 | |
72 | #endif | |
73 | #ifndef FALSE | |
74 | #define FALSE 0 | |
75 | #endif | |
76 | #ifndef NULL | |
77 | #define NULL 0 | |
78 | #endif | |
79 | #ifndef SKIP | |
80 | #define SKIP 0 | |
81 | #endif | |
82 | ||
83 | /* From oslib:os.h */ | |
84 | typedef _kernel_oserror os_error; | |
85 | typedef byte os_f; | |
86 | ||
87 | /* From oslib:osfile.h */ | |
88 | #undef OS_File | |
89 | #define OS_File 0x8 | |
90 | ||
91 | /* From oslib:osgbpb.h */ | |
92 | #undef OS_GBPB | |
93 | #define OS_GBPB 0xC | |
94 | #undef OSGBPB_Write | |
95 | #define OSGBPB_Write 0x2 | |
96 | #undef OSGBPB_Read | |
97 | #define OSGBPB_Read 0x4 | |
98 | ||
99 | extern os_error *xosgbpb_write (os_f file, | |
100 | byte *data, | |
101 | int size, | |
102 | int *unwritten); | |
103 | extern int osgbpb_write (os_f file, | |
104 | byte *data, | |
105 | int size); | |
106 | ||
107 | #define xosgbpb_write(file, data, size, unwritten) \ | |
108 | (os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_IN(4)|_OUT(3), \ | |
109 | OSGBPB_WriteAt, \ | |
110 | file, \ | |
111 | data, \ | |
112 | size, \ | |
113 | unwritten) | |
114 | ||
115 | #define osgbpb_write(file, data, size) \ | |
116 | _swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \ | |
117 | OSGBPB_Write, \ | |
118 | file, \ | |
119 | data, \ | |
120 | size) | |
121 | ||
122 | extern os_error *xosgbpb_read (os_f file, | |
123 | byte *buffer, | |
124 | int size, | |
125 | int *unread); | |
126 | extern int osgbpb_read (os_f file, | |
127 | byte *buffer, | |
128 | int size); | |
129 | ||
130 | #define xosgbpb_read(file, buffer, size, unread) \ | |
131 | (os_error*) _swix(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_OUT(3), \ | |
132 | OSGBPB_Read, \ | |
133 | file, \ | |
134 | buffer, \ | |
135 | size, \ | |
136 | unread) | |
137 | ||
138 | #define osgbpb_read(file, buffer, size) \ | |
139 | _swi(OS_GBPB, _IN(0)|_IN(1)|_IN(2)|_IN(3)|_RETURN(3), \ | |
140 | OSGBPB_Read, \ | |
141 | file, \ | |
142 | buffer, \ | |
143 | size) | |
144 | ||
145 | /* From oslib:osfind.h */ | |
146 | #undef OS_Find | |
147 | #define OS_Find 0xD | |
148 | #undef OSFind_Openin | |
149 | #define OSFind_Openin 0x40 | |
150 | #undef OSFind_Openout | |
151 | #define OSFind_Openout 0x80 | |
152 | #undef OSFind_Openup | |
153 | #define OSFind_Openup 0xC0 | |
154 | #undef OSFind_Close | |
155 | #define OSFind_Close 0x0 | |
156 | ||
157 | #define xosfind_open(reason, file_name, path, file) \ | |
158 | (os_error*) _swix(OS_Find, _IN(0)|_IN(1)|_IN(2)|_OUT(0), \ | |
159 | reason, file_name, path, file) | |
160 | ||
161 | #define osfind_open(reason, file_name, path) \ | |
162 | (os_f) _swi(OS_Find, _IN(0)|_IN(1)|_IN(2)|_RETURN(0), \ | |
163 | reason, file_name, path) | |
164 | ||
165 | extern os_error *xosfind_openin (bits flags, | |
166 | char *file_name, | |
167 | char *path, | |
168 | os_f *file); | |
169 | extern os_f osfind_openin (bits flags, | |
170 | char *file_name, | |
171 | char *path); | |
172 | ||
173 | #define xosfind_openin(flags, file_name, path, file) \ | |
174 | xosfind_open(flags | OSFind_Openin, file_name, path, file) | |
175 | ||
176 | #define osfind_openin(flags, file_name, path) \ | |
177 | osfind_open(flags | OSFind_Openin, file_name, path) | |
178 | ||
179 | extern os_error *xosfind_openout (bits flags, | |
180 | char *file_name, | |
181 | char *path, | |
182 | os_f *file); | |
183 | extern os_f osfind_openout (bits flags, | |
184 | char *file_name, | |
185 | char *path); | |
186 | ||
187 | #define xosfind_openout(flags, file_name, path, file) \ | |
188 | xosfind_open(flags | OSFind_Openout, file_name, path, file) | |
189 | ||
190 | #define osfind_openout(flags, file_name, path) \ | |
191 | osfind_open(flags | OSFind_Openout, file_name, path) | |
192 | ||
193 | extern os_error *xosfind_openup (bits flags, | |
194 | char *file_name, | |
195 | char *path, | |
196 | os_f *file); | |
197 | extern os_f osfind_openup (bits flags, | |
198 | char *file_name, | |
199 | char *path); | |
200 | ||
201 | #define xosfind_openup(flags, file_name, path, file) \ | |
202 | xosfind_open(flags | OSFind_Openup, file_name, path, file) | |
203 | ||
204 | #define osfind_openup(flags, file_name, path) \ | |
205 | osfind_open(flags | OSFind_Openup, file_name, path) | |
206 | ||
207 | extern os_error *xosfind_close (os_f file); | |
208 | extern void osfind_close (os_f file); | |
209 | ||
210 | #define xosfind_close(file) \ | |
211 | (os_error*) _swix(OS_Find, _IN(0)|_IN(1), \ | |
212 | OSFind_Close, \ | |
213 | file) | |
214 | ||
215 | #define osfind_close(file) \ | |
216 | (void) _swi(OS_Find, _IN(0)|_IN(1), \ | |
217 | OSFind_Close, \ | |
218 | file) | |
219 | ||
220 | /* From oslib:osargs.h */ | |
221 | #undef OS_Args | |
222 | #define OS_Args 0x9 | |
223 | #undef OSArgs_ReadPtr | |
224 | #define OSArgs_ReadPtr 0x0 | |
225 | #undef OSArgs_SetPtr | |
226 | #define OSArgs_SetPtr 0x1 | |
227 | #undef OSArgs_ReadExt | |
228 | #define OSArgs_ReadExt 0x2 | |
229 | ||
230 | extern os_error *xosargs_read_ptr (os_f file, | |
231 | int *ptr); | |
232 | extern int osargs_read_ptr (os_f file); | |
233 | ||
234 | #define xosargs_read_ptr(file, ptr) \ | |
235 | (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \ | |
236 | OSArgs_ReadPtr, \ | |
237 | file, \ | |
238 | ptr) | |
239 | ||
240 | #define osargs_read_ptr(file) \ | |
241 | _swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \ | |
242 | OSArgs_ReadPtr, \ | |
243 | file) | |
244 | ||
245 | extern os_error *xosargs_set_ptr (os_f file, | |
246 | int ptr); | |
247 | extern void osargs_set_ptr (os_f file, | |
248 | int ptr); | |
249 | ||
250 | #define xosargs_set_ptr(file, ptr) \ | |
251 | (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_IN(2), \ | |
252 | OSArgs_SetPtr, \ | |
253 | file, \ | |
254 | ptr) | |
255 | ||
256 | #define osargs_set_ptr(file, ptr) \ | |
257 | (void) _swi(OS_Args, _IN(0)|_IN(1)|_IN(2), \ | |
258 | OSArgs_SetPtr, \ | |
259 | file, \ | |
260 | ptr) | |
261 | ||
262 | extern os_error *xosargs_read_ext (os_f file, | |
263 | int *ext); | |
264 | extern int osargs_read_ext (os_f file); | |
265 | ||
266 | #define xosargs_read_ext(file, ext) \ | |
267 | (os_error*) _swix(OS_Args, _IN(0)|_IN(1)|_OUT(2), \ | |
268 | OSArgs_ReadExt, \ | |
269 | file, \ | |
270 | ext) | |
271 | ||
272 | #define osargs_read_ext(file) \ | |
273 | _swi(OS_Args, _IN(0)|_IN(1)|_RETURN(2), \ | |
274 | OSArgs_ReadExt, \ | |
275 | file) | |
276 | ||
277 | /* OSLIB EMULATION ENDS */ | |
278 | ||
279 | #endif | |
280 | ||
281 | #ifndef __osfcn_h | |
282 | /* Will be set or not during tiffcomp.h */ | |
283 | /* You get this to compile under C++? Please say how! */ | |
284 | ||
285 | extern int open(const char* name, int flags, int mode) | |
286 | { | |
287 | /* From what I can tell, should return <0 for failure */ | |
288 | os_error* e = (os_error*) 1; /* Cheeky way to use a pointer eh? :-) */ | |
289 | os_f file = (os_f) -1; | |
290 | ||
291 | flags = flags; | |
292 | ||
293 | switch(mode) | |
294 | { | |
295 | case O_RDONLY: | |
296 | { | |
297 | e = xosfind_openin(SKIP, name, SKIP, &file); | |
298 | break; | |
299 | } | |
300 | case O_WRONLY: | |
301 | case O_RDWR|O_CREAT: | |
302 | case O_RDWR|O_CREAT|O_TRUNC: | |
303 | { | |
304 | e = xosfind_openout(SKIP, name, SKIP, &file); | |
305 | break; | |
306 | } | |
307 | case O_RDWR: | |
308 | { | |
309 | e = xosfind_openup(SKIP, name, SKIP, &file); | |
310 | break; | |
311 | } | |
312 | } | |
313 | if (e) | |
314 | { | |
315 | file = (os_f) -1; | |
316 | } | |
317 | return (file); | |
318 | } | |
319 | ||
320 | extern int close(int fd) | |
321 | { | |
322 | return ((int) xosfind_close((os_f) fd)); | |
323 | } | |
324 | ||
325 | extern int write(int fd, const char *buf, int nbytes) | |
326 | { | |
327 | /* Returns number of bytes written */ | |
328 | return (nbytes - osgbpb_write((os_f) fd, (const byte*) buf, nbytes)); | |
329 | } | |
330 | ||
331 | extern int read(int fd, char *buf, int nbytes) | |
332 | { | |
333 | /* Returns number of bytes read */ | |
334 | return (nbytes - osgbpb_read((os_f) fd, (byte*) buf, nbytes)); | |
335 | } | |
336 | ||
337 | extern off_t lseek(int fd, off_t offset, int whence) | |
338 | { | |
339 | int absolute = 0; | |
340 | ||
341 | switch (whence) | |
342 | { | |
343 | case SEEK_SET: | |
344 | { | |
345 | absolute = (int) offset; | |
346 | break; | |
347 | } | |
348 | case SEEK_CUR: | |
349 | { | |
350 | absolute = osargs_read_ptr((os_f) fd) + (int) offset; | |
351 | break; | |
352 | } | |
353 | case SEEK_END: | |
354 | { | |
355 | absolute = osargs_read_ext((os_f) fd) + (int) offset; | |
356 | break; | |
357 | } | |
358 | } | |
359 | ||
360 | osargs_set_ptr((os_f) fd, absolute); | |
361 | ||
362 | return ((off_t) osargs_read_ptr((os_f) fd)); | |
363 | } | |
364 | #endif | |
365 | ||
366 | static tsize_t | |
367 | _tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) | |
368 | { | |
369 | return ((tsize_t) read((int) fd, buf, (size_t) size)); | |
370 | } | |
371 | ||
372 | static tsize_t | |
373 | _tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) | |
374 | { | |
375 | return ((tsize_t) write((int) fd, buf, (size_t) size)); | |
376 | } | |
377 | ||
378 | static toff_t | |
379 | _tiffSeekProc(thandle_t fd, toff_t off, int whence) | |
380 | { | |
381 | return ((toff_t) lseek((int) fd, (off_t) off, whence)); | |
382 | } | |
383 | ||
384 | static int | |
385 | _tiffCloseProc(thandle_t fd) | |
386 | { | |
387 | return (close((int) fd)); | |
388 | } | |
389 | ||
390 | static toff_t | |
391 | _tiffSizeProc(thandle_t fd) | |
392 | { | |
393 | return (lseek((int) fd, SEEK_END, SEEK_SET)); | |
394 | } | |
395 | ||
396 | #ifdef HAVE_MMAP | |
397 | #error "I didn't know Acorn had that!" | |
398 | #endif | |
399 | ||
400 | /* !HAVE_MMAP */ | |
401 | static int | |
402 | _tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) | |
403 | { | |
404 | (void) fd; (void) pbase; (void) psize; | |
405 | return (0); | |
406 | } | |
407 | ||
408 | static void | |
409 | _tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) | |
410 | { | |
411 | (void) fd; (void) base; (void) size; | |
412 | } | |
413 | ||
414 | /* | |
415 | * Open a TIFF file descriptor for read/writing. | |
416 | */ | |
417 | TIFF* | |
418 | TIFFFdOpen(int fd, const char* name, const char* mode) | |
419 | { | |
420 | TIFF* tif; | |
421 | ||
422 | tif = TIFFClientOpen(name, mode, | |
423 | (thandle_t) fd, | |
424 | _tiffReadProc, _tiffWriteProc, | |
425 | _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, | |
426 | _tiffMapProc, _tiffUnmapProc); | |
427 | if (tif) | |
428 | { | |
429 | tif->tif_fd = fd; | |
430 | } | |
431 | return (tif); | |
432 | } | |
433 | ||
434 | /* | |
435 | * Open a TIFF file for read/writing. | |
436 | */ | |
437 | TIFF* | |
438 | TIFFOpen(const char* name, const char* mode) | |
439 | { | |
440 | static const char module[] = "TIFFOpen"; | |
441 | int m, fd; | |
442 | ||
443 | m = _TIFFgetMode(mode, module); | |
444 | ||
445 | if (m == -1) | |
446 | { | |
447 | return ((TIFF*) 0); | |
448 | } | |
449 | ||
450 | fd = open(name, 0, m); | |
451 | ||
452 | if (fd < 0) | |
453 | { | |
454 | TIFFError(module, "%s: Cannot open", name); | |
455 | return ((TIFF *)0); | |
456 | } | |
457 | return (TIFFFdOpen(fd, name, mode)); | |
458 | } | |
459 | ||
460 | void* | |
461 | _TIFFmalloc(tsize_t s) | |
462 | { | |
463 | return (malloc((size_t) s)); | |
464 | } | |
465 | ||
466 | void | |
467 | _TIFFfree(tdata_t p) | |
468 | { | |
469 | free(p); | |
470 | } | |
471 | ||
472 | void* | |
473 | _TIFFrealloc(tdata_t p, tsize_t s) | |
474 | { | |
475 | return (realloc(p, (size_t) s)); | |
476 | } | |
477 | ||
478 | void | |
479 | _TIFFmemset(tdata_t p, int v, tsize_t c) | |
480 | { | |
481 | memset(p, v, (size_t) c); | |
482 | } | |
483 | ||
484 | void | |
485 | _TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) | |
486 | { | |
487 | memcpy(d, s, (size_t) c); | |
488 | } | |
489 | ||
490 | int | |
491 | _TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) | |
492 | { | |
493 | return (memcmp(p1, p2, (size_t) c)); | |
494 | } | |
495 | ||
496 | static void | |
497 | acornWarningHandler(const char* module, const char* fmt, va_list ap) | |
498 | { | |
499 | if (module != NULL) | |
500 | { | |
501 | fprintf(stderr, "%s: ", module); | |
502 | } | |
503 | fprintf(stderr, "Warning, "); | |
504 | vfprintf(stderr, fmt, ap); | |
505 | fprintf(stderr, ".\n"); | |
506 | } | |
507 | TIFFErrorHandler _TIFFwarningHandler = acornWarningHandler; | |
508 | ||
509 | static void | |
510 | acornErrorHandler(const char* module, const char* fmt, va_list ap) | |
511 | { | |
512 | if (module != NULL) | |
513 | { | |
514 | fprintf(stderr, "%s: ", module); | |
515 | } | |
516 | vfprintf(stderr, fmt, ap); | |
517 | fprintf(stderr, ".\n"); | |
518 | } | |
519 | TIFFErrorHandler _TIFFerrorHandler = acornErrorHandler; |