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