1/* $Id: tif_win32.c 276 2010-06-30 12:18:30Z nijtmans $ */ 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 Win32-specific Routines. Adapted from tif_unix.c 4/5/95 by 29 * Scott Wagner (wagner@itek.com), Itek Graphix, Rochester, NY USA 30 */ 31#include "tiffiop.h" 32 33#include <windows.h> 34 35static tsize_t 36_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size) 37{ 38 DWORD dwSizeRead; 39 if (!ReadFile(fd, buf, size, &dwSizeRead, NULL)) 40 return(0); 41 return ((tsize_t) dwSizeRead); 42} 43 44static tsize_t 45_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size) 46{ 47 DWORD dwSizeWritten; 48 if (!WriteFile(fd, buf, size, &dwSizeWritten, NULL)) 49 return(0); 50 return ((tsize_t) dwSizeWritten); 51} 52 53static toff_t 54_tiffSeekProc(thandle_t fd, toff_t off, int whence) 55{ 56 ULARGE_INTEGER li; 57 DWORD dwMoveMethod; 58 59 li.QuadPart = off; 60 61 switch(whence) 62 { 63 case SEEK_SET: 64 dwMoveMethod = FILE_BEGIN; 65 break; 66 case SEEK_CUR: 67 dwMoveMethod = FILE_CURRENT; 68 break; 69 case SEEK_END: 70 dwMoveMethod = FILE_END; 71 break; 72 default: 73 dwMoveMethod = FILE_BEGIN; 74 break; 75 } 76 return ((toff_t)SetFilePointer(fd, (LONG) li.LowPart, 77 (PLONG)&li.HighPart, dwMoveMethod)); 78} 79 80static int 81_tiffCloseProc(thandle_t fd) 82{ 83 return (CloseHandle(fd) ? 0 : -1); 84} 85 86static toff_t 87_tiffSizeProc(thandle_t fd) 88{ 89 return ((toff_t)GetFileSize(fd, NULL)); 90} 91 92static int 93_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) 94{ 95 (void) fd; 96 (void) pbase; 97 (void) psize; 98 return (0); 99} 100 101/* 102 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>: 103 * 104 * Windows uses both a handle and a pointer for file mapping, 105 * but according to the SDK documentation and Richter's book 106 * "Advanced Windows Programming" it is safe to free the handle 107 * after obtaining the file mapping pointer 108 * 109 * This removes a nasty OS dependency and cures a problem 110 * with Visual C++ 5.0 111 */ 112static int 113_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize) 114{ 115 toff_t size; 116 HANDLE hMapFile; 117 118 if ((size = _tiffSizeProc(fd)) == 0xFFFFFFFF) 119 return (0); 120 hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, size, NULL); 121 if (hMapFile == NULL) 122 return (0); 123 *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0); 124 CloseHandle(hMapFile); 125 if (*pbase == NULL) 126 return (0); 127 *psize = size; 128 return(1); 129} 130 131static void 132_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size) 133{ 134 (void) fd; 135 (void) base; 136 (void) size; 137} 138 139static void 140_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size) 141{ 142 UnmapViewOfFile(base); 143} 144 145/* 146 * Open a TIFF file descriptor for read/writing. 147 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode 148 * string, which forces the file to be opened unmapped. 149 */ 150TIFF* 151TIFFFdOpen(int ifd, const char* name, const char* mode) 152{ 153 TIFF* tif; 154 BOOL fSuppressMap = (mode[1] == 'u' || (mode[1]!=0 && mode[2] == 'u')); 155 156 tif = TIFFClientOpen(name, mode, (thandle_t)ifd, 157 _tiffReadProc, _tiffWriteProc, 158 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, 159 fSuppressMap ? _tiffDummyMapProc : _tiffMapProc, 160 fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc); 161 if (tif) 162 tif->tif_fd = ifd; 163 return (tif); 164} 165 166#ifndef _WIN32_WCE 167 168/* 169 * Open a TIFF file for read/writing. 170 */ 171TIFF* 172TIFFOpen(const char* name, const char* mode) 173{ 174 static const char module[] = "TIFFOpen"; 175 thandle_t fd; 176 int m; 177 DWORD dwMode; 178 TIFF* tif; 179 180 m = _TIFFgetMode(mode, module); 181 182 switch(m) 183 { 184 case O_RDONLY: 185 dwMode = OPEN_EXISTING; 186 break; 187 case O_RDWR: 188 dwMode = OPEN_ALWAYS; 189 break; 190 case O_RDWR|O_CREAT: 191 dwMode = OPEN_ALWAYS; 192 break; 193 case O_RDWR|O_TRUNC: 194 dwMode = CREATE_ALWAYS; 195 break; 196 case O_RDWR|O_CREAT|O_TRUNC: 197 dwMode = CREATE_ALWAYS; 198 break; 199 default: 200 return ((TIFF*)0); 201 } 202 fd = (thandle_t)CreateFileA(name, 203 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE), 204 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode, 205 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 206 NULL); 207 if (fd == INVALID_HANDLE_VALUE) { 208 TIFFErrorExt(0, module, "%s: Cannot open", name); 209 return ((TIFF *)0); 210 } 211 212 tif = TIFFFdOpen((int)fd, name, mode); 213 if(!tif) 214 CloseHandle(fd); 215 return tif; 216} 217 218/* 219 * Open a TIFF file with a Unicode filename, for read/writing. 220 */ 221TIFF* 222TIFFOpenW(const wchar_t* name, const char* mode) 223{ 224 static const char module[] = "TIFFOpenW"; 225 thandle_t fd; 226 int m; 227 DWORD dwMode; 228 int mbsize; 229 char *mbname; 230 TIFF *tif; 231 232 m = _TIFFgetMode(mode, module); 233 234 switch(m) { 235 case O_RDONLY: dwMode = OPEN_EXISTING; break; 236 case O_RDWR: dwMode = OPEN_ALWAYS; break; 237 case O_RDWR|O_CREAT: dwMode = OPEN_ALWAYS; break; 238 case O_RDWR|O_TRUNC: dwMode = CREATE_ALWAYS; break; 239 case O_RDWR|O_CREAT|O_TRUNC: dwMode = CREATE_ALWAYS; break; 240 default: return ((TIFF*)0); 241 } 242 243 fd = (thandle_t)CreateFileW(name, 244 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE), 245 FILE_SHARE_READ, NULL, dwMode, 246 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL, 247 NULL); 248 if (fd == INVALID_HANDLE_VALUE) { 249 TIFFErrorExt(0, module, "%S: Cannot open", name); 250 return ((TIFF *)0); 251 } 252 253 mbname = NULL; 254 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); 255 if (mbsize > 0) { 256 mbname = (char *)_TIFFmalloc(mbsize); 257 if (!mbname) { 258 TIFFErrorExt(0, module, 259 "Can't allocate space for filename conversion buffer"); 260 return ((TIFF*)0); 261 } 262 263 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, 264 NULL, NULL); 265 } 266 267 tif = TIFFFdOpen((int)fd, 268 (mbname != NULL) ? mbname : "<unknown>", mode); 269 if(!tif) 270 CloseHandle(fd); 271 272 _TIFFfree(mbname); 273 274 return tif; 275} 276 277#endif /* ndef _WIN32_WCE */ 278 279 280tdata_t 281_TIFFmalloc(tsize_t s) 282{ 283 return ((tdata_t)GlobalAlloc(GMEM_FIXED, s)); 284} 285 286void 287_TIFFfree(tdata_t p) 288{ 289 GlobalFree(p); 290 return; 291} 292 293tdata_t 294_TIFFrealloc(tdata_t p, tsize_t s) 295{ 296 void* pvTmp; 297 tsize_t old; 298 299 if(p == NULL) 300 return ((tdata_t)GlobalAlloc(GMEM_FIXED, s)); 301 302 old = GlobalSize(p); 303 304 if (old>=s) { 305 if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) { 306 CopyMemory(pvTmp, p, s); 307 GlobalFree(p); 308 } 309 } else { 310 if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) { 311 CopyMemory(pvTmp, p, old); 312 GlobalFree(p); 313 } 314 } 315 return ((tdata_t)pvTmp); 316} 317 318void 319_TIFFmemset(void* p, int v, tsize_t c) 320{ 321 FillMemory(p, c, (BYTE)v); 322} 323 324void 325_TIFFmemcpy(void* d, const tdata_t s, tsize_t c) 326{ 327 CopyMemory(d, s, c); 328} 329 330int 331_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c) 332{ 333 register const BYTE *pb1 = (const BYTE *) p1; 334 register const BYTE *pb2 = (const BYTE *) p2; 335 register DWORD dwTmp = c; 336 register int iTmp; 337 for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++) 338 ; 339 return (iTmp); 340} 341 342#ifndef _WIN32_WCE 343 344static void 345Win32WarningHandler(const char* module, const char* fmt, va_list ap) 346{ 347#ifndef TIF_PLATFORM_CONSOLE 348 LPTSTR szTitle; 349 LPTSTR szTmp; 350 LPCTSTR szTitleText = "%s Warning"; 351 LPCTSTR szDefaultModule = "LIBTIFF"; 352 LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; 353 if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) + 354 strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL) 355 return; 356 sprintf(szTitle, szTitleText, szTmpModule); 357 szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); 358 vsprintf(szTmp, fmt, ap); 359 MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION); 360 LocalFree(szTitle); 361 return; 362#else 363 if (module != NULL) 364 fprintf(stderr, "%s: ", module); 365 fprintf(stderr, "Warning, "); 366 vfprintf(stderr, fmt, ap); 367 fprintf(stderr, ".\n"); 368#endif 369} 370TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler; 371 372static void 373Win32ErrorHandler(const char* module, const char* fmt, va_list ap) 374{ 375#ifndef TIF_PLATFORM_CONSOLE 376 LPTSTR szTitle; 377 LPTSTR szTmp; 378 LPCTSTR szTitleText = "%s Error"; 379 LPCTSTR szDefaultModule = "LIBTIFF"; 380 LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module; 381 if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) + 382 strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL) 383 return; 384 sprintf(szTitle, szTitleText, szTmpModule); 385 szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char); 386 vsprintf(szTmp, fmt, ap); 387 MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION); 388 LocalFree(szTitle); 389 return; 390#else 391 if (module != NULL) 392 fprintf(stderr, "%s: ", module); 393 vfprintf(stderr, fmt, ap); 394 fprintf(stderr, ".\n"); 395#endif 396} 397TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler; 398 399#endif /* ndef _WIN32_WCE */ 400 401/* vim: set ts=8 sts=8 sw=8 noet: */ 402/* 403 * Local Variables: 404 * mode: c 405 * c-basic-offset: 8 406 * fill-column: 78 407 * End: 408 */ 409