1 /* 2 * Copyright (c) 1988-1997 Sam Leffler 3 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and 6 * its documentation for any purpose is hereby granted without fee, provided 7 * that (i) the above copyright notices and this permission notice appear in 8 * all copies of the software and related documentation, and (ii) the names of 9 * Sam Leffler and Silicon Graphics may not be used in any advertising or 10 * publicity relating to the software without the specific, prior written 11 * permission of Sam Leffler and Silicon Graphics. 12 * 13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 */ 24 25 /* 26 * TIFF Library UNIX-specific Routines. These are should also work with the 27 * Windows Common RunTime Library. 28 */ 29 30 #include "tif_config.h" 31 32 #ifdef HAVE_SYS_TYPES_H 33 # include <sys/types.h> 34 #endif 35 36 #include <errno.h> 37 38 #include <stdarg.h> 39 #include <stdlib.h> 40 #include <sys/stat.h> 41 42 #ifdef HAVE_UNISTD_H 43 # include <unistd.h> 44 #endif 45 46 #ifdef HAVE_FCNTL_H 47 # include <fcntl.h> 48 #endif 49 50 #ifdef HAVE_IO_H 51 # include <io.h> 52 #endif 53 54 #include "tiffiop.h" 55 56 57 #define TIFF_IO_MAX 2147483647U 58 59 60 typedef union fd_as_handle_union 61 { 62 int fd; 63 thandle_t h; 64 } fd_as_handle_union_t; 65 66 static tmsize_t 67 _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) 68 { 69 fd_as_handle_union_t fdh; 70 const size_t bytes_total = (size_t) size; 71 size_t bytes_read; 72 tmsize_t count = -1; 73 if ((tmsize_t) bytes_total != size) 74 { 75 errno=EINVAL; 76 return (tmsize_t) -1; 77 } 78 fdh.h = fd; 79 for (bytes_read=0; bytes_read < bytes_total; bytes_read+=count) 80 { 81 char *buf_offset = (char *) buf+bytes_read; 82 size_t io_size = bytes_total-bytes_read; 83 if (io_size > TIFF_IO_MAX) 84 io_size = TIFF_IO_MAX; 85 count=read(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); 86 if (count <= 0) 87 break; 88 } 89 if (count < 0) 90 return (tmsize_t)-1; 91 return (tmsize_t) bytes_read; 92 } 93 94 static tmsize_t 95 _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) 96 { 97 fd_as_handle_union_t fdh; 98 const size_t bytes_total = (size_t) size; 99 size_t bytes_written; 100 tmsize_t count = -1; 101 if ((tmsize_t) bytes_total != size) 102 { 103 errno=EINVAL; 104 return (tmsize_t) -1; 105 } 106 fdh.h = fd; 107 for (bytes_written=0; bytes_written < bytes_total; bytes_written+=count) 108 { 109 const char *buf_offset = (char *) buf+bytes_written; 110 size_t io_size = bytes_total-bytes_written; 111 if (io_size > TIFF_IO_MAX) 112 io_size = TIFF_IO_MAX; 113 count=write(fdh.fd, buf_offset, (TIFFIOSize_t) io_size); 114 if (count <= 0) 115 break; 116 } 117 if (count < 0) 118 return (tmsize_t)-1; 119 return (tmsize_t) bytes_written; 120 /* return ((tmsize_t) write(fdh.fd, buf, bytes_total)); */ 121 } 122 123 static uint64 124 _tiffSeekProc(thandle_t fd, uint64 off, int whence) 125 { 126 fd_as_handle_union_t fdh; 127 _TIFF_off_t off_io = (_TIFF_off_t) off; 128 if ((uint64) off_io != off) 129 { 130 errno=EINVAL; 131 return (uint64) -1; /* this is really gross */ 132 } 133 fdh.h = fd; 134 return((uint64)_TIFF_lseek_f(fdh.fd,off_io,whence)); 135 } 136 137 static int 138 _tiffCloseProc(thandle_t fd) 139 { 140 fd_as_handle_union_t fdh; 141 fdh.h = fd; 142 return(close(fdh.fd)); 143 } 144 145 static uint64 146 _tiffSizeProc(thandle_t fd) 147 { 148 _TIFF_stat_s sb; 149 fd_as_handle_union_t fdh; 150 fdh.h = fd; 151 if (_TIFF_fstat_f(fdh.fd,&sb)<0) 152 return(0); 153 else 154 return((uint64)sb.st_size); 155 } 156 157 #ifdef HAVE_MMAP 158 #include <sys/mman.h> 159 160 static int 161 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 162 { 163 uint64 size64 = _tiffSizeProc(fd); 164 tmsize_t sizem = (tmsize_t)size64; 165 if ((uint64)sizem==size64) { 166 fd_as_handle_union_t fdh; 167 fdh.h = fd; 168 *pbase = (void*) 169 mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, fdh.fd, 0); 170 if (*pbase != (void*) -1) { 171 *psize = (tmsize_t)sizem; 172 return (1); 173 } 174 } 175 return (0); 176 } 177 178 static void 179 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 180 { 181 (void) fd; 182 (void) munmap(base, (off_t) size); 183 } 184 #else /* !HAVE_MMAP */ 185 static int 186 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 187 { 188 (void) fd; (void) pbase; (void) psize; 189 return (0); 190 } 191 192 static void 193 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 194 { 195 (void) fd; (void) base; (void) size; 196 } 197 #endif /* !HAVE_MMAP */ 198 199 /* 200 * Open a TIFF file descriptor for read/writing. 201 */ 202 TIFF* 203 TIFFFdOpen(int fd, const char* name, const char* mode) 204 { 205 TIFF* tif; 206 207 fd_as_handle_union_t fdh; 208 fdh.fd = fd; 209 tif = TIFFClientOpen(name, mode, 210 fdh.h, 211 _tiffReadProc, _tiffWriteProc, 212 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, 213 _tiffMapProc, _tiffUnmapProc); 214 if (tif) 215 tif->tif_fd = fd; 216 return (tif); 217 } 218 219 /* 220 * Open a TIFF file for read/writing. 221 */ 222 TIFF* 223 TIFFOpen(const char* name, const char* mode) 224 { 225 static const char module[] = "TIFFOpen"; 226 int m, fd; 227 TIFF* tif; 228 229 m = _TIFFgetMode(mode, module); 230 if (m == -1) 231 return ((TIFF*)0); 232 233 /* for cygwin and mingw */ 234 #ifdef O_BINARY 235 m |= O_BINARY; 236 #endif 237 238 fd = open(name, m, 0666); 239 if (fd < 0) { 240 if (errno > 0 && strerror(errno) != NULL ) { 241 TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); 242 } else { 243 TIFFErrorExt(0, module, "%s: Cannot open", name); 244 } 245 return ((TIFF *)0); 246 } 247 248 tif = TIFFFdOpen((int)fd, name, mode); 249 if(!tif) 250 close(fd); 251 return tif; 252 } 253 254 #ifdef __WIN32__ 255 #include <windows.h> 256 /* 257 * Open a TIFF file with a Unicode filename, for read/writing. 258 */ 259 TIFF* 260 TIFFOpenW(const wchar_t* name, const char* mode) 261 { 262 static const char module[] = "TIFFOpenW"; 263 int m, fd; 264 int mbsize; 265 char *mbname; 266 TIFF* tif; 267 268 m = _TIFFgetMode(mode, module); 269 if (m == -1) 270 return ((TIFF*)0); 271 272 /* for cygwin and mingw */ 273 #ifdef O_BINARY 274 m |= O_BINARY; 275 #endif 276 277 fd = _wopen(name, m, 0666); 278 if (fd < 0) { 279 TIFFErrorExt(0, module, "%ls: Cannot open", name); 280 return ((TIFF *)0); 281 } 282 283 mbname = NULL; 284 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); 285 if (mbsize > 0) { 286 mbname = _TIFFmalloc(mbsize); 287 if (!mbname) { 288 TIFFErrorExt(0, module, 289 "Can't allocate space for filename conversion buffer"); 290 return ((TIFF*)0); 291 } 292 293 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, 294 NULL, NULL); 295 } 296 297 tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "<unknown>", 298 mode); 299 300 _TIFFfree(mbname); 301 302 if(!tif) 303 close(fd); 304 return tif; 305 } 306 #endif 307 308 void* 309 _TIFFmalloc(tmsize_t s) 310 { 311 if (s == 0) 312 return ((void *) NULL); 313 314 return (malloc((size_t) s)); 315 } 316 317 void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) 318 { 319 if( nmemb == 0 || siz == 0 ) 320 return ((void *) NULL); 321 322 return calloc((size_t) nmemb, (size_t)siz); 323 } 324 325 void 326 _TIFFfree(void* p) 327 { 328 free(p); 329 } 330 331 void* 332 _TIFFrealloc(void* p, tmsize_t s) 333 { 334 return (realloc(p, (size_t) s)); 335 } 336 337 void 338 _TIFFmemset(void* p, int v, tmsize_t c) 339 { 340 memset(p, v, (size_t) c); 341 } 342 343 void 344 _TIFFmemcpy(void* d, const void* s, tmsize_t c) 345 { 346 memcpy(d, s, (size_t) c); 347 } 348 349 int 350 _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) 351 { 352 return (memcmp(p1, p2, (size_t) c)); 353 } 354 355 static void 356 unixWarningHandler(const char* module, const char* fmt, va_list ap) 357 { 358 if (module != NULL) 359 fprintf(stderr, "%s: ", module); 360 fprintf(stderr, "Warning, "); 361 vfprintf(stderr, fmt, ap); 362 fprintf(stderr, ".\n"); 363 } 364 TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; 365 366 static void 367 unixErrorHandler(const char* module, const char* fmt, va_list ap) 368 { 369 if (module != NULL) 370 fprintf(stderr, "%s: ", module); 371 vfprintf(stderr, fmt, ap); 372 fprintf(stderr, ".\n"); 373 } 374 TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; 375 376 /* vim: set ts=8 sts=8 sw=8 noet: */ 377 378 /* 379 * Local Variables: 380 * mode: c 381 * c-basic-offset: 8 382 * fill-column: 78 383 * End: 384 */ 385