Coverage Report

Created: 2022-10-31 07:00

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