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