Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libtiff / tif_win32.c
1 /* $Id: tif_win32.c,v 1.1 2005-06-17 13:54:52 vp153 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 static tsize_t
34 _tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
35 {
36         DWORD dwSizeRead;
37         if (!ReadFile(fd, buf, size, &dwSizeRead, NULL))
38                 return(0);
39         return ((tsize_t) dwSizeRead);
40 }
41
42 static tsize_t
43 _tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
44 {
45         DWORD dwSizeWritten;
46         if (!WriteFile(fd, buf, size, &dwSizeWritten, NULL))
47                 return(0);
48         return ((tsize_t) dwSizeWritten);
49 }
50
51 static toff_t
52 _tiffSeekProc(thandle_t fd, toff_t off, int whence)
53 {
54         DWORD dwMoveMethod, dwMoveHigh;
55
56         /* we use this as a special code, so avoid accepting it */
57         if( off == 0xFFFFFFFF )
58             return 0xFFFFFFFF;
59         
60         switch(whence)
61         {
62         case SEEK_SET:
63                 dwMoveMethod = FILE_BEGIN;
64                 break;
65         case SEEK_CUR:
66                 dwMoveMethod = FILE_CURRENT;
67                 break;
68         case SEEK_END:
69                 dwMoveMethod = FILE_END;
70                 break;
71         default:
72                 dwMoveMethod = FILE_BEGIN;
73                 break;
74         }
75         dwMoveHigh = 0;
76         return ((toff_t)SetFilePointer(fd, (LONG) off, (PLONG)&dwMoveHigh,
77                                        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 #ifdef __BORLANDC__
93 #pragma argsused
94 #endif
95 static int
96 _tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
97 {
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 #ifdef __BORLANDC__
132 #pragma argsused
133 #endif
134 static void
135 _tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
136 {
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 /*
167  * Open a TIFF file for read/writing.
168  */
169 TIFF*
170 TIFFOpen(const char* name, const char* mode)
171 {
172         static const char module[] = "TIFFOpen";
173         thandle_t fd;
174         int m;
175         DWORD dwMode;
176         TIFF* tif;
177
178         m = _TIFFgetMode(mode, module);
179
180         switch(m)
181         {
182         case O_RDONLY:
183                 dwMode = OPEN_EXISTING;
184                 break;
185         case O_RDWR:
186                 dwMode = OPEN_ALWAYS;
187                 break;
188         case O_RDWR|O_CREAT:
189                 dwMode = OPEN_ALWAYS;
190                 break;
191         case O_RDWR|O_TRUNC:
192                 dwMode = CREATE_ALWAYS;
193                 break;
194         case O_RDWR|O_CREAT|O_TRUNC:
195                 dwMode = CREATE_ALWAYS;
196                 break;
197         default:
198                 return ((TIFF*)0);
199         }
200         fd = (thandle_t)CreateFileA(name,
201                 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ | GENERIC_WRITE),
202                 FILE_SHARE_READ, NULL, dwMode,
203                 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
204                 NULL);
205         if (fd == INVALID_HANDLE_VALUE) {
206                 TIFFError(module, "%s: Cannot open", name);
207                 return ((TIFF *)0);
208         }
209
210         tif = TIFFFdOpen((int)fd, name, mode);
211         if(!tif)
212                 CloseHandle(fd);
213         return tif;
214 }
215
216 /*
217  * Open a TIFF file with a Unicode filename, for read/writing.
218  */
219 TIFF*
220 TIFFOpenW(const wchar_t* name, const char* mode)
221 {
222         static const char module[] = "TIFFOpenW";
223         thandle_t fd;
224         int m;
225         DWORD dwMode;
226         int mbsize;
227         char *mbname;
228         TIFF *tif;
229
230         m = _TIFFgetMode(mode, module);
231
232         switch(m) {
233                 case O_RDONLY:                  dwMode = OPEN_EXISTING; break;
234                 case O_RDWR:                    dwMode = OPEN_ALWAYS;   break;
235                 case O_RDWR|O_CREAT:            dwMode = OPEN_ALWAYS;   break;
236                 case O_RDWR|O_TRUNC:            dwMode = CREATE_ALWAYS; break;
237                 case O_RDWR|O_CREAT|O_TRUNC:    dwMode = CREATE_ALWAYS; break;
238                 default:                        return ((TIFF*)0);
239         }
240
241         fd = (thandle_t)CreateFileW(name,
242                 (m == O_RDONLY)?GENERIC_READ:(GENERIC_READ|GENERIC_WRITE),
243                 FILE_SHARE_READ, NULL, dwMode,
244                 (m == O_RDONLY)?FILE_ATTRIBUTE_READONLY:FILE_ATTRIBUTE_NORMAL,
245                 NULL);
246         if (fd == INVALID_HANDLE_VALUE) {
247                 TIFFError(module, "%S: Cannot open", name);
248                 return ((TIFF *)0);
249         }
250
251         mbname = NULL;
252         mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
253         if (mbsize > 0) {
254                 mbname = _TIFFmalloc(mbsize);
255                 if (!mbname) {
256                         TIFFError(module,
257                         "Can't allocate space for filename conversion buffer");
258                         return ((TIFF*)0);
259                 }
260
261                 WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
262                                     NULL, NULL);
263         }
264
265         tif = TIFFFdOpen((int)fd,
266                          (mbname != NULL) ? mbname : "<unknown>", mode);
267
268         _TIFFfree(mbname);
269
270         return tif;
271 }
272
273 tdata_t
274 _TIFFmalloc(tsize_t s)
275 {
276         return ((tdata_t)GlobalAlloc(GMEM_FIXED, s));
277 }
278
279 void
280 _TIFFfree(tdata_t p)
281 {
282         GlobalFree(p);
283         return;
284 }
285
286 tdata_t
287 _TIFFrealloc(tdata_t p, tsize_t s)
288 {
289         void* pvTmp;
290         tsize_t old;
291
292         if(p == NULL)
293                 return ((tdata_t)GlobalAlloc(GMEM_FIXED, s));
294
295         old = GlobalSize(p);
296
297         if (old>=s) {
298                 if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) {
299                         CopyMemory(pvTmp, p, s);
300                         GlobalFree(p);
301                 }
302         } else {
303                 if ((pvTmp = GlobalAlloc(GMEM_FIXED, s)) != NULL) {
304                         CopyMemory(pvTmp, p, old);
305                         GlobalFree(p);
306                 }
307         }
308         return ((tdata_t)pvTmp);
309 }
310
311 void
312 _TIFFmemset(void* p, int v, tsize_t c)
313 {
314         FillMemory(p, c, (BYTE)v);
315 }
316
317 void
318 _TIFFmemcpy(void* d, const tdata_t s, tsize_t c)
319 {
320         CopyMemory(d, s, c);
321 }
322
323 int
324 _TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
325 {
326         register const BYTE *pb1 = (const BYTE *) p1;
327         register const BYTE *pb2 = (const BYTE *) p2;
328         register DWORD dwTmp = c;
329         register int iTmp;
330         for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++)
331                 ;
332         return (iTmp);
333 }
334
335 static void
336 Win32WarningHandler(const char* module, const char* fmt, va_list ap)
337 {
338 #ifndef TIF_PLATFORM_CONSOLE
339         LPTSTR szTitle;
340         LPTSTR szTmp;
341         LPCTSTR szTitleText = "%s Warning";
342         LPCTSTR szDefaultModule = "LIBTIFF";
343         LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
344         if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) +
345                 strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL)
346                 return;
347         sprintf(szTitle, szTitleText, szTmpModule);
348         szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
349         vsprintf(szTmp, fmt, ap);
350         MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONINFORMATION);
351         LocalFree(szTitle);
352         return;
353 #else
354         if (module != NULL)
355                 fprintf(stderr, "%s: ", module);
356         fprintf(stderr, "Warning, ");
357         vfprintf(stderr, fmt, ap);
358         fprintf(stderr, ".\n");
359 #endif        
360 }
361 TIFFErrorHandler _TIFFwarningHandler = Win32WarningHandler;
362
363 static void
364 Win32ErrorHandler(const char* module, const char* fmt, va_list ap)
365 {
366 #ifndef TIF_PLATFORM_CONSOLE
367         LPTSTR szTitle;
368         LPTSTR szTmp;
369         LPCTSTR szTitleText = "%s Error";
370         LPCTSTR szDefaultModule = "LIBTIFF";
371         LPCTSTR szTmpModule = (module == NULL) ? szDefaultModule : module;
372         if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (strlen(szTmpModule) +
373                 strlen(szTitleText) + strlen(fmt) + 128)*sizeof(char))) == NULL)
374                 return;
375         sprintf(szTitle, szTitleText, szTmpModule);
376         szTmp = szTitle + (strlen(szTitle)+2)*sizeof(char);
377         vsprintf(szTmp, fmt, ap);
378         MessageBoxA(GetFocus(), szTmp, szTitle, MB_OK | MB_ICONEXCLAMATION);
379         LocalFree(szTitle);
380         return;
381 #else
382         if (module != NULL)
383                 fprintf(stderr, "%s: ", module);
384         vfprintf(stderr, fmt, ap);
385         fprintf(stderr, ".\n");
386 #endif        
387 }
388 TIFFErrorHandler _TIFFerrorHandler = Win32ErrorHandler;
389
390 /* vim: set ts=8 sts=8 sw=8 noet: */