Coverage Report

Created: 2026-09-14 07:34

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