d3d8/tests: Test the presentation parameters after creating an additional swap chain.
[wine.git] / libs / tiff / libtiff / tif_win32.c
blob1a6b86dffb5acb122ec9cb5d8dcdfe9dcecf4d90
1 /*
2 * Copyright (c) 1988-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
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.
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.
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.
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
30 #include "tiffiop.h"
31 #include <stdlib.h>
33 #include <windows.h>
36 CreateFileA/CreateFileW return type 'HANDLE' while TIFFFdOpen() takes 'int',
37 which is formally incompatible and can even seemingly be of different size:
38 HANDLE is 64 bit under Win64, while int is still 32 bits there.
40 However, only the lower 32 bits of a HANDLE are significant under Win64 as,
41 for interoperability reasons, they must have the same values in 32- and
42 64-bit programs running on the same system, see
44 https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
46 Because of this, it is safe to define the following trivial functions for
47 casting between ints and HANDLEs, which are only really needed to avoid
48 compiler warnings (and, perhaps, to make the code slightly more clear).
49 Note that using the intermediate cast to "intptr_t" is crucial for warning
50 avoidance, as this integer type has the same size as HANDLE in all builds.
53 static inline thandle_t thandle_from_int(int ifd)
55 return (thandle_t)(intptr_t)ifd;
58 static inline int thandle_to_int(thandle_t fd) { return (int)(intptr_t)fd; }
60 static tmsize_t _tiffReadProc(thandle_t fd, void *buf, tmsize_t size)
62 /* tmsize_t is 64bit on 64bit systems, but the WinAPI ReadFile takes
63 * 32bit sizes, so we loop through the data in suitable 32bit sized
64 * chunks */
65 uint8_t *ma;
66 uint64_t mb;
67 DWORD n;
68 DWORD o;
69 tmsize_t p;
70 ma = (uint8_t *)buf;
71 mb = size;
72 p = 0;
73 while (mb > 0)
75 n = 0x80000000UL;
76 if ((uint64_t)n > mb)
77 n = (DWORD)mb;
78 if (!ReadFile(fd, (LPVOID)ma, n, &o, NULL))
79 return (0);
80 ma += o;
81 mb -= o;
82 p += o;
83 if (o != n)
84 break;
86 return (p);
89 static tmsize_t _tiffWriteProc(thandle_t fd, void *buf, tmsize_t size)
91 /* tmsize_t is 64bit on 64bit systems, but the WinAPI WriteFile takes
92 * 32bit sizes, so we loop through the data in suitable 32bit sized
93 * chunks */
94 uint8_t *ma;
95 uint64_t mb;
96 DWORD n;
97 DWORD o;
98 tmsize_t p;
99 ma = (uint8_t *)buf;
100 mb = size;
101 p = 0;
102 while (mb > 0)
104 n = 0x80000000UL;
105 if ((uint64_t)n > mb)
106 n = (DWORD)mb;
107 if (!WriteFile(fd, (LPVOID)ma, n, &o, NULL))
108 return (0);
109 ma += o;
110 mb -= o;
111 p += o;
112 if (o != n)
113 break;
115 return (p);
118 static uint64_t _tiffSeekProc(thandle_t fd, uint64_t off, int whence)
120 LARGE_INTEGER offli;
121 DWORD dwMoveMethod;
122 offli.QuadPart = off;
123 switch (whence)
125 case SEEK_SET:
126 dwMoveMethod = FILE_BEGIN;
127 break;
128 case SEEK_CUR:
129 dwMoveMethod = FILE_CURRENT;
130 break;
131 case SEEK_END:
132 dwMoveMethod = FILE_END;
133 break;
134 default:
135 dwMoveMethod = FILE_BEGIN;
136 break;
138 offli.LowPart =
139 SetFilePointer(fd, offli.LowPart, &offli.HighPart, dwMoveMethod);
140 if ((offli.LowPart == INVALID_SET_FILE_POINTER) &&
141 (GetLastError() != NO_ERROR))
142 offli.QuadPart = 0;
143 return (offli.QuadPart);
146 static int _tiffCloseProc(thandle_t fd) { return (CloseHandle(fd) ? 0 : -1); }
148 static uint64_t _tiffSizeProc(thandle_t fd)
150 LARGE_INTEGER m;
151 if (GetFileSizeEx(fd, &m))
152 return (m.QuadPart);
153 else
154 return (0);
157 static int _tiffDummyMapProc(thandle_t fd, void **pbase, toff_t *psize)
159 (void)fd;
160 (void)pbase;
161 (void)psize;
162 return (0);
166 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
168 * Windows uses both a handle and a pointer for file mapping,
169 * but according to the SDK documentation and Richter's book
170 * "Advanced Windows Programming" it is safe to free the handle
171 * after obtaining the file mapping pointer
173 * This removes a nasty OS dependency and cures a problem
174 * with Visual C++ 5.0
176 static int _tiffMapProc(thandle_t fd, void **pbase, toff_t *psize)
178 uint64_t size;
179 tmsize_t sizem;
180 HANDLE hMapFile;
182 size = _tiffSizeProc(fd);
183 sizem = (tmsize_t)size;
184 if (!size || (uint64_t)sizem != size)
185 return (0);
187 /* By passing in 0 for the maximum file size, it specifies that we
188 create a file mapping object for the full file size. */
189 hMapFile = CreateFileMapping(fd, NULL, PAGE_READONLY, 0, 0, NULL);
190 if (hMapFile == NULL)
191 return (0);
192 *pbase = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
193 CloseHandle(hMapFile);
194 if (*pbase == NULL)
195 return (0);
196 *psize = size;
197 return (1);
200 static void _tiffDummyUnmapProc(thandle_t fd, void *base, toff_t size)
202 (void)fd;
203 (void)base;
204 (void)size;
207 static void _tiffUnmapProc(thandle_t fd, void *base, toff_t size)
209 (void)fd;
210 (void)size;
211 UnmapViewOfFile(base);
215 * Open a TIFF file descriptor for read/writing.
216 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
217 * string, which forces the file to be opened unmapped.
219 TIFF *TIFFFdOpen(int ifd, const char *name, const char *mode)
221 return TIFFFdOpenExt(ifd, name, mode, NULL);
224 TIFF *TIFFFdOpenExt(int ifd, const char *name, const char *mode,
225 TIFFOpenOptions *opts)
227 TIFF *tif;
228 int fSuppressMap;
229 int m;
231 fSuppressMap = 0;
232 for (m = 0; mode[m] != 0; m++)
234 if (mode[m] == 'u')
236 fSuppressMap = 1;
237 break;
241 tif = TIFFClientOpenExt(
242 name, mode, thandle_from_int(ifd), _tiffReadProc, _tiffWriteProc,
243 _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
244 fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
245 fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc, opts);
246 if (tif)
247 tif->tif_fd = ifd;
248 return (tif);
251 #ifndef _WIN32_WCE
254 * Open a TIFF file for read/writing.
256 TIFF *TIFFOpen(const char *name, const char *mode)
258 return TIFFOpenExt(name, mode, NULL);
261 TIFF *TIFFOpenExt(const char *name, const char *mode, TIFFOpenOptions *opts)
263 static const char module[] = "TIFFOpen";
264 thandle_t fd;
265 int m;
266 DWORD dwMode;
267 TIFF *tif;
269 m = _TIFFgetMode(opts, NULL, mode, module);
271 switch (m)
273 case O_RDONLY:
274 dwMode = OPEN_EXISTING;
275 break;
276 case O_RDWR:
277 dwMode = OPEN_EXISTING;
278 break;
279 case O_RDWR | O_CREAT:
280 dwMode = OPEN_ALWAYS;
281 break;
282 case O_RDWR | O_TRUNC:
283 dwMode = CREATE_ALWAYS;
284 break;
285 case O_RDWR | O_CREAT | O_TRUNC:
286 dwMode = CREATE_ALWAYS;
287 break;
288 default:
289 return ((TIFF *)0);
292 fd = (thandle_t)CreateFileA(
293 name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
294 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
295 (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
296 NULL);
297 if (fd == INVALID_HANDLE_VALUE)
299 _TIFFErrorEarly(opts, NULL, module, "%s: Cannot open", name);
300 return ((TIFF *)0);
303 tif = TIFFFdOpenExt(thandle_to_int(fd), name, mode, opts);
304 if (!tif)
305 CloseHandle(fd);
306 return tif;
310 * Open a TIFF file with a Unicode filename, for read/writing.
312 TIFF *TIFFOpenW(const wchar_t *name, const char *mode)
314 return TIFFOpenWExt(name, mode, NULL);
317 TIFF *TIFFOpenWExt(const wchar_t *name, const char *mode, TIFFOpenOptions *opts)
319 static const char module[] = "TIFFOpenW";
320 thandle_t fd;
321 int m;
322 DWORD dwMode;
323 int mbsize;
324 char *mbname;
325 TIFF *tif;
327 m = _TIFFgetMode(opts, NULL, mode, module);
329 switch (m)
331 case O_RDONLY:
332 dwMode = OPEN_EXISTING;
333 break;
334 case O_RDWR:
335 dwMode = OPEN_EXISTING;
336 break;
337 case O_RDWR | O_CREAT:
338 dwMode = OPEN_ALWAYS;
339 break;
340 case O_RDWR | O_TRUNC:
341 dwMode = CREATE_ALWAYS;
342 break;
343 case O_RDWR | O_CREAT | O_TRUNC:
344 dwMode = CREATE_ALWAYS;
345 break;
346 default:
347 return ((TIFF *)0);
350 fd = (thandle_t)CreateFileW(
351 name, (m == O_RDONLY) ? GENERIC_READ : (GENERIC_READ | GENERIC_WRITE),
352 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwMode,
353 (m == O_RDONLY) ? FILE_ATTRIBUTE_READONLY : FILE_ATTRIBUTE_NORMAL,
354 NULL);
355 if (fd == INVALID_HANDLE_VALUE)
357 _TIFFErrorEarly(opts, NULL, module, "%S: Cannot open", name);
358 return ((TIFF *)0);
361 mbname = NULL;
362 mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
363 if (mbsize > 0)
365 mbname = (char *)_TIFFmalloc(mbsize);
366 if (!mbname)
368 _TIFFErrorEarly(
369 opts, NULL, module,
370 "Can't allocate space for filename conversion buffer");
371 return ((TIFF *)0);
374 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, NULL, NULL);
377 tif = TIFFFdOpenExt(thandle_to_int(fd),
378 (mbname != NULL) ? mbname : "<unknown>", mode, opts);
379 if (!tif)
380 CloseHandle(fd);
382 _TIFFfree(mbname);
384 return tif;
387 #endif /* ndef _WIN32_WCE */
389 void *_TIFFmalloc(tmsize_t s)
391 if (s == 0)
392 return ((void *)NULL);
394 return (malloc((size_t)s));
397 void *_TIFFcalloc(tmsize_t nmemb, tmsize_t siz)
399 if (nmemb == 0 || siz == 0)
400 return ((void *)NULL);
402 return calloc((size_t)nmemb, (size_t)siz);
405 void _TIFFfree(void *p) { free(p); }
407 void *_TIFFrealloc(void *p, tmsize_t s) { return (realloc(p, (size_t)s)); }
409 void _TIFFmemset(void *p, int v, tmsize_t c) { memset(p, v, (size_t)c); }
411 void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
413 memcpy(d, s, (size_t)c);
416 int _TIFFmemcmp(const void *p1, const void *p2, tmsize_t c)
418 return (memcmp(p1, p2, (size_t)c));
421 #ifndef _WIN32_WCE
423 static void Win32WarningHandler(const char *module, const char *fmt, va_list ap)
425 if (module != NULL)
426 fprintf(stderr, "%s: ", module);
427 fprintf(stderr, "Warning, ");
428 vfprintf(stderr, fmt, ap);
429 fprintf(stderr, ".\n");
431 TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
433 static void Win32ErrorHandler(const char *module, const char *fmt, va_list ap)
435 if (module != NULL)
436 fprintf(stderr, "%s: ", module);
437 vfprintf(stderr, fmt, ap);
438 fprintf(stderr, ".\n");
440 TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
442 #endif /* ndef _WIN32_WCE */