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