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 Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by 27 * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA 28 */ 29 30 /* 31 CreateFileA/CreateFileW return type 'HANDLE'. 32 33 thandle_t is declared like 34 35 DECLARE_HANDLE(thandle_t); 36 37 in tiffio.h. 38 39 Windows (from winnt.h) DECLARE_HANDLE logic looks like 40 41 #ifdef STRICT 42 typedef void *HANDLE; 43 #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name 44 #else 45 typedef PVOID HANDLE; 46 #define DECLARE_HANDLE(name) typedef HANDLE name 47 #endif 48 49 See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64 50 builds resulting from this. Unfortunately, the proposed patch was lost. 51 52 */ 53 54 #include <precomp.h> 55 56 #include <stdlib.h> 57 #include <windef.h> 58 #include <winbase.h> 59 #include <winuser.h> 60 #include <winnls.h> 61 62 static tmsize_t 63 _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) 64 { 65 /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes 66 * 32bit sizes, so we loop through the data in suitable 32bit sized 67 * chunks */ 68 uint8* ma; 69 uint64 mb; 70 DWORD n; 71 DWORD o; 72 tmsize_t p; 73 ma=(uint8*)buf; 74 mb=size; 75 p=0; 76 while (mb>0) 77 { 78 n=0x80000000UL; 79 if ((uint64)n>mb) 80 n=(DWORD)mb; 81 if (!ReadFile(fd,(LPVOID)ma,n,&o,NULL)) 82 return(0); 83 ma+=o; 84 mb-=o; 85 p+=o; 86 if (o!=n) 87 break; 88 } 89 return(p); 90 } 91 92 static tmsize_t 93 _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) 94 { 95 /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes 96 * 32bit sizes, so we loop through the data in suitable 32bit sized 97 * chunks */ 98 uint8* ma; 99 uint64 mb; 100 DWORD n; 101 DWORD o; 102 tmsize_t p; 103 ma=(uint8*)buf; 104 mb=size; 105 p=0; 106 while (mb>0) 107 { 108 n=0x80000000UL; 109 if ((uint64)n>mb) 110 n=(DWORD)mb; 111 if (!WriteFile(fd,(LPVOID)ma,n,&o,NULL)) 112 return(0); 113 ma+=o; 114 mb-=o; 115 p+=o; 116 if (o!=n) 117 break; 118 } 119 return(p); 120 } 121 122 static uint64 123 _tiffSeekProc(thandle_t fd, uint64 off, int whence) 124 { 125 LARGE_INTEGER offli; 126 DWORD dwMoveMethod; 127 offli.QuadPart = off; 128 switch(whence) 129 { 130 case SEEK_SET: 131 dwMoveMethod = FILE_BEGIN; 132 break; 133 case SEEK_CUR: 134 dwMoveMethod = FILE_CURRENT; 135 break; 136 case SEEK_END: 137 dwMoveMethod = FILE_END; 138 break; 139 default: 140 dwMoveMethod = FILE_BEGIN; 141 break; 142 } 143 offli.LowPart=SetFilePointer(fd,offli.LowPart,&offli.HighPart,dwMoveMethod); 144 if ((offli.LowPart==INVALID_SET_FILE_POINTER)&&(GetLastError()!=NO_ERROR)) 145 offli.QuadPart=0; 146 return(offli.QuadPart); 147 } 148 149 static int 150 _tiffCloseProc(thandle_t fd) 151 { 152 return (CloseHandle(fd) ? 0 : -1); 153 } 154 155 static uint64 156 _tiffSizeProc(thandle_t fd) 157 { 158 ULARGE_INTEGER m; 159 m.LowPart=GetFileSize(fd,&m.HighPart); 160 return(m.QuadPart); 161 } 162 163 static int 164 _tiffDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) 165 { 166 (void) fd; 167 (void) pbase; 168 (void) psize; 169 return (0); 170 } 171 172 /* 173 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>: 174 * 175 * Windows uses both a handle and a pointer for file mapping, 176 * but according to the SDK documentation and Richter's book 177 * "Advanced Windows Programming" it is safe to free the handle 178 * after obtaining the file mapping pointer 179 * 180 * This removes a nasty OS dependency and cures a problem 181 * with Visual C++ 5.0 182 */ 183 static int 184 _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) 185 { 186 uint64 size; 187 tmsize_t sizem; 188 HANDLE hMapFile; 189 190 size = _tiffSizeProc(fd); 191 sizem = (tmsize_t)size; 192 if ((uint64)sizem!=size) 193 return (0); 194 195 /* By passing in 0 for the maximum file size, it specifies that we 196 create a file mapping object for the full file size. */ 197 hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL); 198 if (hMapFile == NULL) 199 return (0); 200 *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); 201 CloseHandle(hMapFile); 202 if (*pbase == NULL) 203 return (0); 204 *psize = size; 205 return(1); 206 } 207 208 static void 209 _tiffDummyUnmapProc(thandle_t fd, void* base, toff_t size) 210 { 211 (void) fd; 212 (void) base; 213 (void) size; 214 } 215 216 static void 217 _tiffUnmapProc(thandle_t fd, void* base, toff_t size) 218 { 219 (void) fd; 220 (void) size; 221 UnmapViewOfFile(base); 222 } 223 224 /* 225 * Open a TIFF file descriptor for read/writing. 226 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode 227 * string, which forces the file to be opened unmapped. 228 */ 229 TIFF* 230 TIFFFdOpen(int ifd, const char* name, const char* mode) 231 { 232 TIFF* tif; 233 int fSuppressMap; 234 int m; 235 fSuppressMap=0; 236 for (m=0; mode[m]!=0; m++) 237 { 238 if (mode[m]=='u') 239 { 240 fSuppressMap=1; 241 break; 242 } 243 } 244 tif = TIFFClientOpen(name, mode, (thandle_t)ifd, /* FIXME: WIN64 cast to pointer warning */ 245 _tiffReadProc, _tiffWriteProc, 246 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, 247 fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, 248 fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); 249 if (tif) 250 tif->tif_fd = ifd; 251 return (tif); 252 } 253 254 #ifndef _WIN32_WCE 255 256 /* 257 * Open a TIFF file for read/writing. 258 */ 259 TIFF* 260 TIFFOpen(const char* name, const char* mode) 261 { 262 static const char module[] = "TIFFOpen"; 263 thandle_t fd; 264 int m; 265 DWORD dwMode; 266 TIFF* tif; 267 268 m = _TIFFgetMode(mode, module); 269 270 switch(m) { 271 case O_RDONLY: dwMode = OPEN_EXISTING; break; 272 case O_RDWR: dwMode = OPEN_ALWAYS; break; 273 case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; 274 case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; 275 case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; 276 default: return ((TIFF*)0); 277 } 278 279 fd = (thandle_t)CreateFileA(name, 280 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), 281 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, 282 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 283 NULL); 284 if (fd == INVALID_HANDLE_VALUE) { 285 TIFFErrorExt(0, module, "%s: Cannot open", name); 286 return ((TIFF *)0); 287 } 288 289 tif = TIFFFdOpen((int)fd, name, mode); /* FIXME: WIN64 cast from pointer to int warning */ 290 if(!tif) 291 CloseHandle(fd); 292 return tif; 293 } 294 295 /* 296 * Open a TIFF file with a Unicode filename, for read/writing. 297 */ 298 TIFF* 299 TIFFOpenW(const wchar_t* name, const char* mode) 300 { 301 static const char module[] = "TIFFOpenW"; 302 thandle_t fd; 303 int m; 304 DWORD dwMode; 305 int mbsize; 306 char *mbname; 307 TIFF *tif; 308 309 m = _TIFFgetMode(mode, module); 310 311 switch(m) { 312 case O_RDONLY: dwMode = OPEN_EXISTING; break; 313 case O_RDWR: dwMode = OPEN_ALWAYS; break; 314 case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; 315 case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; 316 case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; 317 default: return ((TIFF*)0); 318 } 319 320 fd = (thandle_t)CreateFileW(name, 321 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), 322 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, 323 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 324 NULL); 325 if (fd == INVALID_HANDLE_VALUE) { 326 TIFFErrorExt(0, module, "%S: Cannot open", name); 327 return ((TIFF *)0); 328 } 329 330 mbname = NULL; 331 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); 332 if (mbsize > 0) { 333 mbname = (char *)_TIFFmalloc(mbsize); 334 if (!mbname) { 335 TIFFErrorExt(0, module, 336 "Can't allocate space for filename conversion buffer"); 337 return ((TIFF*)0); 338 } 339 340 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, 341 NULL, NULL); 342 } 343 344 tif = TIFFFdOpen((int)fd, /* FIXME: WIN64 cast from pointer to int warning */ 345 (mbname != NULL) ? mbname : "<unknown>", mode); 346 if(!tif) 347 CloseHandle(fd); 348 349 _TIFFfree(mbname); 350 351 return tif; 352 } 353 354 #endif /* ndef _WIN32_WCE */ 355 356 void* 357 _TIFFmalloc(tmsize_t s) 358 { 359 if (s == 0) 360 return ((void *) NULL); 361 362 return (malloc((size_t) s)); 363 } 364 365 void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) 366 { 367 if( nmemb == 0 || siz == 0 ) 368 return ((void *) NULL); 369 370 return calloc((size_t) nmemb, (size_t)siz); 371 } 372 373 void 374 _TIFFfree(void* p) 375 { 376 free(p); 377 } 378 379 void* 380 _TIFFrealloc(void* p, tmsize_t s) 381 { 382 return (realloc(p, (size_t) s)); 383 } 384 385 void 386 _TIFFmemset(void* p, int v, tmsize_t c) 387 { 388 memset(p, v, (size_t) c); 389 } 390 391 void 392 _TIFFmemcpy(void* d, const void* s, tmsize_t c) 393 { 394 memcpy(d, s, (size_t) c); 395 } 396 397 int 398 _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) 399 { 400 return (memcmp(p1, p2, (size_t) c)); 401 } 402 403 #ifndef _WIN32_WCE 404 405 #if (_MSC_VER < 1500) 406 # define vsnprintf _vsnprintf 407 #endif 408 409 static void 410 Win32WarningHandler(const char* module, const char* fmt, va_list ap) 411 { 412 if (module != NULL) 413 fprintf(stderr, "%s: ", module); 414 fprintf(stderr, "Warning, "); 415 vfprintf(stderr, fmt, ap); 416 fprintf(stderr, ".\n"); 417 } 418 TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; 419 420 static void 421 Win32ErrorHandler(const char* module, const char* fmt, va_list ap) 422 { 423 if (module != NULL) 424 fprintf(stderr, "%s: ", module); 425 vfprintf(stderr, fmt, ap); 426 fprintf(stderr, ".\n"); 427 } 428 TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; 429 430 #endif /* ndef _WIN32_WCE */ 431 432 /* vim: set ts=8 sts=8 sw=8 noet: */ 433 /* 434 * Local Variables: 435 * mode: c 436 * c-basic-offset: 8 437 * fill-column: 78 438 * End: 439 */ 440