Coverage Report

Created: 2026-09-14 07:34

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