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