1 /* PDFlib GmbH cvsid:
2  * $Id: tif_unix.c,v 1.29 2006/07/26 22:00:41 rjs Exp $ */
3 
4 /*
5  * Copyright (c) 1988-1997 Sam Leffler
6  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7  *
8  * Permission to use, copy, modify, distribute, and sell this software and
9  * its documentation for any purpose is hereby granted without fee, provided
10  * that (i) the above copyright notices and this permission notice appear in
11  * all copies of the software and related documentation, and (ii) the names of
12  * Sam Leffler and Silicon Graphics may not be used in any advertising or
13  * publicity relating to the software without the specific, prior written
14  * permission of Sam Leffler and Silicon Graphics.
15  *
16  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
18  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
21  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
22  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
24  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
25  * OF THIS SOFTWARE.
26  */
27 
28 /*
29  * TIFF Library UNIX-specific Routines. These are should also work with the
30  * Windows Common RunTime Library.
31  */
32 #include "tiffconf.h"
33 
34 #include <stdlib.h>
35 #include <sys/stat.h>
36 
37 #ifdef HAVE_UNISTD_H
38 # include <unistd.h>
39 #endif
40 
41 #ifdef HAVE_FCNTL_H
42 # include <fcntl.h>
43 #endif
44 
45 #ifdef HAVE_SYS_TYPES_H
46 # include <sys/types.h>
47 #endif
48 
49 #ifdef HAVE_IO_H
50 # include <io.h>
51 #endif
52 
53 #include "tiffiop.h"
54 #include "pc_config.h"
55 
56 static tsize_t
_tiffReadProc(void * fd,tdata_t buf,tsize_t size)57 _tiffReadProc(void* fd, tdata_t buf, tsize_t size)
58 {
59 	return ((tsize_t) fread(buf, 1, (size_t) size, (FILE *)fd));
60 }
61 
62 static tsize_t
_tiffWriteProc(void * fd,tdata_t buf,tsize_t size)63 _tiffWriteProc(void* fd, tdata_t buf, tsize_t size)
64 {
65     return ((tsize_t) fwrite(buf, 1, (size_t) size, (FILE *)fd));
66 }
67 
68 static toff_t
_tiffSeekProc(void * fd,toff_t off,int whence)69 _tiffSeekProc(void* fd, toff_t off, int whence)
70 {
71     toff_t retval;
72     retval = fseek((FILE *)fd, (long) off, whence);
73     if (retval == 0)
74     {
75         return (ftell((FILE *)fd));
76     }
77     else
78     {
79         return (-1);
80     }
81 
82     /* return ((toff_t) fseek((FILE *)fd, (long) off, whence));*/
83 }
84 
85 static int
_tiffCloseProc(void * fd)86 _tiffCloseProc(void* fd)
87 {
88         return (fclose((FILE *)fd));
89 }
90 
91 static toff_t
_tiffSizeProc(void * fd)92 _tiffSizeProc(void* fd)
93 {
94 #if defined(MVS) && defined(I370)
95 #define PDF_FTELL_BUSIZE        32000
96 
97 	char buf[PDF_FTELL_BUSIZE];
98 	size_t filelen = 0;
99 
100         fseek((FILE *)fd, 0, SEEK_SET);
101 
102         while (!feof((FILE *)fd))
103                 filelen += fread((void *) buf, 1, PDF_FTELL_BUSIZE, (FILE *)fd);
104 
105 	return filelen;
106 #else
107         fseek((FILE *)fd, 0, SEEK_END);
108         return (toff_t) ftell((FILE *)fd);
109 #endif
110 }
111 
112 #ifdef HAVE_MMAP
113 #include <sys/mman.h>
114 
115 static int
_tiffMapProc(void * fd,tdata_t * pbase,toff_t * psize)116 _tiffMapProc(void* fd, tdata_t* pbase, toff_t* psize)
117 {
118         toff_t size = _tiffSizeProc((FILE *)fd);
119 	if (size != (toff_t) -1) {
120 		*pbase = (tdata_t)
121                     mmap(0, size, PROT_READ, MAP_SHARED, (FILE *) fd, 0);
122 		if (*pbase != (tdata_t) -1) {
123 			*psize = size;
124 			return (1);
125 		}
126 	}
127 	return (0);
128 }
129 
130 static void
_tiffUnmapProc(void * fd,tdata_t base,toff_t size)131 _tiffUnmapProc(void* fd, tdata_t base, toff_t size)
132 {
133 	(void) fd;
134 	(void) munmap(base, (off_t) size);
135 }
136 #else /* !HAVE_MMAP */
137 static int
_tiffMapProc(void * fd,tdata_t * pbase,toff_t * psize)138 _tiffMapProc(void* fd, tdata_t* pbase, toff_t* psize)
139 {
140 	(void) fd; (void) pbase; (void) psize;
141 	return (0);
142 }
143 
144 static void
_tiffUnmapProc(void * fd,tdata_t base,toff_t size)145 _tiffUnmapProc(void* fd, tdata_t base, toff_t size)
146 {
147 	(void) fd; (void) base; (void) size;
148 }
149 #endif /* !HAVE_MMAP */
150 
151 /*
152  * Open a TIFF file descriptor for read/writing.
153  */
154 TIFF*
TIFFFdOpen(void * fd,const char * name,const char * mode,void * pdflib_opaque,TIFFmallocHandler malloc_h,TIFFreallocHandler realloc_h,TIFFfreeHandler free_h,TIFFErrorHandler error_h,TIFFErrorHandler warn_h)155 TIFFFdOpen(void* fd, const char* name, const char* mode, void* pdflib_opaque,
156         TIFFmallocHandler malloc_h, TIFFreallocHandler realloc_h,
157         TIFFfreeHandler free_h, TIFFErrorHandler error_h,
158         TIFFErrorHandler warn_h)
159 {
160         TIFF* tif;
161 
162         tif = TIFFClientOpen(name, mode, fd,
163             _tiffReadProc, _tiffWriteProc,
164             _tiffSeekProc, _tiffCloseProc, _tiffSizeProc,
165             _tiffMapProc, _tiffUnmapProc, pdflib_opaque,
166             malloc_h, realloc_h, free_h, error_h, warn_h);
167         if (tif)
168                 tif->tif_fd = (FILE *)fd;
169         return (tif);
170 }
171 
172 /*
173  * Open a TIFF file for read/writing.
174  */
175 TIFF*
TIFFOpen(const char * name,const char * mode,void * pdflib_opaque,TIFFmallocHandler malloc_h,TIFFreallocHandler realloc_h,TIFFfreeHandler free_h,TIFFErrorHandler error_h,TIFFErrorHandler warn_h)176 TIFFOpen(const char* name, const char* mode, void* pdflib_opaque,
177         TIFFmallocHandler malloc_h, TIFFreallocHandler realloc_h,
178         TIFFfreeHandler free_h, TIFFErrorHandler error_h,
179         TIFFErrorHandler warn_h)
180 {
181         static const char module[] = "TIFFOpen";
182         FILE *fd;
183 	TIFF *tif = NULL;
184 	int m;
185 
186 	m = _TIFFgetMode(mode, module);
187 	if (m == -1)
188 		return ((TIFF*)0);
189 
190 	if (m == O_RDONLY) {
191 	    fd = fopen(name, READBMODE);
192 	} else {
193 	    fd = fopen(name, WRITEMODE);
194 	}
195 
196         if (fd == NULL) {
197                 _TIFFError(tif, module, "%s: Cannot open", name);
198                 return ((TIFF *)0);
199         }
200         tif = TIFFFdOpen(fd, name, mode, pdflib_opaque,
201                         malloc_h, realloc_h, free_h, error_h, warn_h);
202 	if(!tif)
203 		fclose(fd);
204 	return tif;
205 }
206 
207 #ifdef __WIN32__
208 #include <windows.h>
209 /*
210  * Open a TIFF file with a Unicode filename, for read/writing.
211  */
212 TIFF*
TIFFOpenW(const wchar_t * name,const char * mode,void * pdflib_opaque,TIFFmallocHandler malloc_h,TIFFreallocHandler realloc_h,TIFFfreeHandler free_h,TIFFErrorHandler error_h,TIFFErrorHandler warn_h)213 TIFFOpenW(const wchar_t* name, const char* mode, void* pdflib_opaque,
214         TIFFmallocHandler malloc_h, TIFFreallocHandler realloc_h,
215         TIFFfreeHandler free_h, TIFFErrorHandler error_h,
216         TIFFErrorHandler warn_h)
217 {
218 	static const char module[] = "TIFFOpenW";
219 	FILE *fd;
220 	int mbsize;
221 	char *mbname;
222 	TIFF* tif;
223 	int m;
224 
225 	m = _TIFFgetMode(mode, module);
226 	if (m == -1)
227 		return ((TIFF*)0);
228 
229 	if (m == O_RDONLY) {
230 	    fd = _wfopen(name, READBMODE);
231 	} else {
232 	    fd = _wfopen(name, WRITEMODE);
233 	}
234         if (fd == NULL) {
235 		_TIFFError(tif, module, "%s: Cannot open", name);
236 		return ((TIFF *)0);
237 	}
238 
239 	mbname = NULL;
240 	mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL);
241 	if (mbsize > 0) {
242 		mbname = _TIFFmalloc(mbsize);
243 		if (!mbname) {
244 			_TIFFError(tif, module,
245 			"Can't allocate space for filename conversion buffer");
246 			return ((TIFF*)0);
247 		}
248 
249 		WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize,
250 				    NULL, NULL);
251 	}
252 
253         tif = TIFFFdOpen(fd, (mbname != NULL) ? mbname : "<unknown>",
254 			mode, pdflib_opaque,
255                         malloc_h, realloc_h, free_h, error_h, warn_h);
256 
257 	_TIFFfree(mbname);
258 
259 	if(!tif)
260 		fclose(fd);
261 	return tif;
262 }
263 #endif
264 
265 void*
TIFFmalloc(TIFF * tif,tsize_t s)266 TIFFmalloc(TIFF* tif, tsize_t s)
267 {
268         if (tif->pdflib_malloc != NULL)
269             return (tif->pdflib_malloc(tif, (size_t) s));
270         else
271             return (malloc((size_t) s));
272 }
273 
274 void
TIFFfree(TIFF * tif,tdata_t p)275 TIFFfree(TIFF* tif, tdata_t p)
276 {
277         if (tif->pdflib_free != NULL)
278             tif->pdflib_free(tif, p);
279         else
280             free(p);
281 }
282 
283 void*
TIFFrealloc(TIFF * tif,tdata_t p,tsize_t s)284 TIFFrealloc(TIFF* tif, tdata_t p, tsize_t s)
285 {
286         if (tif->pdflib_realloc != NULL)
287             return (tif->pdflib_realloc(tif, p, (size_t) s));
288         else
289             return (realloc(p, (size_t) s));
290 }
291 
292 void
_TIFFmemset(tdata_t p,int v,tsize_t c)293 _TIFFmemset(tdata_t p, int v, tsize_t c)
294 {
295 	memset(p, v, (size_t) c);
296 }
297 
298 void
_TIFFmemcpy(tdata_t d,const tdata_t s,tsize_t c)299 _TIFFmemcpy(tdata_t d, const tdata_t s, tsize_t c)
300 {
301 	memcpy(d, s, (size_t) c);
302 }
303 
304 int
_TIFFmemcmp(const tdata_t p1,const tdata_t p2,tsize_t c)305 _TIFFmemcmp(const tdata_t p1, const tdata_t p2, tsize_t c)
306 {
307 	return (memcmp(p1, p2, (size_t) c));
308 }
309 
310 static void
unixWarningHandler(TIFF * tif,const char * module,const char * fmt,va_list ap)311 unixWarningHandler(TIFF* tif, const char* module, const char* fmt, va_list ap)
312 {
313 	(void) tif;
314 
315 	if (module != NULL)
316 		fprintf(stderr, "%s: ", module);
317 	fprintf(stderr, "Warning, ");
318 	vfprintf(stderr, fmt, ap);
319 	fprintf(stderr, ".\n");
320 }
321 TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler;
322 
323 static void
unixErrorHandler(TIFF * tif,const char * module,const char * fmt,va_list ap)324 unixErrorHandler(TIFF* tif, const char* module, const char* fmt, va_list ap)
325 {
326 	(void) tif;
327 
328 	if (module != NULL)
329 		fprintf(stderr, "%s: ", module);
330 	vfprintf(stderr, fmt, ap);
331 	fprintf(stderr, ".\n");
332 }
333 TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler;
334