Coverage Report

Created: 2022-10-31 07:00

/src/ghostpdl/base/gstiffio.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2022 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.,  1305 Grant Avenue - Suite 200, Novato,
13
   CA 94945, U.S.A., +1(415)492-9861, 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
65.4k
{
77
65.4k
    tifs_io_private *tiffio = (tifs_io_private *)fd;
78
65.4k
    size_t size_io = (size_t) size;
79
65.4k
    size_t written;
80
81
65.4k
    if ((size_t) size_io != size) {
82
0
        return (size_t) -1;
83
0
    }
84
65.4k
    written = (size_t) gp_fwrite (buf, 1, size_io, tiffio->f);
85
65.4k
    return written;
86
65.4k
}
87
88
static uint64_t
89
gs_tifsSeekProc(thandle_t fd, uint64_t off, int whence)
90
65.9k
{
91
65.9k
    tifs_io_private *tiffio = (tifs_io_private *)fd;
92
65.9k
    gs_offset_t off_io = (gs_offset_t) off;
93
94
65.9k
    if ((uint64_t) off_io != off) {
95
0
        return (uint64_t) -1; /* this is really gross */
96
0
    }
97
65.9k
    if (gp_fseek(tiffio->f , (gs_offset_t)off_io, whence) < 0) {
98
0
        return (uint64_t) -1;
99
0
    }
100
65.9k
    return (gp_ftell(tiffio->f));
101
65.9k
}
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
914
{
141
914
    char mode[5] = "w";
142
914
    int modelen = 1;
143
914
    TIFF *t;
144
914
    tifs_io_private *tiffio;
145
146
914
    if (big_endian)
147
0
        mode[modelen++] = 'b';
148
914
    else
149
914
        mode[modelen++] = 'l';
150
151
914
    if (usebigtiff)
152
    /* this should never happen for libtiff < 4.0 - see tiff_put_some_params() */
153
0
        mode[modelen++] = '8';
154
155
914
    mode[modelen] = (char)0;
156
157
914
    tiffio = (tifs_io_private *)gs_malloc(dev->memory, sizeof(tifs_io_private), 1, "tiff_from_filep");
158
914
    if (!tiffio) {
159
0
        return NULL;
160
0
    }
161
914
    tiffio->f = filep;
162
914
    tiffio->memory = dev->memory;
163
164
914
    t = TIFFClientOpen(name, mode,
165
914
        (thandle_t) tiffio, (TIFFReadWriteProc)gs_tifsReadProc,
166
914
        (TIFFReadWriteProc)gs_tifsWriteProc, (TIFFSeekProc)gs_tifsSeekProc,
167
914
        gs_tifsCloseProc, (TIFFSizeProc)gs_tifsSizeProc, gs_tifsDummyMapProc,
168
914
        gs_tifsDummyUnmapProc);
169
170
914
    return t;
171
914
}
172
173
int tiff_filename_from_tiff(TIFF *t, char **name)
174
914
{
175
914
    *name = (char *)TIFFFileName(t);
176
914
    return 0;
177
914
}
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
0
{
198
0
    tifs_io_private *tiffio = (tifs_io_private *)client_data;
199
0
    const char *max_size_error = "Maximum TIFF file size exceeded";
200
0
    int count;
201
0
    char buf[TIFF_PRINT_BUF_LENGTH];
202
203
0
    count = vsnprintf(buf, sizeof(buf), fmt, ap);
204
0
    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
0
    } else {
208
0
        dmlprintf1(tiffio->memory, "%s\n", buf);
209
0
    }
210
211
0
#if (TIFFLIB_VERSION >= 20111221)
212
0
    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
0
#endif
216
0
}
217
218
void tiff_set_handlers (void)
219
765
{
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
765
    (void)TIFFSetErrorHandler(NULL);
227
765
    (void)TIFFSetWarningHandler(NULL);
228
765
#if SHARE_LIBTIFF == 0
229
765
    (void)TIFFSetErrorHandlerExt(gs_tifsErrorHandlerEx);
230
765
    (void)TIFFSetWarningHandlerExt(gs_tifsWarningHandlerEx);
231
765
#endif
232
765
}
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
32.1k
{
257
32.1k
    return (malloc((size_t) s));
258
32.1k
}
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
42.7k
{
274
42.7k
    free(p);
275
42.7k
}
276
277
void*
278
_TIFFrealloc(void* p, tmsize_t s)
279
14.6k
{
280
14.6k
    return (realloc(p, (size_t) s));
281
14.6k
}
282
283
void
284
_TIFFmemset(void* p, int v, tmsize_t c)
285
74.5k
{
286
74.5k
    memset(p, v, (size_t) c);
287
74.5k
}
288
289
void
290
_TIFFmemcpy(void* d, const void* s, tmsize_t c)
291
2.00M
{
292
2.00M
    memcpy(d, s, (size_t) c);
293
2.00M
}
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
0
{
308
0
    int count;
309
0
    va_list args;
310
311
0
    va_start(args, format);
312
0
    count = gs_vsnprintf(buf, size, format, args);
313
0
    va_end(args);
314
0
    return count;
315
0
}
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 */