Coverage Report

Created: 2026-07-24 07:44

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
28.0k
{
109
28.0k
    const byte *hdr = (const byte *)s;
110
28.0k
    if (len >= 4) {
111
28.0k
        if (hdr[0] == 'I' && hdr[1] == 'I' && (hdr[2] == 42 || hdr[2] == 43) && hdr[3] == 0)
112
4.70k
            return 100; /* Intel (LSB) order */
113
23.3k
        if (hdr[0] == 'M' && hdr[1] == 'M' && hdr[2] == 0 && (hdr[3] == 42 || hdr[3] == 43))
114
787
            return 100; /* Motorola (MSB) order */
115
23.3k
    }
116
117
22.5k
    return 0;
118
28.0k
}
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
59.1k
{
129
59.1k
  return &tiff_characteristics;
130
59.1k
}
131
132
static void
133
tiff_deallocate(tiff_interp_instance_t *tiff)
134
16.1k
{
135
16.1k
    if (tiff == NULL)
136
0
        return;
137
138
16.1k
    rc_decrement_cs(tiff->gray, "tiff_deallocate");
139
16.1k
    rc_decrement_cs(tiff->rgb, "tiff_deallocate");
140
16.1k
    rc_decrement_cs(tiff->cmyk, "tiff_deallocate");
141
142
16.1k
    if (tiff->pgs != NULL)
143
16.1k
        gs_gstate_free_chain(tiff->pgs);
144
16.1k
    gs_free_object(tiff->memory, tiff, "tiff_impl_allocate_interp_instance");
145
16.1k
}
146
147
/* Deallocate a interpreter instance */
148
static int
149
tiff_impl_deallocate_interp_instance(pl_interp_implementation_t *impl)
150
16.1k
{
151
16.1k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
152
153
16.1k
    tiff_deallocate(tiff);
154
16.1k
    impl->interp_client_data = NULL;
155
156
16.1k
    return 0;
157
16.1k
}
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
16.1k
{
163
16.1k
    int code;
164
16.1k
    tiff_interp_instance_t *tiff
165
16.1k
        = (tiff_interp_instance_t *)gs_alloc_bytes(mem,
166
16.1k
                                                  sizeof(tiff_interp_instance_t),
167
16.1k
                                                  "tiff_impl_allocate_interp_instance");
168
16.1k
    if (!tiff)
169
0
        return_error(gs_error_VMerror);
170
16.1k
    memset(tiff, 0, sizeof(*tiff));
171
172
16.1k
    tiff->memory = mem;
173
16.1k
    tiff->pgs = gs_gstate_alloc(mem);
174
16.1k
    if (tiff->pgs == NULL)
175
0
        goto failVM;
176
177
    /* Push one save level onto the stack to assuage the memory handling */
178
16.1k
    code = gs_gsave(tiff->pgs);
179
16.1k
    if (code < 0)
180
0
        goto fail;
181
182
16.1k
    code = gsicc_init_iccmanager(tiff->pgs);
183
16.1k
    if (code < 0)
184
0
        goto fail;
185
186
16.1k
    tiff->gray = gs_cspace_new_ICC(mem, tiff->pgs, 1);
187
16.1k
    tiff->rgb  = gs_cspace_new_ICC(mem, tiff->pgs, 3);
188
16.1k
    tiff->cmyk = gs_cspace_new_ICC(mem, tiff->pgs, 4);
189
190
16.1k
    impl->interp_client_data = tiff;
191
192
16.1k
    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
5.48k
{
250
5.48k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
251
252
5.48k
    tiff->dev = device;
253
5.48k
    tiff->state = ii_state_identifying;
254
5.48k
    tiff->buffer_full = 0;
255
256
5.48k
    return 0;
257
5.48k
}
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
5.48k
{
282
5.48k
    return 0;
283
5.48k
}
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
5.48k
{
290
5.48k
    int n;
291
5.48k
    const uint8_t *p = pr->ptr+1;
292
5.48k
    const uint8_t *q;
293
5.48k
    int avail;
294
295
    /* Find out how many bytes we need to check */
296
5.48k
    n = pr->limit - pr->ptr;
297
5.48k
    if (n > required)
298
5.48k
        n = required;
299
300
    /* Make sure there are no UELs in that block */
301
5.48k
    q = p + n;
302
5.48k
    while (p != q) {
303
27.4k
        while (p != q && *p != '\033')
304
21.9k
            p++;
305
5.48k
        if (p == q)
306
5.48k
            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
5.48k
    return (n < required) ? gs_error_NeedInput : 0;
317
5.48k
}
318
319
static int
320
flush_to_uel(stream_cursor_read *pr)
321
5.48k
{
322
5.48k
    const uint8_t *p = pr->ptr+1;
323
5.48k
    const uint8_t *q = pr->limit+1;
324
5.48k
    int avail;
325
326
5.48k
    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
5.48k
    pr->ptr = pr->limit;
345
346
5.48k
    return 0;
347
5.48k
}
348
349
static int
350
bytes_until_uel(const stream_cursor_read *pr)
351
20.1k
{
352
20.1k
    const uint8_t *p = pr->ptr+1;
353
20.1k
    const uint8_t *q = pr->limit+1;
354
20.1k
    int avail;
355
356
28.8k
    while (p != q) {
357
5.12M
        while (p != q && *p != '\033')
358
5.10M
            p++;
359
16.0k
        if (p == q)
360
7.31k
            break;
361
8.74k
        avail = q - p;
362
8.74k
        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
52
            return p - (pr->ptr+1);
366
52
        }
367
8.69k
        p++;
368
8.69k
    }
369
370
20.1k
    return pr->limit - pr->ptr;
371
20.1k
}
372
373
static tmsize_t tifsReadProc(thandle_t  tiff_,
374
                             void      *buf,
375
                             tmsize_t   size)
376
164k
{
377
164k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
378
164k
    tmsize_t available = tiff->buffer_full - tiff->file_pos;
379
164k
    if (available > size)
380
68.8k
        available = size;
381
382
164k
    memcpy(buf, &tiff->tiff_buffer[tiff->file_pos], available);
383
164k
    tiff->file_pos += available;
384
385
164k
    return available;
386
164k
}
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
339k
{
397
339k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
398
339k
    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
339k
    if (whence == 1) { /* SEEK_CURR */
404
0
        offset += pos;
405
339k
    } 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
339k
    if (offset > tiff->buffer_full)
412
191k
        offset = tiff->buffer_full;
413
414
339k
    tiff->file_pos = offset;
415
416
339k
    return offset;
417
339k
}
418
419
static int tifsCloseProc(thandle_t tiff_)
420
1.62k
{
421
1.62k
    return 0;
422
1.62k
}
423
424
static toff_t tifsSizeProc(thandle_t tiff_)
425
2.10k
{
426
2.10k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)tiff_;
427
428
2.10k
    return tiff->buffer_full;
429
2.10k
}
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
49
{
487
49
    int i;
488
420
    for (i = 0; i < n; i++) {
489
415
        if (rmap[i] >= 256 || gmap[i] >= 256 || bmap[i] >= 256)
490
44
            return 16;
491
415
    }
492
5
    return 8;
493
49
}
494
495
static void
496
blend_alpha(tiff_interp_instance_t *tiff, size_t n, int nc, int planar)
497
164
{
498
164
    int i = tiff->raw_byte_width * nc;
499
164
    byte *p = tiff->samples;
500
164
    const byte *q = tiff->samples + i;
501
502
164
    switch (tiff->bpc)
503
164
    {
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
164
    default:
545
164
        break;
546
164
    }
547
548
164
    nc--;
549
164
    p = tiff->samples;
550
164
    if (planar == PLANARCONFIG_CONTIG)
551
160
    {
552
160
        q = (const byte *)tiff->samples;
553
4.06M
        while (n--) {
554
4.06M
            byte a = q[nc];
555
16.2M
            for (i = nc; i > 0; i--) {
556
12.1M
                int c = *q++ * a + 255*(255-a);
557
12.1M
                c += (c>>7);
558
12.1M
                *p++ = c>>8;
559
12.1M
            }
560
4.06M
            q++;
561
4.06M
        }
562
160
    }
563
4
    else
564
4
    {
565
4
        int next_comp = tiff->raw_byte_width;
566
4
        int alpha_offset = nc * next_comp;
567
130k
        while (n--) {
568
130k
            byte a = p[alpha_offset];
569
522k
            for (i = nc; i > 0; i--) {
570
392k
                int c = *p * a + 255*(255-a);
571
392k
                c += (c>>7);
572
392k
                *p = c>>8;
573
392k
                p += next_comp;
574
392k
            }
575
130k
            p -= alpha_offset;
576
130k
            p++;
577
130k
        }
578
4
    }
579
164
}
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
1.22k
{
585
    /* UINT_MAX < b*a means overflow, but we can't calculate that... */
586
1.22k
    if (UINT_MAX/b < a)
587
0
        goto fail;
588
1.22k
    a *= b;
589
1.22k
    if (UINT_MAX/c < a)
590
12
        goto fail;
591
1.20k
    a *= c;
592
1.20k
    if (UINT_MAX-c < d)
593
0
        goto fail;
594
595
1.20k
    return a+d;
596
597
12
fail:
598
12
    emprintf(mem, "Numeric overflow!\n");
599
12
    *code = gs_error_rangecheck;
600
601
12
    return 0;
602
1.20k
}
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
524k
{
607
    /* SIZE_MAX < b*a means overflow, but we can't calculate that... */
608
524k
    if (SIZE_MAX/b < a)
609
0
        goto fail;
610
524k
    a *= b;
611
524k
    if (SIZE_MAX/c < a)
612
0
        goto fail;
613
524k
    a *= c;
614
524k
    if (SIZE_MAX-c < d)
615
0
        goto fail;
616
617
524k
    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
524k
}
624
625
static int
626
do_tiff_decode(tiff_interp_instance_t *tiff)
627
1.64k
{
628
1.64k
    int code = 0;
629
1.64k
    int tx, ty;
630
1.64k
    short planar;
631
1.64k
    float f, scale;
632
1.64k
    gs_color_space *cs;
633
1.64k
    unsigned int used[GS_IMAGE_MAX_COMPONENTS];
634
1.64k
    gs_string plane_data[GS_IMAGE_MAX_COMPONENTS];
635
1.64k
    int invert = 0;
636
1.64k
    int alpha = 0;
637
638
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_COMPRESSION, &tiff->compression);
639
1.64k
    if (tiff->compression == COMPRESSION_JPEG) {
640
55
        TIFFSetField(tiff->handle, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
641
55
    }
642
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_PHOTOMETRIC, &tiff->photometric);
643
1.64k
    if (tiff->photometric == PHOTOMETRIC_LOGL ||
644
1.63k
        tiff->photometric == PHOTOMETRIC_LOGLUV) {
645
210
        TIFFSetField(tiff->handle, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
646
210
    }
647
648
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_IMAGEWIDTH, &tiff->width);
649
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_IMAGELENGTH, &tiff->height);
650
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_TILEWIDTH, &tiff->tile_width);
651
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_TILELENGTH, &tiff->tile_height);
652
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_BITSPERSAMPLE, &tiff->bpc);
653
1.64k
    TIFFGetField(tiff->handle, TIFFTAG_SAMPLESPERPIXEL, &tiff->num_comps);
654
1.64k
    if (tiff->num_comps > GS_IMAGE_MAX_COMPONENTS) {
655
65
        emprintf(tiff->memory, "Unsupported TIFF format: too many components\n");
656
65
        goto fail_decode;
657
65
    }
658
1.57k
    tiff->raw_num_comps = tiff->num_comps;
659
1.57k
    TIFFGetField(tiff->handle, TIFFTAG_PLANARCONFIG, &planar);
660
1.57k
    f = 0;
661
1.57k
    TIFFGetField(tiff->handle, TIFFTAG_XRESOLUTION, &f);
662
1.57k
    tiff->xresolution = (uint32_t)(f+0.5);
663
1.57k
    f = 0;
664
1.57k
    TIFFGetField(tiff->handle, TIFFTAG_YRESOLUTION, &f);
665
1.57k
    tiff->yresolution = (uint32_t)(f+0.5);
666
667
1.57k
    if (tiff->xresolution == 0)
668
1.46k
        tiff->yresolution = tiff->xresolution;
669
1.57k
    if (tiff->yresolution == 0)
670
1.53k
        tiff->xresolution = tiff->yresolution;
671
1.57k
    if (tiff->xresolution == 0)
672
1.53k
        tiff->xresolution = tiff->yresolution = 72;
673
1.57k
    if (tiff->width == 0 || tiff->height == 0 || tiff->bpc == 0 || tiff->num_comps == 0 ||
674
964
        !(planar == PLANARCONFIG_CONTIG || planar == PLANARCONFIG_SEPARATE)) {
675
611
        emprintf(tiff->memory, "Unsupported TIFF format\n");
676
611
        return gs_error_unknownerror;
677
611
    }
678
679
964
    tiff->tiled = TIFFIsTiled(tiff->handle);
680
681
964
    if (!tiff->tiled) {
682
822
        tiff->tile_width = tiff->width;
683
822
        tiff->tile_height = tiff->height;
684
822
    }
685
686
964
    if (tiff->tiled || planar == PLANARCONFIG_CONTIG) {
687
910
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, tiff->num_comps, tiff->tile_width, 7)>>3;
688
910
    } else {
689
54
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, 1, tiff->tile_width, 7)>>3;
690
54
    }
691
964
    if (code < 0) {
692
11
        emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
693
11
        goto fail_decode;
694
11
    }
695
696
953
    tiff->raw_byte_width = tiff->byte_width;
697
953
    if (tiff->photometric == PHOTOMETRIC_RGB && tiff->num_comps == 4)
698
4
    {
699
        /* RGBA, so alpha data */
700
4
        alpha = 1;
701
4
    }
702
953
    if (alpha && tiff->bpp < 8)
703
4
    {
704
        /* We need to expand the data to 8bpp to blend for alpha. */
705
4
        if (tiff->bpc != 1 && tiff->bpc != 2 && tiff->bpc != 4)
706
4
        {
707
4
            emprintf1(tiff->memory, "Unsupported: TIFF with alpha and bpc=%d\n", tiff->bpc);
708
4
            code = gs_error_unknownerror;
709
4
            goto fail_decode;
710
4
        }
711
0
        tiff->byte_width *= 8/tiff->bpc;
712
0
    }
713
714
    /* Allocate 'samples' to hold the raw samples values read from libtiff.
715
     * The exact size of this buffer depends on which of the multifarious
716
     * read routines we are using. (Tiled/RGBAImage/Scanlines) */
717
949
    if (tiff->compression == COMPRESSION_OJPEG ||
718
924
        tiff->photometric == PHOTOMETRIC_YCBCR) {
719
257
        size_t z = size_mla(tiff->memory, &code, sizeof(uint32_t), tiff->width, tiff->height, 0);
720
257
        if (code < 0) {
721
0
            emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
722
0
            goto fail_decode;
723
0
        }
724
257
        tiff->is_rgba = 1;
725
257
        tiff->samples = gs_alloc_bytes(tiff->memory, z, "tiff_image");
726
257
        tiff->tile_width = tiff->width;
727
257
        tiff->tile_height = tiff->height;
728
257
        tiff->byte_width = safe_mla(tiff->memory, &code, tiff->bpc, tiff->num_comps, tiff->tile_width, 7)>>3;
729
257
        if (code < 0) {
730
1
            emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
731
1
            goto fail_decode;
732
1
        }
733
692
    } else if (tiff->tiled) {
734
96
        tiff->samples = gs_alloc_bytes(tiff->memory, TIFFTileSize(tiff->handle), "tiff_tile");
735
596
    } else if (planar == PLANARCONFIG_SEPARATE) {
736
46
        tiff->samples = gs_alloc_bytes(tiff->memory, (size_t)tiff->byte_width * tiff->num_comps, "tiff_scan");
737
550
    } else {
738
550
        tiff->samples = gs_alloc_bytes(tiff->memory, tiff->byte_width, "tiff_scan");
739
550
    }
740
948
    if (tiff->samples == NULL) {
741
6
        code = gs_error_VMerror;
742
6
        goto fail_decode;
743
6
    }
744
942
    tiff->proc_samples = tiff->samples;
745
746
942
    tiff->bpp = tiff->bpc * tiff->num_comps;
747
942
    switch(tiff->photometric) {
748
69
    case PHOTOMETRIC_MINISWHITE:
749
69
        invert = 1;
750
        /* Fall through */
751
193
    case PHOTOMETRIC_MINISBLACK:
752
193
        if (tiff->num_comps != 1) {
753
46
            emprintf1(tiff->memory, "Unsupported: TIFF with MINISBLACK with nc=%d\n", tiff->num_comps);
754
46
            code = gs_error_unknownerror;
755
46
            goto fail_decode;
756
46
        }
757
147
        break;
758
147
    case PHOTOMETRIC_RGB:
759
113
        if (tiff->num_comps == 4) {
760
0
            alpha = 1;
761
0
            tiff->num_comps = 3;
762
0
            tiff->bpp = tiff->bpp * 3/4;
763
0
            tiff->byte_width = tiff->byte_width * 3/4;
764
113
        } else if (tiff->num_comps != 3) {
765
2
            emprintf1(tiff->memory, "Unsupported: RGB TIFF nc=%d\n", tiff->num_comps);
766
2
            code = gs_error_unknownerror;
767
2
            goto fail_decode;
768
2
        }
769
111
        break;
770
111
    case PHOTOMETRIC_PALETTE:
771
50
    {
772
50
        uint16_t *rmap, *gmap, *bmap;
773
50
        int i, n = 1<<tiff->bpc;
774
50
        if (tiff->num_comps != 1) {
775
1
            emprintf1(tiff->memory, "Unsupported: Paletted TIFF with nc=%d\n", tiff->num_comps);
776
1
            code = gs_error_unknownerror;
777
1
            goto fail_decode;
778
1
        }
779
49
        if (tiff->bpc > 8) {
780
0
            emprintf1(tiff->memory, "Unsupported: Paletted TIFF with bpc=%d\n", tiff->bpc);
781
0
            code = gs_error_unknownerror;
782
0
            goto fail_decode;
783
0
        }
784
49
        if (!TIFFGetField(tiff->handle, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
785
0
            emprintf(tiff->memory, "Unsupported: Paletted TIFF with bad palette\n");
786
0
            code = gs_error_unknownerror;
787
0
            goto fail_decode;
788
0
        }
789
49
        tiff->palette = gs_alloc_bytes(tiff->memory, 3*256, "palette");
790
49
        if (tiff->palette == NULL) {
791
0
            code = gs_error_VMerror;
792
0
            goto fail_decode;
793
0
        }
794
49
        memset(tiff->palette, 0, 3 * 256);
795
49
        if (guess_pal_depth(n, rmap, gmap, bmap) == 8) {
796
287
            for (i=0; i < n; i++) {
797
282
                tiff->palette[3*i+0] = rmap[i];
798
282
                tiff->palette[3*i+1] = gmap[i];
799
282
                tiff->palette[3*i+2] = bmap[i];
800
282
            }
801
44
        } else {
802
5.64k
            for (i=0; i < n; i++) {
803
5.60k
                tiff->palette[3*i+0] = rmap[i]*255/65535;
804
5.60k
                tiff->palette[3*i+1] = gmap[i]*255/65535;
805
5.60k
                tiff->palette[3*i+2] = bmap[i]*255/65535;
806
5.60k
            }
807
44
        }
808
49
        tiff->pal_bpc = tiff->bpc;
809
49
        tiff->bpc = 8;
810
49
        tiff->num_comps = 3;
811
49
        tiff->raw_num_comps = 1;
812
49
        tiff->bpp = 24;
813
49
        tiff->byte_width = tiff->tile_width * 3;
814
49
        tiff->raw_byte_width = tiff->byte_width;
815
        /* Now we need to make a "proc_samples" area to store the
816
         * processed samples in. */
817
49
        if (tiff->is_rgba) {
818
0
            emprintf(tiff->memory, "Unsupported: Paletted TIFF with RGBA\n");
819
0
            code = gs_error_unknownerror;
820
0
            goto fail_decode;
821
49
        } else if (tiff->tiled) {
822
5
            size_t z = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 3, 0);
823
5
            if (code < 0) {
824
0
                emprintf(tiff->memory, "Unsupported: TIFF size overflow\n");
825
0
                goto fail_decode;
826
0
            }
827
5
            tiff->proc_samples = gs_alloc_bytes(tiff->memory, z, "tiff_tile");
828
5
            if (tiff->proc_samples == NULL) {
829
0
                emprintf(tiff->memory, "Memory allocation failure\n");
830
0
                goto fail_decode;
831
0
            }
832
44
        } else {
833
44
            size_t z = size_mla(tiff->memory, &code, tiff->tile_width, 1, 3, 0);
834
44
            tiff->proc_samples = gs_alloc_bytes(tiff->memory, z, "tiff_scan");
835
44
            if (tiff->proc_samples == NULL) {
836
0
                emprintf(tiff->memory, "Memory allocation failure\n");
837
0
                goto fail_decode;
838
0
            }
839
44
        }
840
49
        break;
841
49
    }
842
49
    case PHOTOMETRIC_MASK:
843
7
        if (tiff->num_comps != 1) {
844
1
            emprintf1(tiff->memory, "Unsupported: Mask TIFF with nc=%d\n", tiff->num_comps);
845
1
            code = gs_error_unknownerror;
846
1
            goto fail_decode;
847
1
        }
848
6
        break;
849
82
    case PHOTOMETRIC_SEPARATED:
850
82
        if (tiff->num_comps == 3 || tiff->num_comps == 4)
851
81
        {
852
81
            emprintf1(tiff->memory, "Unsupported: Separated TIFF with nc=%d\n", tiff->num_comps);
853
81
            break;
854
81
        }
855
250
    case PHOTOMETRIC_YCBCR:
856
275
    case PHOTOMETRIC_CIELAB:
857
276
    case PHOTOMETRIC_ICCLAB:
858
276
    case PHOTOMETRIC_ITULAB:
859
276
        if (tiff->num_comps != 3) {
860
6
            emprintf1(tiff->memory, "Unsupported: YUV/LAB TIFF with nc=%d\n", tiff->num_comps);
861
6
            code = gs_error_unknownerror;
862
6
            goto fail_decode;
863
6
        }
864
270
        break;
865
270
    case PHOTOMETRIC_CFA:
866
222
    default:
867
222
        emprintf(tiff->memory, "Unsupported TIFF\n");
868
222
        tiff->state = ii_state_flush;
869
222
        break;
870
942
    }
871
886
    switch(tiff->num_comps) {
872
26
    default:
873
186
    case 1:
874
186
        cs = tiff->gray;
875
186
        break;
876
609
    case 3:
877
609
        cs = tiff->rgb;
878
609
        break;
879
91
    case 4:
880
91
        cs = tiff->cmyk;
881
91
        break;
882
886
    }
883
884
886
    switch (tiff->bpc)
885
886
    {
886
24
    case 1:
887
40
    case 2:
888
49
    case 4:
889
784
    case 8:
890
875
    case 16:
891
        /* We can cope with all these. */
892
875
        break;
893
11
    default:
894
11
        emprintf1(tiff->memory, "Unsupported: TIFF with bpc=%d\n", tiff->bpc);
895
11
        code = gs_error_unknownerror;
896
11
        goto fail_decode;
897
886
    }
898
899
    /* Scale to fit, if too large. */
900
875
    scale = 1.0f;
901
875
    if (tiff->width * tiff->dev->HWResolution[0] > tiff->dev->width * tiff->xresolution)
902
124
        scale = ((float)tiff->dev->width * tiff->xresolution) / (tiff->width * tiff->dev->HWResolution[0]);
903
875
    if (scale * tiff->height * tiff->dev->HWResolution[1] > tiff->dev->height * tiff->yresolution)
904
86
        scale = ((float)tiff->dev->height * tiff->yresolution) / (tiff->height * tiff->dev->HWResolution[1]);
905
906
875
    code = gs_erasepage(tiff->pgs);
907
875
    if (code < 0)
908
0
        return code;
909
910
38.4k
    for (ty = 0; ty < tiff->height; ty += tiff->tile_height) {
911
454k
        for (tx = 0; tx < tiff->width; tx += tiff->tile_width) {
912
416k
            int y, s;
913
416k
            byte *row;
914
416k
            float xext, xoffset, yext, yoffset;
915
416k
            int tremx, tremy;
916
917
416k
            tiff->penum = gs_image_enum_alloc(tiff->memory, "tiff_impl_process(penum)");
918
416k
            if (tiff->penum == NULL)
919
0
                return_error(gs_error_VMerror);
920
921
            /* Centre - Extents and offsets are all calculated in points (1/72 of an inch) */
922
416k
            xext = (((float)tiff->width - tx * 2) * 72 * scale / tiff->xresolution);
923
416k
            xoffset = (tiff->dev->width * 72 / tiff->dev->HWResolution[0] - xext)/2;
924
416k
            yext = (((float)tiff->height - ty * 2) * 72 * scale / tiff->yresolution);
925
416k
            yoffset = (tiff->dev->height * 72 / tiff->dev->HWResolution[1] - yext)/2;
926
927
416k
            gs_initmatrix(tiff->pgs);
928
929
            /* By default the ctm is set to:
930
             *   xres/72   0
931
             *   0         -yres/72
932
             *   0         dev->height * yres/72
933
             * i.e. it moves the origin from being top right to being bottom left.
934
             * We want to move it back, as without this, the image will be displayed
935
             * upside down.
936
             */
937
416k
            code = gs_translate(tiff->pgs, 0.0, tiff->dev->height * 72 / tiff->dev->HWResolution[1]);
938
416k
            if (code >= 0)
939
416k
                code = gs_translate(tiff->pgs, xoffset, -yoffset);
940
416k
            if (code >= 0)
941
416k
                code = gs_scale(tiff->pgs, scale, -scale);
942
416k
            if (code < 0)
943
0
               goto fail_decode;
944
945
416k
            memset(&tiff->image, 0, sizeof(tiff->image));
946
416k
            gs_image_t_init(&tiff->image, cs);
947
416k
            tiff->image.BitsPerComponent = tiff->bpp/tiff->num_comps;
948
416k
            if (alpha)
949
0
                tiff->image.BitsPerComponent = 8;
950
416k
            tiff->image.Width = tiff->tile_width;
951
416k
            tiff->image.Height = tiff->tile_height;
952
953
416k
            tiff->image.ImageMatrix.xx = tiff->xresolution / 72.0f;
954
416k
            tiff->image.ImageMatrix.yy = tiff->yresolution / 72.0f;
955
416k
            if (invert) {
956
4.90k
                tiff->image.Decode[0] = 1;
957
4.90k
                tiff->image.Decode[1] = 0;
958
4.90k
                tiff->image.Decode[2] = 1;
959
4.90k
                tiff->image.Decode[3] = 0;
960
4.90k
                tiff->image.Decode[4] = 1;
961
4.90k
                tiff->image.Decode[5] = 0;
962
4.90k
                tiff->image.Decode[6] = 1;
963
4.90k
                tiff->image.Decode[7] = 0;
964
4.90k
            }
965
966
416k
            if (tiff->is_rgba) {
967
247
                size_t z = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 1, 0);
968
247
                if (code < 0)
969
0
                    goto fail_decode;
970
247
                if (TIFFReadRGBAImage(tiff->handle, tiff->width, tiff->height,
971
247
                                      (uint32_t *)tiff->samples, 0) == 0) {
972
83
                    code = gs_error_unknownerror;
973
83
                    goto fail_decode;
974
83
                }
975
164
                blend_alpha(tiff, z, 4, planar);
976
416k
            } else if (tiff->tiled) {
977
415k
                if (TIFFReadTile(tiff->handle, tiff->samples, tx, ty, 0, 0) == 0) {
978
0
                    code = gs_error_unknownerror;
979
0
                    goto fail_decode;
980
0
                }
981
415k
            } else if (planar != PLANARCONFIG_CONTIG) {
982
39
                tiff->image.format = gs_image_format_component_planar;
983
39
            }
984
985
416k
            if (!tiff->is_rgba && tiff->tiled) {
986
415k
                if (tiff->palette) {
987
107k
                    size_t n = size_mla(tiff->memory, &code, tiff->tile_width, tiff->tile_height, 1, 0);
988
107k
                    byte *q = tiff->samples;
989
107k
                    byte *p = tiff->proc_samples;
990
107k
                    if (code < 0)
991
0
                        goto fail_decode;
992
971k
                    while (n--) {
993
863k
                        byte *v = &tiff->palette[3 * *q++];
994
863k
                        p[0] = *v++;
995
863k
                        p[1] = *v++;
996
863k
                        p[2] = *v++;
997
863k
                        p += 3;
998
863k
                    }
999
107k
                }
1000
415k
                if (alpha) {
1001
0
                    blend_alpha(tiff, tiff->tile_width, tiff->num_comps, planar);
1002
0
                }
1003
415k
            }
1004
1005
416k
            code = gs_image_init(tiff->penum,
1006
416k
                                 &tiff->image,
1007
416k
                                 false,
1008
416k
                                 false,
1009
416k
                                 tiff->pgs);
1010
416k
            if (code < 0) {
1011
2
                goto fail_decode;
1012
2
            }
1013
1014
416k
            tremx = tiff->width - tx;
1015
416k
            if (tremx > tiff->tile_width)
1016
378k
                tremx = tiff->tile_width;
1017
416k
            tremy = tiff->height - ty;
1018
416k
            if (tremy > tiff->tile_height)
1019
407k
                tremy = tiff->tile_height;
1020
416k
            {
1021
                /* Make sure we won't overflow in the loop. */
1022
416k
                (void)size_mla(tiff->memory, &code, tiff->byte_width, tiff->tile_height, 1, 0);
1023
416k
                if (code < 0)
1024
0
                    goto fail_decode;
1025
416k
            }
1026
4.39M
            for (y = 0; y < tremy; y++) {
1027
3.98M
                if (tiff->is_rgba) {
1028
941k
                    row = tiff->proc_samples + (size_t)tiff->byte_width * (tiff->tile_height-1-y);
1029
3.04M
                } else if (tiff->tiled) {
1030
1.61M
                    row = tiff->proc_samples + (size_t)tiff->byte_width * y;
1031
1.61M
                } else if (planar == PLANARCONFIG_CONTIG) {
1032
1.40M
                    row = tiff->proc_samples;
1033
1.40M
                    if (TIFFReadScanline(tiff->handle, tiff->samples, ty+y, 0) == 0) {
1034
0
                        code = gs_error_unknownerror;
1035
0
                        goto fail_decode;
1036
0
                    }
1037
1.40M
                } else {
1038
16.0k
                    int span = tiff->raw_byte_width;
1039
16.0k
                    byte *in_row = tiff->samples;
1040
16.0k
                    row = tiff->proc_samples;
1041
37.1k
                    for (s = 0; s < tiff->raw_num_comps; s++) {
1042
21.1k
                         plane_data[s].data = row;
1043
21.1k
                         plane_data[s].size = span;
1044
21.1k
                         if (TIFFReadScanline(tiff->handle, in_row, ty+y, s) == 0) {
1045
0
                             code = gs_error_unknownerror;
1046
0
                             goto fail_decode;
1047
0
                         }
1048
21.1k
                         row += span;
1049
21.1k
                         in_row += span;
1050
21.1k
                    }
1051
16.0k
                    row -= span * tiff->raw_num_comps;
1052
16.0k
                }
1053
1054
3.98M
                if (tiff->bpc == 16)
1055
552k
                {
1056
552k
                    byte *p = row;
1057
552k
                    int n = tiff->tile_width * tiff->raw_num_comps;
1058
30.4M
                    while (n--)
1059
29.8M
                    {
1060
29.8M
                        byte b = p[0];
1061
29.8M
                        p[0] = p[1];
1062
29.8M
                        p[1] = b;
1063
29.8M
                        p += 2;
1064
29.8M
                    }
1065
552k
                }
1066
1067
3.98M
                if (!tiff->tiled) {
1068
1.51M
                    if (tiff->palette) {
1069
26.6k
                        int n = tiff->tile_width;
1070
26.6k
                        const byte *q = tiff->samples;
1071
26.6k
                        byte *p = tiff->proc_samples;
1072
26.6k
                        switch (tiff->pal_bpc)
1073
26.6k
                        {
1074
11.1k
                        case 8:
1075
8.93M
                            while (n--) {
1076
8.92M
                                byte *v = &tiff->palette[3 * *q++];
1077
8.92M
                                p[0] = *v++;
1078
8.92M
                                p[1] = *v++;
1079
8.92M
                                p[2] = *v++;
1080
8.92M
                                p += 3;
1081
8.92M
                            }
1082
11.1k
                            break;
1083
15.2k
                        case 1:
1084
15.2k
                        {
1085
15.2k
                            int sh = 7;
1086
14.7M
                            while (n--) {
1087
14.6M
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 1)];
1088
14.6M
                                sh--;
1089
14.6M
                                if (sh < 0)
1090
1.83M
                                    sh = 7, q++;
1091
14.6M
                                p[0] = *v++;
1092
14.6M
                                p[1] = *v++;
1093
14.6M
                                p[2] = *v++;
1094
14.6M
                                p += 3;
1095
14.6M
                            }
1096
15.2k
                            break;
1097
0
                        }
1098
111
                        case 2:
1099
111
                        {
1100
111
                            int sh = 6;
1101
36.3k
                            while (n--) {
1102
36.1k
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 3)];
1103
36.1k
                                sh -= 2;
1104
36.1k
                                if (sh < 0)
1105
9.04k
                                    sh = 6, q++;
1106
36.1k
                                p[0] = *v++;
1107
36.1k
                                p[1] = *v++;
1108
36.1k
                                p[2] = *v++;
1109
36.1k
                                p += 3;
1110
36.1k
                            }
1111
111
                            break;
1112
0
                        }
1113
161
                        case 4:
1114
161
                        {
1115
161
                            int sh = 4;
1116
4.34k
                            while (n--) {
1117
4.17k
                                byte *v = &tiff->palette[3 * (((*q)>>sh) & 15)];
1118
4.17k
                                sh ^= 4;
1119
4.17k
                                if (sh == 4)
1120
2.07k
                                    q++;
1121
4.17k
                                p[0] = *v++;
1122
4.17k
                                p[1] = *v++;
1123
4.17k
                                p[2] = *v++;
1124
4.17k
                                p += 3;
1125
4.17k
                            }
1126
161
                            break;
1127
0
                        }
1128
26.6k
                        }
1129
26.6k
                    }
1130
1.51M
                    if (alpha) {
1131
0
                        blend_alpha(tiff, tiff->tile_width, tiff->raw_num_comps, planar);
1132
0
                    }
1133
1.51M
                }
1134
1135
3.98M
                if (tiff->image.format == gs_image_format_component_planar) {
1136
16.0k
                    code = gs_image_next_planes(tiff->penum, (gs_const_string *)&plane_data[0], used, false);
1137
3.96M
                } else {
1138
3.96M
                    code = gs_image_next(tiff->penum, row, tiff->byte_width, used);
1139
3.96M
                }
1140
3.98M
                if (code < 0) {
1141
22
                    code = gs_error_unknownerror;
1142
22
                    goto fail_decode;
1143
22
                }
1144
3.98M
            }
1145
416k
            code = gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1146
416k
            tiff->penum = NULL;
1147
416k
            if (code < 0)
1148
0
                return code;
1149
416k
        }
1150
37.7k
    }
1151
768
    tiff->state = ii_state_flush;
1152
768
    (void)pl_finish_page(tiff->memory->gs_lib_ctx->top_of_system,
1153
768
                         tiff->pgs, 1, true);
1154
768
    return 0;
1155
1156
261
fail_decode:
1157
261
    if (tiff->penum)
1158
107
    {
1159
107
        (void)gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1160
107
        tiff->penum = NULL;
1161
107
    }
1162
261
    tiff->state = ii_state_flush;
1163
1164
261
    return code;
1165
875
}
1166
1167
static int
1168
decode_all_tiffs(tiff_interp_instance_t *tiff)
1169
1.62k
{
1170
1.62k
    int code;
1171
1172
1.62k
    tiff->nulldev = gs_currentdevice(tiff->pgs);
1173
1.62k
    rc_increment(tiff->nulldev);
1174
1.62k
    code = gs_setdevice_no_erase(tiff->pgs, tiff->dev);
1175
1.62k
    if (code < 0)
1176
0
        return code;
1177
1178
1.62k
    do
1179
1.64k
    {
1180
1.64k
        code = do_tiff_decode(tiff);
1181
1.64k
        if (code < 0)
1182
807
            return code;
1183
1.64k
    }
1184
1.62k
    while (TIFFReadDirectory(tiff->handle));
1185
1186
816
    return 0;
1187
1.62k
}
1188
1189
1190
static int
1191
do_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr, int eof)
1192
12.8k
{
1193
12.8k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
1194
12.8k
    int code = 0;
1195
12.8k
    ii_state ostate = (ii_state)-1;
1196
12.8k
    int bytes_left = 0;
1197
1198
44.0k
    while (tiff->state != ostate || pr->limit - pr->ptr != bytes_left)
1199
36.6k
    {
1200
36.6k
        ostate = tiff->state;
1201
36.6k
        bytes_left = pr->limit - pr->ptr;
1202
36.6k
        switch(tiff->state)
1203
36.6k
        {
1204
5.48k
        case ii_state_identifying:
1205
5.48k
        {
1206
5.48k
            const byte *hdr;
1207
            /* Try and get us 4 bytes */
1208
5.48k
            code = ensure_bytes(tiff, pr, 4);
1209
5.48k
            if (code < 0)
1210
0
                return code;
1211
5.48k
            hdr = pr->ptr+1;
1212
5.48k
            if (hdr[0] == 'I' && hdr[1] == 'I' && (hdr[2] == 42 || hdr[2] == 43) && hdr[3] == 0) {
1213
4.69k
                tiff->state = ii_state_tiff;
1214
4.69k
                break;
1215
4.69k
            }
1216
787
            if (hdr[0] == 'M' && hdr[1] == 'M' && hdr[2] == 0 && (hdr[3] == 42 || hdr[3] == 43)) {
1217
787
                tiff->state = ii_state_tiff;
1218
787
                break;
1219
787
            }
1220
0
            tiff->state = ii_state_flush;
1221
0
            break;
1222
787
        }
1223
20.1k
        case ii_state_tiff:
1224
20.1k
        {
1225
            /* Gather data into a buffer */
1226
20.1k
            int bytes = bytes_until_uel(pr);
1227
1228
20.1k
            if (bytes == 0 && pr->limit - pr->ptr > 9) {
1229
                /* No bytes until UEL, and there is space for a UEL in the buffer */
1230
0
                tiff->state = ii_state_tiff_decode;
1231
0
                tiff->file_pos = 0;
1232
0
                break;
1233
0
            }
1234
20.1k
            if (bytes == 0 && eof) {
1235
                /* No bytes until UEL, and we are at eof */
1236
5.48k
                tiff->state = ii_state_tiff_decode;
1237
5.48k
                tiff->file_pos = 0;
1238
5.48k
                break;
1239
5.48k
            }
1240
1241
14.7k
            if (tiff->buffer_full + bytes > tiff->buffer_max) {
1242
                /* Need to expand our buffer */
1243
5.51k
                size_t proposed = tiff->buffer_full*2;
1244
5.51k
                if (proposed == 0)
1245
5.48k
                    proposed = 32768;
1246
5.51k
                while (proposed < tiff->buffer_full + bytes)
1247
0
                    proposed *= 2;
1248
1249
5.51k
                if (tiff->tiff_buffer == NULL) {
1250
5.48k
                    tiff->tiff_buffer = gs_alloc_bytes(tiff->memory, proposed, "tiff_buffer");
1251
5.48k
                    if (tiff->tiff_buffer == NULL) {
1252
0
                        tiff->state = ii_state_flush;
1253
0
                        break;
1254
0
                    }
1255
5.48k
                } else {
1256
29
                    void *new_buf = gs_resize_object(tiff->memory, tiff->tiff_buffer, proposed, "tiff_buffer");
1257
29
                    if (new_buf == NULL) {
1258
0
                        tiff->state = ii_state_flush;
1259
0
                        break;
1260
0
                    }
1261
29
                    tiff->tiff_buffer = new_buf;
1262
29
                }
1263
5.51k
                tiff->buffer_max = proposed;
1264
5.51k
            }
1265
1266
14.7k
            memcpy(&tiff->tiff_buffer[tiff->buffer_full], pr->ptr+1, bytes);
1267
14.7k
            tiff->buffer_full += bytes;
1268
14.7k
            pr->ptr += bytes;
1269
14.7k
            code = gs_error_NeedInput;
1270
14.7k
            break;
1271
14.7k
        }
1272
5.48k
        case ii_state_tiff_decode:
1273
5.48k
        {
1274
5.48k
            tiff->handle = TIFFClientOpen("dummy", "rm",
1275
5.48k
                                          (thandle_t)tiff,
1276
5.48k
                                          tifsReadProc,
1277
5.48k
                                          tifsWriteProc,
1278
5.48k
                                          tifsSeekProc,
1279
5.48k
                                          tifsCloseProc,
1280
5.48k
                                          tifsSizeProc,
1281
5.48k
                                          NULL,
1282
5.48k
                                          NULL);
1283
5.48k
            if (tiff->handle == NULL) {
1284
3.86k
                tiff->state = ii_state_flush;
1285
3.86k
                break;
1286
3.86k
            }
1287
1288
1.62k
#if defined(SHARE_JPEG) && SHARE_JPEG==0
1289
1.62k
            TIFFSetJpegMemFunction(tiff->handle,
1290
1.62k
                                   &tiff_jpeg_mem_callback);
1291
1.62k
#endif
1292
1293
1.62k
            code = decode_all_tiffs(tiff);
1294
1.62k
            if (code < 0)
1295
807
            {
1296
807
                tiff->state = ii_state_flush;
1297
807
                break;
1298
807
            }
1299
816
            break;
1300
1.62k
        }
1301
816
        default:
1302
5.48k
        case ii_state_flush:
1303
1304
5.48k
            if (tiff->handle) {
1305
1.62k
                TIFFClose(tiff->handle);
1306
1.62k
                tiff->handle = NULL;
1307
1.62k
            }
1308
1309
5.48k
            if (tiff->penum) {
1310
0
                (void)gs_image_cleanup_and_free_enum(tiff->penum, tiff->pgs);
1311
0
                tiff->penum = NULL;
1312
0
            }
1313
1314
5.48k
            if (tiff->proc_samples && tiff->proc_samples != tiff->samples) {
1315
48
                gs_free_object(tiff->memory, tiff->proc_samples, "tiff_impl_process(samples)");
1316
48
                tiff->proc_samples = NULL;
1317
48
            }
1318
1319
5.48k
            if (tiff->samples) {
1320
927
                gs_free_object(tiff->memory, tiff->samples, "tiff_impl_process(samples)");
1321
927
                tiff->samples = NULL;
1322
927
                tiff->proc_samples = NULL;
1323
927
            }
1324
1325
5.48k
            if (tiff->palette) {
1326
48
                gs_free_object(tiff->memory, tiff->palette, "tiff_impl_process(samples)");
1327
48
                tiff->palette = NULL;
1328
48
            }
1329
1330
5.48k
            if (tiff->tiff_buffer) {
1331
5.48k
                gs_free_object(tiff->memory, tiff->tiff_buffer, "tiff_impl_process(tiff_buffer)");
1332
5.48k
                tiff->tiff_buffer = NULL;
1333
5.48k
                tiff->buffer_max = 0;
1334
5.48k
                tiff->buffer_full = 0;
1335
5.48k
            }
1336
            /* We want to bin any data we get up to, but not including
1337
             * a UEL. */
1338
5.48k
            return flush_to_uel(pr);
1339
36.6k
        }
1340
36.6k
    }
1341
1342
7.37k
    return code;
1343
12.8k
}
1344
1345
static int
1346
7.37k
tiff_impl_process(pl_interp_implementation_t * impl, stream_cursor_read * pr) {
1347
7.37k
    return do_impl_process(impl, pr, 0);
1348
7.37k
}
1349
1350
static int
1351
tiff_impl_process_end(pl_interp_implementation_t * impl)
1352
5.48k
{
1353
5.48k
    return 0;
1354
5.48k
}
1355
1356
/* Not implemented */
1357
static int
1358
tiff_impl_flush_to_eoj(pl_interp_implementation_t *impl, stream_cursor_read *cursor)
1359
0
{
1360
0
    const byte *p = cursor->ptr;
1361
0
    const byte *rlimit = cursor->limit;
1362
1363
    /* Skip to, but leave UEL in buffer for PJL to find later */
1364
0
    for (; p < rlimit; ++p)
1365
0
        if (p[1] == '\033') {
1366
0
            uint avail = rlimit - p;
1367
1368
0
            if (memcmp(p + 1, "\033%-12345X", min(avail, 9)))
1369
0
                continue;
1370
0
            if (avail < 9)
1371
0
                break;
1372
0
            cursor->ptr = p;
1373
0
            return 1;           /* found eoj */
1374
0
        }
1375
0
    cursor->ptr = p;
1376
0
    return 0;                   /* need more */
1377
0
}
1378
1379
/* Parser action for end-of-file */
1380
static int
1381
tiff_impl_process_eof(pl_interp_implementation_t *impl)
1382
5.48k
{
1383
5.48k
    stream_cursor_read r;
1384
1385
5.48k
    r.ptr = NULL;
1386
5.48k
    r.limit = NULL;
1387
5.48k
    return do_impl_process(impl, &r, 1);
1388
5.48k
}
1389
1390
/* Report any errors after running a job */
1391
static int
1392
tiff_impl_report_errors(pl_interp_implementation_t *impl,          /* interp instance to wrap up job in */
1393
                        int                         code,          /* prev termination status */
1394
                        long                        file_position, /* file position of error, -1 if unknown */
1395
                        bool                        force_to_cout  /* force errors to cout */
1396
)
1397
0
{
1398
0
    return 0;
1399
0
}
1400
1401
/* Wrap up interp instance after a "job" */
1402
static int
1403
tiff_impl_dnit_job(pl_interp_implementation_t *impl)
1404
5.48k
{
1405
5.48k
    tiff_interp_instance_t *tiff = (tiff_interp_instance_t *)impl->interp_client_data;
1406
1407
5.48k
    if (tiff->nulldev) {
1408
1.62k
        int code = gs_setdevice(tiff->pgs, tiff->nulldev);
1409
1.62k
        tiff->dev = NULL;
1410
1.62k
        rc_decrement(tiff->nulldev, "tiff_impl_dnit_job(nulldevice)");
1411
1.62k
        tiff->nulldev = NULL;
1412
1.62k
        return code;
1413
1.62k
    }
1414
3.86k
    return 0;
1415
5.48k
}
1416
1417
/* Parser implementation descriptor */
1418
const pl_interp_implementation_t tiff_implementation = {
1419
  tiff_impl_characteristics,
1420
  tiff_impl_allocate_interp_instance,
1421
  tiff_impl_get_device_memory,
1422
  NULL, /* tiff_impl_set_param */
1423
  NULL, /* tiff_impl_add_path */
1424
  NULL, /* tiff_impl_post_args_init */
1425
  tiff_impl_init_job,
1426
  NULL, /* tiff_impl_run_prefix_commands */
1427
  NULL, /* tiff_impl_process_file */
1428
  tiff_impl_process_begin,
1429
  tiff_impl_process,
1430
  tiff_impl_process_end,
1431
  tiff_impl_flush_to_eoj,
1432
  tiff_impl_process_eof,
1433
  tiff_impl_report_errors,
1434
  tiff_impl_dnit_job,
1435
  tiff_impl_deallocate_interp_instance,
1436
  NULL, /* tiff_impl_reset */
1437
  NULL  /* interp_client_data */
1438
};
1439
#endif /* TIFF_INCLUDED */