blob: 1387558fbabc5bfaebe7b5352fbba352ae912f8f
1 | /* $Id: tif_unix.c,v 1.23 2012-06-01 21:40:59 fwarmerdam 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 UNIX-specific Routines. These are should also work with the |
29 | * Windows Common RunTime Library. |
30 | */ |
31 | |
32 | #include "tif_config.h" |
33 | |
34 | #ifdef HAVE_SYS_TYPES_H |
35 | # include <sys/types.h> |
36 | #endif |
37 | |
38 | #include <errno.h> |
39 | |
40 | #include <stdarg.h> |
41 | #include <stdlib.h> |
42 | #include <sys/stat.h> |
43 | |
44 | #ifdef HAVE_UNISTD_H |
45 | # include <unistd.h> |
46 | #endif |
47 | |
48 | #ifdef HAVE_FCNTL_H |
49 | # include <fcntl.h> |
50 | #endif |
51 | |
52 | #ifdef HAVE_IO_H |
53 | # include <io.h> |
54 | #endif |
55 | |
56 | #include "tiffiop.h" |
57 | |
58 | static tmsize_t |
59 | _tiffReadProc(thandle_t fd, void* buf, tmsize_t size) |
60 | { |
61 | size_t size_io = (size_t) size; |
62 | if ((tmsize_t) size_io != size) |
63 | { |
64 | errno=EINVAL; |
65 | return (tmsize_t) -1; |
66 | } |
67 | return ((tmsize_t) read((int) fd, buf, size_io)); |
68 | } |
69 | |
70 | static tmsize_t |
71 | _tiffWriteProc(thandle_t fd, void* buf, tmsize_t size) |
72 | { |
73 | size_t size_io = (size_t) size; |
74 | if ((tmsize_t) size_io != size) |
75 | { |
76 | errno=EINVAL; |
77 | return (tmsize_t) -1; |
78 | } |
79 | return ((tmsize_t) write((int) fd, buf, size_io)); |
80 | } |
81 | |
82 | static uint64 |
83 | _tiffSeekProc(thandle_t fd, uint64 off, int whence) |
84 | { |
85 | off_t off_io = (off_t) off; |
86 | if ((uint64) off_io != off) |
87 | { |
88 | errno=EINVAL; |
89 | return (uint64) -1; /* this is really gross */ |
90 | } |
91 | return((uint64)lseek((int)fd,off_io,whence)); |
92 | } |
93 | |
94 | static int |
95 | _tiffCloseProc(thandle_t fd) |
96 | { |
97 | return(close((int)fd)); |
98 | } |
99 | |
100 | static uint64 |
101 | _tiffSizeProc(thandle_t fd) |
102 | { |
103 | struct stat sb; |
104 | if (fstat((int)fd,&sb)<0) |
105 | return(0); |
106 | else |
107 | return((uint64)sb.st_size); |
108 | } |
109 | |
110 | #ifdef HAVE_MMAP |
111 | #include <sys/mman.h> |
112 | |
113 | static int |
114 | _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) |
115 | { |
116 | uint64 size64 = _tiffSizeProc(fd); |
117 | tmsize_t sizem = (tmsize_t)size64; |
118 | if ((uint64)sizem==size64) { |
119 | *pbase = (void*) |
120 | mmap(0, (size_t)sizem, PROT_READ, MAP_SHARED, (int) fd, 0); |
121 | if (*pbase != (void*) -1) { |
122 | *psize = (tmsize_t)sizem; |
123 | return (1); |
124 | } |
125 | } |
126 | return (0); |
127 | } |
128 | |
129 | static void |
130 | _tiffUnmapProc(thandle_t fd, void* base, toff_t size) |
131 | { |
132 | (void) fd; |
133 | (void) munmap(base, (off_t) size); |
134 | } |
135 | #else /* !HAVE_MMAP */ |
136 | static int |
137 | _tiffMapProc(thandle_t fd, void** pbase, toff_t* psize) |
138 | { |
139 | (void) fd; (void) pbase; (void) psize; |
140 | return (0); |
141 | } |
142 | |
143 | static void |
144 | _tiffUnmapProc(thandle_t fd, void* base, toff_t size) |
145 | { |
146 | (void) fd; (void) base; (void) size; |
147 | } |
148 | #endif /* !HAVE_MMAP */ |
149 | |
150 | /* |
151 | * Open a TIFF file descriptor for read/writing. |
152 | */ |
153 | TIFF* |
154 | TIFFFdOpen(int fd, const char* name, const char* mode) |
155 | { |
156 | TIFF* tif; |
157 | |
158 | tif = TIFFClientOpen(name, mode, |
159 | (thandle_t) fd, |
160 | _tiffReadProc, _tiffWriteProc, |
161 | _tiffSeekProc, _tiffCloseProc, _tiffSizeProc, |
162 | _tiffMapProc, _tiffUnmapProc); |
163 | if (tif) |
164 | tif->tif_fd = fd; |
165 | return (tif); |
166 | } |
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 | int m, fd; |
176 | TIFF* tif; |
177 | |
178 | m = _TIFFgetMode(mode, module); |
179 | if (m == -1) |
180 | return ((TIFF*)0); |
181 | |
182 | /* for cygwin and mingw */ |
183 | #ifdef O_BINARY |
184 | m |= O_BINARY; |
185 | #endif |
186 | |
187 | fd = open(name, m, 0666); |
188 | if (fd < 0) { |
189 | if (errno > 0 && strerror(errno) != NULL ) { |
190 | TIFFErrorExt(0, module, "%s: %s", name, strerror(errno) ); |
191 | } else { |
192 | TIFFErrorExt(0, module, "%s: Cannot open", name); |
193 | } |
194 | return ((TIFF *)0); |
195 | } |
196 | |
197 | tif = TIFFFdOpen((int)fd, name, mode); |
198 | if(!tif) |
199 | close(fd); |
200 | return tif; |
201 | } |
202 | |
203 | #ifdef __WIN32__ |
204 | #include <windows.h> |
205 | /* |
206 | * Open a TIFF file with a Unicode filename, for read/writing. |
207 | */ |
208 | TIFF* |
209 | TIFFOpenW(const wchar_t* name, const char* mode) |
210 | { |
211 | static const char module[] = "TIFFOpenW"; |
212 | int m, fd; |
213 | int mbsize; |
214 | char *mbname; |
215 | TIFF* tif; |
216 | |
217 | m = _TIFFgetMode(mode, module); |
218 | if (m == -1) |
219 | return ((TIFF*)0); |
220 | |
221 | /* for cygwin and mingw */ |
222 | #ifdef O_BINARY |
223 | m |= O_BINARY; |
224 | #endif |
225 | |
226 | fd = _wopen(name, m, 0666); |
227 | if (fd < 0) { |
228 | TIFFErrorExt(0, module, "%s: Cannot open", name); |
229 | return ((TIFF *)0); |
230 | } |
231 | |
232 | mbname = NULL; |
233 | mbsize = WideCharToMultiByte(CP_ACP, 0, name, -1, NULL, 0, NULL, NULL); |
234 | if (mbsize > 0) { |
235 | mbname = _TIFFmalloc(mbsize); |
236 | if (!mbname) { |
237 | TIFFErrorExt(0, module, |
238 | "Can't allocate space for filename conversion buffer"); |
239 | return ((TIFF*)0); |
240 | } |
241 | |
242 | WideCharToMultiByte(CP_ACP, 0, name, -1, mbname, mbsize, |
243 | NULL, NULL); |
244 | } |
245 | |
246 | tif = TIFFFdOpen((int)fd, (mbname != NULL) ? mbname : "<unknown>", |
247 | mode); |
248 | |
249 | _TIFFfree(mbname); |
250 | |
251 | if(!tif) |
252 | close(fd); |
253 | return tif; |
254 | } |
255 | #endif |
256 | |
257 | void* |
258 | _TIFFmalloc(tmsize_t s) |
259 | { |
260 | return (malloc((size_t) s)); |
261 | } |
262 | |
263 | void |
264 | _TIFFfree(void* p) |
265 | { |
266 | free(p); |
267 | } |
268 | |
269 | void* |
270 | _TIFFrealloc(void* p, tmsize_t s) |
271 | { |
272 | return (realloc(p, (size_t) s)); |
273 | } |
274 | |
275 | void |
276 | _TIFFmemset(void* p, int v, tmsize_t c) |
277 | { |
278 | memset(p, v, (size_t) c); |
279 | } |
280 | |
281 | void |
282 | _TIFFmemcpy(void* d, const void* s, tmsize_t c) |
283 | { |
284 | memcpy(d, s, (size_t) c); |
285 | } |
286 | |
287 | int |
288 | _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) |
289 | { |
290 | return (memcmp(p1, p2, (size_t) c)); |
291 | } |
292 | |
293 | static void |
294 | unixWarningHandler(const char* module, const char* fmt, va_list ap) |
295 | { |
296 | if (module != NULL) |
297 | fprintf(stderr, "%s: ", module); |
298 | fprintf(stderr, "Warning, "); |
299 | vfprintf(stderr, fmt, ap); |
300 | fprintf(stderr, ".\n"); |
301 | } |
302 | TIFFErrorHandler _TIFFwarningHandler = unixWarningHandler; |
303 | |
304 | static void |
305 | unixErrorHandler(const char* module, const char* fmt, va_list ap) |
306 | { |
307 | if (module != NULL) |
308 | fprintf(stderr, "%s: ", module); |
309 | vfprintf(stderr, fmt, ap); |
310 | fprintf(stderr, ".\n"); |
311 | } |
312 | TIFFErrorHandler _TIFFerrorHandler = unixErrorHandler; |
313 | |
314 | /* vim: set ts=8 sts=8 sw=8 noet: */ |
315 | |
316 | /* |
317 | * Local Variables: |
318 | * mode: c |
319 | * c-basic-offset: 8 |
320 | * fill-column: 78 |
321 | * End: |
322 | */ |
323 |