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/* 37Low-level file handling 38~~~~~~~~~~~~~~~~~~~~~~~ 39The functions in osfcn.h are unavailable when compiling under C, as it's a 40C++ header. Therefore they have been implemented here. 41 42Now, why have I done it this way? 43 44The definitive API library for RISC OS is Jonathan Coxhead's OSLib, which 45uses heavily optimised ARM assembler or even plain inline SWI calls for 46maximum performance and minimum runtime size. However, I don't want to make 47LIBTIFF need that to survive. Therefore I have also emulated the functions 48using macros to _swi() and _swix() defined in the swis.h header, and 49borrowing types from kernel.h, which is less efficient but doesn't need any 50third-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 */ 68typedef unsigned int bits; 69typedef 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 */ 84typedef _kernel_oserror os_error; 85typedef 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 99extern os_error *xosgbpb_write (os_f file, 100 byte *data, 101 int size, 102 int *unwritten); 103extern 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 122extern os_error *xosgbpb_read (os_f file, 123 byte *buffer, 124 int size, 125 int *unread); 126extern 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 165extern os_error *xosfind_openin (bits flags, 166 char *file_name, 167 char *path, 168 os_f *file); 169extern 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 179extern os_error *xosfind_openout (bits flags, 180 char *file_name, 181 char *path, 182 os_f *file); 183extern 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 193extern os_error *xosfind_openup (bits flags, 194 char *file_name, 195 char *path, 196 os_f *file); 197extern 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 207extern os_error *xosfind_close (os_f file); 208extern 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 230extern os_error *xosargs_read_ptr (os_f file, 231 int *ptr); 232extern 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 245extern os_error *xosargs_set_ptr (os_f file, 246 int ptr); 247extern 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 262extern os_error *xosargs_read_ext (os_f file, 263 int *ext); 264extern 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 285extern 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 320extern int close(int fd) 321{ 322 return ((int) xosfind_close((os_f) fd)); 323} 324 325extern 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 331extern 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 337extern 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 366static 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 372static 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 378static 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 384static int 385_tiffCloseProc(thandle_t fd) 386{ 387 return (close((int) fd)); 388} 389 390static 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 */ 401static 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 408static 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 */ 417TIFF* 418TIFFFdOpen(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 */ 437TIFF* 438TIFFOpen(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 460void* 461_TIFFmalloc(tsize_t s) 462{ 463 return (malloc((size_t) s)); 464} 465 466void 467_TIFFfree(tdata_t p) 468{ 469 free(p); 470} 471 472void* 473_TIFFrealloc(tdata_t p, tsize_t s) 474{ 475 return (realloc(p, (size_t) s)); 476} 477 478void 479_TIFFmemset(tdata_t p, int v, tsize_t c) 480{ 481 memset(p, v, (size_t) c); 482} 483 484void 485_TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c) 486{ 487 memcpy(d, s, (size_t) c); 488} 489 490int 491_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) 492{ 493 return (memcmp(p1, p2, (size_t) c)); 494} 495 496static void 497acornWarningHandler(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} 507TIFFErrorHandler _TIFFwarningHandler = acornWarningHandler; 508 509static void 510acornErrorHandler(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} 519TIFFErrorHandler _TIFFerrorHandler = acornErrorHandler; 520/* 521 * Local Variables: 522 * mode: c 523 * c-basic-offset: 8 524 * fill-column: 78 525 * End: 526 */ 527