Coverage Report

Created: 2026-02-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/pdf/pdf_image.c
Line
Count
Source
1
/* Copyright (C) 2018-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
/* Image operations for the PDF interpreter */
17
18
#include "pdf_int.h"
19
#include "pdf_stack.h"
20
#include "pdf_font_types.h"
21
#include "pdf_gstate.h"
22
#include "pdf_doc.h"
23
#include "pdf_page.h"
24
#include "pdf_image.h"
25
#include "pdf_file.h"
26
#include "pdf_dict.h"
27
#include "pdf_array.h"
28
#include "pdf_loop_detect.h"
29
#include "pdf_colour.h"
30
#include "pdf_trans.h"
31
#include "pdf_misc.h"
32
#include "pdf_optcontent.h"
33
#include "pdf_mark.h"
34
#include "stream.h"     /* for stell() */
35
#include "gsicc_cache.h"
36
37
#include "gspath2.h"
38
#include "gsiparm4.h"
39
#include "gsiparm3.h"
40
#include "gsipar3x.h"
41
#include "gsform1.h"
42
#include "gstrans.h"
43
#include "gxdevsop.h"               /* For special ops */
44
#include "gspath.h"         /* For gs_moveto() and friends */
45
#include "gsstate.h"        /* For gs_setoverprintmode() */
46
#include "gscoord.h"        /* for gs_concat() and others */
47
#include "gxgstate.h"
48
49
int pdfi_BI(pdf_context *ctx)
50
324k
{
51
324k
    int code;
52
53
324k
    if (ctx->text.BlockDepth != 0) {
54
22
        ctx->text.BlockDepth = 0;
55
22
        if (ctx->text.TextClip) {
56
0
            gx_device *dev = gs_currentdevice_inline(ctx->pgs);
57
58
0
            ctx->text.TextClip = false;
59
0
            (void)dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
60
0
        }
61
22
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_BI", NULL);
62
22
        if (code < 0)
63
0
            return code;
64
22
    }
65
66
324k
    return pdfi_mark_stack(ctx, PDF_DICT_MARK);
67
324k
}
68
69
typedef struct {
70
    int comps;
71
    int bpc;
72
    uint32_t cs_enum;
73
    bool iccbased;
74
    bool no_data;
75
    bool is_valid;
76
    uint32_t icc_offset;
77
    uint32_t icc_length;
78
} pdfi_jpx_info_t;
79
80
typedef struct {
81
    /* Type and SubType were already checked by caller */
82
    /* OPI, Metadata -- do we care? */
83
    bool ImageMask;
84
    bool Interpolate;
85
    int64_t Length;
86
    int64_t Height;
87
    int64_t Width;
88
    int64_t BPC;
89
    int64_t StructParent;
90
    int64_t SMaskInData;
91
    pdf_obj *Mask;
92
    pdf_obj *SMask;
93
    pdf_obj *ColorSpace;
94
    pdf_name *Intent;
95
    pdf_obj *Alternates;
96
    pdf_obj *Name; /* obsolete, do we still support? */
97
    pdf_obj *Decode;
98
    pdf_dict *OC;  /* Optional Content */
99
    /* Filter and DecodeParms handled by pdfi_filter() (can probably remove, but I like the info while debugging) */
100
    bool is_JPXDecode;
101
    pdf_obj *Filter;
102
    pdf_obj *DecodeParms;
103
104
    /* Convenience variables (save these here instead of passing around as params) */
105
    pdf_dict *page_dict;
106
    pdf_dict *stream_dict;
107
    bool inline_image;
108
    pdfi_jpx_info_t jpx_info;
109
} pdfi_image_info_t;
110
111
static void
112
pdfi_free_image_info_components(pdfi_image_info_t *info)
113
1.23M
{
114
1.23M
    if (info->Mask)
115
909
        pdfi_countdown(info->Mask);
116
1.23M
    if (info->SMask)
117
28.8k
        pdfi_countdown(info->SMask);
118
1.23M
    if (info->ColorSpace)
119
106k
        pdfi_countdown(info->ColorSpace);
120
1.23M
    if (info->Intent)
121
8.86k
        pdfi_countdown(info->Intent);
122
1.23M
    if (info->Alternates)
123
0
        pdfi_countdown(info->Alternates);
124
1.23M
    if (info->Name)
125
22.0k
        pdfi_countdown(info->Name);
126
1.23M
    if (info->Decode)
127
288k
        pdfi_countdown(info->Decode);
128
1.23M
    if (info->OC)
129
52
        pdfi_countdown(info->OC);
130
1.23M
    if (info->Filter)
131
113k
        pdfi_countdown(info->Filter);
132
1.23M
    if (info->DecodeParms)
133
40.5k
        pdfi_countdown(info->DecodeParms);
134
1.23M
    memset(info, 0, sizeof(*info));
135
1.23M
}
136
137
138
static inline uint64_t
139
pdfi_get_image_data_size(gs_data_image_t *pim, int comps)
140
389k
{
141
389k
    int size;
142
389k
    int64_t H, W, B;
143
144
389k
    H = pim->Height;
145
389k
    W = pim->Width;
146
389k
    B = pim->BitsPerComponent;
147
148
389k
    size = (((W * comps * B) + 7) / 8) * H;
149
389k
    return size;
150
389k
}
151
152
static inline uint64_t
153
pdfi_data_size_from_image_info(pdfi_image_info_t *info, int comps)
154
0
{
155
0
    int size;
156
0
    int64_t H, W, B;
157
0
158
0
    H = info->Height;
159
0
    W = info->Width;
160
0
    B = info->BPC;
161
0
162
0
    size = (((W * comps * B) + 7) / 8) * H;
163
0
    return size;
164
0
}
165
166
static inline uint64_t
167
pdfi_get_image_line_size(gs_data_image_t *pim, int comps)
168
0
{
169
0
    int size;
170
0
    int64_t W, B;
171
0
172
0
    W = pim->Width;
173
0
    B = pim->BitsPerComponent;
174
0
175
0
    size = (((W * comps * B) + 7) / 8);
176
0
    return size;
177
0
}
178
179
/* Find first dictionary in array that contains "/DefaultForPrinting true" */
180
static pdf_stream *
181
pdfi_find_alternate(pdf_context *ctx, pdf_obj *alt)
182
0
{
183
0
    pdf_array *array = NULL;
184
0
    pdf_obj *item = NULL;
185
0
    pdf_stream *alt_stream = NULL;
186
0
    int i;
187
0
    int code;
188
0
    bool flag;
189
190
0
    if (pdfi_type_of(alt) != PDF_ARRAY)
191
0
        return NULL;
192
193
0
    array = (pdf_array *)alt;
194
0
    for (i=0; i<pdfi_array_size(array);i++) {
195
0
        code = pdfi_array_get_type(ctx, array, (uint64_t)i, PDF_DICT, &item);
196
0
        if (code != 0)
197
0
            continue;
198
0
        code = pdfi_dict_get_bool(ctx, (pdf_dict *)item, "DefaultForPrinting", &flag);
199
0
        if (code != 0 || !flag) {
200
0
            pdfi_countdown(item);
201
0
            item = NULL;
202
0
            continue;
203
0
        }
204
0
        code = pdfi_dict_get_type(ctx, (pdf_dict *)item, "Image", PDF_STREAM, (pdf_obj **)&alt_stream);
205
0
        pdfi_countdown(item);
206
0
        item = NULL;
207
0
        if (code != 0)
208
0
            continue;
209
0
        return alt_stream;
210
0
    }
211
0
    return NULL;
212
0
}
213
214
129k
#define READ32BE(i) (((i)[0] << 24) | ((i)[1] << 16) | ((i)[2] << 8) | (i)[3])
215
10.4k
#define READ16BE(i) (((i)[0] << 8) | (i)[1])
216
57.1k
#define K4(a, b, c, d) ((a << 24) + (b << 16) + (c << 8) + d)
217
31.2k
#define LEN_IHDR 14
218
13.0k
#define LEN_DATA 2048
219
220
/* Returns either < 0, or exactly 8 */
221
static int
222
get_box(pdf_context *ctx, pdf_c_stream *source, int length, uint32_t *box_len, uint32_t *box_val)
223
59.3k
{
224
59.3k
    int code;
225
59.3k
    byte blob[4];
226
227
59.3k
    if (length < 8)
228
5
        return_error(gs_error_limitcheck);
229
59.3k
    code = pdfi_read_bytes(ctx, blob, 1, 4, source);
230
59.3k
    if (code < 0)
231
0
        return code;
232
59.3k
    *box_len = READ32BE(blob);
233
59.3k
    if (*box_len < 8)
234
24
        return_error(gs_error_limitcheck);
235
59.3k
    code = pdfi_read_bytes(ctx, blob, 1, 4, source);
236
59.3k
    if (code < 0)
237
0
        return code;
238
59.3k
    *box_val = READ32BE(blob);
239
240
59.3k
    if(ctx->args.pdfdebug)
241
59.3k
        dbgmprintf3(ctx->memory, "JPXFilter: BOX: l:%d, v:%x (%4.4s)\n", *box_len, *box_val, blob);
242
59.3k
    return 8;
243
59.3k
}
244
245
/* Scan JPX image for header info */
246
static int
247
pdfi_scan_jpxfilter(pdf_context *ctx, pdf_c_stream *source, int length, pdfi_jpx_info_t *info)
248
13.0k
{
249
13.0k
    uint32_t box_len = 0;
250
13.0k
    uint32_t box_val = 0;
251
13.0k
    int code;
252
13.0k
    byte ihdr_data[LEN_IHDR];
253
13.0k
    byte *data = NULL;
254
13.0k
    int data_buf_len = 0;
255
13.0k
    int avail = length;
256
13.0k
    int bpc = 0;
257
13.0k
    int comps = 0;
258
13.0k
    int cs_meth = 0;
259
13.0k
    uint32_t cs_enum = 0;
260
13.0k
    bool got_color = false;
261
262
13.0k
    if (ctx->args.pdfdebug)
263
13.0k
        dbgmprintf1(ctx->memory, "JPXFilter: Image length %d\n", length);
264
265
    /* Clear out the info param */
266
13.0k
    memset(info, 0, sizeof(pdfi_jpx_info_t));
267
268
13.0k
    info->no_data = false;
269
270
    /* Allocate a data buffer that hopefully is big enough */
271
13.0k
    data_buf_len = LEN_DATA;
272
13.0k
    data = gs_alloc_bytes(ctx->memory, data_buf_len, "pdfi_scan_jpxfilter (data)");
273
13.0k
    if (!data) {
274
0
        code = gs_note_error(gs_error_VMerror);
275
0
        goto exit;
276
0
    }
277
278
    /* Find the 'jp2h' box, skipping over everything else */
279
38.9k
    while (avail > 0) {
280
38.4k
        code = get_box(ctx, source, avail, &box_len, &box_val);
281
38.4k
        if (code < 0)
282
19
            goto exit;
283
38.4k
        avail -= 8;
284
38.4k
        box_len -= 8;
285
38.4k
        if (box_len <= 0 || box_len > avail) {
286
2.07k
            code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_INVALID_JPX_HDR, "pdfi_scan_jpxfilter", NULL);
287
2.07k
            goto exit;
288
2.07k
        }
289
36.3k
        if (box_val == K4('j','p','2','h')) {
290
10.4k
            break;
291
10.4k
        }
292
25.9k
        pdfi_seek(ctx, source, box_len, SEEK_CUR);
293
25.9k
        avail -= box_len;
294
25.9k
    }
295
10.9k
    if (avail <= 0) {
296
543
        info->no_data = true;
297
543
        code = gs_note_error(gs_error_ioerror);
298
543
        goto exit;
299
543
    }
300
301
    /* Now we are only looking inside the jp2h box */
302
10.4k
    avail = box_len;
303
304
    /* The first thing in the 'jp2h' box is an 'ihdr', get that */
305
10.4k
    code = get_box(ctx, source, avail, &box_len, &box_val);
306
10.4k
    if (code < 0)
307
0
        goto exit;
308
10.4k
    avail -= 8;
309
10.4k
    box_len -= 8;
310
10.4k
    if (box_val != K4('i','h','d','r')) {
311
1
        code = gs_note_error(gs_error_syntaxerror);
312
1
        goto exit;
313
1
    }
314
10.4k
    if (box_len != LEN_IHDR) {
315
0
        code = gs_note_error(gs_error_syntaxerror);
316
0
        goto exit;
317
0
    }
318
319
    /* Get things we care about from ihdr */
320
10.4k
    code = pdfi_read_bytes(ctx, ihdr_data, 1, LEN_IHDR, source);
321
10.4k
    if (code < 0)
322
0
        goto exit;
323
10.4k
    avail -= LEN_IHDR;
324
10.4k
    comps = READ16BE(ihdr_data+8);
325
10.4k
    if (ctx->args.pdfdebug)
326
10.4k
        dbgmprintf1(ctx->memory, "    COMPS: %d\n", comps);
327
10.4k
    bpc = ihdr_data[10];
328
10.4k
    if (bpc != 255)
329
10.4k
        bpc += 1;
330
10.4k
    if (ctx->args.pdfdebug)
331
10.4k
        dbgmprintf1(ctx->memory, "    BPC: %d\n", bpc);
332
333
    /* Parse the rest of the things */
334
20.8k
    while (avail > 0) {
335
10.4k
        code = get_box(ctx, source, avail, &box_len, &box_val);
336
10.4k
        if (code < 0)
337
10
            goto exit;
338
10.4k
        avail -= 8;
339
10.4k
        box_len -= 8;
340
10.4k
        if (box_len <= 0) {
341
0
            code = gs_note_error(gs_error_syntaxerror);
342
0
            goto exit;
343
0
        }
344
        /* Re-alloc buffer if it wasn't big enough (unlikely) */
345
10.4k
        if (box_len > data_buf_len) {
346
14
            if (ctx->args.pdfdebug)
347
14
                dbgmprintf2(ctx->memory, "data buffer (size %d) was too small, reallocing to size %d\n",
348
14
                      data_buf_len, box_len);
349
14
            gs_free_object(ctx->memory, data, "pdfi_scan_jpxfilter (data)");
350
14
            data_buf_len = box_len;
351
14
            data = gs_alloc_bytes(ctx->memory, data_buf_len, "pdfi_scan_jpxfilter (data)");
352
14
            if (!data) {
353
9
                code = gs_note_error(gs_error_VMerror);
354
9
                goto exit;
355
9
            }
356
14
        }
357
10.4k
        code = pdfi_read_bytes(ctx, data, 1, box_len, source);
358
10.4k
        if (code < 0)
359
0
            goto exit;
360
10.4k
        avail -= box_len;
361
10.4k
        switch(box_val) {
362
0
        case K4('b','p','c','c'):
363
0
            {
364
0
                int i;
365
0
                int bpc2;
366
367
0
                bpc2 = data[0];
368
0
                for (i=1;i<comps;i++) {
369
0
                    if (bpc2 != data[i]) {
370
0
                        emprintf(ctx->memory,
371
0
                                 "*** Error: JPX image colour channels do not all have the same colour depth\n");
372
0
                        emprintf(ctx->memory,
373
0
                                 "    Output may be incorrect.\n");
374
0
                    }
375
0
                }
376
0
                bpc = bpc2+1;
377
0
                if (ctx->args.pdfdebug)
378
0
                    dbgmprintf1(ctx->memory, "    BPCC: %d\n", bpc);
379
0
            }
380
0
            break;
381
10.4k
        case K4('c','o','l','r'):
382
10.4k
            if (got_color) {
383
0
                if (ctx->args.pdfdebug)
384
0
                    dbgmprintf(ctx->memory, "JPXFilter: Ignore extra COLR specs\n");
385
0
                break;
386
0
            }
387
10.4k
            cs_meth = data[0];
388
10.4k
            if (cs_meth == 1)
389
10.4k
                cs_enum = READ32BE(data+3);
390
3
            else if (cs_meth == 2 || cs_meth == 3) {
391
                /* This is an ICCBased color space just sitting there in the buffer.
392
                 * TODO: I could create the colorspace now while I have the buffer,
393
                 * but code flow is more consistent if I do it later.  Could change this.
394
                 *
395
                 * NOTE: cs_meth == 3 is apparently treated the same as 2.
396
                 * No idea why... it's really not documented anywhere.
397
                 */
398
0
                info->iccbased = true;
399
0
                info->icc_offset = pdfi_tell(source) - (box_len-3);
400
0
                info->icc_length = box_len - 3;
401
0
                if (ctx->args.pdfdebug)
402
0
                    dbgmprintf5(ctx->memory, "JPXDecode: COLR Meth %d at offset %d(0x%x), length %d(0x%x)\n",
403
0
                                cs_meth, info->icc_offset, info->icc_offset,
404
0
                                info->icc_length, info->icc_length);
405
0
                cs_enum = 0;
406
3
            } else {
407
3
                if (ctx->args.pdfdebug)
408
3
                    dbgmprintf1(ctx->memory, "JPXDecode: COLR unexpected method %d\n", cs_meth);
409
3
                cs_enum = 0;
410
3
            }
411
10.4k
            if (ctx->args.pdfdebug)
412
10.4k
                dbgmprintf2(ctx->memory, "    COLR: M:%d, ENUM:%d\n", cs_meth, cs_enum);
413
10.4k
            got_color = true;
414
10.4k
            break;
415
31
        case K4('p','c','l','r'):
416
            /* Apparently we just grab the BPC out of this */
417
31
            if (ctx->args.pdfdebug)
418
31
                dbgmprintf7(ctx->memory, "    PCLR Data: %x %x %x %x %x %x %x\n",
419
31
                      data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
420
31
            bpc = data[3];
421
31
            bpc = (bpc & 0x7) + 1;
422
31
            if (ctx->args.pdfdebug)
423
31
                dbgmprintf1(ctx->memory, "    PCLR BPC: %d\n", bpc);
424
31
            break;
425
0
        case K4('c','d','e','f'):
426
0
            dbgmprintf(ctx->memory, "JPXDecode: CDEF not supported yet\n");
427
0
            break;
428
36
        default:
429
36
            break;
430
10.4k
        }
431
432
10.4k
    }
433
434
10.4k
    info->comps = comps;
435
10.4k
    info->bpc = bpc;
436
10.4k
    info->cs_enum = cs_enum;
437
10.4k
    info->is_valid = true;
438
439
13.0k
 exit:
440
13.0k
    if (data)
441
13.0k
        gs_free_object(ctx->memory, data, "pdfi_scan_jpxfilter (data)");
442
    /* Always return 0 -- there are cases where this no image header at all, and just ignoring
443
     * the header seems to work.  In this case is_valid will be false, so we know not to rely on
444
     * the data from it.
445
     * Sample: tests_private/comparefiles/Bug694873.pdf
446
     */
447
13.0k
    return 0;
448
10.4k
}
449
450
/* Get image info out of dict into more convenient form, enforcing some requirements from the spec */
451
static int
452
pdfi_get_image_info(pdf_context *ctx, pdf_stream *image_obj,
453
                    pdf_dict *page_dict, pdf_dict *stream_dict, bool inline_image,
454
                    pdfi_image_info_t *info)
455
412k
{
456
412k
    int code;
457
412k
    double temp_f;
458
412k
    pdf_dict *image_dict = NULL;
459
460
412k
    memset(info, 0, sizeof(*info));
461
412k
    info->page_dict = page_dict;
462
412k
    info->stream_dict = stream_dict;
463
412k
    info->inline_image = inline_image;
464
465
    /* Not Handled: "ID", "OPI" */
466
467
    /* Length if it's in a stream dict */
468
412k
    info->Length = pdfi_stream_length(ctx, image_obj);
469
470
412k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)image_obj, &image_dict);
471
412k
    if (code < 0)
472
0
        goto errorExit;
473
474
    /* Required */
475
412k
    code = pdfi_dict_get_number2(ctx, image_dict, "Height", "H", &temp_f);
476
412k
    if (code < 0)
477
1.41k
        goto errorExit;
478
    /* This is bonkers, but... Bug695872.pdf has /W and /H which are real numbers */
479
411k
    info->Height = (int)temp_f;
480
411k
    if ((int)temp_f != (int)(temp_f+.5)) {
481
57
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
482
0
            goto errorExit;
483
57
    }
484
411k
    if (info->Height < 0) {
485
58
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
486
0
            goto errorExit;
487
58
        info->Height = 0;
488
58
    }
489
490
    /* Required */
491
411k
    code = pdfi_dict_get_number2(ctx, image_dict, "Width", "W", &temp_f);
492
411k
    if (code < 0)
493
685
        goto errorExit;
494
410k
    info->Width = (int)temp_f;
495
410k
    if ((int)temp_f != (int)(temp_f+.5)) {
496
19
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
497
0
            goto errorExit;
498
19
    }
499
410k
    if (info->Width < 0) {
500
16
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
501
0
            goto errorExit;
502
16
        info->Width = 0;
503
16
    }
504
505
    /* Optional, default false */
506
410k
    code = pdfi_dict_get_bool2(ctx, image_dict, "ImageMask", "IM", &info->ImageMask);
507
410k
    if (code != 0) {
508
114k
        if (code != gs_error_undefined)
509
8
            goto errorExit;
510
114k
        info->ImageMask = false;
511
114k
    }
512
513
    /* Optional, default false */
514
410k
    code = pdfi_dict_get_bool2(ctx, image_dict, "Interpolate", "I", &info->Interpolate);
515
410k
    if (code != 0) {
516
373k
        if (code != gs_error_undefined)
517
3
            goto errorExit;
518
373k
        info->Interpolate = false;
519
373k
    }
520
521
    /* Optional (Required, unless ImageMask is true)
522
     * But apparently for JPXDecode filter, this can be omitted.
523
     * Let's try a default of 1 for now...
524
     */
525
410k
    code = pdfi_dict_get_int2(ctx, image_dict, "BitsPerComponent", "BPC", &info->BPC);
526
410k
    if (code < 0) {
527
6.55k
        if (code != gs_error_undefined) {
528
32
            goto errorExit;
529
32
        }
530
6.51k
        info->BPC = 1;
531
6.51k
    }
532
404k
    else if (info->BPC != 1 && info->BPC != 2 && info->BPC != 4 && info->BPC != 8 && info->BPC != 16) {
533
323
        code = gs_note_error(gs_error_rangecheck);
534
323
        goto errorExit;
535
323
    }
536
    /* TODO: spec says if ImageMask is specified, and BPC is specified, then BPC must be 1
537
       Should we flag an error if this is violated?
538
     */
539
540
    /* Optional (apparently there is no "M" abbreviation for "Mask"? */
541
410k
    code = pdfi_dict_get(ctx, image_dict, "Mask", &info->Mask);
542
410k
    if (code < 0) {
543
        /* A lack of a Mask is not an error. If there is a genuine error reading
544
         * the Mask, ignore it unless PDFSTOPONWARNING is set. We can still render
545
         * the image. Arguably we should not, and Acrobat doesn't, but the current
546
         * GS implementation does.
547
         */
548
409k
        if (code != gs_error_undefined) {
549
81
           if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
550
0
               goto errorExit;
551
81
        }
552
409k
    }
553
410k
    if (info->Mask != NULL && (pdfi_type_of(info->Mask) != PDF_ARRAY && pdfi_type_of(info->Mask) != PDF_STREAM)) {
554
5
        pdfi_countdown(info->Mask);
555
5
        info->Mask = NULL;
556
5
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
557
0
            goto errorExit;
558
5
    }
559
560
    /* Optional (apparently there is no abbreviation for "SMask"? */
561
410k
    code = pdfi_dict_get(ctx, image_dict, "SMask", &info->SMask);
562
410k
    if (code < 0) {
563
381k
        if (code != gs_error_undefined) {
564
            /* Broken SMask, Warn, and ignore the SMask */
565
5.94k
            if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", (char *)"*** Warning: Image has invalid SMask.  Ignoring it")) < 0)
566
0
                goto errorExit;
567
5.94k
        }
568
381k
    } else {
569
29.0k
        if (pdfi_type_of(info->SMask) == PDF_NAME) {
570
4
            pdf_obj *o = NULL;
571
572
4
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", (pdf_name *)info->SMask, image_dict, page_dict, &o);
573
4
            if (code >= 0) {
574
0
                pdfi_countdown(info->SMask);
575
0
                info->SMask = o;
576
0
            }
577
4
        }
578
579
29.0k
        if (pdfi_type_of(info->SMask) != PDF_STREAM){
580
198
            pdfi_countdown(info->SMask);
581
198
            info->SMask = NULL;
582
198
            if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
583
0
                goto errorExit;
584
198
        }
585
29.0k
    }
586
587
    /* Optional, for JPXDecode filter images
588
     * (If non-zero, then SMask shouldn't be  specified)
589
     * Default: 0
590
     */
591
410k
    code = pdfi_dict_get_int(ctx, image_dict, "SMaskInData", &info->SMaskInData);
592
410k
    if (code < 0) {
593
410k
        if (code != gs_error_undefined)
594
0
            goto errorExit;
595
410k
        info->SMaskInData = 0;
596
410k
    }
597
598
    /* Optional (Required except for ImageMask, not allowed for ImageMask)*/
599
    /* TODO: Should we enforce this required/not allowed thing? */
600
410k
    code = pdfi_dict_get2(ctx, image_dict, "ColorSpace", "CS", &info->ColorSpace);
601
410k
    if (code < 0) {
602
302k
        if (code != gs_error_undefined)
603
122
            goto errorExit;
604
302k
    }
605
410k
    if (info->ColorSpace != NULL && (pdfi_type_of(info->ColorSpace) != PDF_NAME && pdfi_type_of(info->ColorSpace) != PDF_ARRAY)) {
606
127
        pdfi_countdown(info->ColorSpace);
607
127
        info->ColorSpace = NULL;
608
127
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
609
0
            goto errorExit;
610
127
    }
611
612
    /* Optional (default is to use from graphics state) */
613
    /* (no abbreviation for inline) */
614
410k
    code = pdfi_dict_get_type(ctx, image_dict, "Intent", PDF_NAME, (pdf_obj **)&info->Intent);
615
410k
    if (code < 0) {
616
401k
        if (code != gs_error_undefined)
617
0
            goto errorExit;
618
401k
    }
619
620
    /* Optional (array of alternate image dicts, can't be nested) */
621
410k
    code = pdfi_dict_get(ctx, image_dict, "Alternates", &info->Alternates);
622
410k
    if (code < 0) {
623
410k
        if (code != gs_error_undefined)
624
0
            goto errorExit;
625
410k
    }
626
410k
    if (info->Alternates != NULL && pdfi_type_of(info->Alternates) != PDF_ARRAY) {
627
0
        pdfi_countdown(info->Alternates);
628
0
        info->Alternates = NULL;
629
0
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
630
0
            goto errorExit;
631
0
    }
632
633
    /* Optional (required in PDF1.0, obsolete, do we support?) */
634
410k
    code = pdfi_dict_get(ctx, image_dict, "Name", &info->Name);
635
410k
    if (code < 0) {
636
388k
        if (code != gs_error_undefined)
637
0
            goto errorExit;
638
388k
    }
639
410k
    if (info->Name != NULL && pdfi_type_of(info->Name) != PDF_NAME) {
640
0
        pdfi_countdown(info->Name);
641
0
        info->Name = NULL;
642
0
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGENAME, "pdfi_get_image_info", NULL)) < 0)
643
0
            goto errorExit;
644
0
    }
645
646
    /* Required "if image is structural content item" */
647
    /* TODO: Figure out what to do here */
648
410k
    code = pdfi_dict_get_int(ctx, image_dict, "StructParent", &info->StructParent);
649
410k
    if (code < 0) {
650
410k
        if (code != gs_error_undefined)
651
0
            goto errorExit;
652
410k
    }
653
654
    /* Optional (default is probably [0,1] per component) */
655
410k
    code = pdfi_dict_get2(ctx, image_dict, "Decode", "D", &info->Decode);
656
410k
    if (code < 0) {
657
121k
        if (code != gs_error_undefined)
658
0
            goto errorExit;
659
121k
    }
660
410k
    if (info->Decode != NULL && pdfi_type_of(info->Decode) != PDF_ARRAY) {
661
292
        pdfi_countdown(info->Decode);
662
292
        info->Decode = NULL;
663
292
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
664
0
            goto errorExit;
665
292
    }
666
667
    /* Optional "Optional Content" */
668
410k
    code = pdfi_dict_get_type(ctx, image_dict, "OC", PDF_DICT, (pdf_obj **)&info->OC);
669
410k
    if (code < 0) {
670
410k
        if (code != gs_error_undefined)
671
0
            goto errorExit;
672
410k
    }
673
674
    /* Optional */
675
410k
    code = pdfi_dict_get2(ctx, image_dict, "Filter", "F", &info->Filter);
676
410k
    if (code < 0) {
677
297k
        if (code != gs_error_undefined)
678
0
            goto errorExit;
679
297k
    }
680
410k
    if (info->Filter != NULL && (pdfi_type_of(info->Filter) != PDF_NAME && pdfi_type_of(info->Filter) != PDF_ARRAY)) {
681
0
        pdfi_countdown(info->Filter);
682
0
        info->Filter = NULL;
683
0
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
684
0
             goto errorExit;
685
0
    }
686
687
    /* Check and set JPXDecode flag for later */
688
410k
    info->is_JPXDecode = false;
689
410k
    if (info->Filter && pdfi_type_of(info->Filter) == PDF_NAME) {
690
102k
        if (pdfi_name_is((pdf_name *)info->Filter, "JPXDecode"))
691
10.6k
            info->is_JPXDecode = true;
692
102k
    }
693
694
    /* Optional */
695
410k
    code = pdfi_dict_get2(ctx, image_dict, "DecodeParms", "DP", &info->DecodeParms);
696
410k
    if (code < 0) {
697
369k
        if (code != gs_error_undefined)
698
9
            goto errorExit;
699
369k
    }
700
410k
    if (info->DecodeParms != NULL && (pdfi_type_of(info->DecodeParms) != PDF_DICT && pdfi_type_of(info->DecodeParms) != PDF_ARRAY)) {
701
        /* null is legal. Pointless but legal. */
702
0
        if (pdfi_type_of(info->DecodeParms) != PDF_NULL) {
703
0
            if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
704
0
                goto errorExit;
705
0
        }
706
0
        pdfi_countdown(info->DecodeParms);
707
0
        info->DecodeParms = NULL;
708
0
    }
709
710
410k
    return 0;
711
712
2.59k
 errorExit:
713
2.59k
    pdfi_free_image_info_components(info);
714
2.59k
    return code;
715
410k
}
716
717
static int pdfi_check_inline_image_keys(pdf_context *ctx, pdf_dict *image_dict)
718
110k
{
719
110k
    bool known = false;
720
721
110k
    pdfi_dict_known(ctx, image_dict, "BPC", &known);
722
110k
    if (known)
723
0
        goto error_inline_check;
724
110k
    pdfi_dict_known(ctx, image_dict, "CS", &known);
725
110k
    if (known)
726
0
        goto error_inline_check;
727
110k
    pdfi_dict_known(ctx, image_dict, "D", &known);
728
110k
    if (known)
729
0
        goto error_inline_check;
730
110k
    pdfi_dict_known(ctx, image_dict, "DP", &known);
731
110k
    if (known)
732
0
        goto error_inline_check;
733
110k
    pdfi_dict_known(ctx, image_dict, "F", &known);
734
110k
    if (known)
735
0
        goto error_inline_check;
736
110k
    pdfi_dict_known(ctx, image_dict, "H", &known);
737
110k
    if (known)
738
0
        goto error_inline_check;
739
110k
    pdfi_dict_known(ctx, image_dict, "IM", &known);
740
110k
    if (known)
741
0
        goto error_inline_check;
742
110k
    pdfi_dict_known(ctx, image_dict, "I", &known);
743
110k
    if (known)
744
0
        goto error_inline_check;
745
110k
    pdfi_dict_known(ctx, image_dict, "W", &known);
746
110k
    if (known)
747
1
        goto error_inline_check;
748
749
110k
    return 0;
750
751
1
error_inline_check:
752
1
    return pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_BAD_INLINEIMAGEKEY, "pdfi_check_inline_image_keys", NULL);
753
110k
}
754
755
/* Render a PDF image
756
 * pim can be type1 (or imagemask), type3, type4
757
 */
758
static int
759
pdfi_render_image(pdf_context *ctx, gs_pixel_image_t *pim, pdf_c_stream *image_stream,
760
                  unsigned char *mask_buffer, uint64_t mask_size,
761
                  int comps, bool ImageMask)
762
389k
{
763
389k
    int code;
764
389k
    gs_image_enum *penum = NULL;
765
389k
    uint64_t bytes_left;
766
389k
    uint64_t bytes_used = 0;
767
389k
    uint64_t bytes_avail = 0;
768
389k
    gs_const_string plane_data[GS_IMAGE_MAX_COMPONENTS];
769
389k
    int main_plane=0, mask_plane=0;
770
389k
    bool no_progress = false;
771
389k
    int min_left;
772
773
#if DEBUG_IMAGES
774
    dbgmprintf(ctx->memory, "pdfi_render_image BEGIN\n");
775
#endif
776
777
389k
    code = pdfi_gsave(ctx);
778
389k
    if (code < 0)
779
0
        return code;
780
781
    /* Disable overprint mode for images that are not a mask */
782
389k
    if (!ImageMask)
783
93.6k
        gs_setoverprintmode(ctx->pgs, 0);
784
785
389k
    penum = gs_image_enum_alloc(ctx->memory, "pdfi_render_image (gs_image_enum_alloc)");
786
389k
    if (!penum) {
787
0
        code = gs_note_error(gs_error_VMerror);
788
0
        goto cleanupExit;
789
0
    }
790
791
    /* Took this logic from gs_image_init()
792
     * (the other tests in there have already been handled elsewhere)
793
     */
794
389k
    {
795
389k
        gx_image_enum_common_t *pie;
796
797
389k
        if (!ImageMask) {
798
            /* TODO: Can in_cachedevice ever be set in PDF? */
799
93.6k
            if (ctx->pgs->in_cachedevice != CACHE_DEVICE_NONE) {
800
0
                code = gs_note_error(gs_error_undefined);
801
0
                goto cleanupExit;
802
0
            }
803
93.6k
        }
804
805
389k
        code = gs_image_begin_typed((const gs_image_common_t *)pim, ctx->pgs, ImageMask, false, &pie);
806
389k
        if (code < 0)
807
255
            goto cleanupExit;
808
809
389k
        code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, ctx->pgs);
810
389k
        if (code < 0)
811
0
            goto cleanupExit;
812
389k
    }
813
814
    /* NOTE: I used image_file_continue() as my template for this code.
815
     * But this case is (hopefully) much much simpler.
816
     * We only handle two situations -- if there is mask_data, then we assume there are two planes.
817
     * If no mask_data, then there is one plane.
818
     */
819
389k
    if (mask_buffer) {
820
3.18k
        main_plane = 1;
821
3.18k
        mask_plane = 0;
822
3.18k
        plane_data[mask_plane].data = mask_buffer;
823
3.18k
        plane_data[mask_plane].size = mask_size;
824
385k
    } else {
825
385k
        main_plane = 0;
826
385k
    }
827
828
389k
    bytes_left = pdfi_get_image_data_size((gs_data_image_t *)pim, comps);
829
8.21M
    while (bytes_left > 0) {
830
7.85M
        uint used[GS_IMAGE_MAX_COMPONENTS];
831
832
15.4M
        while ((bytes_avail = sbufavailable(image_stream->s)) <= (min_left = sbuf_min_left(image_stream->s))) {
833
7.57M
            switch (image_stream->s->end_status) {
834
7.54M
            case 0:
835
7.54M
                s_process_read_buf(image_stream->s);
836
7.54M
                continue;
837
6.32k
            case EOFC:
838
6.32k
            case INTC:
839
6.32k
            case CALLC:
840
6.32k
                break;
841
29.1k
            default:
842
                /* case ERRC: */
843
29.1k
                code = gs_note_error(gs_error_ioerror);
844
29.1k
                goto cleanupExit;
845
7.57M
            }
846
6.32k
            break;   /* for EOFC */
847
7.57M
        }
848
849
        /*
850
         * Note that in the EOF case, we can get here with no data
851
         * available.
852
         */
853
7.82M
        if (bytes_avail >= min_left)
854
7.82M
            bytes_avail = (bytes_avail - min_left); /* may be 0 */
855
856
7.82M
        plane_data[main_plane].data = sbufptr(image_stream->s);
857
7.82M
        plane_data[main_plane].size = bytes_avail;
858
859
7.82M
        code = gs_image_next_planes(penum, plane_data, used, false);
860
7.82M
        if (code < 0) {
861
51
            goto cleanupExit;
862
51
        }
863
        /* If no data was consumed twice in a row, then there must be some kind of error,
864
         * even if the error code was not < 0.  Saw this with pdfwrite device.
865
         */
866
7.82M
        if (used[main_plane] == 0 && used[mask_plane] == 0) {
867
7.16k
            if (no_progress) {
868
3.58k
                code = gs_note_error(gs_error_unknownerror);
869
3.58k
                goto cleanupExit;
870
3.58k
            }
871
3.58k
            no_progress = true;
872
7.82M
        } else {
873
7.82M
            no_progress = false;
874
7.82M
        }
875
876
7.82M
        (void)sbufskip(image_stream->s, used[main_plane]);
877
878
        /* It might not always consume all the data, but so far the only case
879
         * I have seen with that was one that had mask data.
880
         * In that case, it used all of plane 0, and none of plane 1 on the first pass.
881
         * (image_2bpp.pdf)
882
         *
883
         * Anyway, this math should handle that case (as well as a case where it consumed only
884
         * part of the data, if that can actually happen).
885
         */
886
7.82M
        bytes_used = used[main_plane];
887
7.82M
        bytes_left -= bytes_used;
888
7.82M
        bytes_avail -= bytes_used;
889
7.82M
    }
890
891
356k
    code = 0;
892
893
389k
 cleanupExit:
894
389k
    if (penum)
895
389k
        gs_image_cleanup_and_free_enum(penum, ctx->pgs);
896
389k
    pdfi_grestore(ctx);
897
#if DEBUG_IMAGES
898
    dbgmprintf(ctx->memory, "pdfi_render_image END\n");
899
#endif
900
389k
    return code;
901
356k
}
902
903
/* Load up params common to the different image types */
904
static int
905
pdfi_data_image_params(pdf_context *ctx, pdfi_image_info_t *info,
906
                       gs_data_image_t *pim, int comps, gs_color_space *pcs)
907
395k
{
908
395k
    int code;
909
910
395k
    pim->BitsPerComponent = info->BPC;
911
395k
    pim->Width = info->Width;
912
395k
    pim->Height = info->Height;
913
395k
    pim->ImageMatrix.xx = (float)info->Width;
914
395k
    pim->ImageMatrix.yy = (float)(info->Height * -1);
915
395k
    pim->ImageMatrix.ty = (float)info->Height;
916
917
395k
    pim->Interpolate = info->Interpolate;
918
919
    /* Get the decode array (required for ImageMask, probably for everything) */
920
395k
    if (info->Decode) {
921
288k
        pdf_array *decode_array = (pdf_array *)info->Decode;
922
288k
        int i;
923
288k
        double num;
924
925
288k
        if (pdfi_array_size(decode_array) > GS_IMAGE_MAX_COMPONENTS * 2) {
926
0
            code = gs_note_error(gs_error_limitcheck);
927
0
            goto cleanupExit;
928
0
        }
929
930
866k
        for (i=0; i<pdfi_array_size(decode_array); i++) {
931
578k
            code = pdfi_array_get_number(ctx, decode_array, i, &num);
932
578k
            if (code < 0)
933
18
                goto cleanupExit;
934
578k
            pim->Decode[i] = (float)num;
935
578k
        }
936
288k
    } else {
937
        /* Provide a default if not specified [0 1 ...] per component */
938
107k
        int i;
939
107k
        float minval, maxval;
940
941
        /* TODO: Is there a less hacky way to identify Indexed case? */
942
107k
        if (pcs && (pcs->type == &gs_color_space_type_Indexed ||
943
84.9k
                    pcs->type == &gs_color_space_type_Indexed_Named)) {
944
            /* Default value is [0,N], where N=2^n-1, our hival (which depends on BPC)*/
945
9.96k
            minval = 0.0;
946
9.96k
            maxval = (float)((1 << info->BPC) - 1);
947
97.4k
        } else {
948
97.4k
            bool islab = false;
949
950
97.4k
            if (pcs && pcs->cmm_icc_profile_data != NULL)
951
84.7k
                islab = pcs->cmm_icc_profile_data->islab;
952
953
97.4k
            if(islab) {
954
0
                pim->Decode[0] = 0.0;
955
0
                pim->Decode[1] = 100.0;
956
0
                pim->Decode[2] = pcs->cmm_icc_profile_data->Range.ranges[1].rmin;
957
0
                pim->Decode[3] = pcs->cmm_icc_profile_data->Range.ranges[1].rmax;
958
0
                pim->Decode[4] = pcs->cmm_icc_profile_data->Range.ranges[2].rmin;
959
0
                pim->Decode[5] = pcs->cmm_icc_profile_data->Range.ranges[2].rmax;
960
0
                return 0;
961
97.4k
            } else {
962
97.4k
                minval = 0.0;
963
97.4k
                maxval = 1.0;
964
97.4k
            }
965
97.4k
        }
966
321k
        for (i=0; i<comps*2; i+=2) {
967
213k
            pim->Decode[i] = minval;
968
213k
            pim->Decode[i+1] = maxval;
969
213k
        }
970
107k
    }
971
395k
    code = 0;
972
973
395k
 cleanupExit:
974
395k
    return code;
975
395k
}
976
977
/* Returns number of components in Matte array or 0 if not found, <0 if error */
978
static int
979
pdfi_image_get_matte(pdf_context *ctx, pdf_obj *smask_obj, float *vals, int size, bool *has_Matte)
980
26.3k
{
981
26.3k
    int i;
982
26.3k
    pdf_array *Matte = NULL;
983
26.3k
    int code;
984
26.3k
    double f;
985
26.3k
    pdf_dict *smask_dict = NULL;
986
987
26.3k
    *has_Matte = false;
988
26.3k
    code = pdfi_dict_from_obj(ctx, smask_obj, &smask_dict);
989
26.3k
    if (code < 0)
990
0
        goto exit;
991
992
26.3k
    code = pdfi_dict_knownget_type(ctx, smask_dict, "Matte",
993
26.3k
                                   PDF_ARRAY, (pdf_obj **)&Matte);
994
26.3k
    if (code <= 0)
995
26.3k
        goto exit;
996
997
34
    *has_Matte = true;
998
34
    if (pdfi_array_size(Matte) > size) {
999
0
        code = gs_note_error(gs_error_rangecheck);
1000
0
        goto exit;
1001
0
    }
1002
1003
136
    for (i = 0; i < pdfi_array_size(Matte); i++) {
1004
102
        code = pdfi_array_get_number(ctx, Matte, (uint64_t)i, &f);
1005
102
        if (code < 0)
1006
0
            goto exit;
1007
102
        vals[i] = (float)f;
1008
102
    }
1009
34
    if (i == pdfi_array_size(Matte))
1010
34
        code = i;
1011
1012
26.3k
 exit:
1013
26.3k
    pdfi_countdown(Matte);
1014
26.3k
    return code;
1015
34
}
1016
1017
/* See ztrans.c/zbegintransparencymaskimage() and pdf_draw.ps/doimagesmask */
1018
static int
1019
pdfi_do_image_smask(pdf_context *ctx, pdf_c_stream *source, pdfi_image_info_t *image_info, bool *has_Matte)
1020
23.5k
{
1021
23.5k
    gs_rect bbox = { { 0, 0} , { 1, 1} };
1022
23.5k
    gs_transparency_mask_params_t params;
1023
23.5k
    gs_offset_t savedoffset = 0;
1024
23.5k
    int code, code1;
1025
23.5k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
1026
23.5k
    pdf_stream *stream_obj = NULL;
1027
23.5k
    gs_rect clip_box;
1028
23.5k
    int empty = 0;
1029
1030
#if DEBUG_IMAGES
1031
    dbgmprintf(ctx->memory, "pdfi_do_image_smask BEGIN\n");
1032
#endif
1033
1034
23.5k
    code = pdfi_loop_detector_mark(ctx);
1035
23.5k
    if (code < 0)
1036
0
        return code;
1037
1038
23.5k
    if (pdfi_type_of(image_info->SMask) != PDF_STREAM)
1039
0
        return_error(gs_error_typecheck);
1040
1041
23.5k
    if (image_info->SMask->object_num != 0) {
1042
23.5k
        if (pdfi_loop_detector_check_object(ctx, image_info->SMask->object_num))
1043
0
            return gs_note_error(gs_error_circular_reference);
1044
23.5k
        code = pdfi_loop_detector_add_object(ctx, image_info->SMask->object_num);
1045
23.5k
        if (code < 0)
1046
0
            goto exit;
1047
23.5k
    }
1048
1049
23.5k
    gs_trans_mask_params_init(&params, TRANSPARENCY_MASK_Luminosity);
1050
1051
    /* gs_begin_transparency_mask is going to crap all over the current
1052
     * graphics state. We need to be sure that everything goes back as
1053
     * it was. So, gsave here, and grestore on the 'end', right? Well
1054
     * that doesn't work, cos then we throw away the SMask we've just
1055
     * drawn! We'll do some magic to ensure that doesn't happen. */
1056
23.5k
    code = gs_gsave(ctx->pgs);
1057
23.5k
    if (code < 0)
1058
0
        goto exit;
1059
1060
23.5k
    if (gs_clip_bounds_in_user_space(ctx->pgs, &clip_box) >= 0)
1061
23.4k
    {
1062
23.4k
        rect_intersect(bbox, clip_box);
1063
23.4k
        if (bbox.p.x >= bbox.q.x || bbox.p.y >= bbox.q.y)
1064
854
        {
1065
            /* If the bbox is illegal, we still need to set up an empty mask.
1066
             * We can't just skip forwards as everything will now be unmasked!
1067
             * We can skip doing the actual work though. */
1068
854
            empty = 1;
1069
854
        }
1070
23.4k
    }
1071
1072
23.5k
    code = pdfi_image_get_matte(ctx, image_info->SMask, params.Matte, GS_CLIENT_COLOR_MAX_COMPONENTS, has_Matte);
1073
1074
23.5k
    if (code < 0) {
1075
0
        code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_ERROR_IN_MATTE, "", NULL);
1076
0
        if (code < 0)
1077
0
            goto exitSaved;
1078
0
    }
1079
23.5k
    if (code >= 0)
1080
23.5k
        params.Matte_components = code;
1081
1082
23.5k
    code = gs_begin_transparency_mask(ctx->pgs, &params, &bbox, true);
1083
23.5k
    if (code < 0)
1084
0
        goto exitSaved;
1085
23.5k
    if (empty)
1086
854
        goto exitMasked;
1087
22.6k
    savedoffset = pdfi_tell(ctx->main_stream);
1088
22.6k
    code = pdfi_gsave(ctx);
1089
22.6k
    if (code < 0)
1090
0
        goto exitMasked;
1091
1092
    /* Disable SMask for inner image */
1093
22.6k
    pdfi_gstate_smask_free(igs);
1094
1095
22.6k
    gs_setstrokeconstantalpha(ctx->pgs, 1.0);
1096
22.6k
    gs_setfillconstantalpha(ctx->pgs, 1.0);
1097
22.6k
    gs_setblendmode(ctx->pgs, BLEND_MODE_Compatible);
1098
1099
22.6k
    pdfi_seek(ctx, ctx->main_stream,
1100
22.6k
              pdfi_stream_offset(ctx, (pdf_stream *)image_info->SMask), SEEK_SET);
1101
1102
22.6k
    switch (pdfi_type_of(image_info->SMask)) {
1103
0
        case PDF_DICT:
1104
0
            code = pdfi_obj_dict_to_stream(ctx, (pdf_dict *)image_info->SMask, &stream_obj, false);
1105
0
            if (code == 0) {
1106
0
                code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
1107
0
                                             image_info->page_dict, (pdf_obj *)stream_obj);
1108
1109
0
                pdfi_countdown(stream_obj);
1110
0
            }
1111
0
            break;
1112
22.6k
        case PDF_STREAM:
1113
22.6k
            code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
1114
22.6k
                                         image_info->page_dict, image_info->SMask);
1115
22.6k
            break;
1116
0
        default:
1117
0
            code = gs_note_error(gs_error_typecheck);
1118
0
            goto exitSavedTwice;
1119
22.6k
    }
1120
1121
22.6k
exitSavedTwice:
1122
22.6k
    pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
1123
1124
22.6k
    code1 = pdfi_grestore(ctx);
1125
22.6k
    if (code < 0)
1126
0
        code = code1;
1127
23.5k
exitMasked:
1128
23.5k
    code1 = gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
1129
23.5k
    if (code < 0)
1130
0
        code = code1;
1131
23.5k
exitSaved:
1132
    /* This is where we have to do some magic. If we just grestore here, then
1133
     * any SMask we've rendered will be popped away. */
1134
23.5k
    {
1135
        /* Stash the flag that means 'Pop the SMask'. */
1136
23.5k
        int flag = ctx->pgs->trans_flags.xstate_change;
1137
        /* Clear the flag so the SMask will live. */
1138
23.5k
        ctx->pgs->trans_flags.xstate_change = 0;
1139
23.5k
        code1 = gs_grestore(ctx->pgs);
1140
23.5k
        if (code < 0)
1141
0
            code = code1;
1142
        /* Put the flag back 1 level higher. This relies on the fact that
1143
         * the graphics state we return to does not already have this set.
1144
         * We ensure that by ensuring that callers have gsaved/grestored
1145
         * around this. */
1146
23.5k
        ctx->pgs->trans_flags.xstate_change = flag;
1147
23.5k
    }
1148
1149
23.5k
 exit:
1150
#if DEBUG_IMAGES
1151
    dbgmprintf(ctx->memory, "pdfi_do_image_smask END\n");
1152
#endif
1153
23.5k
    pdfi_loop_detector_cleartomark(ctx);
1154
23.5k
    return code;
1155
23.5k
}
1156
1157
1158
/* Setup for transparency (see pdf_draw.ps/doimage) */
1159
static int
1160
pdfi_image_setup_trans(pdf_context *ctx, pdfi_trans_state_t *state)
1161
7.23k
{
1162
7.23k
    int code;
1163
7.23k
    gs_rect bbox;
1164
1165
    /* We need to create a bbox in order to pass it to the transparency setup,
1166
     * which (potentially, at least, uses it to set up a transparency group.
1167
     * Setting up a 1x1 path, and establishing it's BBox will work, because
1168
     * the image scaling is already in place. We don't want to disturb the
1169
     * graphics state, so do this inside a gsave/grestore pair.
1170
     */
1171
7.23k
    code = pdfi_gsave(ctx);
1172
7.23k
    if (code < 0)
1173
0
        return code;
1174
1175
7.23k
    code = gs_newpath(ctx->pgs);
1176
7.23k
    if (code < 0)
1177
0
        goto exit;
1178
7.23k
    code = gs_moveto(ctx->pgs, 1.0, 1.0);
1179
7.23k
    if (code < 0)
1180
0
        goto exit;
1181
7.23k
    code = gs_lineto(ctx->pgs, 0., 0.);
1182
7.23k
    if (code < 0)
1183
0
        goto exit;
1184
1185
7.23k
    code = pdfi_get_current_bbox(ctx, &bbox, false);
1186
7.23k
    if (code < 0)
1187
549
        goto exit;
1188
1189
6.69k
    pdfi_grestore(ctx);
1190
1191
6.69k
    code = pdfi_trans_setup(ctx, state, &bbox, TRANSPARENCY_Caller_Image);
1192
7.23k
 exit:
1193
7.23k
    return code;
1194
6.69k
}
1195
1196
1197
/* Setup a type 4 image, particularly the MaskColor array.
1198
 * Handles error situations like pdf_draw.ps/makemaskimage
1199
 */
1200
static int
1201
pdfi_image_setup_type4(pdf_context *ctx, pdfi_image_info_t *image_info,
1202
                       gs_image4_t *t4image,
1203
                       pdf_array *mask_array, gs_color_space *pcs)
1204
210
{
1205
210
    int i;
1206
210
    double num;
1207
210
    int code = 0;
1208
210
    int bpc = image_info->BPC;
1209
210
    uint mask = (1 << bpc) - 1;
1210
210
    uint maxval = mask;
1211
210
    int64_t intval;
1212
210
    bool had_range_error = false;
1213
210
    bool had_float_error = false;
1214
    /* Check for special case of Indexed and BPC=1 (to match AR)
1215
     * See bugs: 692852, 697919, 689717
1216
     */
1217
210
    bool indexed_case = (pcs && pcs->type == &gs_color_space_type_Indexed && bpc == 1);
1218
1219
210
    memset(t4image, 0, sizeof(gs_image4_t));
1220
210
    gs_image4_t_init(t4image, NULL);
1221
1222
210
    if (pdfi_array_size(mask_array) > GS_IMAGE_MAX_COMPONENTS * 2) {
1223
0
        code = gs_note_error(gs_error_rangecheck);
1224
0
        goto exit;
1225
0
    }
1226
1227
1.35k
    for (i=0; i<pdfi_array_size(mask_array); i++) {
1228
1.15k
        code = pdfi_array_get_int(ctx, mask_array, i, &intval);
1229
1.15k
        if (code == gs_error_typecheck) {
1230
11
            code = pdfi_array_get_number(ctx, mask_array, i, &num);
1231
11
            if (code == 0) {
1232
0
                intval = (int64_t)(num + 0.5);
1233
0
                had_float_error = true;
1234
0
            }
1235
11
        }
1236
1.15k
        if (code < 0)
1237
11
            goto exit;
1238
1.14k
        if (intval > maxval) {
1239
14
            had_range_error = true;
1240
14
            if (indexed_case) {
1241
0
                if (i == 0) {
1242
                    /* If first component is invalid, AR9 ignores the mask. */
1243
0
                    code = gs_note_error(gs_error_rangecheck);
1244
0
                    goto exit;
1245
0
                } else {
1246
                    /* If second component is invalid, AR9 replace it with 1. */
1247
0
                    intval = 1;
1248
0
                }
1249
14
            } else {
1250
14
                if (bpc != 1) {
1251
                    /* If not special handling, just mask it off to be in range */
1252
14
                    intval &= mask;
1253
14
                }
1254
14
            }
1255
14
        }
1256
1.14k
        t4image->MaskColor[i] = intval;
1257
1.14k
    }
1258
199
    t4image->MaskColor_is_range = true;
1259
1260
    /* Another special handling (see Bug701468)
1261
     * If 1 BPC and the two entries are not the same, ignore the mask
1262
     */
1263
199
    if (!indexed_case && bpc == 1 && had_range_error) {
1264
0
        if (t4image->MaskColor[0] != t4image->MaskColor[1]) {
1265
0
            code = gs_note_error(gs_error_rangecheck);
1266
0
            goto exit;
1267
0
        } else {
1268
0
            t4image->MaskColor[0] &= mask;
1269
0
            t4image->MaskColor[1] &= mask;
1270
0
        }
1271
0
    }
1272
1273
199
    code = 0;
1274
1275
210
 exit:
1276
210
    if (had_float_error) {
1277
0
        pdfi_set_warning(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_IMAGE_ERROR, "pdfi_image_setup_type4", (char *)"*** Error: Some elements of Mask array are not integers");
1278
0
    }
1279
210
    if (had_range_error) {
1280
14
        pdfi_set_warning(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_IMAGE_ERROR, "pdfi_image_setup_type4", (char *)"*** Error: Some elements of Mask array are out of range");
1281
14
    }
1282
210
    return code;
1283
199
}
1284
1285
/* Setup a type 3x image
1286
 */
1287
static int
1288
pdfi_image_setup_type3x(pdf_context *ctx, pdfi_image_info_t *image_info,
1289
                        gs_image3x_t *t3ximage, pdfi_image_info_t *smask_info, int comps)
1290
2.83k
{
1291
2.83k
    int code = 0;
1292
2.83k
    gs_image3x_mask_t *mask;
1293
1294
2.83k
    memset(t3ximage, 0, sizeof(*t3ximage));
1295
2.83k
    gs_image3x_t_init(t3ximage, NULL);
1296
2.83k
    if (gs_getalphaisshape(ctx->pgs))
1297
8
        mask = &t3ximage->Shape;
1298
2.82k
    else
1299
2.82k
        mask = &t3ximage->Opacity;
1300
2.83k
    mask->InterleaveType = 3;
1301
1302
2.83k
    code = pdfi_image_get_matte(ctx, image_info->SMask, mask->Matte, GS_CLIENT_COLOR_MAX_COMPONENTS, &mask->has_Matte);
1303
2.83k
    if (code < 0)
1304
0
        return code;
1305
1306
2.83k
    code = pdfi_data_image_params(ctx, smask_info, &mask->MaskDict, comps, NULL);
1307
2.83k
    return code;
1308
2.83k
}
1309
1310
static int pdfi_create_JPX_Lab(pdf_context *ctx, pdf_obj **ColorSpace)
1311
0
{
1312
0
    int code, i;
1313
0
    pdf_name *SpaceName = NULL, *WhitePointName = NULL;
1314
0
    pdf_dict *Params = NULL;
1315
0
    pdf_array *WhitePoint = NULL;
1316
0
    double WP[3] = {0.9505, 1.0, 1.0890};
1317
0
    pdf_num *num = NULL;
1318
1319
0
    *ColorSpace = NULL;
1320
0
    code = pdfi_name_alloc(ctx, (byte *)"Lab", 3, (pdf_obj **)&SpaceName);
1321
0
    if (code < 0)
1322
0
        goto cleanupExit;
1323
0
    pdfi_countup(SpaceName);
1324
1325
0
    code = pdfi_dict_alloc(ctx, 1, &Params);
1326
0
    if (code < 0)
1327
0
        goto cleanupExit;
1328
0
    pdfi_countup(Params);
1329
1330
0
    code = pdfi_name_alloc(ctx, (byte *)"WhitePoint", 3, (pdf_obj **)&WhitePointName);
1331
0
    if (code < 0)
1332
0
        goto cleanupExit;
1333
0
    pdfi_countup(WhitePointName);
1334
1335
0
    code = pdfi_array_alloc(ctx, 3, &WhitePoint);
1336
0
    if (code < 0)
1337
0
        goto cleanupExit;
1338
1339
0
    for (i = 0; i < 3; i++) {
1340
0
        code = pdfi_object_alloc(ctx, PDF_REAL, 0, (pdf_obj **)&num);
1341
0
        if (code < 0)
1342
0
            goto cleanupExit;
1343
0
        num->value.d = WP[i];
1344
0
        pdfi_countup(num);
1345
0
        code = pdfi_array_put(ctx, WhitePoint, i, (pdf_obj *)num);
1346
0
        if (code < 0)
1347
0
            goto cleanupExit;
1348
0
        pdfi_countdown(num);
1349
0
    }
1350
0
    num = NULL;
1351
1352
0
    code = pdfi_dict_put_obj(ctx, Params, (pdf_obj *)WhitePointName, (pdf_obj *)WhitePoint, true);
1353
0
    if (code < 0)
1354
0
        goto cleanupExit;
1355
1356
0
    pdfi_countdown(WhitePointName);
1357
0
    WhitePointName = NULL;
1358
0
    pdfi_countdown(WhitePoint);
1359
0
    WhitePoint = NULL;
1360
1361
0
    code = pdfi_array_alloc(ctx, 2, (pdf_array **)ColorSpace);
1362
0
    if (code < 0)
1363
0
        goto cleanupExit;
1364
1365
0
    code = pdfi_array_put(ctx, (pdf_array *)*ColorSpace, 0, (pdf_obj *)SpaceName);
1366
0
    if (code < 0)
1367
0
        goto cleanupExit;
1368
0
    pdfi_countdown(SpaceName);
1369
0
    SpaceName = NULL;
1370
1371
0
    code = pdfi_array_put(ctx, (pdf_array *)*ColorSpace, 1, (pdf_obj *)Params);
1372
0
    if (code < 0)
1373
0
        goto cleanupExit;
1374
0
    pdfi_countdown(Params);
1375
1376
0
    return 0;
1377
1378
0
cleanupExit:
1379
0
    pdfi_countdown(*ColorSpace);
1380
0
    pdfi_countdown(SpaceName);
1381
0
    pdfi_countdown(Params);
1382
0
    pdfi_countdown(WhitePointName);
1383
0
    pdfi_countdown(WhitePoint);
1384
0
    pdfi_countdown(num);
1385
0
    return code;
1386
0
}
1387
1388
static int
1389
pdfi_image_get_color(pdf_context *ctx, pdf_c_stream *source, pdfi_image_info_t *image_info,
1390
                     int *comps, ulong dictkey, gs_color_space **pcs)
1391
397k
{
1392
397k
    int code = 0;
1393
397k
    pdfi_jpx_info_t *jpx_info = &image_info->jpx_info;
1394
397k
    pdf_obj *ColorSpace = NULL;
1395
397k
    char *backup_color_name = NULL;
1396
397k
    bool using_enum_cs = false;
1397
1398
    /* NOTE: Spec says ImageMask and ColorSpace mutually exclusive
1399
     * We need to make sure we do not have both set or we could end up treating
1400
     * an image as a mask or vice versa and trying to use a non-existent colour space.
1401
     */
1402
397k
    if (image_info->ImageMask) {
1403
295k
        if (image_info->ColorSpace == NULL) {
1404
294k
                *comps = 1;
1405
294k
                *pcs = NULL;
1406
294k
                if (image_info->Mask) {
1407
0
                    pdfi_countdown(image_info->Mask);
1408
0
                    image_info->Mask = NULL;
1409
0
                }
1410
294k
                return 0;
1411
294k
        } else {
1412
1.45k
            if (image_info->BPC != 1 || image_info->Mask != NULL) {
1413
32
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_IMAGE_MASKWITHCOLOR, "pdfi_image_get_color", "BitsPerComonent is not 1, so treating as an image")) < 0) {
1414
0
                    return code;
1415
0
                }
1416
32
                image_info->ImageMask = 0;
1417
32
            }
1418
1.42k
            else {
1419
1.42k
                if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, E_IMAGE_MASKWITHCOLOR, "pdfi_image_get_color", "BitsPerComonent is 1, so treating as a mask")) < 0) {
1420
0
                    return code;
1421
0
                }
1422
1.42k
                pdfi_countdown(image_info->ColorSpace);
1423
1.42k
                image_info->ColorSpace = NULL;
1424
1.42k
                *comps = 1;
1425
1.42k
                *pcs = NULL;
1426
1.42k
                return 0;
1427
1.42k
            }
1428
1.45k
        }
1429
295k
    }
1430
1431
102k
    ColorSpace = image_info->ColorSpace;
1432
102k
    if (ColorSpace)
1433
94.2k
        pdfi_countup(ColorSpace);
1434
102k
    if (ColorSpace == NULL) {
1435
7.86k
        if (image_info->is_JPXDecode) {
1436
            /* The graphics library doesn't support 12-bit images, so the openjpeg layer
1437
             * (see sjpx_openjpeg.c/decode_image()) is going to translate the 12-bits up to 16-bits.
1438
             * That means we just treat it as 16-bit when rendering, so force the value
1439
             * to 16 here.
1440
             */
1441
7.80k
            if (jpx_info->bpc == 12) {
1442
0
                jpx_info->bpc = 16;
1443
0
            }
1444
7.80k
            image_info->BPC = jpx_info->bpc;
1445
1446
7.80k
            if (jpx_info->iccbased) {
1447
0
                int dummy; /* Holds number of components read from the ICC profile, we ignore this here */
1448
1449
0
                code = pdfi_create_icc_colorspace_from_stream(ctx, source, jpx_info->icc_offset,
1450
0
                                                              jpx_info->icc_length, jpx_info->comps, &dummy,
1451
0
                                                              dictkey, pcs);
1452
0
                if (code < 0) {
1453
0
                    code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_JPX_CS_ERROR, "pdfi_image_get_color", NULL);
1454
0
                    dbgprintf2("WARNING JPXDecode: Error setting icc colorspace (offset=%d,len=%d)\n",
1455
0
                              jpx_info->icc_offset, jpx_info->icc_length);
1456
0
                    goto cleanupExit;
1457
0
                }
1458
0
                *comps = gs_color_space_num_components(*pcs);
1459
0
                goto cleanupExit;
1460
7.80k
            } else {
1461
7.80k
                char *color_str = NULL;
1462
1463
                /* TODO: These colorspace names are pulled from the gs code (jp2_csp_dict), but need
1464
                 * to be implemented to actually work.
1465
                 */
1466
7.80k
                backup_color_name = (char *)"DeviceRGB";
1467
7.80k
                switch(jpx_info->cs_enum) {
1468
0
                case 12:
1469
0
                    color_str = (char *)"DeviceCMYK";
1470
0
                    break;
1471
0
                case 14:
1472
                    /* All the other colour spaces are set by name, either a device name or a
1473
                     * 'special' internal name (same as Ghostscript) which is picked up in
1474
                     * pdfi_create_colorspace_by_name() in pdf_colour.c. These names must
1475
                     * match!
1476
                     * However for Lab we need to set a White Point and its simplest just
1477
                     * to create an appropriate color space array here.
1478
                     */
1479
0
                    code = pdfi_create_JPX_Lab(ctx, &ColorSpace);
1480
0
                    if (code < 0)
1481
0
                        goto cleanupExit;
1482
0
                    break;
1483
568
                case 16:
1484
568
                    color_str = (char *)"sRGBICC";
1485
568
                    break;
1486
4.70k
                case 17:
1487
4.70k
                    color_str = (char *)"sGrayICC";
1488
4.70k
                    backup_color_name = (char *)"DeviceGray";
1489
4.70k
                    break;
1490
0
                case 18:
1491
0
                    color_str = (char *)"DeviceRGB";
1492
0
                    break;
1493
0
                case 20:
1494
0
                case 24:
1495
0
                    color_str = (char *)"esRGBICC";
1496
0
                    break;
1497
0
                case 21:
1498
0
                    color_str = (char *)"rommRGBICC";
1499
0
                    break;
1500
2.53k
                default:
1501
2.53k
                    {
1502
2.53k
                        char extra_info[gp_file_name_sizeof];
1503
                        /* TODO: Could try DeviceRGB instead of erroring out? */
1504
2.53k
                        gs_snprintf(extra_info, sizeof(extra_info), "**** Error: JPXDecode: Unsupported EnumCS %d\n", jpx_info->cs_enum);
1505
2.53k
                        pdfi_set_error(ctx, 0, NULL, E_PDF_IMAGECOLOR_ERROR, "pdfi_image_get_color", extra_info);
1506
2.53k
                        code = gs_note_error(gs_error_rangecheck);
1507
2.53k
                        goto cleanupExit;
1508
0
                    }
1509
7.80k
                }
1510
1511
                /* Make a ColorSpace for the name */
1512
5.26k
                if (color_str != NULL) {
1513
5.26k
                    code = pdfi_name_alloc(ctx, (byte *)color_str, strlen(color_str), &ColorSpace);
1514
5.26k
                    if (code < 0)
1515
0
                        goto cleanupExit;
1516
5.26k
                    pdfi_countup(ColorSpace);
1517
5.26k
                    using_enum_cs = true;
1518
5.26k
                }
1519
5.26k
            }
1520
7.80k
        } else {
1521
            /* Assume DeviceRGB colorspace */
1522
60
            if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_undefined), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_image_get_color", (char *)"**** Error: image has no /ColorSpace key; assuming /DeviceRGB")) < 0)
1523
0
                goto cleanupExit;
1524
60
            code = pdfi_name_alloc(ctx, (byte *)"DeviceRGB", strlen("DeviceRGB"), &ColorSpace);
1525
60
            if (code < 0)
1526
0
                goto cleanupExit;
1527
60
            pdfi_countup(ColorSpace);
1528
60
        }
1529
94.2k
    } else {
1530
        /* Override BPC from JPXDecode if applicable
1531
         * Sample: tests_private/comparefiles/Bug695387.pdf
1532
         */
1533
94.2k
        if (image_info->is_JPXDecode && jpx_info->is_valid)
1534
5.13k
            image_info->BPC = jpx_info->bpc;
1535
94.2k
    }
1536
1537
    /* At this point ColorSpace is either a string we just made, or the one from the Image */
1538
99.5k
    code = pdfi_create_colorspace(ctx, ColorSpace,
1539
99.5k
                                  image_info->stream_dict, image_info->page_dict,
1540
99.5k
                                  pcs, image_info->inline_image);
1541
99.5k
    if (code < 0) {
1542
3.03k
        dbgprintf("WARNING: Image has unsupported ColorSpace ");
1543
3.03k
        if (pdfi_type_of(ColorSpace) == PDF_NAME) {
1544
731
            pdf_name *name = (pdf_name *)ColorSpace;
1545
731
            char str[100];
1546
731
            int length = name->length;
1547
1548
731
            if (length > 0) {
1549
719
                if (length > 99)
1550
11
                    length = 99;
1551
1552
719
                memcpy(str, (const char *)name->data, length);
1553
719
                str[length] = '\0';
1554
719
                dbgprintf1("NAME:%s\n", str);
1555
719
            }
1556
2.29k
        } else {
1557
2.29k
            dbgmprintf(ctx->memory, "(not a name)\n");
1558
2.29k
        }
1559
1560
        /* If we were trying an enum_cs, attempt to use backup_color_name instead */
1561
3.03k
        if (using_enum_cs) {
1562
0
            pdfi_countdown(ColorSpace);
1563
0
            code = pdfi_name_alloc(ctx, (byte *)backup_color_name, strlen(backup_color_name), &ColorSpace);
1564
0
            if (code < 0)
1565
0
                goto cleanupExit;
1566
0
            pdfi_countup(ColorSpace);
1567
            /* Try to set the backup name */
1568
0
            code = pdfi_create_colorspace(ctx, ColorSpace,
1569
0
                                          image_info->stream_dict, image_info->page_dict,
1570
0
                                          pcs, image_info->inline_image);
1571
1572
0
            if (code < 0) {
1573
0
                pdfi_set_error(ctx, 0, NULL, E_PDF_IMAGECOLOR_ERROR, "pdfi_image_get_color", NULL);
1574
0
                goto cleanupExit;
1575
0
            }
1576
3.03k
        } else {
1577
3.03k
            pdfi_set_error(ctx, 0, NULL, E_PDF_IMAGECOLOR_ERROR, "pdfi_image_get_color", NULL);
1578
3.03k
            goto cleanupExit;
1579
3.03k
        }
1580
3.03k
    }
1581
96.5k
    *comps = gs_color_space_num_components(*pcs);
1582
1583
102k
 cleanupExit:
1584
102k
    pdfi_countdown(ColorSpace);
1585
102k
    return code;
1586
96.5k
}
1587
1588
/* Make a fake SMask dict from a JPX SMaskInData */
1589
static int
1590
pdfi_make_smask_dict(pdf_context *ctx, pdf_stream *image_stream, pdfi_image_info_t *image_info,
1591
                     int comps)
1592
0
{
1593
0
    int code = 0;
1594
0
    pdf_dict *smask_dict = NULL;
1595
0
    pdf_stream *fake_smask = NULL;
1596
0
    pdf_array *array = NULL;
1597
0
    pdf_array *matte = NULL;
1598
0
    pdf_dict *image_dict = NULL, *dict = NULL; /* alias */
1599
1600
0
    if (image_info->SMask != NULL) {
1601
0
        code = pdfi_set_error_stop(ctx, code, NULL, E_PDF_SMASK_IN_SMASK, "pdfi_make_smask_dict", NULL);
1602
0
        goto exit;
1603
0
    }
1604
1605
0
    if (pdfi_type_of(image_stream) != PDF_STREAM) {
1606
0
        code = gs_note_error(gs_error_typecheck);
1607
0
        goto exit;
1608
0
    }
1609
0
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)image_stream, &image_dict);
1610
0
    if (code < 0) goto exit;
1611
1612
    /* Make a new stream object and a dict for it */
1613
0
    code = pdfi_object_alloc(ctx, PDF_STREAM, 0, (pdf_obj **)&fake_smask);
1614
0
    if (code < 0) goto exit;
1615
0
    pdfi_countup(fake_smask);
1616
1617
0
    code = pdfi_dict_alloc(ctx, 32, &smask_dict);
1618
0
    if (code < 0) goto exit;
1619
1620
0
    fake_smask->stream_dict = smask_dict;
1621
0
    pdfi_countup(smask_dict);
1622
0
    smask_dict = NULL;
1623
0
    dict = fake_smask->stream_dict; /* alias */
1624
1625
    /* Copy everything from the image_dict */
1626
0
    code = pdfi_dict_copy(ctx, dict, image_dict);
1627
0
    fake_smask->stream_offset = image_stream->stream_offset;
1628
1629
0
    code = pdfi_dict_put_int(ctx, dict, "SMaskInData", 0);
1630
0
    if (code < 0) goto exit;
1631
1632
0
    code = pdfi_dict_put_name(ctx, dict, "ColorSpace", "DeviceGray");
1633
0
    if (code < 0) goto exit;
1634
1635
    /* BPC needs to come from the jpxinfo */
1636
0
    code = pdfi_dict_put_int(ctx, dict, "BitsPerComponent", image_info->jpx_info.bpc);
1637
0
    if (code < 0) goto exit;
1638
1639
    /* "Alpha" is a non-standard thing that gs code uses to tell
1640
     * the jpxfilter that it is doing an SMask.  I guess we can do
1641
     * the same, since we're making this dictionary anyway.
1642
     */
1643
0
    code = pdfi_dict_put_bool(ctx, dict, "Alpha", true);
1644
0
    if (code < 0) goto exit;
1645
1646
    /* Make an array [0,1] */
1647
0
    code = pdfi_array_alloc(ctx, 2, &array);
1648
0
    if (code < 0) goto exit;
1649
0
    pdfi_countup(array);
1650
0
    code = pdfi_array_put_int(ctx, array, 0, 0);
1651
0
    if (code < 0) goto exit;
1652
0
    code = pdfi_array_put_int(ctx, array, 1, 1);
1653
0
    if (code < 0) goto exit;
1654
0
    code = pdfi_dict_put(ctx, dict, "Decode", (pdf_obj *)array);
1655
0
    if (code < 0) goto exit;
1656
1657
    /* Make Matte array if needed */
1658
    /* This just makes an array [0,0,0...] of size 'comps'
1659
     * See pdf_draw.ps/makeimagekeys
1660
     * TODO: The only sample in our test suite that triggers this path is fts_17_1718.pdf
1661
     * and this code being there or not makes no difference on that sample, so.. ???
1662
     */
1663
0
    if (image_info->SMaskInData == 2) {
1664
0
        int i;
1665
0
        code = pdfi_array_alloc(ctx, comps, &matte);
1666
0
        if (code < 0) goto exit;
1667
0
        pdfi_countup(matte);
1668
0
        for (i=0; i<comps; i++) {
1669
0
            code = pdfi_array_put_int(ctx, matte, i, 0);
1670
0
            if (code < 0) goto exit;
1671
0
        }
1672
0
        code = pdfi_dict_put(ctx, dict, "Matte", (pdf_obj *)matte);
1673
0
        if (code < 0) goto exit;
1674
0
    }
1675
1676
0
    image_info->SMask = (pdf_obj *)fake_smask;
1677
1678
0
 exit:
1679
0
    if (code < 0) {
1680
0
        pdfi_countdown(fake_smask);
1681
0
        pdfi_countdown(smask_dict);
1682
0
    }
1683
0
    pdfi_countdown(array);
1684
0
    pdfi_countdown(matte);
1685
0
    return code;
1686
0
}
1687
1688
/* NOTE: "source" is the current input stream.
1689
 * on exit:
1690
 *  inline_image = TRUE, stream it will point to after the image data.
1691
 *  inline_image = FALSE, stream position undefined.
1692
 */
1693
static int
1694
pdfi_do_image(pdf_context *ctx, pdf_dict *page_dict, pdf_dict *stream_dict, pdf_stream *image_stream,
1695
              pdf_c_stream *source, bool inline_image)
1696
409k
{
1697
409k
    pdf_c_stream *new_stream = NULL, *SFD_stream = NULL;
1698
409k
    int code = 0, code1 = 0;
1699
409k
    int comps = 0;
1700
409k
    gs_color_space  *pcs = NULL;
1701
409k
    gs_image1_t t1image;
1702
409k
    gs_image4_t t4image;
1703
409k
    gs_image3_t t3image;
1704
409k
    gs_image3x_t t3ximage;
1705
409k
    gs_pixel_image_t *pim = NULL;
1706
409k
    pdf_stream *alt_stream = NULL;
1707
409k
    pdfi_image_info_t image_info, mask_info, smask_info;
1708
409k
    pdf_stream *mask_stream = NULL;
1709
409k
    pdf_stream *smask_stream = NULL; /* only non-null for imagetype 3x (PreserveSMask) */
1710
409k
    pdf_array *mask_array = NULL;
1711
409k
    unsigned char *mask_buffer = NULL;
1712
409k
    uint64_t mask_size = 0;
1713
409k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
1714
409k
    bool transparency_group = false;
1715
409k
    bool need_smask_cleanup = false;
1716
409k
    bool maybe_jpxdecode = false;
1717
409k
    pdfi_trans_state_t trans_state;
1718
409k
    gs_offset_t stream_offset;
1719
409k
    int trans_required;
1720
1721
#if DEBUG_IMAGES
1722
    dbgmprintf(ctx->memory, "pdfi_do_image BEGIN\n");
1723
#endif
1724
409k
    memset(&mask_info, 0, sizeof(mask_info));
1725
409k
    memset(&smask_info, 0, sizeof(mask_info));
1726
1727
    /* Make sure the image is a stream (which we will assume in later code) */
1728
409k
    if (pdfi_type_of(image_stream) != PDF_STREAM)
1729
0
        return_error(gs_error_typecheck);
1730
1731
409k
    if (!inline_image) {
1732
110k
        pdf_dict *image_dict = NULL;
1733
1734
        /* If we are not processing an inline image, check to see if any of the abbreviated
1735
         * keys are present in the image dictionary. If they are, and we need to abort, we'll
1736
         * get an error return, otherwise we can continue.
1737
         */
1738
110k
        code = pdfi_dict_from_obj(ctx, (pdf_obj *)image_stream, &image_dict);
1739
110k
        if (code < 0)
1740
0
            return code;
1741
1742
110k
        code = pdfi_check_inline_image_keys(ctx, image_dict);
1743
110k
        if (code < 0)
1744
0
            return code;
1745
110k
    }
1746
1747
    /* We want to gsave in here so that any changes made by the rendering
1748
     * don't affect the wider world. This is particularly important if we
1749
     * have an SMask here, because that RELIES on this gsave/grestore
1750
     * level being here. Because we want to handle SMask changes we need
1751
     * to push/pop the transparency state changes too. The easiest way to
1752
     * do this is to call 'q' and 'Q'. */
1753
409k
    code = pdfi_op_q(ctx);
1754
409k
    if (code < 0)
1755
0
        return code;
1756
1757
409k
    code = pdfi_get_image_info(ctx, image_stream, page_dict, stream_dict, inline_image, &image_info);
1758
409k
    if (code < 0)
1759
2.46k
        goto cleanupExit;
1760
1761
    /* Don't render this if turned off */
1762
406k
    if (pdfi_oc_is_off(ctx))
1763
8.99k
        goto cleanupExit;
1764
    /* If there is an OC dictionary, see if we even need to render this */
1765
397k
    if (image_info.OC) {
1766
52
        if (!(ctx->device_state.writepdfmarks && ctx->device_state.WantsOptionalContent)) {
1767
50
            if (!pdfi_oc_is_ocg_visible(ctx, image_info.OC))
1768
0
                goto cleanupExit;
1769
50
        }
1770
52
    }
1771
1772
    /* If there is an alternate, swap it in */
1773
    /* If image_info.Alternates, look in the array, see if any of them are flagged as "DefaultForPrinting"
1774
     * and if so, substitute that one for the image we are processing.
1775
     * (it can probably be either an array, or a reference to an array, need an example to test/implement)
1776
     * see p.274 of PDFReference.pdf
1777
     */
1778
1779
397k
    if (image_info.Alternates != NULL) {
1780
0
        alt_stream = pdfi_find_alternate(ctx, image_info.Alternates);
1781
0
        if (alt_stream != NULL) {
1782
0
            image_stream = alt_stream;
1783
0
            pdfi_free_image_info_components(&image_info);
1784
0
            code = pdfi_get_image_info(ctx, image_stream, page_dict, stream_dict, inline_image, &image_info);
1785
0
            if (code < 0)
1786
0
                goto cleanupExit;
1787
0
        }
1788
0
    }
1789
1790
    /* Grab stream_offset after alternate has (possibly) set */
1791
397k
    stream_offset = pdfi_stream_offset(ctx, image_stream);
1792
1793
    /* See if it might be a JPXDecode image even though not in the header */
1794
397k
    if (image_info.ColorSpace == NULL && !image_info.ImageMask)
1795
7.86k
        maybe_jpxdecode = true;
1796
1797
    /* Handle JPXDecode filter pre-scan of header */
1798
397k
    if ((maybe_jpxdecode || image_info.is_JPXDecode) && !inline_image) {
1799
13.0k
        pdfi_seek(ctx, source, stream_offset, SEEK_SET);
1800
13.0k
        code = pdfi_scan_jpxfilter(ctx, source, image_info.Length, &image_info.jpx_info);
1801
13.0k
        if (code < 0 && image_info.is_JPXDecode)
1802
0
            goto cleanupExit;
1803
1804
        /* I saw this JPXDecode images that have SMaskInData */
1805
13.0k
        if (image_info.jpx_info.no_data)
1806
543
            image_info.is_JPXDecode = false;
1807
1808
13.0k
        if (code == 0 && maybe_jpxdecode)
1809
7.80k
            image_info.is_JPXDecode = true;
1810
13.0k
    }
1811
1812
    /* Set the rendering intent if applicable */
1813
397k
    if (image_info.Intent) {
1814
8.73k
        code = pdfi_setrenderingintent(ctx, image_info.Intent);
1815
8.73k
        if (code < 0) {
1816
            /* TODO: Flag a warning on this?  Sample fts_17_1706.pdf has misspelled Intent
1817
               which gs renders without flagging an error */
1818
#if DEBUG_IMAGES
1819
            dbgmprintf(ctx->memory, "WARNING: Image with unexpected Intent\n");
1820
#endif
1821
0
        }
1822
8.73k
    }
1823
1824
    /* Get the color for this image */
1825
397k
    code = pdfi_image_get_color(ctx, source, &image_info, &comps, image_stream->object_num, &pcs);
1826
397k
    if (code < 0)
1827
5.56k
        goto cleanupExit;
1828
1829
392k
    if (image_info.BPC != 1 && image_info.BPC != 2 && image_info.BPC != 4 && image_info.BPC != 8 && image_info.BPC != 16) {
1830
4
        code = gs_note_error(gs_error_rangecheck);
1831
4
        goto cleanupExit;
1832
4
    }
1833
1834
    /* Set the colorspace */
1835
392k
    if (pcs) {
1836
96.5k
        gs_color_space  *pcs1 = pcs;
1837
1838
96.5k
        code = pdfi_gs_setcolorspace(ctx, pcs);
1839
96.5k
        if (code < 0)
1840
0
            goto cleanupExit;
1841
1842
96.5k
        if (pcs->type->index == gs_color_space_index_Indexed)
1843
10.6k
            pcs1 = pcs->base_space;
1844
1845
        /* It is possible that we get no error returned from setting an
1846
         * ICC space, but that we are not able when rendering to create a link
1847
         * between the ICC space and the output device profile.
1848
         * The PostScript PDF interpreter sets the colour after setting the space, which
1849
         * (eventually) causes us to set the device colour, and that actually creates the
1850
         * link. This is apparntly the only way we can detect this error. Otherwise we
1851
         * would carry on until we tried to render the image, and that would fail with
1852
         * a not terribly useful error of -1. So here we try to set the device colour,
1853
         * for images in an ICC profile space. If that fails then we try to manufacture
1854
         * a Device space from the number of components in the profile.
1855
         * I do feel this is something we should be able to handle better!
1856
         */
1857
96.5k
        if (pcs1->type->index == gs_color_space_index_ICC)
1858
96.2k
        {
1859
96.2k
            gs_client_color         cc;
1860
96.2k
            int comp = 0;
1861
96.2k
            pdf_obj *ColorSpace = NULL;
1862
1863
96.2k
            cc.pattern = 0;
1864
316k
            for (comp = 0; comp < pcs1->cmm_icc_profile_data->num_comps;comp++)
1865
220k
                cc.paint.values[comp] = 0;
1866
1867
96.2k
            code = gs_setcolor(ctx->pgs, &cc);
1868
96.2k
            if (code < 0)
1869
5
                goto cleanupExit;
1870
1871
96.2k
            code = gx_set_dev_color(ctx->pgs);
1872
96.2k
            if (code < 0) {
1873
2.27k
                if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_ICC_PROFILE_LINK, "pdfi_do_image", "Attempting to use profile /N to create a device colour space")) < 0)
1874
0
                    goto cleanupExit;
1875
1876
                /* Possibly we couldn't create a link profile, soemthing wrong with the ICC profile, try to use a device space */
1877
2.27k
                switch(pcs1->cmm_icc_profile_data->num_comps) {
1878
420
                    case 1:
1879
420
                        code = pdfi_name_alloc(ctx, (byte *)"DeviceGray", 10, &ColorSpace);
1880
420
                        if (code < 0)
1881
0
                            goto cleanupExit;
1882
420
                        pdfi_countup(ColorSpace);
1883
420
                        break;
1884
1.85k
                    case 3:
1885
1.85k
                        code = pdfi_name_alloc(ctx, (byte *)"DeviceRGB", 9, &ColorSpace);
1886
1.85k
                        if (code < 0)
1887
0
                            goto cleanupExit;
1888
1.85k
                        pdfi_countup(ColorSpace);
1889
1.85k
                        break;
1890
0
                    case 4:
1891
0
                        code = pdfi_name_alloc(ctx, (byte *)"DeviceCMYK", 10, &ColorSpace);
1892
0
                        if (code < 0)
1893
0
                            goto cleanupExit;
1894
0
                        pdfi_countup(ColorSpace);
1895
0
                        break;
1896
0
                    default:
1897
0
                        code = gs_error_unknownerror;
1898
0
                        goto cleanupExit;
1899
0
                        break;
1900
2.27k
                }
1901
2.27k
                if (pcs != NULL)
1902
2.27k
                    rc_decrement_only_cs(pcs, "pdfi_do_image");
1903
                /* At this point ColorSpace is either a string we just made, or the one from the Image */
1904
2.27k
                code = pdfi_create_colorspace(ctx, ColorSpace,
1905
2.27k
                                  image_info.stream_dict, image_info.page_dict,
1906
2.27k
                                  &pcs, image_info.inline_image);
1907
2.27k
                pdfi_countdown(ColorSpace);
1908
2.27k
                if (code < 0)
1909
0
                    goto cleanupExit;
1910
1911
2.27k
                code = pdfi_gs_setcolorspace(ctx, pcs);
1912
2.27k
                if (code < 0)
1913
0
                    goto cleanupExit;
1914
1915
                /* Try to set the device color again as that failure
1916
                   is why we are here. If it fails again, something
1917
                   is very wrong */
1918
2.27k
                code = gx_set_dev_color(ctx->pgs);
1919
2.27k
                if (code < 0)
1920
79
                    goto cleanupExit;
1921
2.27k
            }
1922
96.2k
        }
1923
96.5k
    }
1924
295k
    else {
1925
295k
        if (image_info.ImageMask == 0) {
1926
0
            code = gs_note_error(gs_error_undefined);
1927
0
            goto cleanupExit;
1928
0
        }
1929
295k
    }
1930
1931
    /* Make a fake SMask dict if needed for JPXDecode */
1932
392k
    if (ctx->page.has_transparency && image_info.is_JPXDecode && image_info.SMaskInData != 0) {
1933
0
        code = pdfi_make_smask_dict(ctx, image_stream, &image_info, comps);
1934
0
        if (code < 0)
1935
0
            goto cleanupExit;
1936
0
    }
1937
1938
392k
    if (ctx->page.has_transparency == true && image_info.SMask != NULL) {
1939
26.3k
        bool has_Matte = false;
1940
1941
        /* If this flag is set, then device will process the SMask and we need do nothing
1942
         * here (e.g. pdfwrite).
1943
         */
1944
26.3k
        if (!ctx->device_state.preserve_smask) {
1945
23.5k
            code = pdfi_do_image_smask(ctx, source, &image_info, &has_Matte);
1946
23.5k
            if (code < 0)
1947
0
                goto cleanupExit;
1948
23.5k
            need_smask_cleanup = true;
1949
23.5k
        }
1950
1951
        /* If we are in an overprint situation this group will need
1952
           to have its blend mode set to compatible overprint. */
1953
26.3k
        if (ctx->page.needs_OP) {
1954
3.06k
            if (pdfi_trans_okOPcs(ctx)) {
1955
21
                if (gs_currentfilloverprint(ctx->pgs)) {
1956
0
                    code = gs_setblendmode(ctx->pgs, BLEND_MODE_CompatibleOverprint);
1957
0
                    if (code < 0)
1958
0
                        goto cleanupExit;
1959
0
                }
1960
21
            }
1961
3.06k
        }
1962
1963
26.3k
        if (has_Matte)
1964
32
            code = pdfi_trans_begin_isolated_group(ctx, true, pcs);
1965
26.3k
        else
1966
26.3k
            code = pdfi_trans_begin_isolated_group(ctx, true, NULL);
1967
26.3k
        if (code < 0)
1968
0
            goto cleanupExit;
1969
26.3k
        transparency_group = true;
1970
365k
    } else if (igs->SMask) {
1971
88
        code = pdfi_trans_begin_isolated_group(ctx, false, NULL);
1972
88
        if (code < 0)
1973
0
            goto cleanupExit;
1974
88
        transparency_group = true;
1975
88
    }
1976
1977
392k
    if (transparency_group && !ctx->device_state.preserve_smask) {
1978
23.6k
        gs_setstrokeconstantalpha(ctx->pgs, 1.0);
1979
23.6k
        gs_setfillconstantalpha(ctx->pgs, 1.0);
1980
23.6k
    }
1981
1982
    /* Get the Mask data either as an array or a dict, if present */
1983
392k
    if (image_info.Mask != NULL) {
1984
905
        switch (pdfi_type_of(image_info.Mask)) {
1985
210
            case PDF_ARRAY:
1986
210
                mask_array = (pdf_array *)image_info.Mask;
1987
210
                break;
1988
695
            case PDF_STREAM:
1989
695
                mask_stream = (pdf_stream *)image_info.Mask;
1990
695
                code = pdfi_get_image_info(ctx, mask_stream, page_dict,
1991
695
                                           stream_dict, inline_image, &mask_info);
1992
695
                if (code < 0)
1993
114
                    goto cleanupExit;
1994
581
                break;
1995
581
            default:
1996
0
                pdfi_countdown(image_info.Mask);
1997
0
                image_info.Mask = NULL;
1998
0
                if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_MASK_ERROR, "pdfi_do_image", NULL)) < 0)
1999
0
                    goto cleanupExit;
2000
905
        }
2001
905
    }
2002
2003
    /* Get the SMask info if we will need it (Type 3x images) */
2004
392k
    if (image_info.SMask && pdfi_type_of(image_info.SMask) == PDF_STREAM && ctx->device_state.preserve_smask) {
2005
        /* smask_dict non-NULL is used to flag a Type 3x image below */
2006
2.85k
        smask_stream = (pdf_stream *)image_info.SMask;
2007
2.85k
        code = pdfi_get_image_info(ctx, smask_stream, page_dict, stream_dict,
2008
2.85k
                                   inline_image, &smask_info);
2009
2.85k
        if (code < 0)
2010
18
            goto cleanupExit;
2011
2.85k
    }
2012
2013
    /* Get the image into a supported gs type (type1, type3, type4, type3x) */
2014
392k
    if (!image_info.Mask && !smask_stream) { /* Type 1 and ImageMask */
2015
388k
        memset(&t1image, 0, sizeof(t1image));
2016
388k
        pim = (gs_pixel_image_t *)&t1image;
2017
2018
388k
        if (image_info.ImageMask) {
2019
            /* Sets up timage.ImageMask, amongst other things */
2020
295k
            gs_image_t_init_adjust(&t1image, NULL, false);
2021
295k
        } else {
2022
92.6k
            gs_image_t_init_adjust(&t1image, pcs, true);
2023
92.6k
        }
2024
388k
    } else if (smask_stream) { /* Type 3x */
2025
        /* In the event where we have both /SMask and /Mask, favour /SMask
2026
           See tests_private/pdf/sumatra/1901_-_tiling_inconsistencies.pdf
2027
         */
2028
2.83k
        mask_stream = NULL;
2029
2.83k
        code = pdfi_image_setup_type3x(ctx, &image_info, &t3ximage, &smask_info, comps);
2030
2.83k
        if (code < 0) {
2031
0
            if ((code = pdfi_set_error_stop(ctx, gs_note_error(code), NULL, E_PDF_INVALID_MATTE, "pdfi_do_image", "")) < 0)
2032
0
                goto cleanupExitError;
2033
            /* If this got an error, setup as a Type 1 image */
2034
            /* NOTE: I did this error-handling the same as for Type 4 image below.
2035
             * Dunno if it's better to do this or to just abort the whole image?
2036
             */
2037
0
            memset(&t1image, 0, sizeof(t1image));
2038
0
            pim = (gs_pixel_image_t *)&t1image;
2039
0
            gs_image_t_init_adjust(&t1image, pcs, true);
2040
0
            smask_stream = mask_stream = NULL;
2041
2.83k
        } else {
2042
2.83k
            pim = (gs_pixel_image_t *)&t3ximage;
2043
2.83k
        }
2044
2.83k
    } else {
2045
791
        if (mask_array) { /* Type 4 */
2046
210
            code = pdfi_image_setup_type4(ctx, &image_info, &t4image, mask_array, pcs);
2047
210
            if (code < 0) {
2048
11
                 if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_IMAGE_ERROR, "pdfi_do_image", "")) < 0) {
2049
0
                     goto cleanupExit;
2050
0
                 }
2051
                /* If this got an error, setup as a Type 1 image */
2052
11
                memset(&t1image, 0, sizeof(t1image));
2053
11
                pim = (gs_pixel_image_t *)&t1image;
2054
11
                gs_image_t_init_adjust(&t1image, pcs, true);
2055
199
            } else {
2056
199
                pim = (gs_pixel_image_t *)&t4image;
2057
199
            }
2058
581
        } else { /* Type 3 */
2059
581
            memset(&t3image, 0, sizeof(t3image));
2060
581
            pim = (gs_pixel_image_t *)&t3image;
2061
581
            gs_image3_t_init(&t3image, NULL, interleave_separate_source);
2062
581
            code = pdfi_data_image_params(ctx, &mask_info, &t3image.MaskDict, 1, NULL);
2063
581
            if (code < 0)
2064
0
                goto cleanupExit;
2065
581
        }
2066
791
    }
2067
2068
2069
    /* At this point pim points to a structure containing the specific type
2070
     * of image, and then we can handle it generically from here.
2071
     * The underlying gs image functions will do different things for different
2072
     * types of images.
2073
     */
2074
2075
    /* Setup the common params */
2076
392k
    pim->ColorSpace = pcs;
2077
392k
    code = pdfi_data_image_params(ctx, &image_info, (gs_data_image_t *)pim, comps, pcs);
2078
392k
    if (code < 0)
2079
18
        goto cleanupExit;
2080
2081
    /* Grab the mask_image data buffer in advance.
2082
     * Doing it this way because I don't want to muck with reading from
2083
     * two streams simultaneously -- not even sure that is feasible?
2084
     */
2085
392k
    if (smask_stream) {
2086
2.83k
        mask_size = ((((smask_info.Width * smask_info.BPC) + 7) / 8) * smask_info.Height);
2087
        /* This will happen only in case of PreserveSMask (Type 3x) */
2088
2.83k
        code = pdfi_stream_to_buffer(ctx, smask_stream, &mask_buffer, (int64_t *)&mask_size);
2089
2.83k
        if (code < 0)
2090
93
            goto cleanupExit;
2091
389k
    } else if (mask_stream) {
2092
        /* Calculate expected mask size */
2093
581
        mask_size = ((((t3image.MaskDict.BitsPerComponent * (int64_t)t3image.MaskDict.Width) + 7) / 8) * (int64_t)t3image.MaskDict.Height);
2094
581
        code = pdfi_stream_to_buffer(ctx, mask_stream, &mask_buffer, (int64_t *)&mask_size);
2095
581
        if (code < 0)
2096
19
            goto cleanupExit;
2097
581
    }
2098
    /* Setup the data stream for the image data */
2099
391k
    if (!inline_image) {
2100
94.2k
        pdfi_seek(ctx, source, stream_offset, SEEK_SET);
2101
2102
94.2k
        code = pdfi_apply_SubFileDecode_filter(ctx, 0, "endstream", source, &SFD_stream, false);
2103
94.2k
        if (code < 0)
2104
0
            goto cleanupExit;
2105
94.2k
        source = SFD_stream;
2106
94.2k
    }
2107
2108
391k
    code = pdfi_filter(ctx, image_stream, source, &new_stream, inline_image);
2109
391k
    if (code < 0)
2110
2.08k
        goto cleanupExit;
2111
2112
    /* This duplicates the code in gs_img.ps; if we have an imagemask, with 1 bit per component (is there any other kind ?)
2113
     * and the image is to be interpolated, and we are nto sending it to a high level device. Then check the scaling.
2114
     * If we are scaling up (in device space) by afactor of more than 2, then we install the ImScaleDecode filter,
2115
     * which interpolates the input data by a factor of 4.
2116
     * The scaling of 2 is arbitrary (says so in gs_img.ps) but we use it for consistency. The scaling of the input
2117
     * by 4 is just a magic number, the scaling is always by 4, and we need to know it so we can adjust the Image Matrix
2118
     * and Width and Height values.
2119
     */
2120
389k
    if (image_info.ImageMask == 1 && image_info.BPC == 1 && image_info.Interpolate == 1 && !ctx->device_state.HighLevelDevice)
2121
0
    {
2122
0
        pdf_c_stream *s = new_stream;
2123
0
        gs_matrix mat4 = {4, 0, 0, 4, 0, 0}, inverseIM;
2124
0
        gs_point pt, pt1;
2125
0
        float s1, s2;
2126
2127
0
        code = gs_matrix_invert(&pim->ImageMatrix, &inverseIM);
2128
0
        if (code < 0)
2129
0
            goto cleanupExit;
2130
2131
0
        code = gs_distance_transform(0, 1, &inverseIM, &pt);
2132
0
        if (code < 0)
2133
0
            goto cleanupExit;
2134
2135
0
        code = gs_distance_transform(pt.x, pt.y, &ctm_only(ctx->pgs), &pt1);
2136
0
        if (code < 0)
2137
0
            goto cleanupExit;
2138
2139
0
        s1 = sqrt(pt1.x * pt1.x + pt1.y * pt1.y);
2140
2141
0
        code = gs_distance_transform(1, 0, &inverseIM, &pt);
2142
0
        if (code < 0)
2143
0
            goto cleanupExit;
2144
2145
0
        code = gs_distance_transform(pt.x, pt.y, &ctm_only(ctx->pgs), &pt1);
2146
0
        if (code < 0)
2147
0
            goto cleanupExit;
2148
2149
0
        s2 = sqrt(pt1.x * pt1.x + pt1.y * pt1.y);
2150
2151
0
        if (s1 > 2.0 || s2 > 2.0) {
2152
0
            code = pdfi_apply_imscale_filter(ctx, 0, image_info.Width, image_info.Height, s, &new_stream);
2153
0
            if (code < 0)
2154
0
                goto cleanupExit;
2155
            /* This adds the filter to the 'chain' of filter we created. When we close this filter
2156
             * it closes all the filters in the chain, back to either the SubFileDecode filter or the
2157
             * original main stream. If we don't patch this up then we leak memory for any filters
2158
             * applied in pdfi_filter above.
2159
             */
2160
0
            new_stream->original = s->original;
2161
2162
            /* We'e created a new 'new_stream', which is a C stream, to hold the filter chain
2163
             * but we still need to free the original C stream 'wrapper' we created with pdfi_filter()
2164
             * Do that now.
2165
             */
2166
0
            gs_free_object(ctx->memory, s, "free stream replaced by adding image scaling filter");
2167
0
            image_info.Width *= 4;
2168
0
            image_info.Height *= 4;
2169
0
            pim->Width *= 4;
2170
0
            pim->Height *= 4;
2171
0
            code = gs_matrix_multiply(&pim->ImageMatrix, &mat4, &pim->ImageMatrix);
2172
0
            if (code < 0)
2173
0
                goto cleanupExit;
2174
0
        }
2175
0
    }
2176
2177
389k
    trans_required = pdfi_trans_required(ctx);
2178
2179
389k
    if (trans_required) {
2180
7.23k
        code = pdfi_image_setup_trans(ctx, &trans_state);
2181
7.23k
        if (code < 0)
2182
549
            goto cleanupExit;
2183
7.23k
    }
2184
2185
    /* Render the image */
2186
389k
    code = pdfi_render_image(ctx, pim, new_stream,
2187
389k
                             mask_buffer, mask_size,
2188
389k
                             comps, image_info.ImageMask);
2189
389k
    if (code < 0) {
2190
33.0k
        if (ctx->args.pdfdebug)
2191
0
            outprintf(ctx->memory, "WARNING: pdfi_do_image: error %d from pdfi_render_image\n", code);
2192
33.0k
    }
2193
2194
389k
    if (trans_required) {
2195
6.69k
        code1 = pdfi_trans_teardown(ctx, &trans_state);
2196
6.69k
        if (code == 0)
2197
702
            code = code1;
2198
6.69k
    }
2199
2200
409k
 cleanupExit:
2201
409k
    if (code < 0)
2202
44.0k
        code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_IMAGE_ERROR, "pdfi_do_image", NULL);
2203
2204
409k
 cleanupExitError:
2205
409k
    if (transparency_group) {
2206
26.4k
        pdfi_trans_end_isolated_group(ctx);
2207
26.4k
        if (need_smask_cleanup)
2208
23.5k
            pdfi_trans_end_smask_notify(ctx);
2209
26.4k
    }
2210
2211
    /* See note above on the pdfi_op_q call. This does a grestore, and
2212
     * pops the transparency state. */
2213
409k
    (void)pdfi_op_Q(ctx);
2214
2215
409k
    if (new_stream)
2216
389k
        pdfi_close_file(ctx, new_stream);
2217
409k
    if (SFD_stream)
2218
94.2k
        pdfi_close_file(ctx, SFD_stream);
2219
409k
    if (mask_buffer)
2220
3.30k
        gs_free_object(ctx->memory, mask_buffer, "pdfi_do_image (mask_buffer)");
2221
2222
409k
    pdfi_countdown(alt_stream);
2223
2224
409k
    pdfi_free_image_info_components(&image_info);
2225
409k
    pdfi_free_image_info_components(&mask_info);
2226
409k
    pdfi_free_image_info_components(&smask_info);
2227
2228
409k
    if (pcs != NULL)
2229
96.5k
        rc_decrement_only_cs(pcs, "pdfi_do_image");
2230
2231
#if DEBUG_IMAGES
2232
    dbgmprintf(ctx->memory, "pdfi_do_image END\n");
2233
#endif
2234
409k
    return code;
2235
409k
}
2236
2237
int pdfi_ID(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_c_stream *source)
2238
324k
{
2239
324k
    pdf_dict *d = NULL;
2240
324k
    int code;
2241
324k
    pdf_stream *image_stream;
2242
2243
324k
    if (ctx->text.BlockDepth != 0) {
2244
167
        ctx->text.BlockDepth = 0;
2245
167
        if (ctx->text.TextClip) {
2246
0
            gx_device *dev = gs_currentdevice_inline(ctx->pgs);
2247
2248
0
            ctx->text.TextClip = false;
2249
0
            (void)dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
2250
0
        }
2251
167
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_ID", NULL);
2252
167
        if (code < 0)
2253
0
            return code;
2254
167
    }
2255
2256
    /* we want to have the indirect_num and indirect_gen of the created dictionary
2257
     * be 0, because we are reading from a stream, and the stream has already
2258
     * been decrypted, we don't need to decrypt any strings contained in the
2259
     * inline dictionary.
2260
     */
2261
324k
    code = pdfi_dict_from_stack(ctx, 0, 0, false);
2262
324k
    if (code < 0)
2263
        /* pdfi_dict_from_stack cleans up the stack so we don't need to in case of an error */
2264
25.3k
        return code;
2265
2266
299k
    d = (pdf_dict *)ctx->stack_top[-1];
2267
299k
    pdfi_countup(d);
2268
299k
    pdfi_pop(ctx, 1);
2269
2270
299k
    code = pdfi_obj_dict_to_stream(ctx, d, &image_stream, true);
2271
299k
    if (code < 0)
2272
0
        goto error;
2273
2274
299k
    code = pdfi_do_image(ctx, page_dict, stream_dict, image_stream, source, true);
2275
299k
error:
2276
299k
    pdfi_countdown(image_stream);
2277
299k
    pdfi_countdown(d);
2278
299k
    return code;
2279
299k
}
2280
2281
int pdfi_EI(pdf_context *ctx)
2282
316k
{
2283
316k
    int code;
2284
2285
316k
    if (ctx->text.BlockDepth != 0) {
2286
57
        ctx->text.BlockDepth = 0;
2287
57
        if (ctx->text.TextClip) {
2288
0
            gx_device *dev = gs_currentdevice_inline(ctx->pgs);
2289
2290
0
            ctx->text.TextClip = false;
2291
0
            (void)dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
2292
0
        }
2293
57
        return pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_EI", NULL);
2294
57
    }
2295
2296
/*    pdfi_clearstack(ctx);*/
2297
316k
    return 0;
2298
316k
}
2299
2300
/* see .execgroup */
2301
int pdfi_form_execgroup(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *xobject_obj,
2302
                        gs_gstate *GroupGState, gs_color_space *pcs, gs_client_color *pcc, gs_matrix *matrix)
2303
6.82k
{
2304
6.82k
    int code;
2305
6.82k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2306
2307
6.82k
    code = pdfi_gsave(ctx);
2308
6.82k
    if (code < 0)
2309
0
        goto exit;
2310
2311
6.82k
    if (GroupGState) {
2312
1.35k
        code = pdfi_gs_setgstate(ctx->pgs, GroupGState);
2313
1.35k
        if (code < 0)
2314
0
            goto exit2;
2315
1.35k
    }
2316
2317
    /* Override the colorspace if specified */
2318
6.82k
    if (pcs) {
2319
5.47k
        code = pdfi_gs_setcolorspace(ctx, pcs);
2320
5.47k
        if (code < 0)
2321
0
            goto exit2;
2322
5.47k
        code = gs_setcolor(ctx->pgs, (const gs_client_color *)pcc);
2323
5.47k
        if (code < 0)
2324
0
            goto exit2;
2325
5.47k
    }
2326
2327
    /* Disable the SMask */
2328
6.82k
    pdfi_gstate_smask_free(igs);
2329
2330
6.82k
    gs_setblendmode(ctx->pgs, BLEND_MODE_Compatible);
2331
6.82k
    gs_setstrokeconstantalpha(ctx->pgs, 1.0);
2332
6.82k
    gs_setfillconstantalpha(ctx->pgs, 1.0);
2333
2334
6.82k
    if (matrix)
2335
1.35k
        code = gs_concat(ctx->pgs, matrix);
2336
6.82k
    if (code < 0) {
2337
0
        goto exit2;
2338
0
    }
2339
6.82k
    code = pdfi_run_context(ctx, xobject_obj, page_dict, false, "FORM");
2340
2341
6.82k
 exit2:
2342
6.82k
    if (code != 0)
2343
0
        (void)pdfi_grestore(ctx);
2344
6.82k
    else
2345
6.82k
        code = pdfi_grestore(ctx);
2346
6.82k
 exit:
2347
6.82k
    return code;
2348
6.82k
}
2349
2350
/* See zbeginform() */
2351
static int pdfi_form_highlevel_begin(pdf_context *ctx, pdf_dict *form_dict, gs_matrix *CTM,
2352
                                     gs_rect *BBox, gs_matrix *form_matrix)
2353
13.5k
{
2354
13.5k
    int code = 0;
2355
13.5k
    gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2356
13.5k
    gs_form_template_t template;
2357
13.5k
    gs_point ll, ur;
2358
13.5k
    gs_fixed_rect box;
2359
2360
13.5k
    memset(&template, 0, sizeof(template));
2361
2362
13.5k
    template.CTM = *CTM; /* (structure copy) */
2363
13.5k
    template.BBox = *BBox; /* (structure copy) */
2364
13.5k
    template.form_matrix = *form_matrix; /* (structure copy) */
2365
13.5k
    template.FormID = -1;
2366
13.5k
    template.pcpath = ctx->pgs->clip_path;
2367
13.5k
    template.pgs = ctx->pgs;
2368
2369
13.5k
    code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_form_begin, &template, 0);
2370
    /* return value > 0 means the device sent us back a matrix
2371
     * and wants the CTM set to that.
2372
     * TODO: No idea if we need this nonsense.  See zbeginform()
2373
     */
2374
13.5k
    if (code > 0)
2375
3
    {
2376
3
        gs_setmatrix(ctx->pgs, &template.CTM);
2377
3
        gs_distance_transform(template.BBox.p.x, template.BBox.p.y, &template.CTM, &ll);
2378
3
        gs_distance_transform(template.BBox.q.x, template.BBox.q.y, &template.CTM, &ur);
2379
2380
        /* A form can legitimately have negative co-ordinates in paths
2381
         * because it can be translated. But we always clip paths to the
2382
         * page which (clearly) can't have negative co-ordinates. NB this
2383
         * wouldn't be a problem if we didn't reset the CTM, but that would
2384
         * break the form capture.
2385
         * So here we temporarily set the clip to permit negative values,
2386
         * fortunately this works.....
2387
         */
2388
        /* We choose to permit negative values of the same magnitude as the
2389
         * positive ones.
2390
         */
2391
2392
3
        box.p.x = float2fixed(ll.x);
2393
3
        box.p.y = float2fixed(ll.y);
2394
3
        box.q.x = float2fixed(ur.x);
2395
3
        box.q.y = float2fixed(ur.y);
2396
2397
3
        if (box.p.x < 0) {
2398
0
            if(box.p.x * -1 > box.q.x)
2399
0
                box.q.x = box.p.x * -1;
2400
3
        } else {
2401
3
            if (fabs(ur.x) > fabs(ll.x))
2402
3
                box.p.x = box.q.x * -1;
2403
0
            else {
2404
0
                box.p.x = float2fixed(ll.x * -1);
2405
0
                box.q.x = float2fixed(ll.x);
2406
0
            }
2407
3
        }
2408
3
        if (box.p.y < 0) {
2409
1
            if(box.p.y * -1 > box.q.y)
2410
1
                box.q.y = box.p.y * -1;
2411
2
        } else {
2412
2
            if (fabs(ur.y) > fabs(ll.y))
2413
2
                box.p.y = box.q.y * -1;
2414
0
            else {
2415
0
                box.p.y = float2fixed(ll.y * -1);
2416
0
                box.q.y = float2fixed(ll.y);
2417
0
            }
2418
2
        }
2419
        /* This gets undone when we grestore after the form is executed */
2420
3
        code = gx_clip_to_rectangle(ctx->pgs, &box);
2421
3
    }
2422
2423
13.5k
    return code;
2424
13.5k
}
2425
2426
/* See zendform() */
2427
static int pdfi_form_highlevel_end(pdf_context *ctx)
2428
13.5k
{
2429
13.5k
    int code = 0;
2430
13.5k
    gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2431
2432
13.5k
    code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_form_end, 0, 0);
2433
13.5k
    return code;
2434
13.5k
}
2435
2436
/* See bug #702560. The original file has a Form XObject which is not a stream. Instead
2437
 * the Form XObject has a /Contents key which points to a stream dictionary. This is plainly
2438
 * illegal but, as always, Acrobat can open it....
2439
 * If PDFSTOPONERROR is true then we just exit. Otherwise we look for a /Contents key in the stream
2440
 * dictionary. If we find one we dereference the object to get a stream dictionary, then merge the
2441
 * two dictionaries, ensuring the stream offset is correct, and proceed as if that's what we'd
2442
 * always had. If we don't have a /Contents key then exit with a typecheck error.
2443
 *
2444
 * Sets *hacked_stream to the /Contents stream if it found one.
2445
 */
2446
static int pdfi_form_stream_hack(pdf_context *ctx, pdf_dict *form_dict, pdf_stream **hacked_stream)
2447
1.12k
{
2448
1.12k
    int code = 0;
2449
1.12k
    pdf_stream *stream_obj = NULL;
2450
1.12k
    pdf_obj *Parent = NULL;
2451
1.12k
    pdf_dict *d = NULL;
2452
1.12k
    pdf_dict *stream_dict = NULL;
2453
2454
1.12k
    *hacked_stream = NULL;
2455
2456
1.12k
    if (pdfi_type_of(form_dict) == PDF_STREAM)
2457
0
        return 0;
2458
2459
1.12k
    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL)) < 0) {
2460
0
        goto exit;
2461
0
    }
2462
2463
1.12k
    code = pdfi_dict_knownget_type(ctx, form_dict, "Contents", PDF_STREAM,
2464
1.12k
                                   (pdf_obj **)&stream_obj);
2465
1.12k
    if (code < 0 || stream_obj == NULL) {
2466
1.09k
        pdfi_set_error(ctx, 0, NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL);
2467
1.09k
        code = gs_note_error(gs_error_typecheck);
2468
1.09k
        goto exit;
2469
1.09k
    }
2470
2471
25
    d = form_dict;
2472
25
    pdfi_countup(d);
2473
39
    do {
2474
39
        code = pdfi_dict_knownget(ctx, d, "Parent", (pdf_obj **)&Parent);
2475
39
        if (code > 0 && pdfi_type_of(Parent) == PDF_DICT) {
2476
14
            if (Parent->object_num == stream_obj->object_num) {
2477
0
                pdfi_countdown(d);
2478
0
                pdfi_countdown(Parent);
2479
0
                pdfi_set_error(ctx, 0, NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL);
2480
0
                code = gs_note_error(gs_error_undefined);
2481
0
                goto exit;
2482
0
            }
2483
14
            pdfi_countdown(d);
2484
14
            d = (pdf_dict *)Parent;
2485
25
        } else {
2486
25
            pdfi_countdown(d);
2487
25
            break;
2488
25
        }
2489
39
    } while (1);
2490
2491
25
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
2492
25
    if (code < 0) {
2493
0
        pdfi_set_error(ctx, 0, NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL);
2494
0
        goto exit;
2495
0
    }
2496
25
    pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_HAS_CONTENTS, "pdfi_form_stream_hack", NULL);
2497
25
    code = pdfi_merge_dicts(ctx, stream_dict, form_dict);
2498
    /* Having merged the dictionaries, we don't want the Contents key in the stream dict.
2499
     * We do want to leave it in the form dictionary, in case we use this form again.
2500
     * Leaving the reference in the stream dicttionary leads to a reference counting problem
2501
     * because stream_dict is contained in stream_obj so stream_obj becomes self-referencing.
2502
     */
2503
25
    pdfi_dict_delete(ctx, stream_dict, "Contents");
2504
2505
25
    if (code == 0) {
2506
25
        *hacked_stream = stream_obj;
2507
25
        pdfi_countup(stream_obj);
2508
25
    }
2509
2510
1.12k
 exit:
2511
1.12k
    pdfi_countdown(stream_obj);
2512
1.12k
    return code;
2513
25
}
2514
2515
static int pdfi_do_form(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *form_obj)
2516
234k
{
2517
234k
    int code, code1 = 0;
2518
234k
    bool group_known = false, known = false;
2519
234k
    bool do_group = false;
2520
234k
    pdf_array *FormMatrix = NULL;
2521
234k
    gs_matrix formmatrix, CTM;
2522
234k
    gs_rect bbox;
2523
234k
    pdf_array *BBox = NULL;
2524
234k
    bool save_PreservePDFForm;
2525
234k
    pdf_stream *form_stream = NULL; /* Alias */
2526
234k
    pdf_stream *hacked_stream = NULL;
2527
234k
    pdf_dict *form_dict;
2528
234k
    gs_color_space *pcs = NULL;
2529
234k
    gs_client_color cc, *pcc;
2530
2531
#if DEBUG_IMAGES
2532
    dbgmprintf(ctx->memory, "pdfi_do_form BEGIN\n");
2533
#endif
2534
234k
    if (pdfi_type_of(form_obj) != PDF_STREAM) {
2535
1.12k
        code = pdfi_form_stream_hack(ctx, (pdf_dict *)form_obj, &hacked_stream);
2536
1.12k
        if (code < 0)
2537
1.09k
            return code;
2538
25
        form_stream = hacked_stream;
2539
25
    } else
2540
233k
        form_stream = (pdf_stream *)form_obj;
2541
2542
233k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)form_stream, &form_dict);
2543
233k
    if (code < 0)
2544
0
        goto exit;
2545
2546
233k
    code = pdfi_dict_known(ctx, form_dict, "Group", &group_known);
2547
233k
    if (code < 0)
2548
0
        goto exit;
2549
233k
    if (group_known && ctx->page.has_transparency)
2550
6.01k
        do_group = true;
2551
2552
    /* Grab the CTM before it gets modified */
2553
233k
    code = gs_currentmatrix(ctx->pgs, &CTM);
2554
233k
    if (code < 0) goto exit1;
2555
2556
233k
    code = pdfi_op_q(ctx);
2557
233k
    if (code < 0) goto exit1;
2558
2559
233k
    code = pdfi_dict_knownget_type(ctx, form_dict, "Matrix", PDF_ARRAY, (pdf_obj **)&FormMatrix);
2560
233k
    if (code < 0) goto exit1;
2561
2562
233k
    code = pdfi_array_to_gs_matrix(ctx, FormMatrix, &formmatrix);
2563
233k
    if (code < 0) goto exit1;
2564
2565
233k
    code = pdfi_dict_known(ctx, form_dict, "BBox", &known);
2566
233k
    if (known) {
2567
231k
        code = pdfi_dict_get_type(ctx, form_dict, "BBox", PDF_ARRAY, (pdf_obj **)&BBox);
2568
231k
        if (code < 0) goto exit1;
2569
231k
    } else {
2570
2.08k
        if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_undefined), NULL, E_PDF_MISSING_BBOX, "pdfi_do_form", NULL)) < 0) {
2571
0
            goto exit;
2572
0
        }
2573
2.08k
    }
2574
2575
233k
    code = pdfi_array_to_gs_rect(ctx, BBox, &bbox);
2576
233k
    if (code < 0) goto exit1;
2577
2578
233k
    if (bbox.q.x - bbox.p.x == 0.0 || bbox.q.y - bbox.p.y == 0.0) {
2579
379
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_FORM_CLIPPEDOUT, "pdfi_do_form", "")) < 0)
2580
0
            goto exit1;
2581
2582
379
        if (ctx->PreservePDFForm) {
2583
42
            code = pdfi_form_highlevel_begin(ctx, form_dict, &CTM, &bbox, &formmatrix);
2584
42
            if (code >= 0)
2585
42
                code = pdfi_form_highlevel_end(ctx);
2586
42
        }
2587
379
        goto exit1;
2588
379
    }
2589
2590
233k
    code = gs_concat(ctx->pgs, &formmatrix);
2591
233k
    if (code < 0) goto exit1;
2592
2593
233k
    code = gs_rectclip(ctx->pgs, &bbox, 1);
2594
233k
    if (code < 0) goto exit1;
2595
2596
233k
    if (ctx->PreservePDFForm) {
2597
13.5k
        code = pdfi_form_highlevel_begin(ctx, form_dict, &CTM, &bbox, &formmatrix);
2598
13.5k
        if (code < 0) goto exit1;
2599
13.5k
    }
2600
233k
    save_PreservePDFForm = ctx->PreservePDFForm;
2601
233k
    ctx->PreservePDFForm = false; /* Turn off in case there are any sub-forms */
2602
2603
233k
    if (do_group) {
2604
5.99k
        code = pdfi_loop_detector_mark(ctx);
2605
5.99k
        if (code < 0) goto exit1;
2606
2607
        /* Save the current color space in case it gets changed */
2608
5.99k
        pcs = gs_currentcolorspace(ctx->pgs);
2609
5.99k
        rc_increment(pcs);
2610
5.99k
        pcc = (gs_client_color *)gs_currentcolor(ctx->pgs);
2611
5.99k
        cc = *pcc;
2612
2613
5.99k
        code = pdfi_trans_begin_form_group(ctx, page_dict, form_dict);
2614
5.99k
        (void)pdfi_loop_detector_cleartomark(ctx);
2615
5.99k
        if (code < 0) goto exit1;
2616
2617
5.47k
        code = pdfi_form_execgroup(ctx, page_dict, form_stream, NULL, pcs, &cc, NULL);
2618
5.47k
        code1 = pdfi_trans_end_group(ctx);
2619
5.47k
        if (code == 0) code = code1;
2620
227k
    } else {
2621
227k
        bool saved_decrypt_strings = ctx->encryption.decrypt_strings;
2622
2623
        /* We can run a Form even when we aren't running a page content stresm,
2624
         * eg for an annotation, and we need to *not* decrypt strings in that
2625
         * case (the content stream will be decrypted and strings in content
2626
         * streams are not additionally encrypted).
2627
         */
2628
227k
        ctx->encryption.decrypt_strings = false;
2629
227k
        code = pdfi_run_context(ctx, form_stream, page_dict, false, "FORM");
2630
227k
        ctx->encryption.decrypt_strings = saved_decrypt_strings;
2631
227k
    }
2632
2633
232k
    ctx->PreservePDFForm = save_PreservePDFForm;
2634
232k
    if (ctx->PreservePDFForm) {
2635
13.5k
        code = pdfi_form_highlevel_end(ctx);
2636
13.5k
    }
2637
2638
233k
 exit1:
2639
233k
    code1 = pdfi_op_Q(ctx);
2640
233k
    if (code == 0) code = code1;
2641
2642
233k
 exit:
2643
233k
    pdfi_countdown(FormMatrix);
2644
233k
    pdfi_countdown(BBox);
2645
233k
    pdfi_countdown(hacked_stream);
2646
233k
    if (pcs)
2647
5.99k
        rc_decrement_only_cs(pcs, "pdfi_do_form(pcs)");
2648
#if DEBUG_IMAGES
2649
    dbgmprintf(ctx->memory, "pdfi_do_form END\n");
2650
#endif
2651
233k
    if (code < 0)
2652
703
        return code;
2653
232k
    return 0;
2654
233k
}
2655
2656
int pdfi_do_highlevel_form(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *form_stream)
2657
13.5k
{
2658
13.5k
    int code = 0;
2659
2660
13.5k
    ctx->PreservePDFForm = true;
2661
13.5k
    code = pdfi_do_form(ctx, page_dict, form_stream);
2662
13.5k
    ctx->PreservePDFForm = false;
2663
2664
13.5k
    return code;
2665
13.5k
}
2666
2667
int pdfi_do_image_or_form(pdf_context *ctx, pdf_dict *stream_dict,
2668
                                 pdf_dict *page_dict, pdf_obj *xobject_obj)
2669
331k
{
2670
331k
    int code;
2671
331k
    pdf_name *n = NULL;
2672
331k
    pdf_dict *xobject_dict;
2673
331k
    bool known = false;
2674
331k
    gs_offset_t savedoffset;
2675
2676
331k
    code = pdfi_dict_from_obj(ctx, xobject_obj, &xobject_dict);
2677
331k
    if (code < 0)
2678
0
        return code;
2679
2680
    /* Check Optional Content status */
2681
331k
    code = pdfi_dict_known(ctx, xobject_dict, "OC", &known);
2682
331k
    if (code < 0)
2683
0
        return code;
2684
2685
331k
    if (known) {
2686
713
        pdf_dict *OCDict = NULL;
2687
713
        bool visible = false;
2688
713
        gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2689
2690
713
        code = pdfi_dict_get(ctx, xobject_dict, "OC", (pdf_obj **)&OCDict);
2691
713
        if (code < 0)
2692
44
            return code;
2693
2694
669
        if (pdfi_type_of(OCDict) == PDF_DICT) {
2695
655
            char *label = NULL;
2696
2697
655
            if (ctx->device_state.writepdfmarks && ctx->device_state.WantsOptionalContent) {
2698
40
                code = pdfi_pdfmark_dict(ctx, OCDict);
2699
40
                if (code < 0) {
2700
3
                    if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_DO_OC_FAILED, "pdfi_do_image_or_form", NULL)) < 0) {
2701
0
                        pdfi_countdown(OCDict);
2702
0
                        return code;
2703
0
                    }
2704
3
                }
2705
40
                code = pdfi_obj_get_label(ctx, (pdf_obj *)OCDict, &label);
2706
40
                if (code >= 0) {
2707
40
                    code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_pending_optional_content, label, 0);
2708
40
                    gs_free_object(ctx->memory, label, "");
2709
40
                    if (code < 0) {
2710
0
                        if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_DO_OC_FAILED, "pdfi_do_image_or_form", NULL)) < 0) {
2711
0
                            pdfi_countdown(OCDict);
2712
0
                            return code;
2713
0
                        }
2714
0
                    }
2715
40
                } else {
2716
0
                    if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_DO_OC_FAILED, "pdfi_do_image_or_form", NULL)) < 0) {
2717
0
                        pdfi_countdown(OCDict);
2718
0
                        return code;
2719
0
                    }
2720
0
                }
2721
615
            } else {
2722
615
                visible = pdfi_oc_is_ocg_visible(ctx, OCDict);
2723
615
                if (!visible) {
2724
52
                    pdfi_countdown(OCDict);
2725
52
                    return 0;
2726
52
                }
2727
615
            }
2728
655
        } else {
2729
14
            if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_typecheck), NULL, W_PDF_BAD_OCDICT, "pdfi_do_image_or_form", NULL)) < 0)
2730
0
                return code;
2731
14
        }
2732
617
        pdfi_countdown(OCDict);
2733
617
    }
2734
2735
#if DEBUG_IMAGES
2736
    dbgmprintf1(ctx->memory, "pdfi_do_image_or_form BEGIN (OBJ = %d)\n", xobject_obj->object_num);
2737
#endif
2738
331k
    code = pdfi_trans_set_params(ctx);
2739
331k
    if (code < 0)
2740
92
        return code;
2741
2742
331k
    code = pdfi_dict_get(ctx, xobject_dict, "Subtype", (pdf_obj **)&n);
2743
331k
    if (code < 0) {
2744
3.18k
        if (code == gs_error_undefined) {
2745
3.18k
            int code1 = 0;
2746
            /* This is illegal, because we have no way to tell is an XObject is a Form
2747
             * or Image object. However it seems Acrobat just assumes that it's a Form!
2748
             * See test file /tests_private/pdf/PDFIA1.7_SUBSET/CATX2063.pdf
2749
             */
2750
3.18k
            code1 = pdfi_name_alloc(ctx, (byte *)"Form", 4, (pdf_obj **)&n);
2751
3.18k
            if (code1 == 0) {
2752
3.18k
                pdfi_countup(n);
2753
3.18k
            }
2754
3.18k
            if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_undefined), NULL, E_PDF_NO_SUBTYPE, "pdfi_do_image_or_form", NULL)) < 0) {
2755
0
                goto exit;
2756
0
            }
2757
3.18k
        }
2758
0
        else
2759
0
            goto exit;
2760
3.18k
    }
2761
331k
    if (pdfi_type_of(n) != PDF_NAME) {
2762
17
        code = gs_note_error(gs_error_typecheck);
2763
17
        goto exit;
2764
17
    }
2765
2766
331k
    if (pdfi_name_is(n, "Image")) {
2767
110k
try_as_image:
2768
110k
        if (pdfi_type_of(xobject_obj) != PDF_STREAM) {
2769
465
            code = gs_note_error(gs_error_typecheck);
2770
465
            goto exit;
2771
465
        }
2772
110k
        savedoffset = pdfi_tell(ctx->main_stream);
2773
110k
        code = pdfi_do_image(ctx, page_dict, stream_dict, (pdf_stream *)xobject_obj,
2774
110k
                             ctx->main_stream, false);
2775
110k
        pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
2776
221k
    } else if (pdfi_name_is(n, "Form")) {
2777
        /* In theory a Form must be a stream, but we don't check that here
2778
         * because there is a broken case where it can be a dict.
2779
         * So pdfi_do_form() will handle that crazy case if it's not actually a stream.
2780
         */
2781
221k
        code = pdfi_do_form(ctx, page_dict, (pdf_stream *)xobject_obj);
2782
221k
    } else if (pdfi_name_is(n, "PS")) {
2783
0
        code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_PS_XOBJECT_IGNORED, "pdfi_form_stream_hack", NULL);
2784
912
    } else {
2785
912
        code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BAD_SUBTYPE, "pdfi_do_image_or_form", NULL);
2786
912
        if (code >= 0)
2787
912
            goto try_as_image;
2788
912
    }
2789
2790
331k
 exit:
2791
331k
    pdfi_countdown(n);
2792
#if DEBUG_IMAGES
2793
    dbgmprintf(ctx->memory, "pdfi_do_image_or_form END\n");
2794
#endif
2795
331k
    return code;
2796
331k
}
2797
2798
int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2799
287k
{
2800
287k
    int code = 0;
2801
287k
    pdf_name *n = NULL;
2802
287k
    pdf_obj *o = NULL;
2803
287k
    pdf_dict *sdict = NULL;
2804
287k
    bool known = false, AddedParent = false;
2805
2806
287k
    if (pdfi_count_stack(ctx) < 1) {
2807
2.70k
        code = gs_note_error(gs_error_stackunderflow);
2808
2.70k
        goto exit1;
2809
2.70k
    }
2810
284k
    n = (pdf_name *)ctx->stack_top[-1];
2811
284k
    pdfi_countup(n);
2812
284k
    pdfi_pop(ctx, 1);
2813
2814
284k
    if (pdfi_type_of(n) != PDF_NAME) {
2815
2.39k
        code = gs_note_error(gs_error_typecheck);
2816
2.39k
        goto exit1;
2817
2.39k
    }
2818
2819
282k
    if (ctx->text.BlockDepth != 0) {
2820
2.45k
        ctx->text.BlockDepth = 0;
2821
2.45k
        if (ctx->text.TextClip) {
2822
0
            gx_device *dev = gs_currentdevice_inline(ctx->pgs);
2823
2824
0
            ctx->text.TextClip = false;
2825
0
            (void)dev_proc(dev, dev_spec_op)(dev, gxdso_hilevel_text_clip, (void *)0, 1);
2826
0
        }
2827
2.45k
        code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_Do", NULL);
2828
2.45k
        if (code < 0)
2829
0
            goto exit;
2830
2.45k
    }
2831
2832
282k
    code = pdfi_loop_detector_mark(ctx);
2833
282k
    if (code < 0)
2834
0
        goto exit1;
2835
282k
    code = pdfi_find_resource(ctx, (unsigned char *)"XObject", n, (pdf_dict *)stream_dict, page_dict, &o);
2836
282k
    if (code < 0)
2837
103k
        goto exit;
2838
2839
178k
    if (pdfi_type_of(o) != PDF_STREAM && pdfi_type_of(o) != PDF_DICT) {
2840
8.30k
        code = gs_note_error(gs_error_typecheck);
2841
8.30k
        goto exit;
2842
8.30k
    }
2843
2844
    /* This doesn't count up the stream dictionary, so we don't need to count it down later */
2845
170k
    code = pdfi_dict_from_obj(ctx, o, &sdict);
2846
170k
    if (code < 0)
2847
0
        goto exit;
2848
2849
170k
    code = pdfi_dict_known(ctx, sdict, "Parent", &known);
2850
170k
    if (code < 0)
2851
0
        goto exit;
2852
    /* Add a Parent ref, unless it happens to be a circular reference
2853
     * (sample Bug298226.pdf -- has a circular ref and adding the Parent caused memory leak)
2854
     */
2855
170k
    if (!known && sdict->object_num != stream_dict->object_num) {
2856
170k
        code = pdfi_dict_put(ctx, sdict, "Parent", (pdf_obj *)stream_dict);
2857
170k
        if (code < 0)
2858
0
            goto exit;
2859
170k
        pdfi_countup(sdict);
2860
170k
        AddedParent = true;
2861
170k
    }
2862
2863
170k
    (void)pdfi_loop_detector_cleartomark(ctx);
2864
    /* We used to have a pdfi_gsave/pdfi_grestore around this, this is actually done
2865
     * for us within the functions that pdfi_do_image_or_form calls now. */
2866
170k
    code = pdfi_do_image_or_form(ctx, stream_dict, page_dict, o);
2867
170k
    pdfi_countdown(n);
2868
170k
    pdfi_countdown(o);
2869
170k
    if (AddedParent == true) {
2870
170k
        if (code >= 0)
2871
167k
            code = pdfi_dict_delete(ctx, sdict, "Parent");
2872
2.13k
        else
2873
2.13k
            (void)pdfi_dict_delete(ctx, sdict, "Parent");
2874
170k
        pdfi_countdown(sdict);
2875
170k
    }
2876
170k
    return code;
2877
2878
111k
exit:
2879
111k
    (void)pdfi_loop_detector_cleartomark(ctx);
2880
116k
exit1:
2881
116k
    pdfi_countdown(n);
2882
116k
    pdfi_countdown(o);
2883
116k
    return code;
2884
111k
}