Coverage Report

Created: 2025-06-24 07:01

/src/ghostpdl/pdf/pdf_image.c
Line
Count
Source (jump to first uncovered line)
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
242k
{
51
242k
    if (ctx->text.BlockDepth != 0)
52
328
        pdfi_set_warning(ctx, 0, NULL, W_PDF_OPINVALIDINTEXT, "pdfi_BI", NULL);
53
54
242k
    return pdfi_mark_stack(ctx, PDF_DICT_MARK);
55
242k
}
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.14M
{
102
1.14M
    if (info->Mask)
103
750
        pdfi_countdown(info->Mask);
104
1.14M
    if (info->SMask)
105
50.2k
        pdfi_countdown(info->SMask);
106
1.14M
    if (info->ColorSpace)
107
150k
        pdfi_countdown(info->ColorSpace);
108
1.14M
    if (info->Intent)
109
11.1k
        pdfi_countdown(info->Intent);
110
1.14M
    if (info->Alternates)
111
0
        pdfi_countdown(info->Alternates);
112
1.14M
    if (info->Name)
113
25.3k
        pdfi_countdown(info->Name);
114
1.14M
    if (info->Decode)
115
214k
        pdfi_countdown(info->Decode);
116
1.14M
    if (info->OC)
117
64
        pdfi_countdown(info->OC);
118
1.14M
    if (info->Filter)
119
155k
        pdfi_countdown(info->Filter);
120
1.14M
    if (info->DecodeParms)
121
41.1k
        pdfi_countdown(info->DecodeParms);
122
1.14M
    memset(info, 0, sizeof(*info));
123
1.14M
}
124
125
126
static inline uint64_t
127
pdfi_get_image_data_size(gs_data_image_t *pim, int comps)
128
356k
{
129
356k
    int size;
130
356k
    int64_t H, W, B;
131
132
356k
    H = pim->Height;
133
356k
    W = pim->Width;
134
356k
    B = pim->BitsPerComponent;
135
136
356k
    size = (((W * comps * B) + 7) / 8) * H;
137
356k
    return size;
138
356k
}
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
150k
#define READ32BE(i) (((i)[0] << 24) | ((i)[1] << 16) | ((i)[2] << 8) | (i)[3])
203
11.9k
#define READ16BE(i) (((i)[0] << 8) | (i)[1])
204
66.7k
#define K4(a, b, c, d) ((a << 24) + (b << 16) + (c << 8) + d)
205
35.8k
#define LEN_IHDR 14
206
15.2k
#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
69.4k
{
212
69.4k
    int code;
213
69.4k
    byte blob[4];
214
215
69.4k
    if (length < 8)
216
2
        return_error(gs_error_limitcheck);
217
69.4k
    code = pdfi_read_bytes(ctx, blob, 1, 4, source);
218
69.4k
    if (code < 0)
219
0
        return code;
220
69.4k
    *box_len = READ32BE(blob);
221
69.4k
    if (*box_len < 8)
222
17
        return_error(gs_error_limitcheck);
223
69.4k
    code = pdfi_read_bytes(ctx, blob, 1, 4, source);
224
69.4k
    if (code < 0)
225
0
        return code;
226
69.4k
    *box_val = READ32BE(blob);
227
228
69.4k
    if(ctx->args.pdfdebug)
229
69.4k
        dbgmprintf3(ctx->memory, "JPXFilter: BOX: l:%d, v:%x (%4.4s)\n", *box_len, *box_val, blob);
230
69.4k
    return 8;
231
69.4k
}
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
15.2k
{
237
15.2k
    uint32_t box_len = 0;
238
15.2k
    uint32_t box_val = 0;
239
15.2k
    int code;
240
15.2k
    byte ihdr_data[LEN_IHDR];
241
15.2k
    byte *data = NULL;
242
15.2k
    int data_buf_len = 0;
243
15.2k
    int avail = length;
244
15.2k
    int bpc = 0;
245
15.2k
    int comps = 0;
246
15.2k
    int cs_meth = 0;
247
15.2k
    uint32_t cs_enum = 0;
248
15.2k
    bool got_color = false;
249
250
15.2k
    if (ctx->args.pdfdebug)
251
15.2k
        dbgmprintf1(ctx->memory, "JPXFilter: Image length %d\n", length);
252
253
    /* Clear out the info param */
254
15.2k
    memset(info, 0, sizeof(pdfi_jpx_info_t));
255
256
15.2k
    info->no_data = false;
257
258
    /* Allocate a data buffer that hopefully is big enough */
259
15.2k
    data_buf_len = LEN_DATA;
260
15.2k
    data = gs_alloc_bytes(ctx->memory, data_buf_len, "pdfi_scan_jpxfilter (data)");
261
15.2k
    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
46.2k
    while (avail > 0) {
268
45.5k
        code = get_box(ctx, source, avail, &box_len, &box_val);
269
45.5k
        if (code < 0)
270
12
            goto exit;
271
45.5k
        avail -= 8;
272
45.5k
        box_len -= 8;
273
45.5k
        if (box_len <= 0 || box_len > avail) {
274
2.61k
            code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, E_PDF_INVALID_JPX_HDR, "pdfi_scan_jpxfilter", NULL);
275
2.61k
            goto exit;
276
2.61k
        }
277
42.9k
        if (box_val == K4('j','p','2','h')) {
278
11.9k
            break;
279
11.9k
        }
280
30.9k
        pdfi_seek(ctx, source, box_len, SEEK_CUR);
281
30.9k
        avail -= box_len;
282
30.9k
    }
283
12.6k
    if (avail <= 0) {
284
713
        info->no_data = true;
285
713
        code = gs_note_error(gs_error_ioerror);
286
713
        goto exit;
287
713
    }
288
289
    /* Now we are only looking inside the jp2h box */
290
11.9k
    avail = box_len;
291
292
    /* The first thing in the 'jp2h' box is an 'ihdr', get that */
293
11.9k
    code = get_box(ctx, source, avail, &box_len, &box_val);
294
11.9k
    if (code < 0)
295
0
        goto exit;
296
11.9k
    avail -= 8;
297
11.9k
    box_len -= 8;
298
11.9k
    if (box_val != K4('i','h','d','r')) {
299
0
        code = gs_note_error(gs_error_syntaxerror);
300
0
        goto exit;
301
0
    }
302
11.9k
    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
11.9k
    code = pdfi_read_bytes(ctx, ihdr_data, 1, LEN_IHDR, source);
309
11.9k
    if (code < 0)
310
0
        goto exit;
311
11.9k
    avail -= LEN_IHDR;
312
11.9k
    comps = READ16BE(ihdr_data+8);
313
11.9k
    if (ctx->args.pdfdebug)
314
11.9k
        dbgmprintf1(ctx->memory, "    COMPS: %d\n", comps);
315
11.9k
    bpc = ihdr_data[10];
316
11.9k
    if (bpc != 255)
317
11.9k
        bpc += 1;
318
11.9k
    if (ctx->args.pdfdebug)
319
11.9k
        dbgmprintf1(ctx->memory, "    BPC: %d\n", bpc);
320
321
    /* Parse the rest of the things */
322
23.9k
    while (avail > 0) {
323
11.9k
        code = get_box(ctx, source, avail, &box_len, &box_val);
324
11.9k
        if (code < 0)
325
7
            goto exit;
326
11.9k
        avail -= 8;
327
11.9k
        box_len -= 8;
328
11.9k
        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
11.9k
        if (box_len > data_buf_len) {
334
8
            if (ctx->args.pdfdebug)
335
8
                dbgmprintf2(ctx->memory, "data buffer (size %d) was too small, reallocing to size %d\n",
336
8
                      data_buf_len, box_len);
337
8
            gs_free_object(ctx->memory, data, "pdfi_scan_jpxfilter (data)");
338
8
            data_buf_len = box_len;
339
8
            data = gs_alloc_bytes(ctx->memory, data_buf_len, "pdfi_scan_jpxfilter (data)");
340
8
            if (!data) {
341
3
                code = gs_note_error(gs_error_VMerror);
342
3
                goto exit;
343
3
            }
344
8
        }
345
11.9k
        code = pdfi_read_bytes(ctx, data, 1, box_len, source);
346
11.9k
        if (code < 0)
347
0
            goto exit;
348
11.9k
        avail -= box_len;
349
11.9k
        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
11.9k
        case K4('c','o','l','r'):
370
11.9k
            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
11.9k
            cs_meth = data[0];
376
11.9k
            if (cs_meth == 1)
377
11.9k
                cs_enum = READ32BE(data+3);
378
1
            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
1
            } else {
395
1
                if (ctx->args.pdfdebug)
396
1
                    dbgmprintf1(ctx->memory, "JPXDecode: COLR unexpected method %d\n", cs_meth);
397
1
                cs_enum = 0;
398
1
            }
399
11.9k
            if (ctx->args.pdfdebug)
400
11.9k
                dbgmprintf2(ctx->memory, "    COLR: M:%d, ENUM:%d\n", cs_meth, cs_enum);
401
11.9k
            got_color = true;
402
11.9k
            break;
403
5
        case K4('p','c','l','r'):
404
            /* Apparently we just grab the BPC out of this */
405
5
            if (ctx->args.pdfdebug)
406
5
                dbgmprintf7(ctx->memory, "    PCLR Data: %x %x %x %x %x %x %x\n",
407
5
                      data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
408
5
            bpc = data[3];
409
5
            bpc = (bpc & 0x7) + 1;
410
5
            if (ctx->args.pdfdebug)
411
5
                dbgmprintf1(ctx->memory, "    PCLR BPC: %d\n", bpc);
412
5
            break;
413
0
        case K4('c','d','e','f'):
414
0
            dbgmprintf(ctx->memory, "JPXDecode: CDEF not supported yet\n");
415
0
            break;
416
10
        default:
417
10
            break;
418
11.9k
        }
419
420
11.9k
    }
421
422
11.9k
    info->comps = comps;
423
11.9k
    info->bpc = bpc;
424
11.9k
    info->cs_enum = cs_enum;
425
11.9k
    info->is_valid = true;
426
427
15.2k
 exit:
428
15.2k
    if (data)
429
15.2k
        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
15.2k
    return 0;
436
11.9k
}
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
383k
{
444
383k
    int code;
445
383k
    double temp_f;
446
383k
    pdf_dict *image_dict = NULL;
447
448
383k
    memset(info, 0, sizeof(*info));
449
383k
    info->page_dict = page_dict;
450
383k
    info->stream_dict = stream_dict;
451
383k
    info->inline_image = inline_image;
452
453
    /* Not Handled: "ID", "OPI" */
454
455
    /* Length if it's in a stream dict */
456
383k
    info->Length = pdfi_stream_length(ctx, image_obj);
457
458
383k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)image_obj, &image_dict);
459
383k
    if (code < 0)
460
0
        goto errorExit;
461
462
    /* Required */
463
383k
    code = pdfi_dict_get_number2(ctx, image_dict, "Height", "H", &temp_f);
464
383k
    if (code < 0)
465
1.18k
        goto errorExit;
466
    /* This is bonkers, but... Bug695872.pdf has /W and /H which are real numbers */
467
382k
    info->Height = (int)temp_f;
468
382k
    if ((int)temp_f != (int)(temp_f+.5)) {
469
56
        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
56
    }
472
382k
    if (info->Height < 0) {
473
58
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
474
0
            goto errorExit;
475
58
        info->Height = 0;
476
58
    }
477
478
    /* Required */
479
382k
    code = pdfi_dict_get_number2(ctx, image_dict, "Width", "W", &temp_f);
480
382k
    if (code < 0)
481
595
        goto errorExit;
482
381k
    info->Width = (int)temp_f;
483
381k
    if ((int)temp_f != (int)(temp_f+.5)) {
484
18
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
485
0
            goto errorExit;
486
18
    }
487
381k
    if (info->Width < 0) {
488
16
        if ((code = pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
489
0
            goto errorExit;
490
16
        info->Width = 0;
491
16
    }
492
493
    /* Optional, default false */
494
381k
    code = pdfi_dict_get_bool2(ctx, image_dict, "ImageMask", "IM", &info->ImageMask);
495
381k
    if (code != 0) {
496
158k
        if (code != gs_error_undefined)
497
0
            goto errorExit;
498
158k
        info->ImageMask = false;
499
158k
    }
500
501
    /* Optional, default false */
502
381k
    code = pdfi_dict_get_bool2(ctx, image_dict, "Interpolate", "I", &info->Interpolate);
503
381k
    if (code != 0) {
504
312k
        if (code != gs_error_undefined)
505
2
            goto errorExit;
506
312k
        info->Interpolate = false;
507
312k
    }
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
381k
    code = pdfi_dict_get_int2(ctx, image_dict, "BitsPerComponent", "BPC", &info->BPC);
514
381k
    if (code < 0) {
515
5.90k
        if (code != gs_error_undefined) {
516
7
            goto errorExit;
517
7
        }
518
5.89k
        info->BPC = 1;
519
5.89k
    }
520
375k
    else if (info->BPC != 1 && info->BPC != 2 && info->BPC != 4 && info->BPC != 8 && info->BPC != 16) {
521
228
        code = gs_note_error(gs_error_rangecheck);
522
228
        goto errorExit;
523
228
    }
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
381k
    code = pdfi_dict_get(ctx, image_dict, "Mask", &info->Mask);
530
381k
    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
380k
        if (code != gs_error_undefined) {
537
75
           if ((code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_BAD_IMAGEDICT, "pdfi_get_image_info", NULL)) < 0)
538
0
               goto errorExit;
539
75
        }
540
380k
    }
541
381k
    if (info->Mask != NULL && (pdfi_type_of(info->Mask) != PDF_ARRAY && pdfi_type_of(info->Mask) != PDF_STREAM)) {
542
4
        pdfi_countdown(info->Mask);
543
4
        info->Mask = NULL;
544
4
        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
4
    }
547
548
    /* Optional (apparently there is no abbreviation for "SMask"? */
549
381k
    code = pdfi_dict_get(ctx, image_dict, "SMask", &info->SMask);
550
381k
    if (code < 0) {
551
330k
        if (code != gs_error_undefined) {
552
            /* Broken SMask, Warn, and ignore the SMask */
553
5.99k
            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
5.99k
        }
556
330k
    } else {
557
50.4k
        if (pdfi_type_of(info->SMask) == PDF_NAME) {
558
6
            pdf_obj *o = NULL;
559
560
6
            code = pdfi_find_resource(ctx, (unsigned char *)"ExtGState", (pdf_name *)info->SMask, image_dict, page_dict, &o);
561
6
            if (code >= 0) {
562
0
                pdfi_countdown(info->SMask);
563
0
                info->SMask = o;
564
0
            }
565
6
        }
566
567
50.4k
        if (pdfi_type_of(info->SMask) != PDF_STREAM){
568
160
            pdfi_countdown(info->SMask);
569
160
            info->SMask = NULL;
570
160
            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
160
        }
573
50.4k
    }
574
575
    /* Optional, for JPXDecode filter images
576
     * (If non-zero, then SMask shouldn't be  specified)
577
     * Default: 0
578
     */
579
381k
    code = pdfi_dict_get_int(ctx, image_dict, "SMaskInData", &info->SMaskInData);
580
381k
    if (code < 0) {
581
381k
        if (code != gs_error_undefined)
582
0
            goto errorExit;
583
381k
        info->SMaskInData = 0;
584
381k
    }
585
586
    /* Optional (Required except for ImageMask, not allowed for ImageMask)*/
587
    /* TODO: Should we enforce this required/not allowed thing? */
588
381k
    code = pdfi_dict_get2(ctx, image_dict, "ColorSpace", "CS", &info->ColorSpace);
589
381k
    if (code < 0) {
590
229k
        if (code != gs_error_undefined)
591
110
            goto errorExit;
592
229k
    }
593
381k
    if (info->ColorSpace != NULL && (pdfi_type_of(info->ColorSpace) != PDF_NAME && pdfi_type_of(info->ColorSpace) != PDF_ARRAY)) {
594
120
        pdfi_countdown(info->ColorSpace);
595
120
        info->ColorSpace = NULL;
596
120
        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
120
    }
599
600
    /* Optional (default is to use from graphics state) */
601
    /* (no abbreviation for inline) */
602
381k
    code = pdfi_dict_get_type(ctx, image_dict, "Intent", PDF_NAME, (pdf_obj **)&info->Intent);
603
381k
    if (code < 0) {
604
370k
        if (code != gs_error_undefined)
605
0
            goto errorExit;
606
370k
    }
607
608
    /* Optional (array of alternate image dicts, can't be nested) */
609
381k
    code = pdfi_dict_get(ctx, image_dict, "Alternates", &info->Alternates);
610
381k
    if (code < 0) {
611
381k
        if (code != gs_error_undefined)
612
0
            goto errorExit;
613
381k
    }
614
381k
    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
381k
    code = pdfi_dict_get(ctx, image_dict, "Name", &info->Name);
623
381k
    if (code < 0) {
624
355k
        if (code != gs_error_undefined)
625
0
            goto errorExit;
626
355k
    }
627
381k
    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
381k
    code = pdfi_dict_get_int(ctx, image_dict, "StructParent", &info->StructParent);
637
381k
    if (code < 0) {
638
381k
        if (code != gs_error_undefined)
639
0
            goto errorExit;
640
381k
    }
641
642
    /* Optional (default is probably [0,1] per component) */
643
381k
    code = pdfi_dict_get2(ctx, image_dict, "Decode", "D", &info->Decode);
644
381k
    if (code < 0) {
645
166k
        if (code != gs_error_undefined)
646
0
            goto errorExit;
647
166k
    }
648
381k
    if (info->Decode != NULL && pdfi_type_of(info->Decode) != PDF_ARRAY) {
649
218
        pdfi_countdown(info->Decode);
650
218
        info->Decode = NULL;
651
218
        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
218
    }
654
655
    /* Optional "Optional Content" */
656
381k
    code = pdfi_dict_get_type(ctx, image_dict, "OC", PDF_DICT, (pdf_obj **)&info->OC);
657
381k
    if (code < 0) {
658
381k
        if (code != gs_error_undefined)
659
0
            goto errorExit;
660
381k
    }
661
662
    /* Optional */
663
381k
    code = pdfi_dict_get2(ctx, image_dict, "Filter", "F", &info->Filter);
664
381k
    if (code < 0) {
665
225k
        if (code != gs_error_undefined)
666
0
            goto errorExit;
667
225k
    }
668
381k
    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
381k
    info->is_JPXDecode = false;
677
381k
    if (info->Filter && pdfi_type_of(info->Filter) == PDF_NAME) {
678
142k
        if (pdfi_name_is((pdf_name *)info->Filter, "JPXDecode"))
679
12.0k
            info->is_JPXDecode = true;
680
142k
    }
681
682
    /* Optional */
683
381k
    code = pdfi_dict_get2(ctx, image_dict, "DecodeParms", "DP", &info->DecodeParms);
684
381k
    if (code < 0) {
685
340k
        if (code != gs_error_undefined)
686
8
            goto errorExit;
687
340k
    }
688
381k
    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
0
        if (pdfi_type_of(info->DecodeParms) != PDF_NULL) {
691
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)
692
0
                goto errorExit;
693
0
        }
694
0
        pdfi_countdown(info->DecodeParms);
695
0
        info->DecodeParms = NULL;
696
0
    }
697
698
381k
    return 0;
699
700
2.13k
 errorExit:
701
2.13k
    pdfi_free_image_info_components(info);
702
2.13k
    return code;
703
381k
}
704
705
static int pdfi_check_inline_image_keys(pdf_context *ctx, pdf_dict *image_dict)
706
154k
{
707
154k
    bool known = false;
708
709
154k
    pdfi_dict_known(ctx, image_dict, "BPC", &known);
710
154k
    if (known)
711
0
        goto error_inline_check;
712
154k
    pdfi_dict_known(ctx, image_dict, "CS", &known);
713
154k
    if (known)
714
0
        goto error_inline_check;
715
154k
    pdfi_dict_known(ctx, image_dict, "D", &known);
716
154k
    if (known)
717
0
        goto error_inline_check;
718
154k
    pdfi_dict_known(ctx, image_dict, "DP", &known);
719
154k
    if (known)
720
0
        goto error_inline_check;
721
154k
    pdfi_dict_known(ctx, image_dict, "F", &known);
722
154k
    if (known)
723
0
        goto error_inline_check;
724
154k
    pdfi_dict_known(ctx, image_dict, "H", &known);
725
154k
    if (known)
726
0
        goto error_inline_check;
727
154k
    pdfi_dict_known(ctx, image_dict, "IM", &known);
728
154k
    if (known)
729
0
        goto error_inline_check;
730
154k
    pdfi_dict_known(ctx, image_dict, "I", &known);
731
154k
    if (known)
732
0
        goto error_inline_check;
733
154k
    pdfi_dict_known(ctx, image_dict, "W", &known);
734
154k
    if (known)
735
1
        goto error_inline_check;
736
737
154k
    return 0;
738
739
1
error_inline_check:
740
1
    return pdfi_set_warning_stop(ctx, gs_note_error(gs_error_syntaxerror), NULL, W_PDF_BAD_INLINEIMAGEKEY, "pdfi_check_inline_image_keys", NULL);
741
154k
}
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
356k
{
751
356k
    int code;
752
356k
    gs_image_enum *penum = NULL;
753
356k
    uint64_t bytes_left;
754
356k
    uint64_t bytes_used = 0;
755
356k
    uint64_t bytes_avail = 0;
756
356k
    gs_const_string plane_data[GS_IMAGE_MAX_COMPONENTS];
757
356k
    int main_plane=0, mask_plane=0;
758
356k
    bool no_progress = false;
759
356k
    int min_left;
760
761
#if DEBUG_IMAGES
762
    dbgmprintf(ctx->memory, "pdfi_render_image BEGIN\n");
763
#endif
764
765
356k
    code = pdfi_gsave(ctx);
766
356k
    if (code < 0)
767
0
        return code;
768
769
    /* Disable overprint mode for images that are not a mask */
770
356k
    if (!ImageMask)
771
134k
        gs_setoverprintmode(ctx->pgs, 0);
772
773
356k
    penum = gs_image_enum_alloc(ctx->memory, "pdfi_render_image (gs_image_enum_alloc)");
774
356k
    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
356k
    {
783
356k
        gx_image_enum_common_t *pie;
784
785
356k
        if (!ImageMask) {
786
            /* TODO: Can in_cachedevice ever be set in PDF? */
787
134k
            if (ctx->pgs->in_cachedevice != CACHE_DEVICE_NONE) {
788
0
                code = gs_note_error(gs_error_undefined);
789
0
                goto cleanupExit;
790
0
            }
791
134k
        }
792
793
356k
        code = gs_image_begin_typed((const gs_image_common_t *)pim, ctx->pgs, ImageMask, false, &pie);
794
356k
        if (code < 0)
795
214
            goto cleanupExit;
796
797
356k
        code = gs_image_enum_init(penum, pie, (const gs_data_image_t *)pim, ctx->pgs);
798
356k
        if (code < 0)
799
0
            goto cleanupExit;
800
356k
    }
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
356k
    if (mask_buffer) {
808
3.49k
        main_plane = 1;
809
3.49k
        mask_plane = 0;
810
3.49k
        plane_data[mask_plane].data = mask_buffer;
811
3.49k
        plane_data[mask_plane].size = mask_size;
812
353k
    } else {
813
353k
        main_plane = 0;
814
353k
    }
815
816
356k
    bytes_left = pdfi_get_image_data_size((gs_data_image_t *)pim, comps);
817
14.5M
    while (bytes_left > 0) {
818
14.2M
        uint used[GS_IMAGE_MAX_COMPONENTS];
819
820
28.1M
        while ((bytes_avail = sbufavailable(image_stream->s)) <= (min_left = sbuf_min_left(image_stream->s))) {
821
14.0M
            switch (image_stream->s->end_status) {
822
13.9M
            case 0:
823
13.9M
                s_process_read_buf(image_stream->s);
824
13.9M
                continue;
825
7.32k
            case EOFC:
826
7.32k
            case INTC:
827
7.32k
            case CALLC:
828
7.32k
                break;
829
28.0k
            default:
830
                /* case ERRC: */
831
28.0k
                code = gs_note_error(gs_error_ioerror);
832
28.0k
                goto cleanupExit;
833
14.0M
            }
834
7.32k
            break;   /* for EOFC */
835
14.0M
        }
836
837
        /*
838
         * Note that in the EOF case, we can get here with no data
839
         * available.
840
         */
841
14.1M
        if (bytes_avail >= min_left)
842
14.1M
            bytes_avail = (bytes_avail - min_left); /* may be 0 */
843
844
14.1M
        plane_data[main_plane].data = sbufptr(image_stream->s);
845
14.1M
        plane_data[main_plane].size = bytes_avail;
846
847
14.1M
        code = gs_image_next_planes(penum, plane_data, used, false);
848
14.1M
        if (code < 0) {
849
48
            goto cleanupExit;
850
48
        }
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.1M
        if (used[main_plane] == 0 && used[mask_plane] == 0) {
855
7.94k
            if (no_progress) {
856
3.97k
                code = gs_note_error(gs_error_unknownerror);
857
3.97k
                goto cleanupExit;
858
3.97k
            }
859
3.97k
            no_progress = true;
860
14.1M
        } else {
861
14.1M
            no_progress = false;
862
14.1M
        }
863
864
14.1M
        (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.1M
        bytes_used = used[main_plane];
875
14.1M
        bytes_left -= bytes_used;
876
14.1M
        bytes_avail -= bytes_used;
877
14.1M
    }
878
879
324k
    code = 0;
880
881
356k
 cleanupExit:
882
356k
    if (penum)
883
356k
        gs_image_cleanup_and_free_enum(penum, ctx->pgs);
884
356k
    pdfi_grestore(ctx);
885
#if DEBUG_IMAGES
886
    dbgmprintf(ctx->memory, "pdfi_render_image END\n");
887
#endif
888
356k
    return code;
889
324k
}
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
362k
{
896
362k
    int code;
897
898
362k
    pim->BitsPerComponent = info->BPC;
899
362k
    pim->Width = info->Width;
900
362k
    pim->Height = info->Height;
901
362k
    pim->ImageMatrix.xx = (float)info->Width;
902
362k
    pim->ImageMatrix.yy = (float)(info->Height * -1);
903
362k
    pim->ImageMatrix.ty = (float)info->Height;
904
905
362k
    pim->Interpolate = info->Interpolate;
906
907
    /* Get the decode array (required for ImageMask, probably for everything) */
908
362k
    if (info->Decode) {
909
214k
        pdf_array *decode_array = (pdf_array *)info->Decode;
910
214k
        int i;
911
214k
        double num;
912
913
214k
        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
645k
        for (i=0; i<pdfi_array_size(decode_array); i++) {
919
431k
            code = pdfi_array_get_number(ctx, decode_array, i, &num);
920
431k
            if (code < 0)
921
9
                goto cleanupExit;
922
430k
            pim->Decode[i] = (float)num;
923
430k
        }
924
214k
    } else {
925
        /* Provide a default if not specified [0 1 ...] per component */
926
148k
        int i;
927
148k
        float minval, maxval;
928
929
        /* TODO: Is there a less hacky way to identify Indexed case? */
930
148k
        if (pcs && (pcs->type == &gs_color_space_type_Indexed ||
931
134k
                    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
11.5k
            minval = 0.0;
934
11.5k
            maxval = (float)((1 << info->BPC) - 1);
935
136k
        } else {
936
136k
            bool islab = false;
937
938
136k
            if (pcs && pcs->cmm_icc_profile_data != NULL)
939
123k
                islab = pcs->cmm_icc_profile_data->islab;
940
941
136k
            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
136k
            } else {
950
136k
                minval = 0.0;
951
136k
                maxval = 1.0;
952
136k
            }
953
136k
        }
954
442k
        for (i=0; i<comps*2; i+=2) {
955
294k
            pim->Decode[i] = minval;
956
294k
            pim->Decode[i+1] = maxval;
957
294k
        }
958
148k
    }
959
362k
    code = 0;
960
961
362k
 cleanupExit:
962
362k
    return code;
963
362k
}
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
45.9k
{
969
45.9k
    int i;
970
45.9k
    pdf_array *Matte = NULL;
971
45.9k
    int code;
972
45.9k
    double f;
973
45.9k
    pdf_dict *smask_dict = NULL;
974
975
45.9k
    *has_Matte = false;
976
45.9k
    code = pdfi_dict_from_obj(ctx, smask_obj, &smask_dict);
977
45.9k
    if (code < 0)
978
0
        goto exit;
979
980
45.9k
    code = pdfi_dict_knownget_type(ctx, smask_dict, "Matte",
981
45.9k
                                   PDF_ARRAY, (pdf_obj **)&Matte);
982
45.9k
    if (code <= 0)
983
45.9k
        goto exit;
984
985
52
    *has_Matte = true;
986
52
    if (pdfi_array_size(Matte) > size) {
987
0
        code = gs_note_error(gs_error_rangecheck);
988
0
        goto exit;
989
0
    }
990
991
208
    for (i = 0; i < pdfi_array_size(Matte); i++) {
992
156
        code = pdfi_array_get_number(ctx, Matte, (uint64_t)i, &f);
993
156
        if (code < 0)
994
0
            goto exit;
995
156
        vals[i] = (float)f;
996
156
    }
997
52
    if (i == pdfi_array_size(Matte))
998
52
        code = i;
999
1000
45.9k
 exit:
1001
45.9k
    pdfi_countdown(Matte);
1002
45.9k
    return code;
1003
52
}
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
42.8k
{
1009
42.8k
    gs_rect bbox = { { 0, 0} , { 1, 1} };
1010
42.8k
    gs_transparency_mask_params_t params;
1011
42.8k
    gs_offset_t savedoffset = 0;
1012
42.8k
    int code, code1;
1013
42.8k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
1014
42.8k
    pdf_stream *stream_obj = NULL;
1015
42.8k
    gs_rect clip_box;
1016
42.8k
    int empty = 0;
1017
1018
#if DEBUG_IMAGES
1019
    dbgmprintf(ctx->memory, "pdfi_do_image_smask BEGIN\n");
1020
#endif
1021
1022
42.8k
    code = pdfi_loop_detector_mark(ctx);
1023
42.8k
    if (code < 0)
1024
0
        return code;
1025
1026
42.8k
    if (pdfi_type_of(image_info->SMask) != PDF_STREAM)
1027
0
        return_error(gs_error_typecheck);
1028
1029
42.8k
    if (image_info->SMask->object_num != 0) {
1030
42.8k
        if (pdfi_loop_detector_check_object(ctx, image_info->SMask->object_num))
1031
0
            return gs_note_error(gs_error_circular_reference);
1032
42.8k
        code = pdfi_loop_detector_add_object(ctx, image_info->SMask->object_num);
1033
42.8k
        if (code < 0)
1034
0
            goto exit;
1035
42.8k
    }
1036
1037
42.8k
    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
42.8k
    code = gs_gsave(ctx->pgs);
1045
42.8k
    if (code < 0)
1046
0
        goto exit;
1047
1048
42.8k
    if (gs_clip_bounds_in_user_space(ctx->pgs, &clip_box) >= 0)
1049
42.7k
    {
1050
42.7k
        rect_intersect(bbox, clip_box);
1051
42.7k
        if (bbox.p.x >= bbox.q.x || bbox.p.y >= bbox.q.y)
1052
1.11k
        {
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.11k
            empty = 1;
1057
1.11k
        }
1058
42.7k
    }
1059
1060
42.8k
    code = pdfi_image_get_matte(ctx, image_info->SMask, params.Matte, GS_CLIENT_COLOR_MAX_COMPONENTS, has_Matte);
1061
1062
42.8k
    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
42.8k
    if (code >= 0)
1068
42.8k
        params.Matte_components = code;
1069
1070
42.8k
    code = gs_begin_transparency_mask(ctx->pgs, &params, &bbox, true);
1071
42.8k
    if (code < 0)
1072
0
        goto exitSaved;
1073
42.8k
    if (empty)
1074
1.11k
        goto exitMasked;
1075
41.7k
    savedoffset = pdfi_tell(ctx->main_stream);
1076
41.7k
    code = pdfi_gsave(ctx);
1077
41.7k
    if (code < 0)
1078
0
        goto exitMasked;
1079
1080
    /* Disable SMask for inner image */
1081
41.7k
    pdfi_gstate_smask_free(igs);
1082
1083
41.7k
    gs_setstrokeconstantalpha(ctx->pgs, 1.0);
1084
41.7k
    gs_setfillconstantalpha(ctx->pgs, 1.0);
1085
41.7k
    gs_setblendmode(ctx->pgs, BLEND_MODE_Compatible);
1086
1087
41.7k
    pdfi_seek(ctx, ctx->main_stream,
1088
41.7k
              pdfi_stream_offset(ctx, (pdf_stream *)image_info->SMask), SEEK_SET);
1089
1090
41.7k
    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
41.7k
        case PDF_STREAM:
1101
41.7k
            code = pdfi_do_image_or_form(ctx, image_info->stream_dict,
1102
41.7k
                                         image_info->page_dict, image_info->SMask);
1103
41.7k
            break;
1104
0
        default:
1105
0
            code = gs_note_error(gs_error_typecheck);
1106
0
            goto exitSavedTwice;
1107
41.7k
    }
1108
1109
41.7k
exitSavedTwice:
1110
41.7k
    pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
1111
1112
41.7k
    code1 = pdfi_grestore(ctx);
1113
41.7k
    if (code < 0)
1114
0
        code = code1;
1115
42.8k
exitMasked:
1116
42.8k
    code1 = gs_end_transparency_mask(ctx->pgs, TRANSPARENCY_CHANNEL_Opacity);
1117
42.8k
    if (code < 0)
1118
0
        code = code1;
1119
42.8k
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
42.8k
    {
1123
        /* Stash the flag that means 'Pop the SMask'. */
1124
42.8k
        int flag = ctx->pgs->trans_flags.xstate_change;
1125
        /* Clear the flag so the SMask will live. */
1126
42.8k
        ctx->pgs->trans_flags.xstate_change = 0;
1127
42.8k
        code1 = gs_grestore(ctx->pgs);
1128
42.8k
        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
42.8k
        ctx->pgs->trans_flags.xstate_change = flag;
1135
42.8k
    }
1136
1137
42.8k
 exit:
1138
#if DEBUG_IMAGES
1139
    dbgmprintf(ctx->memory, "pdfi_do_image_smask END\n");
1140
#endif
1141
42.8k
    pdfi_loop_detector_cleartomark(ctx);
1142
42.8k
    return code;
1143
42.8k
}
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
7.09k
{
1150
7.09k
    int code;
1151
7.09k
    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
7.09k
    code = pdfi_gsave(ctx);
1160
7.09k
    if (code < 0)
1161
0
        return code;
1162
1163
7.09k
    code = gs_newpath(ctx->pgs);
1164
7.09k
    if (code < 0)
1165
0
        goto exit;
1166
7.09k
    code = gs_moveto(ctx->pgs, 1.0, 1.0);
1167
7.09k
    if (code < 0)
1168
0
        goto exit;
1169
7.09k
    code = gs_lineto(ctx->pgs, 0., 0.);
1170
7.09k
    if (code < 0)
1171
0
        goto exit;
1172
1173
7.09k
    code = pdfi_get_current_bbox(ctx, &bbox, false);
1174
7.09k
    if (code < 0)
1175
412
        goto exit;
1176
1177
6.68k
    pdfi_grestore(ctx);
1178
1179
6.68k
    code = pdfi_trans_setup(ctx, state, &bbox, TRANSPARENCY_Caller_Image);
1180
7.09k
 exit:
1181
7.09k
    return code;
1182
6.68k
}
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
181
{
1193
181
    int i;
1194
181
    double num;
1195
181
    int code = 0;
1196
181
    int bpc = image_info->BPC;
1197
181
    uint mask = (1 << bpc) - 1;
1198
181
    uint maxval = mask;
1199
181
    int64_t intval;
1200
181
    bool had_range_error = false;
1201
181
    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
181
    bool indexed_case = (pcs && pcs->type == &gs_color_space_type_Indexed && bpc == 1);
1206
1207
181
    memset(t4image, 0, sizeof(gs_image4_t));
1208
181
    gs_image4_t_init(t4image, NULL);
1209
1210
181
    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.18k
    for (i=0; i<pdfi_array_size(mask_array); i++) {
1216
1.00k
        code = pdfi_array_get_int(ctx, mask_array, i, &intval);
1217
1.00k
        if (code == gs_error_typecheck) {
1218
7
            code = pdfi_array_get_number(ctx, mask_array, i, &num);
1219
7
            if (code == 0) {
1220
0
                intval = (int64_t)(num + 0.5);
1221
0
                had_float_error = true;
1222
0
            }
1223
7
        }
1224
1.00k
        if (code < 0)
1225
7
            goto exit;
1226
1.00k
        if (intval > maxval) {
1227
12
            had_range_error = true;
1228
12
            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
12
            } else {
1238
12
                if (bpc != 1) {
1239
                    /* If not special handling, just mask it off to be in range */
1240
12
                    intval &= mask;
1241
12
                }
1242
12
            }
1243
12
        }
1244
1.00k
        t4image->MaskColor[i] = intval;
1245
1.00k
    }
1246
174
    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
174
    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
174
    code = 0;
1262
1263
181
 exit:
1264
181
    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
181
    if (had_range_error) {
1268
12
        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
12
    }
1270
181
    return code;
1271
174
}
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
3.13k
{
1279
3.13k
    int code = 0;
1280
3.13k
    gs_image3x_mask_t *mask;
1281
1282
3.13k
    memset(t3ximage, 0, sizeof(*t3ximage));
1283
3.13k
    gs_image3x_t_init(t3ximage, NULL);
1284
3.13k
    if (gs_getalphaisshape(ctx->pgs))
1285
0
        mask = &t3ximage->Shape;
1286
3.13k
    else
1287
3.13k
        mask = &t3ximage->Opacity;
1288
3.13k
    mask->InterleaveType = 3;
1289
1290
3.13k
    code = pdfi_image_get_matte(ctx, image_info->SMask, mask->Matte, GS_CLIENT_COLOR_MAX_COMPONENTS, &mask->has_Matte);
1291
3.13k
    if (code < 0)
1292
0
        return code;
1293
1294
3.13k
    code = pdfi_data_image_params(ctx, smask_info, &mask->MaskDict, comps, NULL);
1295
3.13k
    return code;
1296
3.13k
}
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
366k
{
1380
366k
    int code = 0;
1381
366k
    pdfi_jpx_info_t *jpx_info = &image_info->jpx_info;
1382
366k
    pdf_obj *ColorSpace = NULL;
1383
366k
    char *backup_color_name = NULL;
1384
366k
    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
366k
    if (image_info->ImageMask) {
1391
222k
        if (image_info->ColorSpace == NULL) {
1392
221k
                *comps = 1;
1393
221k
                *pcs = NULL;
1394
221k
                if (image_info->Mask) {
1395
0
                    pdfi_countdown(image_info->Mask);
1396
0
                    image_info->Mask = NULL;
1397
0
                }
1398
221k
                return 0;
1399
221k
        } else {
1400
1.16k
            if (image_info->BPC != 1 || image_info->Mask != NULL) {
1401
27
                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
27
                image_info->ImageMask = 0;
1405
27
            }
1406
1.13k
            else {
1407
1.13k
                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.13k
                pdfi_countdown(image_info->ColorSpace);
1411
1.13k
                image_info->ColorSpace = NULL;
1412
1.13k
                *comps = 1;
1413
1.13k
                *pcs = NULL;
1414
1.13k
                return 0;
1415
1.13k
            }
1416
1.16k
        }
1417
222k
    }
1418
1419
144k
    ColorSpace = image_info->ColorSpace;
1420
144k
    if (ColorSpace)
1421
136k
        pdfi_countup(ColorSpace);
1422
144k
    if (ColorSpace == NULL) {
1423
8.18k
        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
8.16k
            if (jpx_info->bpc == 12) {
1430
0
                jpx_info->bpc = 16;
1431
0
            }
1432
8.16k
            image_info->BPC = jpx_info->bpc;
1433
1434
8.16k
            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
8.16k
            } else {
1449
8.16k
                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
8.16k
                backup_color_name = (char *)"DeviceRGB";
1455
8.16k
                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
954
                case 16:
1472
954
                    color_str = (char *)"sRGBICC";
1473
954
                    break;
1474
3.94k
                case 17:
1475
3.94k
                    color_str = (char *)"sGrayICC";
1476
3.94k
                    backup_color_name = (char *)"DeviceGray";
1477
3.94k
                    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
3.25k
                default:
1489
3.25k
                    {
1490
3.25k
                        char extra_info[gp_file_name_sizeof];
1491
                        /* TODO: Could try DeviceRGB instead of erroring out? */
1492
3.25k
                        gs_snprintf(extra_info, sizeof(extra_info), "**** Error: JPXDecode: Unsupported EnumCS %d\n", jpx_info->cs_enum);
1493
3.25k
                        pdfi_set_error(ctx, 0, NULL, E_PDF_IMAGECOLOR_ERROR, "pdfi_image_get_color", extra_info);
1494
3.25k
                        code = gs_note_error(gs_error_rangecheck);
1495
3.25k
                        goto cleanupExit;
1496
0
                    }
1497
8.16k
                }
1498
1499
                /* Make a ColorSpace for the name */
1500
4.90k
                if (color_str != NULL) {
1501
4.90k
                    code = pdfi_name_alloc(ctx, (byte *)color_str, strlen(color_str), &ColorSpace);
1502
4.90k
                    if (code < 0)
1503
0
                        goto cleanupExit;
1504
4.90k
                    pdfi_countup(ColorSpace);
1505
4.90k
                    using_enum_cs = true;
1506
4.90k
                }
1507
4.90k
            }
1508
8.16k
        } else {
1509
            /* Assume DeviceRGB colorspace */
1510
21
            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
21
            code = pdfi_name_alloc(ctx, (byte *)"DeviceRGB", strlen("DeviceRGB"), &ColorSpace);
1513
21
            if (code < 0)
1514
0
                goto cleanupExit;
1515
21
            pdfi_countup(ColorSpace);
1516
21
        }
1517
136k
    } else {
1518
        /* Override BPC from JPXDecode if applicable
1519
         * Sample: tests_private/comparefiles/Bug695387.pdf
1520
         */
1521
136k
        if (image_info->is_JPXDecode && jpx_info->is_valid)
1522
7.03k
            image_info->BPC = jpx_info->bpc;
1523
136k
    }
1524
1525
    /* At this point ColorSpace is either a string we just made, or the one from the Image */
1526
141k
    code = pdfi_create_colorspace(ctx, ColorSpace,
1527
141k
                                  image_info->stream_dict, image_info->page_dict,
1528
141k
                                  pcs, image_info->inline_image);
1529
141k
    if (code < 0) {
1530
4.19k
        dbgprintf("WARNING: Image has unsupported ColorSpace ");
1531
4.19k
        if (pdfi_type_of(ColorSpace) == PDF_NAME) {
1532
641
            pdf_name *name = (pdf_name *)ColorSpace;
1533
641
            char str[100];
1534
641
            int length = name->length;
1535
1536
641
            if (length > 0) {
1537
630
                if (length > 99)
1538
9
                    length = 99;
1539
1540
630
                memcpy(str, (const char *)name->data, length);
1541
630
                str[length] = '\0';
1542
630
                dbgprintf1("NAME:%s\n", str);
1543
630
            }
1544
3.54k
        } else {
1545
3.54k
            dbgmprintf(ctx->memory, "(not a name)\n");
1546
3.54k
        }
1547
1548
        /* If we were trying an enum_cs, attempt to use backup_color_name instead */
1549
4.19k
        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
4.19k
        } else {
1565
4.19k
            pdfi_set_error(ctx, 0, NULL, E_PDF_IMAGECOLOR_ERROR, "pdfi_image_get_color", NULL);
1566
4.19k
            goto cleanupExit;
1567
4.19k
        }
1568
4.19k
    }
1569
137k
    *comps = gs_color_space_num_components(*pcs);
1570
1571
144k
 cleanupExit:
1572
144k
    pdfi_countdown(ColorSpace);
1573
144k
    return code;
1574
137k
}
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
379k
{
1685
379k
    pdf_c_stream *new_stream = NULL, *SFD_stream = NULL;
1686
379k
    int code = 0, code1 = 0;
1687
379k
    int comps = 0;
1688
379k
    gs_color_space  *pcs = NULL;
1689
379k
    gs_image1_t t1image;
1690
379k
    gs_image4_t t4image;
1691
379k
    gs_image3_t t3image;
1692
379k
    gs_image3x_t t3ximage;
1693
379k
    gs_pixel_image_t *pim = NULL;
1694
379k
    pdf_stream *alt_stream = NULL;
1695
379k
    pdfi_image_info_t image_info, mask_info, smask_info;
1696
379k
    pdf_stream *mask_stream = NULL;
1697
379k
    pdf_stream *smask_stream = NULL; /* only non-null for imagetype 3x (PreserveSMask) */
1698
379k
    pdf_array *mask_array = NULL;
1699
379k
    unsigned char *mask_buffer = NULL;
1700
379k
    uint64_t mask_size = 0;
1701
379k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
1702
379k
    bool transparency_group = false;
1703
379k
    bool need_smask_cleanup = false;
1704
379k
    bool maybe_jpxdecode = false;
1705
379k
    pdfi_trans_state_t trans_state;
1706
379k
    gs_offset_t stream_offset;
1707
379k
    int trans_required;
1708
1709
#if DEBUG_IMAGES
1710
    dbgmprintf(ctx->memory, "pdfi_do_image BEGIN\n");
1711
#endif
1712
379k
    memset(&mask_info, 0, sizeof(mask_info));
1713
379k
    memset(&smask_info, 0, sizeof(mask_info));
1714
1715
    /* Make sure the image is a stream (which we will assume in later code) */
1716
379k
    if (pdfi_type_of(image_stream) != PDF_STREAM)
1717
0
        return_error(gs_error_typecheck);
1718
1719
379k
    if (!inline_image) {
1720
154k
        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
154k
        code = pdfi_dict_from_obj(ctx, (pdf_obj *)image_stream, &image_dict);
1727
154k
        if (code < 0)
1728
0
            return code;
1729
1730
154k
        code = pdfi_check_inline_image_keys(ctx, image_dict);
1731
154k
        if (code < 0)
1732
0
            return code;
1733
154k
    }
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
379k
    code = pdfi_op_q(ctx);
1742
379k
    if (code < 0)
1743
0
        return code;
1744
1745
379k
    code = pdfi_get_image_info(ctx, image_stream, page_dict, stream_dict, inline_image, &image_info);
1746
379k
    if (code < 0)
1747
2.05k
        goto cleanupExit;
1748
1749
    /* Don't render this if turned off */
1750
377k
    if (pdfi_oc_is_off(ctx))
1751
10.8k
        goto cleanupExit;
1752
    /* If there is an OC dictionary, see if we even need to render this */
1753
366k
    if (image_info.OC) {
1754
64
        if (!(ctx->device_state.writepdfmarks && ctx->device_state.WantsOptionalContent)) {
1755
64
            if (!pdfi_oc_is_ocg_visible(ctx, image_info.OC))
1756
0
                goto cleanupExit;
1757
64
        }
1758
64
    }
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
366k
    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
366k
    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
366k
    if (image_info.ColorSpace == NULL && !image_info.ImageMask)
1783
8.18k
        maybe_jpxdecode = true;
1784
1785
    /* Handle JPXDecode filter pre-scan of header */
1786
366k
    if ((maybe_jpxdecode || image_info.is_JPXDecode) && !inline_image) {
1787
15.2k
        pdfi_seek(ctx, source, stream_offset, SEEK_SET);
1788
15.2k
        code = pdfi_scan_jpxfilter(ctx, source, image_info.Length, &image_info.jpx_info);
1789
15.2k
        if (code < 0 && image_info.is_JPXDecode)
1790
0
            goto cleanupExit;
1791
1792
        /* I saw this JPXDecode images that have SMaskInData */
1793
15.2k
        if (image_info.jpx_info.no_data)
1794
713
            image_info.is_JPXDecode = false;
1795
1796
15.2k
        if (code == 0 && maybe_jpxdecode)
1797
8.16k
            image_info.is_JPXDecode = true;
1798
15.2k
    }
1799
1800
    /* Set the rendering intent if applicable */
1801
366k
    if (image_info.Intent) {
1802
11.1k
        code = pdfi_setrenderingintent(ctx, image_info.Intent);
1803
11.1k
        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
11.1k
    }
1811
1812
    /* Get the color for this image */
1813
366k
    code = pdfi_image_get_color(ctx, source, &image_info, &comps, image_stream->object_num, &pcs);
1814
366k
    if (code < 0)
1815
7.44k
        goto cleanupExit;
1816
1817
359k
    if (image_info.BPC != 1 && image_info.BPC != 2 && image_info.BPC != 4 && image_info.BPC != 8 && image_info.BPC != 16) {
1818
4
        code = gs_note_error(gs_error_rangecheck);
1819
4
        goto cleanupExit;
1820
4
    }
1821
1822
    /* Set the colorspace */
1823
359k
    if (pcs) {
1824
137k
        gs_color_space  *pcs1 = pcs;
1825
1826
137k
        code = pdfi_gs_setcolorspace(ctx, pcs);
1827
137k
        if (code < 0)
1828
0
            goto cleanupExit;
1829
1830
137k
        if (pcs->type->index == gs_color_space_index_Indexed)
1831
12.7k
            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
137k
        if (pcs1->type->index == gs_color_space_index_ICC)
1846
136k
        {
1847
136k
            gs_client_color         cc;
1848
136k
            int comp = 0;
1849
136k
            pdf_obj *ColorSpace = NULL;
1850
1851
136k
            cc.pattern = 0;
1852
440k
            for (comp = 0; comp < pcs1->cmm_icc_profile_data->num_comps;comp++)
1853
303k
                cc.paint.values[comp] = 0;
1854
1855
136k
            code = gs_setcolor(ctx->pgs, &cc);
1856
136k
            if (code < 0)
1857
0
                goto cleanupExit;
1858
1859
136k
            code = gx_set_dev_color(ctx->pgs);
1860
136k
            if (code < 0) {
1861
2.84k
                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
2.84k
                switch(pcs1->cmm_icc_profile_data->num_comps) {
1866
477
                    case 1:
1867
477
                        code = pdfi_name_alloc(ctx, (byte *)"DeviceGray", 10, &ColorSpace);
1868
477
                        if (code < 0)
1869
0
                            goto cleanupExit;
1870
477
                        pdfi_countup(ColorSpace);
1871
477
                        break;
1872
2.36k
                    case 3:
1873
2.36k
                        code = pdfi_name_alloc(ctx, (byte *)"DeviceRGB", 9, &ColorSpace);
1874
2.36k
                        if (code < 0)
1875
0
                            goto cleanupExit;
1876
2.36k
                        pdfi_countup(ColorSpace);
1877
2.36k
                        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
2.84k
                }
1889
2.84k
                if (pcs != NULL)
1890
2.84k
                    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
2.84k
                code = pdfi_create_colorspace(ctx, ColorSpace,
1893
2.84k
                                  image_info.stream_dict, image_info.page_dict,
1894
2.84k
                                  &pcs, image_info.inline_image);
1895
2.84k
                pdfi_countdown(ColorSpace);
1896
2.84k
                if (code < 0)
1897
0
                    goto cleanupExit;
1898
1899
2.84k
                code = pdfi_gs_setcolorspace(ctx, pcs);
1900
2.84k
                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
2.84k
                code = gx_set_dev_color(ctx->pgs);
1907
2.84k
                if (code < 0)
1908
56
                    goto cleanupExit;
1909
2.84k
            }
1910
136k
        }
1911
137k
    }
1912
222k
    else {
1913
222k
        if (image_info.ImageMask == 0) {
1914
0
            code = gs_note_error(gs_error_undefined);
1915
0
            goto cleanupExit;
1916
0
        }
1917
222k
    }
1918
1919
    /* Make a fake SMask dict if needed for JPXDecode */
1920
359k
    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
359k
    if (ctx->page.has_transparency == true && image_info.SMask != NULL) {
1927
45.9k
        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
45.9k
        if (!ctx->device_state.preserve_smask) {
1933
42.8k
            code = pdfi_do_image_smask(ctx, source, &image_info, &has_Matte);
1934
42.8k
            if (code < 0)
1935
0
                goto cleanupExit;
1936
42.8k
            need_smask_cleanup = true;
1937
42.8k
        }
1938
1939
        /* If we are in an overprint situation this group will need
1940
           to have its blend mode set to compatible overprint. */
1941
45.9k
        if (ctx->page.needs_OP) {
1942
5.57k
            if (pdfi_trans_okOPcs(ctx)) {
1943
36
                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
36
            }
1949
5.57k
        }
1950
1951
45.9k
        if (has_Matte)
1952
51
            code = pdfi_trans_begin_isolated_group(ctx, true, pcs);
1953
45.8k
        else
1954
45.8k
            code = pdfi_trans_begin_isolated_group(ctx, true, NULL);
1955
45.9k
        if (code < 0)
1956
0
            goto cleanupExit;
1957
45.9k
        transparency_group = true;
1958
313k
    } 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
359k
    if (transparency_group && !ctx->device_state.preserve_smask) {
1966
42.8k
        gs_setstrokeconstantalpha(ctx->pgs, 1.0);
1967
42.8k
        gs_setfillconstantalpha(ctx->pgs, 1.0);
1968
42.8k
    }
1969
1970
    /* Get the Mask data either as an array or a dict, if present */
1971
359k
    if (image_info.Mask != NULL) {
1972
746
        switch (pdfi_type_of(image_info.Mask)) {
1973
181
            case PDF_ARRAY:
1974
181
                mask_array = (pdf_array *)image_info.Mask;
1975
181
                break;
1976
565
            case PDF_STREAM:
1977
565
                mask_stream = (pdf_stream *)image_info.Mask;
1978
565
                code = pdfi_get_image_info(ctx, mask_stream, page_dict,
1979
565
                                           stream_dict, inline_image, &mask_info);
1980
565
                if (code < 0)
1981
78
                    goto cleanupExit;
1982
487
                break;
1983
487
            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
746
        }
1989
746
    }
1990
1991
    /* Get the SMask info if we will need it (Type 3x images) */
1992
359k
    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
3.13k
        smask_stream = (pdf_stream *)image_info.SMask;
1995
3.13k
        code = pdfi_get_image_info(ctx, smask_stream, page_dict, stream_dict,
1996
3.13k
                                   inline_image, &smask_info);
1997
3.13k
        if (code < 0)
1998
0
            goto cleanupExit;
1999
3.13k
    }
2000
2001
    /* Get the image into a supported gs type (type1, type3, type4, type3x) */
2002
359k
    if (!image_info.Mask && !smask_stream) { /* Type 1 and ImageMask */
2003
355k
        memset(&t1image, 0, sizeof(t1image));
2004
355k
        pim = (gs_pixel_image_t *)&t1image;
2005
2006
355k
        if (image_info.ImageMask) {
2007
            /* Sets up timage.ImageMask, amongst other things */
2008
222k
            gs_image_t_init_adjust(&t1image, NULL, false);
2009
222k
        } else {
2010
133k
            gs_image_t_init_adjust(&t1image, pcs, true);
2011
133k
        }
2012
355k
    } 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
3.13k
        mask_stream = NULL;
2017
3.13k
        code = pdfi_image_setup_type3x(ctx, &image_info, &t3ximage, &smask_info, comps);
2018
3.13k
        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
3.13k
        } else {
2030
3.13k
            pim = (gs_pixel_image_t *)&t3ximage;
2031
3.13k
        }
2032
3.13k
    } else {
2033
668
        if (mask_array) { /* Type 4 */
2034
181
            code = pdfi_image_setup_type4(ctx, &image_info, &t4image, mask_array, pcs);
2035
181
            if (code < 0) {
2036
7
                 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
7
                memset(&t1image, 0, sizeof(t1image));
2041
7
                pim = (gs_pixel_image_t *)&t1image;
2042
7
                gs_image_t_init_adjust(&t1image, pcs, true);
2043
174
            } else {
2044
174
                pim = (gs_pixel_image_t *)&t4image;
2045
174
            }
2046
487
        } else { /* Type 3 */
2047
487
            memset(&t3image, 0, sizeof(t3image));
2048
487
            pim = (gs_pixel_image_t *)&t3image;
2049
487
            gs_image3_t_init(&t3image, NULL, interleave_separate_source);
2050
487
            code = pdfi_data_image_params(ctx, &mask_info, &t3image.MaskDict, 1, NULL);
2051
487
            if (code < 0)
2052
0
                goto cleanupExit;
2053
487
        }
2054
668
    }
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
359k
    pim->ColorSpace = pcs;
2065
359k
    code = pdfi_data_image_params(ctx, &image_info, (gs_data_image_t *)pim, comps, pcs);
2066
359k
    if (code < 0)
2067
9
        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
359k
    if (smask_stream) {
2074
3.13k
        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
3.13k
        code = pdfi_stream_to_buffer(ctx, smask_stream, &mask_buffer, (int64_t *)&mask_size);
2077
3.13k
        if (code < 0)
2078
64
            goto cleanupExit;
2079
355k
    } else if (mask_stream) {
2080
        /* Calculate expected mask size */
2081
487
        mask_size = ((((t3image.MaskDict.BitsPerComponent * (int64_t)t3image.MaskDict.Width) + 7) / 8) * (int64_t)t3image.MaskDict.Height);
2082
487
        code = pdfi_stream_to_buffer(ctx, mask_stream, &mask_buffer, (int64_t *)&mask_size);
2083
487
        if (code < 0)
2084
16
            goto cleanupExit;
2085
487
    }
2086
    /* Setup the data stream for the image data */
2087
358k
    if (!inline_image) {
2088
134k
        pdfi_seek(ctx, source, stream_offset, SEEK_SET);
2089
2090
134k
        code = pdfi_apply_SubFileDecode_filter(ctx, 0, "endstream", source, &SFD_stream, false);
2091
134k
        if (code < 0)
2092
0
            goto cleanupExit;
2093
134k
        source = SFD_stream;
2094
134k
    }
2095
2096
358k
    code = pdfi_filter(ctx, image_stream, source, &new_stream, inline_image);
2097
358k
    if (code < 0)
2098
1.85k
        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
357k
    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
357k
    trans_required = pdfi_trans_required(ctx);
2166
2167
357k
    if (trans_required) {
2168
7.09k
        code = pdfi_image_setup_trans(ctx, &trans_state);
2169
7.09k
        if (code < 0)
2170
412
            goto cleanupExit;
2171
7.09k
    }
2172
2173
    /* Render the image */
2174
356k
    code = pdfi_render_image(ctx, pim, new_stream,
2175
356k
                             mask_buffer, mask_size,
2176
356k
                             comps, image_info.ImageMask);
2177
356k
    if (code < 0) {
2178
32.2k
        if (ctx->args.pdfdebug)
2179
0
            outprintf(ctx->memory, "WARNING: pdfi_do_image: error %d from pdfi_render_image\n", code);
2180
32.2k
    }
2181
2182
356k
    if (trans_required) {
2183
6.68k
        code1 = pdfi_trans_teardown(ctx, &trans_state);
2184
6.68k
        if (code == 0)
2185
854
            code = code1;
2186
6.68k
    }
2187
2188
379k
 cleanupExit:
2189
379k
    if (code < 0)
2190
44.2k
        code = pdfi_set_warning_stop(ctx, code, NULL, W_PDF_IMAGE_ERROR, "pdfi_do_image", NULL);
2191
2192
379k
 cleanupExitError:
2193
379k
    if (transparency_group) {
2194
45.9k
        pdfi_trans_end_isolated_group(ctx);
2195
45.9k
        if (need_smask_cleanup)
2196
42.8k
            pdfi_trans_end_smask_notify(ctx);
2197
45.9k
    }
2198
2199
    /* See note above on the pdfi_op_q call. This does a grestore, and
2200
     * pops the transparency state. */
2201
379k
    (void)pdfi_op_Q(ctx);
2202
2203
379k
    if (new_stream)
2204
357k
        pdfi_close_file(ctx, new_stream);
2205
379k
    if (SFD_stream)
2206
134k
        pdfi_close_file(ctx, SFD_stream);
2207
379k
    if (mask_buffer)
2208
3.54k
        gs_free_object(ctx->memory, mask_buffer, "pdfi_do_image (mask_buffer)");
2209
2210
379k
    pdfi_countdown(alt_stream);
2211
2212
379k
    pdfi_free_image_info_components(&image_info);
2213
379k
    pdfi_free_image_info_components(&mask_info);
2214
379k
    pdfi_free_image_info_components(&smask_info);
2215
2216
379k
    if (pcs != NULL)
2217
137k
        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
379k
    return code;
2223
379k
}
2224
2225
int pdfi_ID(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict, pdf_c_stream *source)
2226
242k
{
2227
242k
    pdf_dict *d = NULL;
2228
242k
    int code;
2229
242k
    pdf_stream *image_stream;
2230
2231
242k
    if (ctx->text.BlockDepth != 0) {
2232
420
        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
420
    }
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
242k
    code = pdfi_dict_from_stack(ctx, 0, 0, false);
2242
242k
    if (code < 0)
2243
        /* pdfi_dict_from_stack cleans up the stack so we don't need to in case of an error */
2244
17.8k
        return code;
2245
2246
225k
    d = (pdf_dict *)ctx->stack_top[-1];
2247
225k
    pdfi_countup(d);
2248
225k
    pdfi_pop(ctx, 1);
2249
2250
225k
    code = pdfi_obj_dict_to_stream(ctx, d, &image_stream, true);
2251
225k
    if (code < 0)
2252
0
        goto error;
2253
2254
225k
    code = pdfi_do_image(ctx, page_dict, stream_dict, image_stream, source, true);
2255
225k
error:
2256
225k
    pdfi_countdown(image_stream);
2257
225k
    pdfi_countdown(d);
2258
225k
    return code;
2259
225k
}
2260
2261
int pdfi_EI(pdf_context *ctx)
2262
237k
{
2263
237k
    if (ctx->text.BlockDepth != 0) {
2264
316
        return pdfi_set_warning_stop(ctx, gs_note_error(gs_error_rangecheck), NULL, W_PDF_OPINVALIDINTEXT, "pdfi_EI", NULL);
2265
316
    }
2266
2267
/*    pdfi_clearstack(ctx);*/
2268
237k
    return 0;
2269
237k
}
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
17.0k
{
2275
17.0k
    int code;
2276
17.0k
    pdfi_int_gstate *igs = (pdfi_int_gstate *)ctx->pgs->client_data;
2277
2278
17.0k
    code = pdfi_gsave(ctx);
2279
17.0k
    if (code < 0)
2280
0
        goto exit;
2281
2282
17.0k
    if (GroupGState) {
2283
2.62k
        code = pdfi_gs_setgstate(ctx->pgs, GroupGState);
2284
2.62k
        if (code < 0)
2285
0
            goto exit2;
2286
2.62k
    }
2287
2288
    /* Override the colorspace if specified */
2289
17.0k
    if (pcs) {
2290
14.4k
        code = pdfi_gs_setcolorspace(ctx, pcs);
2291
14.4k
        if (code < 0)
2292
0
            goto exit2;
2293
14.4k
        code = gs_setcolor(ctx->pgs, (const gs_client_color *)pcc);
2294
14.4k
        if (code < 0)
2295
0
            goto exit2;
2296
14.4k
    }
2297
2298
    /* Disable the SMask */
2299
17.0k
    pdfi_gstate_smask_free(igs);
2300
2301
17.0k
    gs_setblendmode(ctx->pgs, BLEND_MODE_Compatible);
2302
17.0k
    gs_setstrokeconstantalpha(ctx->pgs, 1.0);
2303
17.0k
    gs_setfillconstantalpha(ctx->pgs, 1.0);
2304
2305
17.0k
    if (matrix)
2306
2.62k
        code = gs_concat(ctx->pgs, matrix);
2307
17.0k
    if (code < 0) {
2308
0
        goto exit2;
2309
0
    }
2310
17.0k
    code = pdfi_run_context(ctx, xobject_obj, page_dict, false, "FORM");
2311
2312
17.0k
 exit2:
2313
17.0k
    if (code != 0)
2314
0
        (void)pdfi_grestore(ctx);
2315
17.0k
    else
2316
17.0k
        code = pdfi_grestore(ctx);
2317
17.0k
 exit:
2318
17.0k
    return code;
2319
17.0k
}
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
140
{
2325
140
    int code = 0;
2326
140
    gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2327
140
    gs_form_template_t template;
2328
140
    gs_point ll, ur;
2329
140
    gs_fixed_rect box;
2330
2331
140
    memset(&template, 0, sizeof(template));
2332
2333
140
    template.CTM = *CTM; /* (structure copy) */
2334
140
    template.BBox = *BBox; /* (structure copy) */
2335
140
    template.form_matrix = *form_matrix; /* (structure copy) */
2336
140
    template.FormID = -1;
2337
140
    template.pcpath = ctx->pgs->clip_path;
2338
140
    template.pgs = ctx->pgs;
2339
2340
140
    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
140
    if (code > 0)
2346
0
    {
2347
0
        gs_setmatrix(ctx->pgs, &template.CTM);
2348
0
        gs_distance_transform(template.BBox.p.x, template.BBox.p.y, &template.CTM, &ll);
2349
0
        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
0
        box.p.x = float2fixed(ll.x);
2364
0
        box.p.y = float2fixed(ll.y);
2365
0
        box.q.x = float2fixed(ur.x);
2366
0
        box.q.y = float2fixed(ur.y);
2367
2368
0
        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
0
        } else {
2372
0
            if (fabs(ur.x) > fabs(ll.x))
2373
0
                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
0
        }
2379
0
        if (box.p.y < 0) {
2380
0
            if(box.p.y * -1 > box.q.y)
2381
0
                box.q.y = box.p.y * -1;
2382
0
        } else {
2383
0
            if (fabs(ur.y) > fabs(ll.y))
2384
0
                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
0
        }
2390
        /* This gets undone when we grestore after the form is executed */
2391
0
        code = gx_clip_to_rectangle(ctx->pgs, &box);
2392
0
    }
2393
2394
140
    return code;
2395
140
}
2396
2397
/* See zendform() */
2398
static int pdfi_form_highlevel_end(pdf_context *ctx)
2399
140
{
2400
140
    int code = 0;
2401
140
    gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2402
2403
140
    code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_form_end, 0, 0);
2404
140
    return code;
2405
140
}
2406
2407
/* See bug #702560. The original file has a Form XObject which is not a stream. Instead
2408
 * the Form XObject has a /Contents key which points to a stream dictionary. This is plainly
2409
 * illegal but, as always, Acrobat can open it....
2410
 * If PDFSTOPONERROR is true then we just exit. Otherwise we look for a /Contents key in the stream
2411
 * dictionary. If we find one we dereference the object to get a stream dictionary, then merge the
2412
 * two dictionaries, ensuring the stream offset is correct, and proceed as if that's what we'd
2413
 * always had. If we don't have a /Contents key then exit with a typecheck error.
2414
 *
2415
 * Sets *hacked_stream to the /Contents stream if it found one.
2416
 */
2417
static int pdfi_form_stream_hack(pdf_context *ctx, pdf_dict *form_dict, pdf_stream **hacked_stream)
2418
1.84k
{
2419
1.84k
    int code = 0;
2420
1.84k
    pdf_stream *stream_obj = NULL;
2421
1.84k
    pdf_obj *Parent = NULL;
2422
1.84k
    pdf_dict *d = NULL;
2423
1.84k
    pdf_dict *stream_dict = NULL;
2424
2425
1.84k
    *hacked_stream = NULL;
2426
2427
1.84k
    if (pdfi_type_of(form_dict) == PDF_STREAM)
2428
0
        return 0;
2429
2430
1.84k
    if ((code = pdfi_set_error_stop(ctx, gs_note_error(gs_error_typecheck), NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL)) < 0) {
2431
0
        goto exit;
2432
0
    }
2433
2434
1.84k
    code = pdfi_dict_knownget_type(ctx, form_dict, "Contents", PDF_STREAM,
2435
1.84k
                                   (pdf_obj **)&stream_obj);
2436
1.84k
    if (code < 0 || stream_obj == NULL) {
2437
1.82k
        pdfi_set_error(ctx, 0, NULL, E_PDF_BADSTREAMDICT, "pdfi_form_stream_hack", NULL);
2438
1.82k
        code = gs_note_error(gs_error_typecheck);
2439
1.82k
        goto exit;
2440
1.82k
    }
2441
2442
17
    d = form_dict;
2443
17
    pdfi_countup(d);
2444
30
    do {
2445
30
        code = pdfi_dict_knownget(ctx, d, "Parent", (pdf_obj **)&Parent);
2446
30
        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
17
        } else {
2457
17
            pdfi_countdown(d);
2458
17
            break;
2459
17
        }
2460
30
    } while (1);
2461
2462
17
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)stream_obj, &stream_dict);
2463
17
    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
17
    pdfi_set_warning(ctx, 0, NULL, W_PDF_STREAM_HAS_CONTENTS, "pdfi_form_stream_hack", NULL);
2468
17
    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
17
    pdfi_dict_delete(ctx, stream_dict, "Contents");
2475
2476
17
    if (code == 0) {
2477
17
        *hacked_stream = stream_obj;
2478
17
        pdfi_countup(stream_obj);
2479
17
    }
2480
2481
1.84k
 exit:
2482
1.84k
    pdfi_countdown(stream_obj);
2483
1.84k
    return code;
2484
17
}
2485
2486
static int pdfi_do_form(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *form_obj)
2487
211k
{
2488
211k
    int code, code1 = 0;
2489
211k
    bool group_known = false, known = false;
2490
211k
    bool do_group = false;
2491
211k
    pdf_array *FormMatrix = NULL;
2492
211k
    gs_matrix formmatrix, CTM;
2493
211k
    gs_rect bbox;
2494
211k
    pdf_array *BBox = NULL;
2495
211k
    bool save_PreservePDFForm;
2496
211k
    pdf_stream *form_stream = NULL; /* Alias */
2497
211k
    pdf_stream *hacked_stream = NULL;
2498
211k
    pdf_dict *form_dict;
2499
211k
    gs_color_space *pcs = NULL;
2500
211k
    gs_client_color cc, *pcc;
2501
2502
#if DEBUG_IMAGES
2503
    dbgmprintf(ctx->memory, "pdfi_do_form BEGIN\n");
2504
#endif
2505
211k
    if (pdfi_type_of(form_obj) != PDF_STREAM) {
2506
1.84k
        code = pdfi_form_stream_hack(ctx, (pdf_dict *)form_obj, &hacked_stream);
2507
1.84k
        if (code < 0)
2508
1.82k
            return code;
2509
17
        form_stream = hacked_stream;
2510
17
    } else
2511
209k
        form_stream = (pdf_stream *)form_obj;
2512
2513
209k
    code = pdfi_dict_from_obj(ctx, (pdf_obj *)form_stream, &form_dict);
2514
209k
    if (code < 0)
2515
0
        goto exit;
2516
2517
209k
    code = pdfi_dict_known(ctx, form_dict, "Group", &group_known);
2518
209k
    if (code < 0)
2519
0
        goto exit;
2520
209k
    if (group_known && ctx->page.has_transparency)
2521
15.5k
        do_group = true;
2522
2523
    /* Grab the CTM before it gets modified */
2524
209k
    code = gs_currentmatrix(ctx->pgs, &CTM);
2525
209k
    if (code < 0) goto exit1;
2526
2527
209k
    code = pdfi_op_q(ctx);
2528
209k
    if (code < 0) goto exit1;
2529
2530
209k
    code = pdfi_dict_knownget_type(ctx, form_dict, "Matrix", PDF_ARRAY, (pdf_obj **)&FormMatrix);
2531
209k
    if (code < 0) goto exit1;
2532
2533
209k
    code = pdfi_array_to_gs_matrix(ctx, FormMatrix, &formmatrix);
2534
209k
    if (code < 0) goto exit1;
2535
2536
209k
    code = pdfi_dict_known(ctx, form_dict, "BBox", &known);
2537
209k
    if (known) {
2538
205k
        code = pdfi_dict_get_type(ctx, form_dict, "BBox", PDF_ARRAY, (pdf_obj **)&BBox);
2539
205k
        if (code < 0) goto exit1;
2540
205k
    } else {
2541
3.20k
        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
3.20k
    }
2545
2546
209k
    code = pdfi_array_to_gs_rect(ctx, BBox, &bbox);
2547
209k
    if (code < 0) goto exit1;
2548
2549
208k
    if (bbox.q.x - bbox.p.x == 0.0 || bbox.q.y - bbox.p.y == 0.0) {
2550
355
        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
355
        if (ctx->PreservePDFForm) {
2554
0
            code = pdfi_form_highlevel_begin(ctx, form_dict, &CTM, &bbox, &formmatrix);
2555
0
            if (code >= 0)
2556
0
                code = pdfi_form_highlevel_end(ctx);
2557
0
        }
2558
355
        goto exit1;
2559
355
    }
2560
2561
208k
    code = gs_concat(ctx->pgs, &formmatrix);
2562
208k
    if (code < 0) goto exit1;
2563
2564
208k
    code = gs_rectclip(ctx->pgs, &bbox, 1);
2565
208k
    if (code < 0) goto exit1;
2566
2567
208k
    if (ctx->PreservePDFForm) {
2568
140
        code = pdfi_form_highlevel_begin(ctx, form_dict, &CTM, &bbox, &formmatrix);
2569
140
        if (code < 0) goto exit1;
2570
140
    }
2571
208k
    save_PreservePDFForm = ctx->PreservePDFForm;
2572
208k
    ctx->PreservePDFForm = false; /* Turn off in case there are any sub-forms */
2573
2574
208k
    if (do_group) {
2575
15.5k
        code = pdfi_loop_detector_mark(ctx);
2576
15.5k
        if (code < 0) goto exit1;
2577
2578
        /* Save the current color space in case it gets changed */
2579
15.5k
        pcs = gs_currentcolorspace(ctx->pgs);
2580
15.5k
        rc_increment(pcs);
2581
15.5k
        pcc = (gs_client_color *)gs_currentcolor(ctx->pgs);
2582
15.5k
        cc = *pcc;
2583
2584
15.5k
        code = pdfi_trans_begin_form_group(ctx, page_dict, form_dict);
2585
15.5k
        (void)pdfi_loop_detector_cleartomark(ctx);
2586
15.5k
        if (code < 0) goto exit1;
2587
2588
14.4k
        code = pdfi_form_execgroup(ctx, page_dict, form_stream, NULL, pcs, &cc, NULL);
2589
14.4k
        code1 = pdfi_trans_end_group(ctx);
2590
14.4k
        if (code == 0) code = code1;
2591
193k
    } else {
2592
193k
        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
193k
        ctx->encryption.decrypt_strings = false;
2600
193k
        code = pdfi_run_context(ctx, form_stream, page_dict, false, "FORM");
2601
193k
        ctx->encryption.decrypt_strings = saved_decrypt_strings;
2602
193k
    }
2603
2604
207k
    ctx->PreservePDFForm = save_PreservePDFForm;
2605
207k
    if (ctx->PreservePDFForm) {
2606
140
        code = pdfi_form_highlevel_end(ctx);
2607
140
    }
2608
2609
209k
 exit1:
2610
209k
    code1 = pdfi_op_Q(ctx);
2611
209k
    if (code == 0) code = code1;
2612
2613
209k
 exit:
2614
209k
    pdfi_countdown(FormMatrix);
2615
209k
    pdfi_countdown(BBox);
2616
209k
    pdfi_countdown(hacked_stream);
2617
209k
    if (pcs)
2618
15.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
209k
    if (code < 0)
2623
1.39k
        return code;
2624
207k
    return 0;
2625
209k
}
2626
2627
int pdfi_do_highlevel_form(pdf_context *ctx, pdf_dict *page_dict, pdf_stream *form_stream)
2628
140
{
2629
140
    int code = 0;
2630
2631
140
    ctx->PreservePDFForm = true;
2632
140
    code = pdfi_do_form(ctx, page_dict, form_stream);
2633
140
    ctx->PreservePDFForm = false;
2634
2635
140
    return code;
2636
140
}
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
366k
{
2641
366k
    int code;
2642
366k
    pdf_name *n = NULL;
2643
366k
    pdf_dict *xobject_dict;
2644
366k
    bool known = false;
2645
366k
    gs_offset_t savedoffset;
2646
2647
366k
    code = pdfi_dict_from_obj(ctx, xobject_obj, &xobject_dict);
2648
366k
    if (code < 0)
2649
0
        return code;
2650
2651
    /* Check Optional Content status */
2652
366k
    code = pdfi_dict_known(ctx, xobject_dict, "OC", &known);
2653
366k
    if (code < 0)
2654
0
        return code;
2655
2656
366k
    if (known) {
2657
893
        pdf_dict *OCDict = NULL;
2658
893
        bool visible = false;
2659
893
        gx_device *cdev = gs_currentdevice_inline(ctx->pgs);
2660
2661
893
        code = pdfi_dict_get(ctx, xobject_dict, "OC", (pdf_obj **)&OCDict);
2662
893
        if (code < 0)
2663
29
            return code;
2664
2665
864
        if (pdfi_type_of(OCDict) == PDF_DICT) {
2666
854
            char *label = NULL;
2667
2668
854
            if (ctx->device_state.writepdfmarks && ctx->device_state.WantsOptionalContent) {
2669
1
                code = pdfi_pdfmark_dict(ctx, OCDict);
2670
1
                if (code < 0) {
2671
0
                    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
0
                }
2676
1
                code = pdfi_obj_get_label(ctx, (pdf_obj *)OCDict, &label);
2677
1
                if (code >= 0) {
2678
1
                    code = dev_proc(cdev, dev_spec_op)(cdev, gxdso_pending_optional_content, label, 0);
2679
1
                    gs_free_object(ctx->memory, label, "");
2680
1
                    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
1
                } 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
853
            } else {
2693
853
                visible = pdfi_oc_is_ocg_visible(ctx, OCDict);
2694
853
                if (!visible) {
2695
52
                    pdfi_countdown(OCDict);
2696
52
                    return 0;
2697
52
                }
2698
853
            }
2699
854
        } else {
2700
10
            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
10
        }
2703
812
        pdfi_countdown(OCDict);
2704
812
    }
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
365k
    code = pdfi_trans_set_params(ctx);
2710
365k
    if (code < 0)
2711
76
        return code;
2712
2713
365k
    code = pdfi_dict_get(ctx, xobject_dict, "Subtype", (pdf_obj **)&n);
2714
365k
    if (code < 0) {
2715
5.10k
        if (code == gs_error_undefined) {
2716
5.10k
            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
5.10k
            code1 = pdfi_name_alloc(ctx, (byte *)"Form", 4, (pdf_obj **)&n);
2722
5.10k
            if (code1 == 0) {
2723
5.10k
                pdfi_countup(n);
2724
5.10k
            }
2725
5.10k
            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
5.10k
        }
2729
0
        else
2730
0
            goto exit;
2731
5.10k
    }
2732
365k
    if (pdfi_type_of(n) != PDF_NAME) {
2733
11
        code = gs_note_error(gs_error_typecheck);
2734
11
        goto exit;
2735
11
    }
2736
2737
365k
    if (pdfi_name_is(n, "Image")) {
2738
154k
try_as_image:
2739
154k
        if (pdfi_type_of(xobject_obj) != PDF_STREAM) {
2740
551
            code = gs_note_error(gs_error_typecheck);
2741
551
            goto exit;
2742
551
        }
2743
154k
        savedoffset = pdfi_tell(ctx->main_stream);
2744
154k
        code = pdfi_do_image(ctx, page_dict, stream_dict, (pdf_stream *)xobject_obj,
2745
154k
                             ctx->main_stream, false);
2746
154k
        pdfi_seek(ctx, ctx->main_stream, savedoffset, SEEK_SET);
2747
211k
    } 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
210k
        code = pdfi_do_form(ctx, page_dict, (pdf_stream *)xobject_obj);
2753
210k
    } 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.05k
    } else {
2756
1.05k
        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.05k
        if (code >= 0)
2758
1.05k
            goto try_as_image;
2759
1.05k
    }
2760
2761
365k
 exit:
2762
365k
    pdfi_countdown(n);
2763
#if DEBUG_IMAGES
2764
    dbgmprintf(ctx->memory, "pdfi_do_image_or_form END\n");
2765
#endif
2766
365k
    return code;
2767
365k
}
2768
2769
int pdfi_Do(pdf_context *ctx, pdf_dict *stream_dict, pdf_dict *page_dict)
2770
322k
{
2771
322k
    int code = 0;
2772
322k
    pdf_name *n = NULL;
2773
322k
    pdf_obj *o = NULL;
2774
322k
    pdf_dict *sdict = NULL;
2775
322k
    bool known = false, AddedParent = false;
2776
2777
322k
    if (pdfi_count_stack(ctx) < 1) {
2778
2.37k
        code = gs_note_error(gs_error_stackunderflow);
2779
2.37k
        goto exit1;
2780
2.37k
    }
2781
319k
    n = (pdf_name *)ctx->stack_top[-1];
2782
319k
    pdfi_countup(n);
2783
319k
    pdfi_pop(ctx, 1);
2784
2785
319k
    if (pdfi_type_of(n) != PDF_NAME) {
2786
2.18k
        code = gs_note_error(gs_error_typecheck);
2787
2.18k
        goto exit1;
2788
2.18k
    }
2789
2790
317k
    if (ctx->text.BlockDepth != 0) {
2791
7.76k
        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
7.76k
    }
2794
2795
317k
    code = pdfi_loop_detector_mark(ctx);
2796
317k
    if (code < 0)
2797
0
        goto exit1;
2798
317k
    code = pdfi_find_resource(ctx, (unsigned char *)"XObject", n, (pdf_dict *)stream_dict, page_dict, &o);
2799
317k
    if (code < 0)
2800
112k
        goto exit;
2801
2802
205k
    if (pdfi_type_of(o) != PDF_STREAM && pdfi_type_of(o) != PDF_DICT) {
2803
6.36k
        code = gs_note_error(gs_error_typecheck);
2804
6.36k
        goto exit;
2805
6.36k
    }
2806
2807
    /* This doesn't count up the stream dictionary, so we don't need to count it down later */
2808
198k
    code = pdfi_dict_from_obj(ctx, o, &sdict);
2809
198k
    if (code < 0)
2810
0
        goto exit;
2811
2812
198k
    code = pdfi_dict_known(ctx, sdict, "Parent", &known);
2813
198k
    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
198k
    if (!known && sdict->object_num != stream_dict->object_num) {
2819
198k
        code = pdfi_dict_put(ctx, sdict, "Parent", (pdf_obj *)stream_dict);
2820
198k
        if (code < 0)
2821
0
            goto exit;
2822
198k
        pdfi_countup(sdict);
2823
198k
        AddedParent = true;
2824
198k
    }
2825
2826
198k
    (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
198k
    code = pdfi_do_image_or_form(ctx, stream_dict, page_dict, o);
2830
198k
    pdfi_countdown(n);
2831
198k
    pdfi_countdown(o);
2832
198k
    if (AddedParent == true) {
2833
198k
        if (code >= 0)
2834
194k
            code = pdfi_dict_delete(ctx, sdict, "Parent");
2835
3.42k
        else
2836
3.42k
            (void)pdfi_dict_delete(ctx, sdict, "Parent");
2837
198k
        pdfi_countdown(sdict);
2838
198k
    }
2839
198k
    return code;
2840
2841
118k
exit:
2842
118k
    (void)pdfi_loop_detector_cleartomark(ctx);
2843
123k
exit1:
2844
123k
    pdfi_countdown(n);
2845
123k
    pdfi_countdown(o);
2846
123k
    return code;
2847
118k
}