Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/gpdl/tifftop.c
Line
Count
Source
1
/* Copyright (C) 2019-2026 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
/* tifftop.c */
17
/* Top-level API implementation of "TIF" Language Interface */
18
#ifdef TIFF_INCLUDED
19
20
#include "pltop.h"
21
#include "gserrors.h"
22
#include "gxdevice.h"
23
#include "gsstate.h"
24
#include "strimpl.h"
25
#include "gscoord.h"
26
#include "gsicc_manage.h"
27
#include "gspaint.h"
28
#include "plmain.h"
29
#include "tiffio.h"
30
#if defined(SHARE_JPEG) && SHARE_JPEG==0
31
#include "jmemcust.h"
32
#endif
33
#include "gsmchunk.h"
34
35
#include <limits.h>
36
37
/* Forward decls */
38
39
/************************************************************/
40
/******** Language wrapper implementation (see pltop.h) *****/
41
/************************************************************/
42
43
typedef enum
44
{
45
    ii_state_identifying = 0,
46
    ii_state_tiff,
47
    ii_state_tiff_header,
48
    ii_state_tiff_decode,
49
    ii_state_flush
50
} ii_state;
51
52
/*
53
 * Tiff interpreter instance
54
 */
55
typedef struct tiff_interp_instance_s {
56
    gs_memory_t       *memory;
57
    gs_memory_t       *cmemory;
58
    gx_device         *dev;
59
    gx_device         *nulldev;
60
61
    gs_color_space    *gray;
62
    gs_color_space    *rgb;
63
    gs_color_space    *cmyk;
64
65
    /* Tiff parser state machine */
66
    ii_state           state;
67
68
    uint32_t           bpp;
69
    uint32_t           bpc;
70
    uint32_t           pal_bpc;
71
    uint32_t           cs;
72
    uint32_t           width;
73
    uint32_t           height;
74
    uint32_t           xresolution;
75
    uint32_t           yresolution;
76
    uint32_t           tile_height;
77
    uint32_t           tile_width;
78
    uint32_t           tiled;
79
    uint32_t           compression;
80
    uint32_t           photometric;
81
    uint8_t           *palette;
82
83
    uint32_t           raw_num_comps; /* As specified in the file */
84
    uint32_t           num_comps;     /* After processing */
85
    uint32_t           raw_byte_width;
86
    uint32_t           byte_width;
87
88
    gs_image_t         image;
89
    gs_image_enum     *penum;
90
    gs_gstate         *pgs;
91
92
    size_t             buffer_full;
93
    size_t             buffer_max;
94
    byte              *tiff_buffer;
95
    size_t             file_pos;
96
    TIFF              *handle;
97
    int                is_rgba;
98
99
    byte              *samples;
100
    byte              *proc_samples;
101
#if defined(SHARE_JPEG) && SHARE_JPEG==0
102
    jpeg_cust_mem_data jmem;
103
#endif
104
} tiff_interp_instance_t;
105
106
static int
107
tiff_detect_language(const char *s, int len)
108
19.2k
{
109
19.2k
    const byte *hdr = (const byte *)s;
110
19.2k
    if (len >= 4) {
111
19.2k
        if (hdr[0] == 'I' && hdr[1] == 'I' && (hdr[2] == 42 || hdr[2] == 43) && hdr[3] == 0)
112
151
            return 100; /* Intel (LSB) order */
113
19.0k
        if (hdr[0] == 'M' && hdr[1] == 'M' && hdr[2] == 0 && (hdr[3] == 42 || hdr[3] == 43))
114
0
            return 100; /* Motorola (MSB) order */
115
19.0k
    }
116
117
19.0k
    return 0;
118
19.2k
}
119
120
static const pl_interp_characteristics_t tiff_characteristics = {
121
    "TIFF",
122
    tiff_detect_language,
123
};
124
125
/* Get implementation's characteristics */
126
static const pl_interp_characteristics_t * /* always returns a descriptor */
127
tiff_impl_characteristics(const pl_interp_implementation_t *impl)     /* implementation of interpreter to alloc */
128
40.9k
{
129
40.9k
  return &tiff_characteristics;
130
40.9k
}
131
132
static void
133
tiff_deallocate(tiff_interp_instance_t *tiff)
134
8.97k
{
135
8.97k
    if (tiff == NULL)
136
0
        return;
137
138
8.97k
    rc_decrement_cs(tiff->gray, "tiff_deallocate");
139
8.97k
    rc_decrement_cs(tiff->rgb, "tiff_deallocate");
140
8.97k
    rc_decrement_cs(tiff->cmyk, "tiff_deallocate");
141
142
8.97k
    if (tiff->pgs != NULL)
143
8.97k
        gs_gstate_free_chain(tiff->pgs);
144
8.97k
    gs_free_object(tiff->memory, tiff, "tiff_impl_allocate_interp_instance");
145
8.97k
}
146
147
/* Deallocate a interpreter instance */
148
static int
149
tiff_impl_deallocate_interp_instance(pl_interp_implementation_t *impl)
150
8.97k
{
151
8.97k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
152
153
8.97k
    tiff_deallocate(tiff);
154
8.97k
    impl->interp_client_data = NULL;
155
156
8.97k
    return 0;
157
8.97k
}
158
159
/* Do per-instance interpreter allocation/init. */
160
static int
161
tiff_impl_allocate_interp_instance(pl_interp_implementation_t *impl, gs_memory_t *mem)
162
8.97k
{
163
8.97k
    int code;
164
8.97k
    tiff_interp_instance_t *tiff
165
8.97k
        = (tiff_interp_instance_t *)gs_alloc_bytes(mem,
166
8.97k
                                                  sizeof(tiff_interp_instance_t),
167
8.97k
                                                  "tiff_impl_allocate_interp_instance");
168
8.97k
    if (!tiff)
169
0
        return_error(gs_error_VMerror);
170
8.97k
    memset(tiff, 0, sizeof(*tiff));
171
172
8.97k
    tiff->memory = mem;
173
8.97k
    tiff->pgs = gs_gstate_alloc(mem);
174
8.97k
    if (tiff->pgs == NULL)
175
0
        goto failVM;
176
177
    /* Push one save level onto the stack to assuage the memory handling */
178
8.97k
    code = gs_gsave(tiff->pgs);
179
8.97k
    if (code < 0)
180
0
        goto fail;
181
182
8.97k
    code = gsicc_init_iccmanager(tiff->pgs);
183
8.97k
    if (code < 0)
184
0
        goto fail;
185
186
8.97k
    tiff->gray = gs_cspace_new_ICC(mem, tiff->pgs, 1);
187
8.97k
    tiff->rgb  = gs_cspace_new_ICC(mem, tiff->pgs, 3);
188
8.97k
    tiff->cmyk = gs_cspace_new_ICC(mem, tiff->pgs, 4);
189
190
8.97k
    impl->interp_client_data = tiff;
191
192
8.97k
    return 0;
193
194
0
failVM:
195
0
    code = gs_note_error(gs_error_VMerror);
196
0
fail:
197
0
    (void)tiff_deallocate(tiff);
198
0
    return code;
199
0
}
200
201
/*
202
 * Get the allocator with which to allocate a device
203
 */
204
static gs_memory_t *
205
tiff_impl_get_device_memory(pl_interp_implementation_t *impl)
206
0
{
207
0
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
208
209
0
    return tiff->dev ? tiff->dev->memory : NULL;
210
0
}
211
212
#if 0 /* UNUSED */
213
static int
214
tiff_impl_set_param(pl_interp_implementation_t *impl,
215
                   pl_set_param_type           type,
216
                   const char                 *param,
217
                   const void                 *val)
218
{
219
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
220
221
    /* No params set here */
222
    return 0;
223
}
224
225
static int
226
tiff_impl_add_path(pl_interp_implementation_t *impl,
227
                  const char                 *path)
228
{
229
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
230
231
    /* No paths to add */
232
    return 0;
233
}
234
235
static int
236
tiff_impl_post_args_init(pl_interp_implementation_t *impl)
237
{
238
    tiff_interp_instance_t *tiff = (jpg_interp_instance_t *)impl->interp_client_data;
239
240
    /* No post args processing */
241
    return 0;
242
}
243
#endif
244
245
/* Prepare interp instance for the next "job" */
246
static int
247
tiff_impl_init_job(pl_interp_implementation_t *impl,
248
                  gx_device                  *device)
249
151
{
250
151
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
251
252
151
    tiff->dev = device;
253
151
    tiff->state = ii_state_identifying;
254
151
    tiff->buffer_full = 0;
255
256
151
    return 0;
257
151
}
258
259
#if 0 /* UNUSED */
260
static int
261
tiff_impl_run_prefix_commands(pl_interp_implementation_t *impl,
262
                             const char                 *prefix)
263
{
264
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
265
266
    return 0;
267
}
268
269
static int
270
tiff_impl_process_file(pl_interp_implementation_t *impl, const char *filename)
271
{
272
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
273
274
    return 0;
275
}
276
#endif
277
278
/* Do any setup for parser per-cursor */
279
static int                      /* ret 0 or +ve if ok, else -ve error code */
280
tiff_impl_process_begin(pl_interp_implementation_t * impl)
281
151
{
282
151
    return 0;
283
151
}
284
285
/* Ensure we have 'required' bytes to read, and further ensure
286
 * that we have no UEL's within those bytes. */
287
static int
288
ensure_bytes(tiff_interp_instance_t *jpg, stream_cursor_read *pr, int required)
289
151
{
290
151
    int n;
291
151
    const uint8_t *p = pr->ptr+1;
292
151
    const uint8_t *q;
293
151
    int avail;
294
295
    /* Find out how many bytes we need to check */
296
151
    n = pr->limit - pr->ptr;
297
151
    if (n > required)
298
149
        n = required;
299
300
    /* Make sure there are no UELs in that block */
301
151
    q = p + n;
302
151
    while (p != q) {
303
755
        while (p != q && *p != '\033')
304
604
            p++;
305
151
        if (p == q)
306
151
            break;
307
0
        avail = pr->limit - pr->ptr;
308
0
        if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
309
            /* At least a partial match to a UEL */
310
0
            return avail < 9 ? gs_error_NeedInput : gs_error_InterpreterExit;
311
0
        }
312
0
        p++;
313
0
    }
314
315
    /* If we have enough bytes, great, if not, get some more */
316
151
    return (n < required) ? gs_error_NeedInput : 0;
317
151
}
318
319
static int
320
flush_to_uel(stream_cursor_read *pr)
321
151
{
322
151
    const uint8_t *p = pr->ptr+1;
323
151
    const uint8_t *q = pr->limit+1;
324
151
    int avail;
325
326
151
    while (p != q) {
327
0
        while (p != q && *p != '\033')
328
0
            p++;
329
0
        if (p == q)
330
0
            break;
331
0
        avail = pr->limit - pr->ptr;
332
0
        if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
333
            /* At least a partial match to a UEL. Bin everything to
334
             * the start of the match. */
335
0
            pr->ptr = p-1;
336
0
            if (avail == 9) /* Complete match. Exit! */
337
0
                return gs_error_InterpreterExit;
338
            /* Partial match. Get more data. */
339
0
            return gs_error_NeedInput;
340
0
        }
341
0
        p++;
342
0
    }
343
344
151
    pr->ptr = pr->limit;
345
346
151
    return 0;
347
151
}
348
349
static int
350
bytes_until_uel(const stream_cursor_read *pr)
351
952
{
352
952
    const uint8_t *p = pr->ptr+1;
353
952
    const uint8_t *q = pr->limit+1;
354
952
    int avail;
355
356
8.58k
    while (p != q) {
357
660k
        while (p != q && *p != '\033')
358
652k
            p++;
359
8.03k
        if (p == q)
360
386
            break;
361
7.64k
        avail = q - p;
362
7.64k
        if (memcmp(p, "\033%-12345X", min(avail, 9)) == 0) {
363
            /* At least a partial match to a UEL. Everything up to
364
             * the start of the match is up for grabs. */
365
10
            return p - (pr->ptr+1);
366
10
        }
367
7.63k
        p++;
368
7.63k
    }
369
370
942
    return pr->limit - pr->ptr;
371
952
}
372
373
static tmsize_t tifsReadProc(thandle_t  tiff_,
374
                             void      *buf,
375
                             tmsize_t   size)
376
513
{
377
513
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
378
513
    tmsize_t available = tiff->buffer_full - tiff->file_pos;
379
513
    if (available > size)
380
468
        available = size;
381
382
513
    memcpy(buf, &tiff->tiff_buffer[tiff->file_pos], available);
383
513
    tiff->file_pos += available;
384
385
513
    return available;
386
513
}
387
388
static tmsize_t tifsWriteProc(thandle_t  tiff_,
389
                              void      *buf,
390
                              tmsize_t   size)
391
0
{
392
0
    return 0;
393
0
}
394
395
static toff_t tifsSeekProc(thandle_t tiff_, toff_t offset, int whence)
396
281
{
397
281
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
398
281
    size_t pos = tiff->file_pos;
399
400
    /* toff_t is unsigned, which kind of implies they'll never use
401
     * SEEK_CUR, or SEEK_END, which makes you wonder why they include
402
     * whence at all, but... */
403
281
    if (whence == 1) { /* SEEK_CURR */
404
0
        offset += pos;
405
281
    } else if (whence == 2) { /* SEEK_END */
406
0
        offset += tiff->buffer_full;
407
0
    }
408
    /* else assume SEEK_SET */
409
410
    /* Clamp (Don't check against 0 as toff_t is unsigned) */
411
281
    if (offset > tiff->buffer_full)
412
138
        offset = tiff->buffer_full;
413
414
281
    tiff->file_pos = offset;
415
416
281
    return offset;
417
281
}
418
419
static int tifsCloseProc(thandle_t tiff_)
420
4
{
421
4
    return 0;
422
4
}
423
424
static toff_t tifsSizeProc(thandle_t tiff_)
425
97
{
426
97
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
427
428
97
    return tiff->buffer_full;
429
97
}
430
431
#if defined(SHARE_JPEG) && SHARE_JPEG==0
432
static void *gs_j_mem_alloc(j_common_ptr cinfo, size_t size)
433
0
{
434
0
    gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv);
435
436
0
    return(gs_alloc_bytes(mem, size, "JPEG allocation"));
437
0
}
438
439
static void gs_j_mem_free(j_common_ptr cinfo, void *object, size_t size)
440
0
{
441
0
    gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv);
442
443
0
    gs_free_object(mem, object, "JPEG free");
444
0
}
445
446
static long gs_j_mem_init (j_common_ptr cinfo)
447
0
{
448
0
    gs_memory_t *mem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv);
449
0
    gs_memory_t *cmem = NULL;
450
451
0
    if (gs_memory_chunk_wrap(&(cmem), mem) < 0) {
452
0
        return (-1);
453
0
    }
454
455
0
    (void)jpeg_cust_mem_set_private(GET_CUST_MEM_DATA(cinfo), cmem);
456
457
0
    return 0;
458
0
}
459
460
static void gs_j_mem_term (j_common_ptr cinfo)
461
0
{
462
0
    gs_memory_t *cmem = (gs_memory_t *)(GET_CUST_MEM_DATA(cinfo)->priv);
463
0
    gs_memory_t *mem = gs_memory_chunk_target(cmem);
464
465
0
    gs_memory_chunk_release(cmem);
466
467
0
    (void)jpeg_cust_mem_set_private(GET_CUST_MEM_DATA(cinfo), mem);
468
0
}
469
470
static void *
471
tiff_jpeg_mem_callback(thandle_t tiff_)
472
0
{
473
0
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
474
475
0
    (void)jpeg_cust_mem_init(&tiff->jmem, (void *)tiff->memory,
476
0
                             gs_j_mem_init, gs_j_mem_term, NULL,
477
0
                            gs_j_mem_alloc, gs_j_mem_free,
478
0
                            gs_j_mem_alloc, gs_j_mem_free, NULL);
479
480
0
    return &tiff->jmem;
481
0
}
482
#endif /* SHARE_JPEG == 0 */
483
484
static int
485
guess_pal_depth(int n, uint16_t *rmap, uint16_t *gmap, uint16_t *bmap)
486
0
{
487
0
    int i;
488
0
    for (i = 0; i < n; i++) {
489
0
        if (rmap[i] >= 256 || gmap[i] >= 256 || bmap[i] >= 256)
490
0
            return 16;
491
0
    }
492
0
    return 8;
493
0
}
494
495
static void
496
blend_alpha(tiff_interp_instance_t *tiff, size_t n, int nc, int planar)
497
0
{
498
0
    int i = tiff->raw_byte_width * nc;
499
0
    byte *p = tiff->samples;
500
0
    const byte *q = tiff->samples + i;
501
502
0
    switch (tiff->bpc)
503
0
    {
504
0
    case 1:
505
0
        p += i*8;
506
0
        do
507
0
        {
508
0
            byte a = *--q;
509
0
            *--p = ( a     & 1)*255;
510
0
            *--p = ((a>>1) & 1)*255;
511
0
            *--p = ((a>>2) & 1)*255;
512
0
            *--p = ((a>>3) & 1)*255;
513
0
            *--p = ((a>>4) & 1)*255;
514
0
            *--p = ((a>>5) & 1)*255;
515
0
            *--p = ((a>>6) & 1)*255;
516
0
            *--p = ((a>>7) & 1)*255;
517
0
        }
518
0
        while (--i);
519
0
        break;
520
0
    case 2:
521
0
        p += i*4;
522
0
        do
523
0
        {
524
0
            byte a = *--q;
525
0
            *--p = ( a     & 3)*0x55;
526
0
            *--p = ((a>>1) & 3)*0x55;
527
0
            *--p = ((a>>2) & 3)*0x55;
528
0
            *--p = ((a>>3) & 3)*0x55;
529
0
        }
530
0
        while (--i);
531
0
        break;
532
0
    case 4:
533
0
        p += i*2;
534
0
        do
535
0
        {
536
0
            byte a = *--q;
537
0
            *--p = ( a     & 15)*0x11;
538
0
            *--p = ((a>>1) & 15)*0x11;
539
0
            *--p = ((a>>2) & 15)*0x11;
540
0
            *--p = ((a>>3) & 15)*0x11;
541
0
        }
542
0
        while (--i);
543
0
        break;
544
0
    default:
545
0
        break;
546
0
    }
547
548
0
    nc--;
549
0
    p = tiff->samples;
550
0
    if (planar == PLANARCONFIG_CONTIG)
551
0
    {
552
0
        q = (const byte *)tiff->samples;
553
0
        while (n--) {
554
0
            byte a = q[nc];
555
0
            for (i = nc; i > 0; i--) {
556
0
                int c = *q++ * a + 255*(255-a);
557
0
                c += (c>>7);
558
0
                *p++ = c>>8;
559
0
            }
560
0
            q++;
561
0
        }
562
0
    }
563
0
    else
564
0
    {
565
0
        int next_comp = tiff->raw_byte_width;
566
0
        int alpha_offset = nc * next_comp;
567
0
        while (n--) {
568
0
            byte a = p[alpha_offset];
569
0
            for (i = nc; i > 0; i--) {
570
0
                int c = *p * a + 255*(255-a);
571
0
                c += (c>>7);
572
0
                *p = c>>8;
573
0
                p += next_comp;
574
0
            }
575
0
            p -= alpha_offset;
576
0
            p++;
577
0
        }
578
0
    }
579
0
}
580
581
/* Calulate (a*b*c+d) safely */
582
static uint32_t
583
safe_mla(const gs_memory_t *mem, int *code, uint32_t a, uint32_t b, uint32_t c, uint32_t d)
584
4
{
585
    /* UINT_MAX < b*a means overflow, but we can't calculate that... */
586
4
    if (UINT_MAX/b < a)
587
0
        goto fail;
588
4
    a *= b;
589
4
    if (UINT_MAX/c < a)
590
0
        goto fail;
591
4
    a *= c;
592
4
    if (UINT_MAX-c < d)
593
0
        goto fail;
594
595
4
    return a+d;
596
597
0
fail:
598
0
    emprintf(mem, "Numeric overflow!\n");
599
0
    *code = gs_error_rangecheck;
600
601
0
    return 0;
602
4
}
603
604
static size_t
605
size_mla(const gs_memory_t *mem, int *code, size_t a, size_t b, size_t c, size_t d)
606
0
{
607
    /* SIZE_MAX < b*a means overflow, but we can't calculate that... */
608
0
    if (SIZE_MAX/b < a)
609
0
        goto fail;
610
0
    a *= b;
611
0
    if (SIZE_MAX/c < a)
612
0
        goto fail;
613
0
    a *= c;
614
0
    if (SIZE_MAX-c < d)
615
0
        goto fail;
616
617
0
    return a+d;
618
619
0
fail:
620
0
    emprintf(mem, "Numeric overflow!\n");
621
0
    *code = gs_error_rangecheck;
622
0
    return 0;
623
0
}
624
625
static int
626
do_tiff_decode(tiff_interp_instance_t *tiff)
627
4
{
628
4
    int code = 0;
629
4
    int tx, ty;
630
4
    short planar;
631
4
    float f, scale;
632
4
    gs_color_space *cs;
633
4
    unsigned int used[GS_IMAGE_MAX_COMPONENTS];
634
4
    gs_string plane_data[GS_IMAGE_MAX_COMPONENTS];
635
4
    int invert = 0;
636
4
    int alpha = 0;
637
638
4
    TIFFGetField(tiff->handle, TIFFTAG_COMPRESSION, &tiff->compression);
639
4
    if (tiff->compression == COMPRESSION_JPEG) {
640
0
        TIFFSetField(tiff->handle, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
641
0
    }
642
4
    TIFFGetField(tiff->handle, TIFFTAG_PHOTOMETRIC, &tiff->photometric);
643
4
    if (tiff->photometric == PHOTOMETRIC_LOGL ||
644
4
        tiff->photometric == PHOTOMETRIC_LOGLUV) {
645
0
        TIFFSetField(tiff->handle, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
646
0
    }
647
648
4
    TIFFGetField(tiff->handle, TIFFTAG_IMAGEWIDTH, &tiff->width);
649
4
    TIFFGetField(tiff->handle, TIFFTAG_IMAGELENGTH, &tiff->height);
650
4
    TIFFGetField(tiff->handle, TIFFTAG_TILEWIDTH, &tiff->tile_width);
651
4
    TIFFGetField(tiff->handle, TIFFTAG_TILELENGTH, &tiff->tile_height);
652
4
    TIFFGetField(tiff->handle, TIFFTAG_BITSPERSAMPLE, &tiff->bpc);
653
4
    TIFFGetField(tiff->handle, TIFFTAG_SAMPLESPERPIXEL, &tiff->num_comps);
654
4
    tiff->raw_num_comps = tiff->num_comps;
655
4
    TIFFGetField(tiff->handle, TIFFTAG_PLANARCONFIG, &planar);
656
4
    f = 0;
657
4
    TIFFGetField(tiff->handle, TIFFTAG_XRESOLUTION, &f);
658
4
    tiff->xresolution = (uint32_t)(f+0.5);
659
4
    f = 0;
660
4
    TIFFGetField(tiff->handle, TIFFTAG_YRESOLUTION, &f);
661
4
    tiff->yresolution = (uint32_t)(f+0.5);
662
663
4
    if (tiff->xresolution == 0)
664
4
        tiff->yresolution = tiff->xresolution;
665
4
    if (tiff->yresolution == 0)
666
4
        tiff->xresolution = tiff->yresolution;
667
4
    if (tiff->xresolution == 0)
668
4
        tiff->xresolution = tiff->yresolution = 72;
669
4
    if (tiff->width == 0 || tiff->height == 0 || tiff->bpc == 0 || tiff->num_comps == 0 ||
670
4
        !(planar == PLANARCONFIG_CONTIG || planar == PLANARCONFIG_SEPARATE)) {
671
0
        emprintf(tiff->memory, "Unsupported TIFF format\n");
672
0
        return gs_error_unknownerror;
673
0
    }
674
675
4
    tiff->tiled = TIFFIsTiled(tiff->handle);
676
677
4
    if (!tiff->tiled) {
678
4
        tiff->tile_width = tiff->width;
679
4
        tiff->tile_height = tiff->height;
680
4
    }
681
682
4
    if (tiff->tiled || planar == PLANARCONFIG_CONTIG) {
683
3
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, tiff->num_comps, tiff->tile_width, 7)>>3;
684
3
    } else {
685
1
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, 1, tiff->tile_width, 7)>>3;
686
1
    }
687
4
    if (code < 0) {
688
0
        emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
689
0
        goto fail_decode;
690
0
    }
691
692
4
    tiff->raw_byte_width = tiff->byte_width;
693
4
    if (tiff->photometric == PHOTOMETRIC_RGB && tiff->num_comps == 4)
694
0
    {
695
        /* RGBA, so alpha data */
696
0
        alpha = 1;
697
0
    }
698
4
    if (alpha && tiff->bpp < 8)
699
0
    {
700
        /* We need to expand the data to 8bpp to blend for alpha. */
701
0
        if (tiff->bpc != 1 && tiff->bpc != 2 && tiff->bpc != 4)
702
0
        {
703
0
            emprintf1(tiff->memory, "Unsupported: TIFF with alpha and bpc=%d\n", tiff->bpc);
704
0
            code = gs_error_unknownerror;
705
0
            goto fail_decode;
706
0
        }
707
0
        tiff->byte_width *= 8/tiff->bpc;
708
0
    }
709
710
    /* Allocate 'samples' to hold the raw samples values read from libtiff.
711
     * The exact size of this buffer depends on which of the multifarious
712
     * read routines we are using. (Tiled/RGBAImage/Scanlines) */
713
4
    if (tiff->compression == COMPRESSION_OJPEG ||
714
4
        tiff->photometric == PHOTOMETRIC_YCBCR) {
715
0
        size_t z = size_mla(tiff->memory, &code, sizeof(uint32_t), tiff->width, tiff->height, 0);
716
0
        if (code < 0) {
717
0
            emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
718
0
            goto fail_decode;
719
0
        }
720
0
        tiff->is_rgba = 1;
721
0
        tiff->samples = gs_alloc_bytes(tiff->memory, z, "tiff_image");
722
0
        tiff->tile_width = tiff->width;
723
0
        tiff->tile_height = tiff->height;
724
0
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, tiff->num_comps, tiff->tile_width, 7)>>3;
725
0
        if (code < 0) {
726
0
            emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
727
0
            goto fail_decode;
728
0
        }
729
4
    } else if (tiff->tiled) {
730
0
        tiff->samples = gs_alloc_bytes(tiff->memory, TIFFTileSize(tiff->handle), "tiff_tile");
731
4
    } else if (planar == PLANARCONFIG_SEPARATE) {
732
1
        tiff->samples = gs_alloc_bytes(tiff->memory, (size_t)tiff->byte_width * tiff->num_comps, "tiff_scan");
733
3
    } else {
734
3
        tiff->samples = gs_alloc_bytes(tiff->memory, tiff->byte_width, "tiff_scan");
735
3
    }
736
4
    if (tiff->samples == NULL) {
737
0
        code = gs_error_VMerror;
738
0
        goto fail_decode;
739
0
    }
740
4
    tiff->proc_samples = tiff->samples;
741
742
4
    tiff->bpp = tiff->bpc * tiff->num_comps;
743
4
    switch(tiff->photometric) {
744
4
    case PHOTOMETRIC_MINISWHITE:
745
4
        invert = 1;
746
        /* Fall through */
747
4
    case PHOTOMETRIC_MINISBLACK:
748
4
        if (tiff->num_comps != 1) {
749
4
            emprintf1(tiff->memory, "Unsupported: TIFF with MINISBLACK with nc=%d\n", tiff->num_comps);
750
4
            code = gs_error_unknownerror;
751
4
            goto fail_decode;
752
4
        }
753
0
        break;
754
0
    case PHOTOMETRIC_RGB:
755
0
        if (tiff->num_comps == 4) {
756
0
            alpha = 1;
757
0
            tiff->num_comps = 3;
758
0
            tiff->bpp = tiff->bpp * 3/4;
759
0
            tiff->byte_width = tiff->byte_width * 3/4;
760
0
        } else if (tiff->num_comps != 3) {
761
0
            emprintf1(tiff->memory, "Unsupported: RGB TIFF nc=%d\n", tiff->num_comps);
762
0
            code = gs_error_unknownerror;
763
0
            goto fail_decode;
764
0
        }
765
0
        break;
766
0
    case PHOTOMETRIC_PALETTE:
767
0
    {
768
0
        uint16_t *rmap, *gmap, *bmap;
769
0
        int i, n = 1<<tiff->bpc;
770
0
        if (tiff->num_comps != 1) {
771
0
            emprintf1(tiff->memory, "Unsupported: Paletted TIFF with nc=%d\n", tiff->num_comps);
772
0
            code = gs_error_unknownerror;
773
0
            goto fail_decode;
774
0
        }
775
0
        if (tiff->bpc > 8) {
776
0
            emprintf1(tiff->memory, "Unsupported: Paletted TIFF with bpc=%d\n", tiff->bpc);
777
0
            code = gs_error_unknownerror;
778
0
            goto fail_decode;
779
0
        }
780
0
        if (!TIFFGetField(tiff->handle, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
781
0
            emprintf(tiff->memory, "Unsupported: Paletted TIFF with bad palette\n");
782
0
            code = gs_error_unknownerror;
783
0
            goto fail_decode;
784
0
        }
785
0
        tiff->palette = gs_alloc_bytes(tiff->memory, 3*256, "palette");
786
0
        if (tiff->palette == NULL) {
787
0
            code = gs_error_VMerror;
788
0
            goto fail_decode;
789
0
        }
790
0
        memset(tiff->palette, 0, 3 * 256);
791
0
        if (guess_pal_depth(n, rmap, gmap, bmap) == 8) {
792
0
            for (i=0; i < n; i++) {
793
0
                tiff->palette[3*i+0] = rmap[i];
794
0
                tiff->palette[3*i+1] = gmap[i];
795
0
                tiff->palette[3*i+2] = bmap[i];
796
0
            }
797
0
        } else {
798
0
            for (i=0; i < n; i++) {
799
0
                tiff->palette[3*i+0] = rmap[i]*255/65535;
800
0
                tiff->palette[3*i+1] = gmap[i]*255/65535;
801
0
                tiff->palette[3*i+2] = bmap[i]*255/65535;
802
0
            }
803
0
        }
804
0
        tiff->pal_bpc = tiff->bpc;
805
0
        tiff->bpc = 8;
806
0
        tiff->num_comps = 3;
807
0
        tiff->raw_num_comps = 1;
808
0
        tiff->bpp = 24;
809
0
        tiff->byte_width = tiff->tile_width * 3;
810
0
        tiff->raw_byte_width = tiff->byte_width;
811
        /* Now we need to make a "proc_samples" area to store the
812
         * processed samples in. */
813
0
        if (tiff->is_rgba) {
814
0
            emprintf(tiff->memory, "Unsupported: Paletted TIFF with RGBA\n");
815
0
            code = gs_error_unknownerror;
816
0
            goto fail_decode;
817
0
        } else if (tiff->tiled) {
818
0
            size_t z = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 3, 0);
819
0
            if (code < 0) {
820
0
                emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
821
0
                goto fail_decode;
822
0
            }
823
0
            tiff->proc_samples = gs_alloc_bytes(tiff->memory, z, "tiff_tile");
824
0
            if (tiff->proc_samples == NULL) {
825
0
                emprintf(tiff->memory, "Memory allocation failure\n");
826
0
                goto fail_decode;
827
0
            }
828
0
        } else {
829
0
            size_t z = size_mla(tiff->memory, &code, tiff->tile_width, 1, 3, 0);
830
0
            tiff->proc_samples = gs_alloc_bytes(tiff->memory, z, "tiff_scan");
831
0
            if (tiff->proc_samples == NULL) {
832
0
                emprintf(tiff->memory, "Memory allocation failure\n");
833
0
                goto fail_decode;
834
0
            }
835
0
        }
836
0
        break;
837
0
    }
838
0
    case PHOTOMETRIC_MASK:
839
0
        if (tiff->num_comps != 1) {
840
0
            emprintf1(tiff->memory, "Unsupported: Mask TIFF with nc=%d\n", tiff->num_comps);
841
0
            code = gs_error_unknownerror;
842
0
            goto fail_decode;
843
0
        }
844
0
        break;
845
0
    case PHOTOMETRIC_SEPARATED:
846
0
        if (tiff->num_comps == 3 || tiff->num_comps == 4)
847
0
        {
848
0
            emprintf1(tiff->memory, "Unsupported: Separated TIFF with nc=%d\n", tiff->num_comps);
849
0
            break;
850
0
        }
851
0
    case PHOTOMETRIC_YCBCR:
852
0
    case PHOTOMETRIC_CIELAB:
853
0
    case PHOTOMETRIC_ICCLAB:
854
0
    case PHOTOMETRIC_ITULAB:
855
0
        if (tiff->num_comps != 3) {
856
0
            emprintf1(tiff->memory, "Unsupported: YUV/LAB TIFF with nc=%d\n", tiff->num_comps);
857
0
            code = gs_error_unknownerror;
858
0
            goto fail_decode;
859
0
        }
860
0
        break;
861
0
    case PHOTOMETRIC_CFA:
862
0
    default:
863
0
        emprintf(tiff->memory, "Unsupported TIFF\n");
864
0
        tiff->state = ii_state_flush;
865
0
        break;
866
4
    }
867
0
    switch(tiff->num_comps) {
868
0
    default:
869
0
    case 1:
870
0
        cs = tiff->gray;
871
0
        break;
872
0
    case 3:
873
0
        cs = tiff->rgb;
874
0
        break;
875
0
    case 4:
876
0
        cs = tiff->cmyk;
877
0
        break;
878
0
    }
879
880
0
    switch (tiff->bpc)
881
0
    {
882
0
    case 1:
883
0
    case 2:
884
0
    case 4:
885
0
    case 8:
886
0
    case 16:
887
        /* We can cope with all these. */
888
0
        break;
889
0
    default:
890
0
        emprintf1(tiff->memory, "Unsupported: TIFF with bpc=%d\n", tiff->bpc);
891
0
        code = gs_error_unknownerror;
892
0
        goto fail_decode;
893
0
    }
894
895
    /* Scale to fit, if too large. */
896
0
    scale = 1.0f;
897
0
    if (tiff->width * tiff->dev->HWResolution[0] > tiff->dev->width * tiff->xresolution)
898
0
        scale = ((float)tiff->dev->width * tiff->xresolution) / (tiff->width * tiff->dev->HWResolution[0]);
899
0
    if (scale * tiff->height * tiff->dev->HWResolution[1] > tiff->dev->height * tiff->yresolution)
900
0
        scale = ((float)tiff->dev->height * tiff->yresolution) / (tiff->height * tiff->dev->HWResolution[1]);
901
902
0
    code = gs_erasepage(tiff->pgs);
903
0
    if (code < 0)
904
0
        return code;
905
906
0
    for (ty = 0; ty < tiff->height; ty += tiff->tile_height) {
907
0
        for (tx = 0; tx < tiff->width; tx += tiff->tile_width) {
908
0
            int y, s;
909
0
            byte *row;
910
0
            float xext, xoffset, yext, yoffset;
911
0
            int tremx, tremy;
912
913
0
            tiff->penum = gs_image_enum_alloc(tiff->memory, "tiff_impl_process(penum)");
914
0
            if (tiff->penum == NULL)
915
0
                return_error(gs_error_VMerror);
916
917
            /* Centre - Extents and offsets are all calculated in points (1/72 of an inch) */
918
0
            xext = (((float)tiff->width - tx * 2) * 72 * scale / tiff->xresolution);
919
0
            xoffset = (tiff->dev->width * 72 / tiff->dev->HWResolution[0] - xext)/2;
920
0
            yext = (((float)tiff->height - ty * 2) * 72 * scale / tiff->yresolution);
921
0
            yoffset = (tiff->dev->height * 72 / tiff->dev->HWResolution[1] - yext)/2;
922
923
0
            gs_initmatrix(tiff->pgs);
924
925
            /* By default the ctm is set to:
926
             *   xres/72   0
927
             *   0         -yres/72
928
             *   0         dev->height * yres/72
929
             * i.e. it moves the origin from being top right to being bottom left.
930
             * We want to move it back, as without this, the image will be displayed
931
             * upside down.
932
             */
933
0
            code = gs_translate(tiff->pgs, 0.0, tiff->dev->height * 72 / tiff->dev->HWResolution[1]);
934
0
            if (code >= 0)
935
0
                code = gs_translate(tiff->pgs, xoffset, -yoffset);
936
0
            if (code >= 0)
937
0
                code = gs_scale(tiff->pgs, scale, -scale);
938
0
            if (code < 0)
939
0
               goto fail_decode;
940
941
0
            memset(&tiff->image, 0, sizeof(tiff->image));
942
0
            gs_image_t_init(&tiff->image, cs);
943
0
            tiff->image.BitsPerComponent = tiff->bpp/tiff->num_comps;
944
0
            if (alpha)
945
0
                tiff->image.BitsPerComponent = 8;
946
0
            tiff->image.Width = tiff->tile_width;
947
0
            tiff->image.Height = tiff->tile_height;
948
949
0
            tiff->image.ImageMatrix.xx = tiff->xresolution / 72.0f;
950
0
            tiff->image.ImageMatrix.yy = tiff->yresolution / 72.0f;
951
0
            if (invert) {
952
0
                tiff->image.Decode[0] = 1;
953
0
                tiff->image.Decode[1] = 0;
954
0
                tiff->image.Decode[2] = 1;
955
0
                tiff->image.Decode[3] = 0;
956
0
                tiff->image.Decode[4] = 1;
957
0
                tiff->image.Decode[5] = 0;
958
0
                tiff->image.Decode[6] = 1;
959
0
                tiff->image.Decode[7] = 0;
960
0
            }
961
962
0
            if (tiff->is_rgba) {
963
0
                size_t z = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 1, 0);
964
0
                if (code < 0)
965
0
                    goto fail_decode;
966
0
                if (TIFFReadRGBAImage(tiff->handle, tiff->width, tiff->height,
967
0
                                      (uint32_t *)tiff->samples, 0) == 0) {
968
0
                    code = gs_error_unknownerror;
969
0
                    goto fail_decode;
970
0
                }
971
0
                blend_alpha(tiff, z, 4, planar);
972
0
            } else if (tiff->tiled) {
973
0
                if (TIFFReadTile(tiff->handle, tiff->samples, tx, ty, 0, 0) == 0) {
974
0
                    code = gs_error_unknownerror;
975
0
                    goto fail_decode;
976
0
                }
977
0
            } else if (planar != PLANARCONFIG_CONTIG) {
978
0
                tiff->image.format = gs_image_format_component_planar;
979
0
            }
980
981
0
            if (!tiff->is_rgba && tiff->tiled) {
982
0
                if (tiff->palette) {
983
0
                    size_t n = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 1, 0);
984
0
                    byte *q = tiff->samples;
985
0
                    byte *p = tiff->proc_samples;
986
0
                    if (code < 0)
987
0
                        goto fail_decode;
988
0
                    while (n--) {
989
0
                        byte *v = &tiff->palette[3 * *q++];
990
0
                        p[0] = *v++;
991
0
                        p[1] = *v++;
992
0
                        p[2] = *v++;
993
0
                        p += 3;
994
0
                    }
995
0
                }
996
0
                if (alpha) {
997
0
                    blend_alpha(tiff, tiff->tile_width, tiff->num_comps, planar);
998
0
                }
999
0
            }
1000
1001
0
            code = gs_image_init(tiff->penum,
1002
0
                                 &tiff->image,
1003
0
                                 false,
1004
0
                                 false,
1005
0
                                 tiff->pgs);
1006
0
            if (code < 0) {
1007
0
                goto fail_decode;
1008
0
            }
1009
1010
0
            tremx = tiff->width - tx;
1011
0
            if (tremx > tiff->tile_width)
1012
0
                tremx = tiff->tile_width;
1013
0
            tremy = tiff->height - ty;
1014
0
            if (tremy > tiff->tile_height)
1015
0
                tremy = tiff->tile_height;
1016
0
            {
1017
                /* Make sure we won't overflow in the loop. */
1018
0
                (void)size_mla(tiff->memory, &code, tiff->byte_width, tiff->tile_height, 1, 0);
1019
0
                if (code < 0)
1020
0
                    goto fail_decode;
1021
0
            }
1022
0
            for (y = 0; y < tremy; y++) {
1023
0
                if (tiff->is_rgba) {
1024
0
                    row = tiff->proc_samples + (size_t)tiff->byte_width * (tiff->tile_height-1-y);
1025
0
                } else if (tiff->tiled) {
1026
0
                    row = tiff->proc_samples + (size_t)tiff->byte_width * y;
1027
0
                } else if (planar == PLANARCONFIG_CONTIG) {
1028
0
                    row = tiff->proc_samples;
1029
0
                    if (TIFFReadScanline(tiff->handle, tiff->samples, ty+y, 0) == 0) {
1030
0
                        code = gs_error_unknownerror;
1031
0
                        goto fail_decode;
1032
0
                    }
1033
0
                } else {
1034
0
                    int span = tiff->raw_byte_width;
1035
0
                    byte *in_row = tiff->samples;
1036
0
                    row = tiff->proc_samples;
1037
0
                    for (s = 0; s < tiff->raw_num_comps; s++) {
1038
0
                         plane_data[s].data = row;
1039
0
                         plane_data[s].size = span;
1040
0
                         if (TIFFReadScanline(tiff->handle, in_row, ty+y, s) == 0) {
1041
0
                             code = gs_error_unknownerror;
1042
0
                             goto fail_decode;
1043
0
                         }
1044
0
                         row += span;
1045
0
                         in_row += span;
1046
0
                    }
1047
0
                    row -= span * tiff->raw_num_comps;
1048
0
                }
1049
1050
0
                if (tiff->bpc == 16)
1051
0
                {
1052
0
                    byte *p = row;
1053
0
                    int n = tiff->tile_width * tiff->raw_num_comps;
1054
0
                    while (n--)
1055
0
                    {
1056
0
                        byte b = p[0];
1057
0
                        p[0] = p[1];
1058
0
                        p[1] = b;
1059
0
                        p += 2;
1060
0
                    }
1061
0
                }
1062
1063
0
                if (!tiff->tiled) {
1064
0
                    if (tiff->palette) {
1065
0
                        int n = tiff->tile_width;
1066
0
                        const byte *q = tiff->samples;
1067
0
                        byte *p = tiff->proc_samples;
1068
0
                        switch (tiff->pal_bpc)
1069
0
                        {
1070
0
                        case 8:
1071
0
                            while (n--) {
1072
0
                                byte *v = &tiff->palette[3 * *q++];
1073
0
                                p[0] = *v++;
1074
0
                                p[1] = *v++;
1075
0
                                p[2] = *v++;
1076
0
                                p += 3;
1077
0
                            }
1078
0
                            break;
1079
0
                        case 1:
1080
0
                        {
1081
0
                            int sh = 7;
1082
0
                            while (n--) {
1083
0
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 1)];
1084
0
                                sh--;
1085
0
                                if (sh < 0)
1086
0
                                    sh = 7, q++;
1087
0
                                p[0] = *v++;
1088
0
                                p[1] = *v++;
1089
0
                                p[2] = *v++;
1090
0
                                p += 3;
1091
0
                            }
1092
0
                            break;
1093
0
                        }
1094
0
                        case 2:
1095
0
                        {
1096
0
                            int sh = 6;
1097
0
                            while (n--) {
1098
0
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 3)];
1099
0
                                sh -= 2;
1100
0
                                if (sh < 0)
1101
0
                                    sh = 6, q++;
1102
0
                                p[0] = *v++;
1103
0
                                p[1] = *v++;
1104
0
                                p[2] = *v++;
1105
0
                                p += 3;
1106
0
                            }
1107
0
                            break;
1108
0
                        }
1109
0
                        case 4:
1110
0
                        {
1111
0
                            int sh = 4;
1112
0
                            while (n--) {
1113
0
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 15)];
1114
0
                                sh ^= 4;
1115
0
                                if (sh == 4)
1116
0
                                    q++;
1117
0
                                p[0] = *v++;
1118
0
                                p[1] = *v++;
1119
0
                                p[2] = *v++;
1120
0
                                p += 3;
1121
0
                            }
1122
0
                            break;
1123
0
                        }
1124
0
                        }
1125
0
                    }
1126
0
                    if (alpha) {
1127
0
                        blend_alpha(tiff, tiff->tile_width, tiff->raw_num_comps, planar);
1128
0
                    }
1129
0
                }
1130
1131
0
                if (tiff->image.format == gs_image_format_component_planar) {
1132
0
                    code = gs_image_next_planes(tiff->penum, (gs_const_string *)&plane_data[0], used, false);
1133
0
                } else {
1134
0
                    code = gs_image_next(tiff->penum, row, tiff->byte_width, used);
1135
0
                }
1136
0
                if (code < 0) {
1137
0
                    code = gs_error_unknownerror;
1138
0
                    goto fail_decode;
1139
0
                }
1140
0
            }
1141
0
            code = gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1142
0
            tiff->penum = NULL;
1143
0
            if (code < 0)
1144
0
                return code;
1145
0
        }
1146
0
    }
1147
0
    tiff->state = ii_state_flush;
1148
0
    (void)pl_finish_page(tiff->memory->gs_lib_ctx->top_of_system,
1149
0
                         tiff->pgs, 1, true);
1150
0
    return 0;
1151
1152
4
fail_decode:
1153
4
    if (tiff->penum)
1154
0
    {
1155
0
        (void)gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1156
0
        tiff->penum = NULL;
1157
0
    }
1158
4
    tiff->state = ii_state_flush;
1159
1160
4
    return code;
1161
0
}
1162
1163
static int
1164
decode_all_tiffs(tiff_interp_instance_t *tiff)
1165
4
{
1166
4
    int code;
1167
1168
4
    tiff->nulldev = gs_currentdevice(tiff->pgs);
1169
4
    rc_increment(tiff->nulldev);
1170
4
    code = gs_setdevice_no_erase(tiff->pgs, tiff->dev);
1171
4
    if (code < 0)
1172
0
        return code;
1173
1174
4
    do
1175
4
    {
1176
4
        code = do_tiff_decode(tiff);
1177
4
        if (code < 0)
1178
4
            return code;
1179
4
    }
1180
4
    while (TIFFReadDirectory(tiff->handle));
1181
1182
0
    return 0;
1183
4
}
1184
1185
1186
static int
1187
do_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr, int eof)
1188
561
{
1189
561
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
1190
561
    int code = 0;
1191
561
    ii_state ostate = (ii_state)-1;
1192
561
    int bytes_left = 0;
1193
1194
1.81k
    while (tiff->state != ostate || pr->limit - pr->ptr != bytes_left)
1195
1.40k
    {
1196
1.40k
        ostate = tiff->state;
1197
1.40k
        bytes_left = pr->limit - pr->ptr;
1198
1.40k
        switch(tiff->state)
1199
1.40k
        {
1200
151
        case ii_state_identifying:
1201
151
        {
1202
151
            const byte *hdr;
1203
            /* Try and get us 4 bytes */
1204
151
            code = ensure_bytes(tiff, pr, 4);
1205
151
            if (code < 0)
1206
0
                return code;
1207
151
            hdr = pr->ptr+1;
1208
151
            if (hdr[0] == 'I' && hdr[1] == 'I' && (hdr[2] == 42 || hdr[2] == 43) && hdr[3] == 0) {
1209
151
                tiff->state = ii_state_tiff;
1210
151
                break;
1211
151
            }
1212
0
            if (hdr[0] == 'M' && hdr[1] == 'M' && hdr[2] == 0 && (hdr[3] == 42 || hdr[3] == 43)) {
1213
0
                tiff->state = ii_state_tiff;
1214
0
                break;
1215
0
            }
1216
0
            tiff->state = ii_state_flush;
1217
0
            break;
1218
0
        }
1219
952
        case ii_state_tiff:
1220
952
        {
1221
            /* Gather data into a buffer */
1222
952
            int bytes = bytes_until_uel(pr);
1223
1224
952
            if (bytes == 0 && pr->limit - pr->ptr > 9) {
1225
                /* No bytes until UEL, and there is space for a UEL in the buffer */
1226
0
                tiff->state = ii_state_tiff_decode;
1227
0
                tiff->file_pos = 0;
1228
0
                break;
1229
0
            }
1230
952
            if (bytes == 0 && eof) {
1231
                /* No bytes until UEL, and we are at eof */
1232
151
                tiff->state = ii_state_tiff_decode;
1233
151
                tiff->file_pos = 0;
1234
151
                break;
1235
151
            }
1236
1237
801
            if (tiff->buffer_full + bytes > tiff->buffer_max) {
1238
                /* Need to expand our buffer */
1239
155
                size_t proposed = tiff->buffer_full*2;
1240
155
                if (proposed == 0)
1241
151
                    proposed = 32768;
1242
155
                while (proposed < tiff->buffer_full + bytes)
1243
0
                    proposed *= 2;
1244
1245
155
                if (tiff->tiff_buffer == NULL) {
1246
151
                    tiff->tiff_buffer = gs_alloc_bytes(tiff->memory, proposed, "tiff_buffer");
1247
151
                    if (tiff->tiff_buffer == NULL) {
1248
0
                        tiff->state = ii_state_flush;
1249
0
                        break;
1250
0
                    }
1251
151
                } else {
1252
4
                    void *new_buf = gs_resize_object(tiff->memory, tiff->tiff_buffer, proposed, "tiff_buffer");
1253
4
                    if (new_buf == NULL) {
1254
0
                        tiff->state = ii_state_flush;
1255
0
                        break;
1256
0
                    }
1257
4
                    tiff->tiff_buffer = new_buf;
1258
4
                }
1259
155
                tiff->buffer_max = proposed;
1260
155
            }
1261
1262
801
            memcpy(&tiff->tiff_buffer[tiff->buffer_full], pr->ptr+1, bytes);
1263
801
            tiff->buffer_full += bytes;
1264
801
            pr->ptr += bytes;
1265
801
            code = gs_error_NeedInput;
1266
801
            break;
1267
801
        }
1268
151
        case ii_state_tiff_decode:
1269
151
        {
1270
151
            tiff->handle = TIFFClientOpen("dummy", "rm",
1271
151
                                          (thandle_t)tiff,
1272
151
                                          tifsReadProc,
1273
151
                                          tifsWriteProc,
1274
151
                                          tifsSeekProc,
1275
151
                                          tifsCloseProc,
1276
151
                                          tifsSizeProc,
1277
151
                                          NULL,
1278
151
                                          NULL);
1279
151
            if (tiff->handle == NULL) {
1280
147
                tiff->state = ii_state_flush;
1281
147
                break;
1282
147
            }
1283
1284
4
#if defined(SHARE_JPEG) && SHARE_JPEG==0
1285
4
            TIFFSetJpegMemFunction(tiff->handle,
1286
4
                                   &tiff_jpeg_mem_callback);
1287
4
#endif
1288
1289
4
            code = decode_all_tiffs(tiff);
1290
4
            if (code < 0)
1291
4
            {
1292
4
                tiff->state = ii_state_flush;
1293
4
                break;
1294
4
            }
1295
0
            break;
1296
4
        }
1297
0
        default:
1298
151
        case ii_state_flush:
1299
1300
151
            if (tiff->handle) {
1301
4
                TIFFClose(tiff->handle);
1302
4
                tiff->handle = NULL;
1303
4
            }
1304
1305
151
            if (tiff->penum) {
1306
0
                (void)gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1307
0
                tiff->penum = NULL;
1308
0
            }
1309
1310
151
            if (tiff->proc_samples && tiff->proc_samples != tiff->samples) {
1311
0
                gs_free_object(tiff->memory, tiff->proc_samples, "tiff_impl_process(samples)");
1312
0
                tiff->proc_samples = NULL;
1313
0
            }
1314
1315
151
            if (tiff->samples) {
1316
4
                gs_free_object(tiff->memory, tiff->samples, "tiff_impl_process(samples)");
1317
4
                tiff->samples = NULL;
1318
4
                tiff->proc_samples = NULL;
1319
4
            }
1320
1321
151
            if (tiff->palette) {
1322
0
                gs_free_object(tiff->memory, tiff->palette, "tiff_impl_process(samples)");
1323
0
                tiff->palette = NULL;
1324
0
            }
1325
1326
151
            if (tiff->tiff_buffer) {
1327
151
                gs_free_object(tiff->memory, tiff->tiff_buffer, "tiff_impl_process(tiff_buffer)");
1328
151
                tiff->tiff_buffer = NULL;
1329
151
                tiff->buffer_max = 0;
1330
151
                tiff->buffer_full = 0;
1331
151
            }
1332
            /* We want to bin any data we get up to, but not including
1333
             * a UEL. */
1334
151
            return flush_to_uel(pr);
1335
1.40k
        }
1336
1.40k
    }
1337
1338
410
    return code;
1339
561
}
1340
1341
static int
1342
410
tiff_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr) {
1343
410
    return do_impl_process(impl, pr, 0);
1344
410
}
1345
1346
static int
1347
tiff_impl_process_end(pl_interp_implementation_t * impl)
1348
151
{
1349
151
    return 0;
1350
151
}
1351
1352
/* Not implemented */
1353
static int
1354
tiff_impl_flush_to_eoj(pl_interp_implementation_t *impl, stream_cursor_read *cursor)
1355
0
{
1356
0
    const byte *p = cursor->ptr;
1357
0
    const byte *rlimit = cursor->limit;
1358
1359
    /* Skip to, but leave UEL in buffer for PJL to find later */
1360
0
    for (; p < rlimit; ++p)
1361
0
        if (p[1] == '\033') {
1362
0
            uint avail = rlimit - p;
1363
1364
0
            if (memcmp(p + 1, "\033%-12345X", min(avail, 9)))
1365
0
                continue;
1366
0
            if (avail < 9)
1367
0
                break;
1368
0
            cursor->ptr = p;
1369
0
            return 1;           /* found eoj */
1370
0
        }
1371
0
    cursor->ptr = p;
1372
0
    return 0;                   /* need more */
1373
0
}
1374
1375
/* Parser action for end-of-file */
1376
static int
1377
tiff_impl_process_eof(pl_interp_implementation_t *impl)
1378
151
{
1379
151
    stream_cursor_read r;
1380
1381
151
    r.ptr = NULL;
1382
151
    r.limit = NULL;
1383
151
    return do_impl_process(impl, &r, 1);
1384
151
}
1385
1386
/* Report any errors after running a job */
1387
static int
1388
tiff_impl_report_errors(pl_interp_implementation_t *impl,          /* interp instance to wrap up job in */
1389
                        int                         code,          /* prev termination status */
1390
                        long                        file_position, /* file position of error, -1 if unknown */
1391
                        bool                        force_to_cout  /* force errors to cout */
1392
)
1393
0
{
1394
0
    return 0;
1395
0
}
1396
1397
/* Wrap up interp instance after a "job" */
1398
static int
1399
tiff_impl_dnit_job(pl_interp_implementation_t *impl)
1400
151
{
1401
151
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
1402
1403
151
    if (tiff->nulldev) {
1404
4
        int code = gs_setdevice(tiff->pgs, tiff->nulldev);
1405
4
        tiff->dev = NULL;
1406
4
        rc_decrement(tiff->nulldev, "tiff_impl_dnit_job(nulldevice)");
1407
4
        tiff->nulldev = NULL;
1408
4
        return code;
1409
4
    }
1410
147
    return 0;
1411
151
}
1412
1413
/* Parser implementation descriptor */
1414
const pl_interp_implementation_t tiff_implementation = {
1415
  tiff_impl_characteristics,
1416
  tiff_impl_allocate_interp_instance,
1417
  tiff_impl_get_device_memory,
1418
  NULL, /* tiff_impl_set_param */
1419
  NULL, /* tiff_impl_add_path */
1420
  NULL, /* tiff_impl_post_args_init */
1421
  tiff_impl_init_job,
1422
  NULL, /* tiff_impl_run_prefix_commands */
1423
  NULL, /* tiff_impl_process_file */
1424
  tiff_impl_process_begin,
1425
  tiff_impl_process,
1426
  tiff_impl_process_end,
1427
  tiff_impl_flush_to_eoj,
1428
  tiff_impl_process_eof,
1429
  tiff_impl_report_errors,
1430
  tiff_impl_dnit_job,
1431
  tiff_impl_deallocate_interp_instance,
1432
  NULL, /* tiff_impl_reset */
1433
  NULL  /* interp_client_data */
1434
};
1435
#endif /* TIFF_INCLUDED */