Coverage Report

Created: 2026-04-01 07:17

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