"Initial commit to Gerrit"
[profile/ivi/libtiff.git] / libtiff / tif_acorn.c
1 /* $Header: /cvs/maptools/cvsroot/libtiff/libtiff/Attic/tif_acorn.c,v 1.2.2.1 2010-06-08 18:50:41 bfriesen Exp $ */
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                 TIFFErrorExt(0, 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;
520 /*
521  * Local Variables:
522  * mode: c
523  * c-basic-offset: 8
524  * fill-column: 78
525  * End:
526  */