1 /* $Id: tif_win32.c,v 1.42 2017-01-11 19:02:49 erouault Exp $ */
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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
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
33 CreateFileA/CreateFileW return type 'HANDLE'.
35 thandle_t is declared like
37 DECLARE_HANDLE(thandle_t);
41 Windows (from winnt.h) DECLARE_HANDLE logic looks like
45 #define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
48 #define DECLARE_HANDLE(name) typedef HANDLE name
51 See http://bugzilla.maptools.org/show_bug.cgi?id=1941 for problems in WIN64
52 builds resulting from this. Unfortunately, the proposed patch was lost.
65 _tiffReadProc(thandle_t fd
, void* buf
, tmsize_t size
)
67 /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes
68 * 32bit sizes, so we loop through the data in suitable 32bit sized
83 if (!ReadFile(fd
,(LPVOID
)ma
,n
,&o
,NULL
))
95 _tiffWriteProc(thandle_t fd
, void* buf
, tmsize_t size
)
97 /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes
98 * 32bit sizes, so we loop through the data in suitable 32bit sized
113 if (!WriteFile(fd
,(LPVOID
)ma
,n
,&o
,NULL
))
125 _tiffSeekProc(thandle_t fd
, uint64 off
, int whence
)
129 offli
.QuadPart
= off
;
133 dwMoveMethod
= FILE_BEGIN
;
136 dwMoveMethod
= FILE_CURRENT
;
139 dwMoveMethod
= FILE_END
;
142 dwMoveMethod
= FILE_BEGIN
;
145 offli
.LowPart
=SetFilePointer(fd
,offli
.LowPart
,&offli
.HighPart
,dwMoveMethod
);
146 if ((offli
.LowPart
==INVALID_SET_FILE_POINTER
)&&(GetLastError()!=NO_ERROR
))
148 return(offli
.QuadPart
);
152 _tiffCloseProc(thandle_t fd
)
154 return (CloseHandle(fd
) ? 0 : -1);
158 _tiffSizeProc(thandle_t fd
)
161 m
.LowPart
=GetFileSize(fd
,&m
.HighPart
);
166 _tiffDummyMapProc(thandle_t fd
, void** pbase
, toff_t
* psize
)
175 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
177 * Windows uses both a handle and a pointer for file mapping,
178 * but according to the SDK documentation and Richter's book
179 * "Advanced Windows Programming" it is safe to free the handle
180 * after obtaining the file mapping pointer
182 * This removes a nasty OS dependency and cures a problem
183 * with Visual C++ 5.0
186 _tiffMapProc(thandle_t fd
, void** pbase
, toff_t
* psize
)
192 size
= _tiffSizeProc(fd
);
193 sizem
= (tmsize_t
)size
;
194 if ((uint64
)sizem
!=size
)
197 /* By passing in 0 for the maximum file size, it specifies that we
198 create a file mapping object for the full file size. */
199 hMapFile
= CreateFileMapping(fd
, NULL
, PAGE_READONLY
, 0, 0, NULL
);
200 if (hMapFile
== NULL
)
202 *pbase
= MapViewOfFile(hMapFile
, FILE_MAP_READ
, 0, 0, 0);
203 CloseHandle(hMapFile
);
211 _tiffDummyUnmapProc(thandle_t fd
, void* base
, toff_t size
)
219 _tiffUnmapProc(thandle_t fd
, void* base
, toff_t size
)
223 UnmapViewOfFile(base
);
227 * Open a TIFF file descriptor for read/writing.
228 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
229 * string, which forces the file to be opened unmapped.
232 TIFFFdOpen(int ifd
, const char* name
, const char* mode
)
238 for (m
=0; mode
[m
]!=0; m
++)
246 tif
= TIFFClientOpen(name
, mode
, (thandle_t
)ifd
, /* FIXME: WIN64 cast to pointer warning */
247 _tiffReadProc
, _tiffWriteProc
,
248 _tiffSeekProc
, _tiffCloseProc
, _tiffSizeProc
,
249 fSuppressMap
? _tiffDummyMapProc
: _tiffMapProc
,
250 fSuppressMap
? _tiffDummyUnmapProc
: _tiffUnmapProc
);
259 * Open a TIFF file for read/writing.
262 TIFFOpen(const char* name
, const char* mode
)
264 static const char module
[] = "TIFFOpen";
270 m
= _TIFFgetMode(mode
, module
);
273 case O_RDONLY
: dwMode
= OPEN_EXISTING
; break;
274 case O_RDWR
: dwMode
= OPEN_ALWAYS
; break;
275 case O_RDWR
|O_CREAT
: dwMode
= OPEN_ALWAYS
; break;
276 case O_RDWR
|O_TRUNC
: dwMode
= CREATE_ALWAYS
; break;
277 case O_RDWR
|O_CREAT
|O_TRUNC
: dwMode
= CREATE_ALWAYS
; break;
278 default: return ((TIFF
*)0);
281 fd
= (thandle_t
)CreateFileA(name
,
282 (m
== O_RDONLY
)?GENERIC_READ
:(GENERIC_READ
| GENERIC_WRITE
),
283 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, dwMode
,
284 (m
== O_RDONLY
)?FILE_ATTRIBUTE_READONLY
:FILE_ATTRIBUTE_NORMAL
,
286 if (fd
== INVALID_HANDLE_VALUE
) {
287 TIFFErrorExt(0, module
, "%s: Cannot open", name
);
291 tif
= TIFFFdOpen((int)fd
, name
, mode
); /* FIXME: WIN64 cast from pointer to int warning */
298 * Open a TIFF file with a Unicode filename, for read/writing.
301 TIFFOpenW(const wchar_t* name
, const char* mode
)
303 static const char module
[] = "TIFFOpenW";
311 m
= _TIFFgetMode(mode
, module
);
314 case O_RDONLY
: dwMode
= OPEN_EXISTING
; break;
315 case O_RDWR
: dwMode
= OPEN_ALWAYS
; break;
316 case O_RDWR
|O_CREAT
: dwMode
= OPEN_ALWAYS
; break;
317 case O_RDWR
|O_TRUNC
: dwMode
= CREATE_ALWAYS
; break;
318 case O_RDWR
|O_CREAT
|O_TRUNC
: dwMode
= CREATE_ALWAYS
; break;
319 default: return ((TIFF
*)0);
322 fd
= (thandle_t
)CreateFileW(name
,
323 (m
== O_RDONLY
)?GENERIC_READ
:(GENERIC_READ
|GENERIC_WRITE
),
324 FILE_SHARE_READ
| FILE_SHARE_WRITE
, NULL
, dwMode
,
325 (m
== O_RDONLY
)?FILE_ATTRIBUTE_READONLY
:FILE_ATTRIBUTE_NORMAL
,
327 if (fd
== INVALID_HANDLE_VALUE
) {
328 TIFFErrorExt(0, module
, "%S: Cannot open", name
);
333 mbsize
= WideCharToMultiByte(CP_ACP
, 0, name
, -1, NULL
, 0, NULL
, NULL
);
335 mbname
= (char *)_TIFFmalloc(mbsize
);
337 TIFFErrorExt(0, module
,
338 "Can't allocate space for filename conversion buffer");
342 WideCharToMultiByte(CP_ACP
, 0, name
, -1, mbname
, mbsize
,
346 tif
= TIFFFdOpen((int)fd
, /* FIXME: WIN64 cast from pointer to int warning */
347 (mbname
!= NULL
) ? mbname
: "<unknown>", mode
);
356 #endif /* ndef _WIN32_WCE */
359 _TIFFmalloc(tmsize_t s
)
362 return ((void *) NULL
);
364 return (malloc((size_t) s
));
367 void* _TIFFcalloc(tmsize_t nmemb
, tmsize_t siz
)
369 if( nmemb
== 0 || siz
== 0 )
370 return ((void *) NULL
);
372 return calloc((size_t) nmemb
, (size_t)siz
);
382 _TIFFrealloc(void* p
, tmsize_t s
)
384 return (realloc(p
, (size_t) s
));
388 _TIFFmemset(void* p
, int v
, tmsize_t c
)
390 memset(p
, v
, (size_t) c
);
394 _TIFFmemcpy(void* d
, const void* s
, tmsize_t c
)
396 memcpy(d
, s
, (size_t) c
);
400 _TIFFmemcmp(const void* p1
, const void* p2
, tmsize_t c
)
402 return (memcmp(p1
, p2
, (size_t) c
));
407 #if (_MSC_VER < 1500)
408 # define vsnprintf _vsnprintf
412 Win32WarningHandler(const char* module
, const char* fmt
, va_list ap
)
414 #ifndef TIF_PLATFORM_CONSOLE
417 LPCTSTR szTitleText
= "%s Warning";
418 LPCTSTR szDefaultModule
= "LIBTIFF";
419 LPCTSTR szTmpModule
= (module
== NULL
) ? szDefaultModule
: module
;
420 SIZE_T nBufSize
= (strlen(szTmpModule
) +
421 strlen(szTitleText
) + strlen(fmt
) + 256)*sizeof(char);
423 if ((szTitle
= (LPTSTR
)LocalAlloc(LMEM_FIXED
, nBufSize
)) == NULL
)
425 sprintf(szTitle
, szTitleText
, szTmpModule
);
426 szTmp
= szTitle
+ (strlen(szTitle
)+2)*sizeof(char);
427 vsnprintf(szTmp
, nBufSize
-(strlen(szTitle
)+2)*sizeof(char), fmt
, ap
);
428 MessageBoxA(GetFocus(), szTmp
, szTitle
, MB_OK
| MB_ICONINFORMATION
);
434 fprintf(stderr
, "%s: ", module
);
435 fprintf(stderr
, "Warning, ");
436 vfprintf(stderr
, fmt
, ap
);
437 fprintf(stderr
, ".\n");
440 TIFFErrorHandler _TIFFwarningHandler
= Win32WarningHandler
;
443 Win32ErrorHandler(const char* module
, const char* fmt
, va_list ap
)
445 #ifndef TIF_PLATFORM_CONSOLE
448 LPCTSTR szTitleText
= "%s Error";
449 LPCTSTR szDefaultModule
= "LIBTIFF";
450 LPCTSTR szTmpModule
= (module
== NULL
) ? szDefaultModule
: module
;
451 SIZE_T nBufSize
= (strlen(szTmpModule
) +
452 strlen(szTitleText
) + strlen(fmt
) + 256)*sizeof(char);
454 if ((szTitle
= (LPTSTR
)LocalAlloc(LMEM_FIXED
, nBufSize
)) == NULL
)
456 sprintf(szTitle
, szTitleText
, szTmpModule
);
457 szTmp
= szTitle
+ (strlen(szTitle
)+2)*sizeof(char);
458 vsnprintf(szTmp
, nBufSize
-(strlen(szTitle
)+2)*sizeof(char), fmt
, ap
);
459 MessageBoxA(GetFocus(), szTmp
, szTitle
, MB_OK
| MB_ICONEXCLAMATION
);
464 fprintf(stderr
, "%s: ", module
);
465 vfprintf(stderr
, fmt
, ap
);
466 fprintf(stderr
, ".\n");
469 TIFFErrorHandler _TIFFerrorHandler
= Win32ErrorHandler
;
471 #endif /* ndef _WIN32_WCE */
473 /* vim: set ts=8 sts=8 sw=8 noet: */