/src/ghostpdl/base/gstiffio.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* TIFF hooks and stubs */ |
18 | | |
19 | | #include "stdint_.h" /* for tiff.h */ |
20 | | #include "stdio_.h" |
21 | | #include "time_.h" |
22 | | #include "malloc_.h" |
23 | | #include "gstypes.h" |
24 | | #include "gscdefs.h" |
25 | | #include "gdevprn.h" |
26 | | |
27 | | #include "scommon.h" |
28 | | #include "stream.h" |
29 | | #include "strmio.h" |
30 | | |
31 | | #include "gstiffio.h" |
32 | | |
33 | | #define TIFF_PRINT_BUF_LENGTH 1024 |
34 | | static const char tifs_msg_truncated[] = "\n*** Previous line has been truncated.\n"; |
35 | | |
36 | | /* place to hold the data for our libtiff i/o hooks |
37 | | */ |
38 | | typedef struct tifs_io_private_t |
39 | | { |
40 | | gp_file *f; |
41 | | gs_memory_t *memory; |
42 | | } tifs_io_private; |
43 | | |
44 | | /* libtiff i/o hooks */ |
45 | | static int |
46 | | gs_tifsDummyMapProc(thandle_t fd, void** pbase, toff_t* psize) |
47 | 0 | { |
48 | 0 | (void) fd; |
49 | 0 | (void) pbase; |
50 | 0 | (void) psize; |
51 | 0 | return (0); |
52 | 0 | } |
53 | | |
54 | | static void |
55 | | gs_tifsDummyUnmapProc(thandle_t fd, void* base, toff_t size) |
56 | 0 | { |
57 | 0 | (void) fd; |
58 | 0 | (void) base; |
59 | 0 | (void) size; |
60 | 0 | } |
61 | | |
62 | | static size_t |
63 | | gs_tifsReadProc(thandle_t fd, void* buf, size_t size) |
64 | 0 | { |
65 | 0 | tifs_io_private *tiffio = (tifs_io_private *)fd; |
66 | 0 | size_t size_io = (size_t) size; |
67 | |
|
68 | 0 | if ((size_t) size_io != size) { |
69 | 0 | return (size_t) -1; |
70 | 0 | } |
71 | 0 | return((size_t) gp_fread (buf, 1, size_io, tiffio->f)); |
72 | 0 | } |
73 | | |
74 | | static size_t |
75 | | gs_tifsWriteProc(thandle_t fd, void* buf, size_t size) |
76 | 1.13M | { |
77 | 1.13M | tifs_io_private *tiffio = (tifs_io_private *)fd; |
78 | 1.13M | size_t size_io = (size_t) size; |
79 | 1.13M | size_t written; |
80 | | |
81 | 1.13M | if ((size_t) size_io != size) { |
82 | 0 | return (size_t) -1; |
83 | 0 | } |
84 | 1.13M | written = (size_t) gp_fwrite (buf, 1, size_io, tiffio->f); |
85 | 1.13M | return written; |
86 | 1.13M | } |
87 | | |
88 | | static uint64_t |
89 | | gs_tifsSeekProc(thandle_t fd, uint64_t off, int whence) |
90 | 1.16M | { |
91 | 1.16M | tifs_io_private *tiffio = (tifs_io_private *)fd; |
92 | 1.16M | gs_offset_t off_io = (gs_offset_t) off; |
93 | | |
94 | 1.16M | if ((uint64_t) off_io != off) { |
95 | 0 | return (uint64_t) -1; /* this is really gross */ |
96 | 0 | } |
97 | 1.16M | if (gp_fseek(tiffio->f , (gs_offset_t)off_io, whence) < 0) { |
98 | 0 | return (uint64_t) -1; |
99 | 0 | } |
100 | 1.16M | return (gp_ftell(tiffio->f)); |
101 | 1.16M | } |
102 | | |
103 | | static int |
104 | | gs_tifsCloseProc(thandle_t fd) |
105 | 0 | { |
106 | 0 | tifs_io_private *tiffio = (tifs_io_private *)fd; |
107 | | |
108 | | /* We don't close tiffio->f as this will be closed later by the |
109 | | * device. */ |
110 | |
|
111 | 0 | gs_free(tiffio->memory, tiffio, sizeof(tifs_io_private), 1, "gs_tifsCloseProc"); |
112 | |
|
113 | 0 | return 0; |
114 | 0 | } |
115 | | |
116 | | static uint64_t |
117 | | gs_tifsSizeProc(thandle_t fd) |
118 | 0 | { |
119 | 0 | tifs_io_private *tiffio = (tifs_io_private *)fd; |
120 | 0 | uint64_t length; |
121 | 0 | gs_offset_t curpos = gp_ftell(tiffio->f); |
122 | |
|
123 | 0 | if (curpos < 0) { |
124 | 0 | return(0); |
125 | 0 | } |
126 | | |
127 | 0 | if (gp_fseek(tiffio->f, (gs_offset_t)0, SEEK_END) < 0) { |
128 | 0 | return(0); |
129 | 0 | } |
130 | 0 | length = (uint64_t)gp_ftell(tiffio->f); |
131 | |
|
132 | 0 | if (gp_fseek(tiffio->f, curpos, SEEK_SET) < 0) { |
133 | 0 | return(0); |
134 | 0 | } |
135 | 0 | return length; |
136 | 0 | } |
137 | | |
138 | | TIFF * |
139 | | tiff_from_filep(gx_device_printer *dev, const char *name, gp_file *filep, int big_endian, bool usebigtiff) |
140 | 16.7k | { |
141 | 16.7k | char mode[5] = "w"; |
142 | 16.7k | int modelen = 1; |
143 | 16.7k | TIFF *t; |
144 | 16.7k | tifs_io_private *tiffio; |
145 | | |
146 | 16.7k | if (big_endian) |
147 | 0 | mode[modelen++] = 'b'; |
148 | 16.7k | else |
149 | 16.7k | mode[modelen++] = 'l'; |
150 | | |
151 | 16.7k | if (usebigtiff) |
152 | | /* this should never happen for libtiff < 4.0 - see tiff_put_some_params() */ |
153 | 0 | mode[modelen++] = '8'; |
154 | | |
155 | 16.7k | mode[modelen] = (char)0; |
156 | | |
157 | 16.7k | tiffio = (tifs_io_private *)gs_malloc(dev->memory, sizeof(tifs_io_private), 1, "tiff_from_filep"); |
158 | 16.7k | if (!tiffio) { |
159 | 0 | return NULL; |
160 | 0 | } |
161 | 16.7k | tiffio->f = filep; |
162 | 16.7k | tiffio->memory = dev->memory; |
163 | | |
164 | 16.7k | t = TIFFClientOpen(name, mode, |
165 | 16.7k | (thandle_t) tiffio, (TIFFReadWriteProc)gs_tifsReadProc, |
166 | 16.7k | (TIFFReadWriteProc)gs_tifsWriteProc, (TIFFSeekProc)gs_tifsSeekProc, |
167 | 16.7k | gs_tifsCloseProc, (TIFFSizeProc)gs_tifsSizeProc, gs_tifsDummyMapProc, |
168 | 16.7k | gs_tifsDummyUnmapProc); |
169 | | |
170 | 16.7k | return t; |
171 | 16.7k | } |
172 | | |
173 | | int tiff_filename_from_tiff(TIFF *t, char **name) |
174 | 16.7k | { |
175 | 16.7k | *name = (char *)TIFFFileName(t); |
176 | 16.7k | return 0; |
177 | 16.7k | } |
178 | | |
179 | | static void |
180 | | gs_tifsWarningHandlerEx(thandle_t client_data, const char* module, const char* fmt, va_list ap) |
181 | 0 | { |
182 | 0 | tifs_io_private *tiffio = (tifs_io_private *)client_data; |
183 | 0 | int count; |
184 | 0 | char buf[TIFF_PRINT_BUF_LENGTH]; |
185 | |
|
186 | 0 | count = vsnprintf(buf, sizeof(buf), fmt, ap); |
187 | 0 | if (count < 0 || count >= sizeof(buf)) { /* MSVC || C99 */ |
188 | 0 | dmlprintf1(tiffio->memory, "%s", buf); |
189 | 0 | dmlprintf1(tiffio->memory, "%s\n", tifs_msg_truncated); |
190 | 0 | } else { |
191 | 0 | dmlprintf1(tiffio->memory, "%s\n", buf); |
192 | 0 | } |
193 | 0 | } |
194 | | |
195 | | static void |
196 | | gs_tifsErrorHandlerEx(thandle_t client_data, const char* module, const char* fmt, va_list ap) |
197 | 21.0k | { |
198 | 21.0k | tifs_io_private *tiffio = (tifs_io_private *)client_data; |
199 | 21.0k | const char *max_size_error = "Maximum TIFF file size exceeded"; |
200 | 21.0k | int count; |
201 | 21.0k | char buf[TIFF_PRINT_BUF_LENGTH]; |
202 | | |
203 | 21.0k | count = vsnprintf(buf, sizeof(buf), fmt, ap); |
204 | 21.0k | if (count < 0 || count >= sizeof(buf) ) { /* MSVC || C99 */ |
205 | 0 | dmlprintf1(tiffio->memory, "%s\n", buf); |
206 | 0 | dmlprintf1(tiffio->memory, "%s", tifs_msg_truncated); |
207 | 21.0k | } else { |
208 | 21.0k | dmlprintf1(tiffio->memory, "%s\n", buf); |
209 | 21.0k | } |
210 | | |
211 | 21.0k | #if (TIFFLIB_VERSION >= 20111221) |
212 | 21.0k | if (!strncmp(fmt, max_size_error, strlen(max_size_error))) { |
213 | 0 | dmlprintf(tiffio->memory, "Use -dUseBigTIFF(=true) for BigTIFF output\n"); |
214 | 0 | } |
215 | 21.0k | #endif |
216 | 21.0k | } |
217 | | |
218 | | void tiff_set_handlers (void) |
219 | 16.6k | { |
220 | | /* Bad things happen if we set custom error/warning |
221 | | * handlers, and multiple callers are using the shared |
222 | | * libtiff - our handlers may be triggered in the |
223 | | * context of the other caller(s) meaning it's not |
224 | | * our client_data being passed in. |
225 | | */ |
226 | 16.6k | (void)TIFFSetErrorHandler(NULL); |
227 | 16.6k | (void)TIFFSetWarningHandler(NULL); |
228 | 16.6k | #if SHARE_LIBTIFF == 0 |
229 | 16.6k | (void)TIFFSetErrorHandlerExt(gs_tifsErrorHandlerEx); |
230 | 16.6k | (void)TIFFSetWarningHandlerExt(gs_tifsWarningHandlerEx); |
231 | 16.6k | #endif |
232 | 16.6k | } |
233 | | |
234 | | #if SHARE_LIBTIFF == 0 |
235 | | TIFF* |
236 | | TIFFFdOpen(int fd, const char* name, const char* mode) |
237 | 0 | { |
238 | 0 | (void)fd; |
239 | 0 | (void)name; |
240 | 0 | (void)mode; |
241 | |
|
242 | 0 | return(NULL); |
243 | 0 | } |
244 | | |
245 | | TIFF* |
246 | | TIFFOpen(const char* name, const char* mode) |
247 | 0 | { |
248 | 0 | (void)name; |
249 | 0 | (void)mode; |
250 | |
|
251 | 0 | return(NULL); |
252 | 0 | } |
253 | | |
254 | | void* |
255 | | _TIFFmalloc(tmsize_t s) |
256 | 371k | { |
257 | 371k | return (malloc((size_t) s)); |
258 | 371k | } |
259 | | |
260 | | void* _TIFFcalloc(tmsize_t nmemb, tmsize_t siz) |
261 | 0 | { |
262 | 0 | void *m = NULL; |
263 | 0 | if( nmemb != 0 && siz != 0 ) { |
264 | 0 | m = malloc((size_t)(nmemb * siz)); |
265 | 0 | } |
266 | 0 | if (m) |
267 | 0 | memset(m, 0x00, (size_t)(nmemb * siz)); |
268 | 0 | return m; |
269 | 0 | } |
270 | | |
271 | | void |
272 | | _TIFFfree(void* p) |
273 | 479k | { |
274 | 479k | free(p); |
275 | 479k | } |
276 | | |
277 | | void* |
278 | | _TIFFrealloc(void* p, tmsize_t s) |
279 | 161k | { |
280 | 161k | return (realloc(p, (size_t) s)); |
281 | 161k | } |
282 | | |
283 | | void |
284 | | _TIFFmemset(void* p, int v, tmsize_t c) |
285 | 1.14M | { |
286 | 1.14M | memset(p, v, (size_t) c); |
287 | 1.14M | } |
288 | | |
289 | | void |
290 | | _TIFFmemcpy(void* d, const void* s, tmsize_t c) |
291 | 31.7M | { |
292 | 31.7M | memcpy(d, s, (size_t) c); |
293 | 31.7M | } |
294 | | |
295 | | int |
296 | | _TIFFmemcmp(const void* p1, const void* p2, tmsize_t c) |
297 | 0 | { |
298 | 0 | return (memcmp(p1, p2, (size_t) c)); |
299 | 0 | } |
300 | | |
301 | | #if !defined(HAVE_SNPRINTF) && !defined(HAVE__SNPRINTF) |
302 | | #include "gssprintf.h" |
303 | | /* gets rid of compiler warning -- could include tiffiop.h, not sure which is better */ |
304 | | int _TIFF_snprintf_f(char* buf, size_t size, const char* format, ...); |
305 | | int |
306 | | _TIFF_snprintf_f(char* buf, size_t size, const char* format, ...) |
307 | | { |
308 | | int count; |
309 | | va_list args; |
310 | | |
311 | | va_start(args, format); |
312 | | count = gs_vsnprintf(buf, size, format, args); |
313 | | va_end(args); |
314 | | return count; |
315 | | } |
316 | | #endif |
317 | | |
318 | | /* We supply our own warning/error handlers when we invoke libtiff */ |
319 | | TIFFErrorHandler _TIFFwarningHandler = NULL; |
320 | | TIFFErrorHandler _TIFFerrorHandler = NULL; |
321 | | |
322 | | #endif /* SHARE_LIBTIFF == 0 */ |