1/* $Header$ */
2
3/*
4 * Copyright (c) 1988-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 *
7 * modifed for use with OS/2 by David Webster
8 *
9 * Permission to use, copy, modify, distribute, and sell this software and
10 * its documentation for any purpose is hereby granted without fee, provided
11 * that (i) the above copyright notices and this permission notice appear in
12 * all copies of the software and related documentation, and (ii) the names of
13 * Sam Leffler and Silicon Graphics may not be used in any advertising or
14 * publicity relating to the software without the specific, prior written
15 * permission of Sam Leffler and Silicon Graphics.
16 *
17 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
19 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20 *
21 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
22 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
23 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
25 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26 * OF THIS SOFTWARE.
27 */
28
29/*
30 * TIFF Library OS/2-specific Routines.  Adapted from tif_win32.c 2/16/00 by
31 * David Webster (dwebster@bhmi.com), Baldwin, Hackett, and Meeks, Inc., Omaha, NE USA
32 */
33#define INCL_PM
34#define INCL_BASE
35#include <os2.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include "tiffiop.h"
39
40/* Some windows datatypes */
41
42typedef ULONG DWORD;
43typedef ULONG HANDLE;
44typedef PCHAR LPTSTR;
45typedef const PCHAR LPCTSTR;
46typedef CHAR TCHAR;
47#define GlobalAlloc(a,b) malloc(b)
48#define LocalAlloc(a,b) malloc(b)
49#define GlobalFree(b) free(b)
50#define LocalFree(b) free(b)
51#define GlobalReAlloc(p, s, t) realloc(p, s)
52#define CopyMemory(p, v, s) memcpy(p, v, s)
53#define FillMemory(p, c, s) memset(p, c, s)
54#define GlobalSize(p) sizeof(p)
55#define wsprintf sprintf
56#define wvsprintf vsprintf
57#define lstrlen strlen
58
59static tsize_t LINKAGEMODE
60_tiffReadProc(thandle_t fd, tdata_t buf, tsize_t size)
61{
62	DWORD dwSizeRead;
63	if (!DosRead((HFILE)fd, buf, size, &dwSizeRead))
64		return(0);
65	return ((tsize_t) dwSizeRead);
66}
67
68static tsize_t LINKAGEMODE
69_tiffWriteProc(thandle_t fd, tdata_t buf, tsize_t size)
70{
71	DWORD dwSizeWritten;
72	if (!DosWrite((HFILE)fd, buf, size, &dwSizeWritten))
73		return(0);
74	return ((tsize_t) dwSizeWritten);
75}
76
77static toff_t LINKAGEMODE
78_tiffSeekProc(thandle_t fd, toff_t off, int whence)
79{
80	DWORD dwMoveMethod;
81    ULONG ibActual;
82	switch(whence)
83	{
84	case 0:
85		dwMoveMethod = FILE_BEGIN;
86		break;
87	case 1:
88		dwMoveMethod = FILE_CURRENT;
89		break;
90	case 2:
91		dwMoveMethod = FILE_END;
92		break;
93	default:
94		dwMoveMethod = FILE_BEGIN;
95		break;
96	}
97	DosSetFilePtr((HFILE)fd, off, dwMoveMethod, &ibActual);
98 return((toff_t)ibActual);
99}
100
101static int LINKAGEMODE
102_tiffCloseProc(thandle_t fd)
103{
104	return (DosClose((HFILE)fd) ? 0 : -1);
105}
106
107static toff_t LINKAGEMODE
108_tiffSizeProc(thandle_t fd)
109{
110   FILESTATUS3    vStatus;
111
112   DosQueryFileInfo((HFILE)fd, FIL_STANDARD, &vStatus, sizeof(FILESTATUS3));
113   return (vStatus.cbFile);
114}
115
116static int LINKAGEMODE
117_tiffDummyMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
118{
119	return (0);
120}
121
122/*
123 * From "Hermann Josef Hill" <lhill@rhein-zeitung.de>:
124 *
125 * Windows uses both a handle and a pointer for file mapping,
126 * but according to the SDK documentation and Richter's book
127 * "Advanced Windows Programming" it is safe to free the handle
128 * after obtaining the file mapping pointer
129 *
130 * This removes a nasty OS dependency and cures a problem
131 * with Visual C++ 5.0
132 */
133static int LINKAGEMODE
134_tiffMapProc(thandle_t fd, tdata_t* pbase, toff_t* psize)
135{
136    return(0);
137}
138
139static void LINKAGEMODE
140_tiffDummyUnmapProc(thandle_t fd, tdata_t base, toff_t size)
141{
142}
143
144static void LINKAGEMODE
145_tiffUnmapProc(thandle_t fd, tdata_t base, toff_t size)
146{
147}
148
149/*
150 * Open a TIFF file descriptor for read/writing.
151 * Note that TIFFFdOpen and TIFFOpen recognise the character 'u' in the mode
152 * string, which forces the file to be opened unmapped.
153 */
154TIFF*
155TIFFFdOpen(int ifd, const char* name, const char* mode)
156{
157	TIFF* tif;
158	BOOL fSuppressMap = (mode[1] == 'u' || mode[2] == 'u');
159
160	tif = TIFFClientOpen(name, mode,
161		 (thandle_t)ifd,
162	    _tiffReadProc, _tiffWriteProc,
163	    _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
164		 fSuppressMap ? _tiffDummyMapProc : _tiffMapProc,
165		 fSuppressMap ? _tiffDummyUnmapProc : _tiffUnmapProc);
166	if (tif)
167		tif->tif_fd = ifd;
168	return (tif);
169}
170
171/*
172 * Open a TIFF file for read/writing.
173 */
174TIFF*
175TIFFOpen(const char* name, const char* mode)
176{
177	static const char module[] = "TIFFOpen";
178	thandle_t fd;
179	int m;
180	DWORD dwOpenMode;
181 DWORD dwOpenFlags;
182 DWORD dwAction;
183 APIRET ulrc;
184
185	m = _TIFFgetMode(mode, module);
186
187	switch(m)
188	{
189	case O_RDONLY:
190		dwOpenMode = OPEN_ACCESS_READONLY;
191		dwOpenFlags = OPEN_ACTION_FAIL_IF_NEW;
192		break;
193	case O_RDWR:
194		dwOpenMode = OPEN_ACCESS_READWRITE;
195		dwOpenFlags = OPEN_ACTION_FAIL_IF_NEW;
196		break;
197	case O_RDWR|O_CREAT:
198		dwOpenMode = OPEN_ACCESS_READWRITE;
199		dwOpenFlags = OPEN_ACTION_CREATE_IF_NEW;
200		break;
201	case O_RDWR|O_TRUNC:
202		dwOpenMode = OPEN_ACCESS_READWRITE;
203		dwOpenFlags = OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS;
204		break;
205	case O_RDWR|O_CREAT|O_TRUNC:
206		dwOpenMode = OPEN_ACCESS_READWRITE;
207		dwOpenFlags = OPEN_ACTION_CREATE_IF_NEW | OPEN_ACTION_REPLACE_IF_EXISTS;
208		break;
209	default:
210		return ((TIFF*)0);
211	}
212 ulrc = DosOpen( name, (HFILE*)&fd, &dwAction, FILE_ARCHIVED|FILE_NORMAL
213                ,1000L, dwOpenFlags, dwOpenMode, NULL
214               );
215	if (fd != NO_ERROR) {
216		TIFFError(module, "%s: Cannot open", name);
217		return ((TIFF *)0);
218	}
219	return (TIFFFdOpen((int)fd, name, mode));
220}
221
222tdata_t
223_TIFFmalloc(tsize_t s)
224{
225	return ((tdata_t)GlobalAlloc(GMEM_FIXED, s));
226}
227
228void
229_TIFFfree(tdata_t p)
230{
231	GlobalFree(p);
232	return;
233}
234
235tdata_t
236_TIFFrealloc(tdata_t p, tsize_t s)
237{
238	void* pvTmp;
239	if ((pvTmp = GlobalReAlloc(p, s, 0)) == NULL) {
240		if ((pvTmp = GlobalAlloc(sGMEM_FIXED, s)) != NULL) {
241			CopyMemory(pvTmp, p, GlobalSize(p));
242			GlobalFree(p);
243		}
244	}
245	return ((tdata_t)pvTmp);
246}
247
248void
249_TIFFmemset(void* p, int v, tsize_t c)
250{
251	FillMemory(p, c, (BYTE)v);
252}
253
254void
255_TIFFmemcpy(void* d, const tdata_t s, tsize_t c)
256{
257	CopyMemory(d, s, c);
258}
259
260int
261_TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
262{
263	register const *pb1 = (const int*)p1;
264	register const *pb2 = (const int*)p2;
265	register DWORD dwTmp = c;
266	register int iTmp;
267	for (iTmp = 0; dwTmp-- && !iTmp; iTmp = (int)*pb1++ - (int)*pb2++)
268		;
269	return (iTmp);
270}
271
272static void LINKAGEMODE
273Os2WarningHandler(const char* module, const char* fmt, va_list ap)
274{
275#ifndef TIF_PLATFORM_CONSOLE
276	LPTSTR szTitle;
277	LPTSTR szTmp;
278	LPCTSTR szTitleText = "%s Warning";
279	LPCTSTR szDefaultModule = "TIFFLIB";
280	szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module;
281	if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) +
282			lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL)
283		return;
284	wsprintf(szTitle, szTitleText, szTmp);
285	szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR);
286	wvsprintf(szTmp, fmt, ap);
287	WinMessageBox( HWND_DESKTOP
288               ,WinQueryFocus(HWND_DESKTOP)
289               ,szTmp
290               ,szTitle
291               ,0
292               ,MB_OK | MB_INFORMATION
293              );
294	LocalFree(szTitle);
295	return;
296#else
297	if (module != NULL)
298		fprintf(stderr, "%s: ", module);
299	fprintf(stderr, "Warning, ");
300	vfprintf(stderr, fmt, ap);
301	fprintf(stderr, ".\n");
302#endif
303}
304TIFFErrorHandler _TIFFwarningHandler = Os2WarningHandler;
305
306static void LINKAGEMODE
307Os2ErrorHandler(const char* module, const char* fmt, va_list ap)
308{
309#ifndef TIF_PLATFORM_CONSOLE
310	LPTSTR szTitle;
311	LPTSTR szTmp;
312	LPCTSTR szTitleText = "%s Error";
313	LPCTSTR szDefaultModule = "TIFFLIB";
314	szTmp = (module == NULL) ? (LPTSTR)szDefaultModule : (LPTSTR)module;
315	if ((szTitle = (LPTSTR)LocalAlloc(LMEM_FIXED, (lstrlen(szTmp) +
316			lstrlen(szTitleText) + lstrlen(fmt) + 128)*sizeof(TCHAR))) == NULL)
317		return;
318	wsprintf(szTitle, szTitleText, szTmp);
319	szTmp = szTitle + (lstrlen(szTitle)+2)*sizeof(TCHAR);
320	wvsprintf(szTmp, fmt, ap);
321	WinMessageBox( HWND_DESKTOP
322               ,WinQueryFocus(HWND_DESKTOP)
323               ,szTmp
324               ,szTitle
325               ,0
326               ,MB_OK | MB_ICONEXCLAMATION
327              );
328	LocalFree(szTitle);
329	return;
330#else
331	if (module != NULL)
332		fprintf(stderr, "%s: ", module);
333	vfprintf(stderr, fmt, ap);
334	fprintf(stderr, ".\n");
335#endif
336}
337TIFFErrorHandler _TIFFerrorHandler = Os2ErrorHandler;
338
339