Coverage Report

Created: 2026-04-01 07:17

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