1 /* $Id: tif_unix.c,v 1.23 2012-06-01 21:40:59 fwarmerdam 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 UNIX-specific Routines. These are should also work with the 29 * Windows Common RunTime Library. 30 */ 31 32 #include "tif_config.h" 33 34 #ifdef HAVE_SYS_TYPES_H 35 # include <sys/types.h> 36 #endif 37 38 #include <errno.h> 39 40 #include <stdarg.h> 41 #include <stdlib.h> 42 #include <sys/stat.h> 43 44 #ifdef HAVE_UNISTD_H 45 # include <unistd.h> 46 #endif 47 48 #ifdef HAVE_FCNTL_H 49 # include <fcntl.h> 50 #endif 51 52 #ifdef HAVE_IO_H 53 # include <io.h> 54 #endif 55 56 #include "tiffiop.h" 57 58 static tmsize_t 59 _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) 60 { 61 size_t size_io = (size_t) size; 62 if ((tmsize_t) size_io != size) 63 { 64 errno=EINVAL; 65 return (tmsize_t) -1; 66 } 67 return ((tmsize_t) read((int)(intptr_t) fd, buf, size_io)); 68 } 69 70 static tmsize_t 71 _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) 72 { 73 size_t size_io = (size_t) size; 74 if ((tmsize_t) size_io != size) 75 { 76 errno=EINVAL; 77 return (tmsize_t) -1; 78 } 79 return ((tmsize_t) write((int)(intptr_t) fd, buf, size_io)); 80 } 81 82 static uint64 83 _tiffSeekProc(thandle_t fd, uint64 off, int whence) 84 { 85 off_t off_io = (off_t) off; 86 if ((uint64) off_io != off) 87 { 88 errno=EINVAL; 89 return (uint64) -1; /* this is really gross */ 90 } 91 return((uint64)lseek((int)(intptr_t)fd,off_io,whence)); 92 } 93 94 static int 95 _tiffCloseProc(thandle_t fd) 96 { 97 return(close((int)(intptr_t)fd)); 98 } 99 100 static uint64 101 _tiffSizeProc(thandle_t fd) 102 { 103 struct stat sb; 104 if (fstat((int)(intptr_t)fd,&sb)<0) 105 return(0); 106 else 107 return((uint64)sb.st_size); 108 } 109 110 #ifdef HAVE_MMAP 111 #include <sys/mman.h> 112 113 static int 114 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 115 { 116 uint64 size64 = _tiffSizeProc(fd); 117 tmsize_t sizem = (tmsize_t)size64; 118 if ((uint64)sizem==size64) { 119 *pbase = (void*) 120 mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int)(intptr_t) fd, 0); 121 if (*pbase != (void*) -1) { 122 *psize = (tmsize_t)sizem; 123 return (1); 124 } 125 } 126 return (0); 127 } 128 129 static void 130 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 131 { 132 (void) fd; 133 (void) munmap(base, (off_t) size); 134 } 135 #else /* !HAVE_MMAP */ 136 static int 137 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 138 { 139 (void) fd; (void) pbase; (void) psize; 140 return (0); 141 } 142 143 static void 144 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 145 { 146 (void) fd; (void) base; (void) size; 147 } 148 #endif /* !HAVE_MMAP */ 149 150 /* 151 * Open a TIFF file descriptor for read/writing. 152 */ 153 TIFF* 154 TIFFFdOpen(int fd, const char* name, const char* mode) 155 { 156 TIFF* tif; 157 158 tif = TIFFClientOpen(name, mode, 159 (thandle_t)(intptr_t) fd, 160 _tiffReadProc, _tiffWriteProc, 161 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, 162 _tiffMapProc, _tiffUnmapProc); 163 if (tif) 164 tif->tif_fd = fd; 165 return (tif); 166 } 167 168 /* 169 * Open a TIFF file for read/writing. 170 */ 171 TIFF* 172 TIFFOpen(const char* name, const char* mode) 173 { 174 static const char module[] = "TIFFOpen"; 175 int m, fd; 176 TIFF* tif; 177 178 m = _TIFFgetMode(mode, module); 179 if (m == -1) 180 return ((TIFF*)0); 181 182 /* for cygwin and mingw */ 183 #ifdef O_BINARY 184 m |= O_BINARY; 185 #endif 186 187 fd = open(name, m, 0666); 188 if (fd < 0) { 189 if (errno > 0 && strerror(errno) != NULL ) { 190 TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); 191 } else { 192 TIFFErrorExt(0, module, "%s: Cannot open", name); 193 } 194 return ((TIFF *)0); 195 } 196 197 tif = TIFFFdOpen((int)fd, name, mode); 198 if(!tif) 199 close(fd); 200 return tif; 201 } 202 203 #ifdef __WIN32__ 204 #include <windows.h> 205 /* 206 * Open a TIFF file with a Unicode filename, for read/writing. 207 */ 208 TIFF* 209 TIFFOpenW(const wchar_t* name, const char* mode) 210 { 211 static const char module[] = "TIFFOpenW"; 212 int m, fd; 213 int mbsize; 214 char *mbname; 215 TIFF* tif; 216 217 m = _TIFFgetMode(mode, module); 218 if (m == -1) 219 return ((TIFF*)0); 220 221 /* for cygwin and mingw */ 222 #ifdef O_BINARY 223 m |= O_BINARY; 224 #endif 225 226 fd = _wopen(name, m, 0666); 227 if (fd < 0) { 228 TIFFErrorExt(0, module, "%s: Cannot open", name); 229 return ((TIFF *)0); 230 } 231 232 mbname = NULL; 233 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); 234 if (mbsize > 0) { 235 mbname = _TIFFmalloc(mbsize); 236 if (!mbname) { 237 TIFFErrorExt(0, module, 238 "Can't allocate space for filename conversion buffer"); 239 return ((TIFF*)0); 240 } 241 242 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, 243 NULL, NULL); 244 } 245 246 tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "<unknown>", 247 mode); 248 249 _TIFFfree(mbname); 250 251 if(!tif) 252 close(fd); 253 return tif; 254 } 255 #endif 256 257 void* 258 _TIFFmalloc(tmsize_t s) 259 { 260 return (malloc((size_t) s)); 261 } 262 263 void 264 _TIFFfree(void* p) 265 { 266 free(p); 267 } 268 269 void* 270 _TIFFrealloc(void* p, tmsize_t s) 271 { 272 return (realloc(p, (size_t) s)); 273 } 274 275 void 276 _TIFFmemset(void* p, int v, tmsize_t c) 277 { 278 memset(p, v, (size_t) c); 279 } 280 281 void 282 _TIFFmemcpy(void* d, const void* s, tmsize_t c) 283 { 284 memcpy(d, s, (size_t) c); 285 } 286 287 int 288 _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) 289 { 290 return (memcmp(p1, p2, (size_t) c)); 291 } 292 293 static void 294 unixWarningHandler(const char* module, const char* fmt, va_list ap) 295 { 296 if (module != NULL) 297 fprintf(stderr, "%s: ", module); 298 fprintf(stderr, "Warning, "); 299 vfprintf(stderr, fmt, ap); 300 fprintf(stderr, ".\n"); 301 } 302 TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; 303 304 static void 305 unixErrorHandler(const char* module, const char* fmt, va_list ap) 306 { 307 if (module != NULL) 308 fprintf(stderr, "%s: ", module); 309 vfprintf(stderr, fmt, ap); 310 fprintf(stderr, ".\n"); 311 } 312 TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; 313 314 /* vim: set ts=8 sts=8 sw=8 noet: */ 315 316 /* 317 * Local Variables: 318 * mode: c 319 * c-basic-offset: 8 320 * fill-column: 78 321 * End: 322 */ 323