Coverage Report

Created: 2025-11-16 07:40

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