Coverage Report

Created: 2025-06-24 07:01

/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 */