[LIBTIFF] Update to version 4.0.10. CORE-15854
[reactos.git] / dll / 3rdparty / libtiff / tif_win32.c
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 */