Coverage Report

Created: 2026-04-09 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpdfi.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
/* Image handling for PDF-writing driver */
18
#include "memory_.h"
19
#include "math_.h"
20
#include "gx.h"
21
#include "gserrors.h"
22
#include "gsdevice.h"
23
#include "gsflip.h"
24
#include "gsstate.h"
25
#include "gscolor2.h"
26
#include "gdevpdfx.h"
27
#include "gdevpdfg.h"
28
#include "gdevpdfo.h"   /* for data stream */
29
#include "gxcspace.h"
30
#include "gximage3.h"
31
#include "gximag3x.h"
32
#include "gsiparm4.h"
33
#include "gxdcolor.h"
34
#include "gxpcolor.h"
35
#include "gxcolor2.h"
36
#include "gxhldevc.h"
37
#include "gxdevsop.h"
38
#include "gsicc_manage.h"
39
#include "gsform1.h"
40
#include "gxpath.h"
41
#include "gxcdevn.h"
42
43
extern_st(st_gs_gstate);
44
45
/* Forward references */
46
static image_enum_proc_plane_data(pdf_image_plane_data);
47
static image_enum_proc_end_image(pdf_image_end_image);
48
static image_enum_proc_end_image(pdf_image_end_image_object);
49
static image_enum_proc_end_image(pdf_image_end_image_object2);
50
static image_enum_proc_end_image(pdf_image_end_image_cvd);
51
static IMAGE3_MAKE_MID_PROC(pdf_image3_make_mid);
52
static IMAGE3_MAKE_MCDE_PROC(pdf_image3_make_mcde);
53
static IMAGE3X_MAKE_MID_PROC(pdf_image3x_make_mid);
54
static IMAGE3X_MAKE_MCDE_PROC(pdf_image3x_make_mcde);
55
56
static const gx_image_enum_procs_t pdf_image_enum_procs = {
57
    pdf_image_plane_data,
58
    pdf_image_end_image
59
};
60
static const gx_image_enum_procs_t pdf_image_object_enum_procs = {
61
    pdf_image_plane_data,
62
    pdf_image_end_image_object
63
};
64
static const gx_image_enum_procs_t pdf_image_object_enum_procs2 = {
65
    pdf_image_plane_data,
66
    pdf_image_end_image_object2
67
};
68
static const gx_image_enum_procs_t pdf_image_cvd_enum_procs = {
69
    gx_image1_plane_data,
70
    pdf_image_end_image_cvd,
71
    gx_image1_flush
72
};
73
74
/* ---------------- Driver procedures ---------------- */
75
76
/* Define the structure for keeping track of progress through an image. */
77
typedef struct pdf_image_enum_s {
78
    gx_image_enum_common;
79
    int width;
80
    int bits_per_pixel;   /* bits per pixel (per plane) */
81
    int rows_left;
82
    pdf_image_writer writer;
83
    gs_matrix mat;
84
    gs_color_space_index initial_colorspace;
85
    int JPEG_PassThrough;
86
    int JPX_PassThrough;
87
} pdf_image_enum;
88
gs_private_st_composite(st_pdf_image_enum, pdf_image_enum, "pdf_image_enum",
89
  pdf_image_enum_enum_ptrs, pdf_image_enum_reloc_ptrs);
90
/* GC procedures */
91
0
static ENUM_PTRS_WITH(pdf_image_enum_enum_ptrs, pdf_image_enum *pie)
92
0
    if (index < pdf_image_writer_max_ptrs) {
93
0
        gs_ptr_type_t ret =
94
0
            ENUM_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer),
95
0
                       index);
96
97
0
        if (ret == 0)   /* don't stop early */
98
0
            ENUM_RETURN(0);
99
0
        return ret;
100
0
    }
101
0
    return ENUM_USING_PREFIX(st_gx_image_enum_common,
102
0
                             pdf_image_writer_max_ptrs);
103
0
ENUM_PTRS_END
104
0
static RELOC_PTRS_WITH(pdf_image_enum_reloc_ptrs, pdf_image_enum *pie)
105
0
{
106
0
    RELOC_USING(st_pdf_image_writer, &pie->writer, sizeof(pie->writer));
107
0
    RELOC_USING(st_gx_image_enum_common, vptr, size);
108
0
}
109
0
RELOC_PTRS_END
110
111
/*
112
 * Test whether we can write an image in-line.  This is always true,
113
 * because we only support PDF 1.2 and later.
114
 */
115
static bool
116
can_write_image_in_line(const gx_device_pdf *pdev, const gs_image_t *pim)
117
52.6k
{
118
52.6k
    return true;
119
52.6k
}
120
121
/*
122
 * Convert a Type 4 image to a Type 1 masked image if possible.
123
 * Type 1 masked images are more compact, and are supported in all PDF
124
 * versions, whereas general masked images require PDF 1.3 or higher.
125
 * Also, Acrobat 5 for Windows has a bug that causes an error for images
126
 * with a color-key mask, at least for 1-bit-deep images using an Indexed
127
 * color space.
128
 */
129
static int
130
color_is_black_or_white(gx_device *dev, const gx_drawing_color *pdcolor)
131
0
{
132
0
    return (!color_is_pure(pdcolor) ? -1 :
133
0
            gx_dc_pure_color(pdcolor) == gx_device_black(dev) ? 0 :
134
0
            gx_dc_pure_color(pdcolor) == gx_device_white(dev) ? 1 : -1);
135
0
}
136
static int
137
pdf_convert_image4_to_image1(gx_device_pdf *pdev,
138
                             const gs_gstate *pgs,
139
                             const gx_drawing_color *pbcolor,
140
                             const gs_image4_t *pim4, gs_image_t *pim1,
141
                             gx_drawing_color *pdcolor)
142
22
{
143
22
    if (pim4->BitsPerComponent == 1 &&
144
0
        pim4->ColorSpace->type->num_components(pim4->ColorSpace) == 1 &&
145
0
        (pim4->MaskColor_is_range ?
146
0
         pim4->MaskColor[0] | pim4->MaskColor[1] :
147
0
         pim4->MaskColor[0]) <= 1
148
22
        ) {
149
0
        gx_device *const dev = (gx_device *)pdev;
150
0
        const gs_color_space *pcs = pim4->ColorSpace;
151
0
        bool write_1s = !pim4->MaskColor[0];
152
0
        gs_client_color cc;
153
0
        int code;
154
155
        /*
156
         * Prepare the drawing color.  (pdf_prepare_imagemask will set it.)
157
         * This is the other color in the image (the one that isn't the
158
         * mask key), taking Decode into account.
159
         */
160
161
0
        cc.paint.values[0] = pim4->Decode[(int)write_1s];
162
0
        cc.pattern = 0;
163
0
        code = pcs->type->remap_color(&cc, pcs, pdcolor, pgs, dev,
164
0
                                      gs_color_select_texture);
165
0
        if (code < 0)
166
0
            return code;
167
168
        /*
169
         * The PDF imaging model doesn't support RasterOp.  We can convert a
170
         * Type 4 image to a Type 1 imagemask only if the effective RasterOp
171
         * passes through the source color unchanged.  "Effective" means we
172
         * take into account CombineWithColor, and whether the source and/or
173
         * texture are black, white, or neither.
174
         */
175
0
        {
176
0
            gs_logical_operation_t lop = pgs->log_op;
177
0
            int black_or_white = color_is_black_or_white(dev, pdcolor);
178
179
0
            lop = lop_sanitize(lop);
180
181
0
            switch (black_or_white) {
182
0
            case 0: lop = lop_know_S_0(lop); break;
183
0
            case 1: lop = lop_know_S_1(lop); break;
184
0
            default: DO_NOTHING;
185
0
            }
186
0
            if (pim4->CombineWithColor)
187
0
                switch (color_is_black_or_white(dev, pbcolor)) {
188
0
                case 0: lop = lop_know_T_0(lop); break;
189
0
                case 1: lop = lop_know_T_1(lop); break;
190
0
                default: DO_NOTHING;
191
0
                }
192
0
            else
193
0
                lop = lop_know_T_0(lop);
194
0
            switch (lop_rop(lop)) {
195
0
            case rop3_0:
196
0
                if (black_or_white != 0)
197
0
                    return -1;
198
0
                break;
199
0
            case rop3_1:
200
0
                if (black_or_white != 1)
201
0
                    return -1;
202
0
                break;
203
0
            case rop3_S:
204
0
                break;
205
0
            default:
206
0
                return -1;
207
0
            }
208
0
        }
209
210
        /* All conditions are met.  Convert to a masked image. */
211
212
0
        gs_image_t_init_mask_adjust(pim1, write_1s, false);
213
0
#define COPY_ELEMENT(e) pim1->e = pim4->e
214
0
        COPY_ELEMENT(ImageMatrix);
215
0
        COPY_ELEMENT(Width);
216
0
        COPY_ELEMENT(Height);
217
0
        pim1->BitsPerComponent = 1;
218
        /* not Decode */
219
0
        COPY_ELEMENT(Interpolate);
220
0
        pim1->format = gs_image_format_chunky; /* BPC = 1, doesn't matter */
221
0
#undef COPY_ELEMENT
222
0
        return 0;
223
0
    }
224
22
    return -1;     /* arbitrary <0 */
225
22
}
226
227
static int
228
pdf_begin_image_data_decoded(gx_device_pdf *pdev, int num_components, const gs_range_t *pranges, int i,
229
                             gs_pixel_image_t *pi, cos_value_t *cs_value, pdf_image_enum *pie)
230
57.5k
{
231
232
57.5k
    if (pranges) {
233
        /* Rescale the Decode values for the image data. */
234
0
        const gs_range_t *pr = pranges;
235
0
        float *decode = pi->Decode;
236
0
        int j;
237
238
0
        for (j = 0; j < num_components; ++j, ++pr, decode += 2) {
239
0
            double vmin = decode[0], vmax = decode[1];
240
0
            double base = pr->rmin, factor = pr->rmax - base;
241
242
0
            decode[1] = (vmax - vmin) / factor + (vmin - base);
243
0
            decode[0] = vmin - base;
244
0
        }
245
0
    }
246
57.5k
    return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
247
57.5k
}
248
249
static int
250
make_device_color_space(gx_device_pdf *pdev,
251
                        gs_color_space_index output_cspace_index,
252
                        gs_color_space **ppcs)
253
2.54k
{
254
2.54k
    gs_color_space *cs;
255
2.54k
    gs_memory_t *mem = pdev->v_memory;
256
257
2.54k
    switch (output_cspace_index) {
258
0
        case gs_color_space_index_DeviceGray:
259
0
            cs = gs_cspace_new_DeviceGray(mem);
260
0
            break;
261
2.54k
        case gs_color_space_index_DeviceRGB:
262
2.54k
            cs = gs_cspace_new_DeviceRGB(mem);
263
2.54k
            break;
264
0
        case gs_color_space_index_DeviceCMYK:
265
0
            cs = gs_cspace_new_DeviceCMYK(mem);
266
0
            break;
267
0
        default:
268
            /* Notify the user and terminate.
269
               Don't emit rangecheck becuause it would fall back
270
               to a default implementation (rasterisation).
271
             */
272
0
            emprintf(mem, "Unsupported ProcessColorModel");
273
0
            return_error(gs_error_undefined);
274
2.54k
    }
275
276
2.54k
    if (cs == NULL)
277
0
        return_error(gs_error_VMerror);
278
279
2.54k
    *ppcs = cs;
280
2.54k
    return 0;
281
2.54k
}
282
283
/*
284
 * Start processing an image.  This procedure takes extra arguments because
285
 * it has to do something slightly different for the parts of an ImageType 3
286
 * image.
287
 */
288
typedef enum {
289
    PDF_IMAGE_DEFAULT,
290
    PDF_IMAGE_TYPE3_MASK, /* no in-line, don't render */
291
    PDF_IMAGE_TYPE3_DATA  /* no in-line */
292
} pdf_typed_image_context_t;
293
294
/*
295
 * We define this union because psdf_setup_image_filters may alter the
296
 * gs_pixel_image_t part, but pdf_begin_image_data must also have access
297
 * to the type-specific parameters.
298
 */
299
typedef union image_union_s {
300
    gs_pixel_image_t pixel; /* we may change some components */
301
    gs_image1_t type1;
302
    gs_image3_t type3;
303
    gs_image3x_t type3x;
304
    gs_image4_t type4;
305
} image_union_t;
306
307
static int pdf_begin_typed_image(gx_device_pdf *pdev,
308
    const gs_gstate * pgs, const gs_matrix *pmat,
309
    const gs_image_common_t *pic, const gs_int_rect * prect,
310
    const gx_drawing_color * pdcolor, const gx_clip_path * pcpath,
311
    gs_memory_t * mem, gx_image_enum_common_t ** pinfo,
312
    pdf_typed_image_context_t context);
313
314
static int setup_type1_image(gx_device_pdf *pdev, const gs_image_common_t *pic,
315
                             const gx_drawing_color * pdcolor, image_union_t *image,
316
                             pdf_typed_image_context_t context)
317
55.2k
{
318
55.2k
    const gs_image_t *pim1 = (const gs_image_t *)pic;
319
320
55.2k
    if (pim1->Alpha != gs_image_alpha_none)
321
0
        return -1;
322
55.2k
    if (pim1->ImageMask) {
323
        /* If parameters are invalid, use the fallback implementation. */
324
43.0k
        if (!(gx_dc_is_pattern1_color(pdcolor)))
325
42.8k
            if (pim1->BitsPerComponent != 1 ||
326
42.8k
                !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
327
41.6k
                  (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
328
42.8k
                )
329
10
                return -1;
330
43.0k
    }
331
55.2k
    image[0].type1 = *pim1;
332
    /* If we can write in-line then make it so */
333
55.2k
    return (context == PDF_IMAGE_DEFAULT &&
334
52.6k
        can_write_image_in_line(pdev, pim1));
335
55.2k
}
336
337
static int setup_type3_image(gx_device_pdf *pdev, const gs_gstate * pgs,
338
                      const gs_matrix *pmat, const gs_image_common_t *pic,
339
                      const gs_int_rect * prect,
340
                      const gx_drawing_color * pdcolor,
341
                      const gx_clip_path * pcpath, gs_memory_t * mem,
342
                      gx_image_enum_common_t ** pinfo,
343
                      image_union_t *image)
344
88
{
345
88
    const gs_image3_t *pim3 = (const gs_image3_t *)pic;
346
88
    gs_image3_t pim3a;
347
88
    const gs_image_common_t *pic1 = pic;
348
88
    gs_matrix m, mi;
349
88
    const gs_matrix *pmat1 = pmat;
350
88
    int code;
351
352
88
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
353
88
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
354
88
        if (code < 0)
355
0
            return code;
356
88
        if (pdf_must_put_clip_path(pdev, pcpath))
357
21
            code = pdf_unclip(pdev);
358
67
        else
359
67
            code = pdf_open_page(pdev, PDF_IN_STREAM);
360
88
        if (code < 0)
361
0
            return code;
362
88
        code = pdf_put_clip_path(pdev, pcpath);
363
88
        if (code < 0)
364
0
            return code;
365
88
        gs_make_identity(&m);
366
88
        pmat1 = &m;
367
88
        m.tx = floor(pgs->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
368
88
        m.ty = floor(pgs->ctm.ty + 0.5);
369
88
        pim3a = *pim3;
370
88
        code = gs_matrix_invert(&pim3a.ImageMatrix, &mi);
371
88
        if (code < 0)
372
1
            return code;
373
87
        gs_make_identity(&pim3a.ImageMatrix);
374
87
        if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
375
21
            int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
376
377
21
            gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
378
21
            gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
379
21
        }
380
87
        if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
381
14
            int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
382
383
14
            gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
384
14
            gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
385
14
        }
386
87
        gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
387
87
        pim3a.imagematrices_are_untrustworthy = 1;
388
87
        pic1 = (gs_image_common_t *)&pim3a;
389
        /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
390
87
        gs_matrix_multiply(&mi, &ctm_only(pgs), &pdev->converting_image_matrix);
391
87
    }
392
    /*
393
     * We handle ImageType 3 images in a completely different way:
394
     * the default implementation sets up the enumerator.
395
     */
396
87
    return gx_begin_image3_generic((gx_device *)pdev, pgs, pmat1, pic1,
397
87
                                   prect, pdcolor, pcpath, mem,
398
87
                                   pdf_image3_make_mid,
399
87
                                   pdf_image3_make_mcde, pinfo);
400
88
}
401
402
static int convert_type4_image(gx_device_pdf *pdev, const gs_gstate * pgs,
403
                      const gs_matrix *pmat, const gs_image_common_t *pic,
404
                      const gs_int_rect * prect,
405
                      const gx_drawing_color * pdcolor,
406
                      const gx_clip_path * pcpath, gs_memory_t * mem,
407
                      gx_image_enum_common_t ** pinfo,
408
                      pdf_typed_image_context_t context, image_union_t *image,
409
                      cos_dict_t *pnamed)
410
22
{
411
    /* Try to convert the image to a plain masked image. */
412
22
    gx_drawing_color icolor;
413
22
    int code = 1;
414
415
22
    pdev->image_mask_is_SMask = false;
416
22
    if (pdf_convert_image4_to_image1(pdev, pgs, pdcolor,
417
22
                                     (const gs_image4_t *)pic,
418
22
                                     &image[0].type1, &icolor) >= 0) {
419
0
        if (pgs == NULL)
420
0
            return_error(gs_error_unregistered); /* Must not happen. */
421
422
        /* Undo the pop of the NI stack if necessary. */
423
0
        if (pnamed)
424
0
            cos_array_add_object(pdev->NI_stack, COS_OBJECT(pnamed));
425
        /* HACK: temporary patch the color space, to allow
426
           pdf_prepare_imagemask to write the right color for the imagemask. */
427
0
        code = gs_gsave((gs_gstate *)pgs);
428
0
        if (code < 0)
429
0
            return code;
430
        /* {csrc}: const cast warning */
431
0
        code = gs_setcolorspace((gs_gstate *)pgs, ((const gs_image4_t *)pic)->ColorSpace);
432
0
        if (code < 0)
433
0
            return code;
434
0
        code = pdf_begin_typed_image(pdev, pgs, pmat,
435
0
                                     (gs_image_common_t *)&image[0].type1,
436
0
                                     prect, &icolor, pcpath, mem,
437
0
                                     pinfo, context);
438
0
        if (code < 0)
439
0
            return code;
440
0
        code = gs_grestore((gs_gstate *)pgs);
441
        /* To account for the above pdf_begin_typed_image() being with a gsave/grestore */
442
0
        (*pinfo)->pgs_level = pgs->level;
443
0
    }
444
22
    return code;
445
22
}
446
447
static int convert_type4_to_masked_image(gx_device_pdf *pdev, const gs_gstate * pgs,
448
                      const gs_image_common_t *pic,
449
                      const gs_int_rect * prect,
450
                      const gx_drawing_color * pdcolor,
451
                      const gx_clip_path * pcpath, gs_memory_t * mem,
452
                      gx_image_enum_common_t ** pinfo)
453
22
{
454
22
        gs_matrix m, m1, mi;
455
22
        gs_image4_t pi4 = *(const gs_image4_t *)pic;
456
22
        int code;
457
22
        pdf_lcvd_t *cvd = NULL;
458
459
22
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
460
22
        if (code < 0)
461
0
            return code;
462
22
        if (pdf_must_put_clip_path(pdev, pcpath))
463
21
            code = pdf_unclip(pdev);
464
1
        else
465
1
            code = pdf_open_page(pdev, PDF_IN_STREAM);
466
22
        if (code < 0)
467
0
            return code;
468
22
        code = pdf_put_clip_path(pdev, pcpath);
469
22
        if (code < 0)
470
0
            return code;
471
22
        gs_make_identity(&m1);
472
22
        code = gs_matrix_invert(&pic->ImageMatrix, &mi);
473
22
        if (code < 0)
474
0
            return code;
475
22
        gs_matrix_multiply(&mi, &ctm_only(pgs), &m);
476
22
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
477
22
                             true, 0, 0, pi4.Width, pi4.Height, false);
478
22
        if (code < 0)
479
0
            return code;
480
22
        cvd->mdev.is_open = true; /* fixme: same as above. */
481
22
        cvd->mask->is_open = true; /* fixme: same as above. */
482
22
        cvd->mask_is_empty = false;
483
22
        code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
484
22
                    0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
485
22
        if (code < 0)
486
0
            return code;
487
22
        gx_device_retain((gx_device *)cvd, true);
488
22
        gx_device_retain((gx_device *)cvd->mask, true);
489
22
        gs_make_identity(&pi4.ImageMatrix);
490
22
        code = gx_default_begin_typed_image((gx_device *)cvd,
491
22
            pgs, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
492
22
        if (code < 0)
493
0
            return code;
494
22
        (*pinfo)->procs = &pdf_image_cvd_enum_procs;
495
22
        return 0;
496
22
}
497
498
static int setup_image_process_colorspace(gx_device_pdf *pdev, image_union_t *image, gs_color_space **pcs_orig,
499
                                          const char *sname, cos_value_t *cs_value)
500
1.27k
{
501
1.27k
    int code;
502
1.27k
    gs_color_space *pcs_device = NULL;
503
504
1.27k
    cos_c_string_value(cs_value, sname);
505
1.27k
    *pcs_orig = image->pixel.ColorSpace;
506
1.27k
    code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
507
1.27k
    if (code < 0)
508
0
        return code;
509
1.27k
    image->pixel.ColorSpace = pcs_device;
510
1.27k
    return 0;
511
1.27k
}
512
513
static int check_colorants_for_pdfx4(const gs_color_space *pcs)
514
0
{
515
0
    int comp, all_present = 1;
516
0
    char *ink;
517
0
    gs_device_n_colorant *colorant = NULL;
518
519
0
    if (pcs->params.device_n.colorants == NULL) {
520
0
        return 0;
521
0
    } else {
522
0
        for (comp = 0; comp < pcs->params.device_n.num_components;comp++){
523
0
            colorant = pcs->params.device_n.colorants;
524
0
            ink = pcs->params.device_n.names[comp];
525
0
            do {
526
0
                if (memcmp(colorant->colorant_name, ink, strlen(ink)) == 0)
527
0
                    break;
528
0
                colorant = colorant->next;
529
0
            }while(colorant);
530
0
            if (!colorant) {
531
0
                all_present = 0;
532
0
                break;
533
0
            }
534
0
        }
535
0
    }
536
0
    return all_present;
537
0
}
538
/* 0 = write unchanged
539
   1 = convert to process
540
   2 = write as ICC
541
   3 = convert base space (Separation)
542
   4 = convert base space (DeviceN)
543
 */
544
static int setup_image_colorspace(gx_device_pdf *pdev, image_union_t *image, const gs_color_space *pcs, gs_color_space **pcs_orig,
545
                                  const pdf_color_space_names_t *names, cos_value_t *cs_value)
546
10.7k
{
547
10.7k
    int code=0;
548
10.7k
    gs_color_space_index csi;
549
10.7k
    gs_color_space_index csi2;
550
10.7k
    const gs_color_space *pcs2 = pcs;
551
552
10.7k
    csi = csi2 = gs_color_space_get_index(pcs);
553
10.7k
    if (csi == gs_color_space_index_ICC) {
554
8.99k
        csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
555
8.99k
    }
556
    /* Figure out what to do if we are outputting to really ancient versions of PDF */
557
    /* NB ps2write sets CompatibilityLevel to 1.2 so we cater for it here */
558
10.7k
    if (pdev->CompatibilityLevel <= 1.2) {
559
560
        /* If we have an /Indexed space, we need to look at the base space */
561
6.62k
        if (csi2 == gs_color_space_index_Indexed) {
562
939
            pcs2 = pcs->base_space;
563
939
            csi2 = gs_color_space_get_index(pcs2);
564
939
        }
565
566
6.62k
        switch (csi2) {
567
505
            case gs_color_space_index_DeviceGray:
568
505
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
569
505
                    pdev->params.ColorConversionStrategy == ccs_Gray) {
570
505
                    return 0;
571
505
                }
572
0
                else {
573
0
                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
574
0
                    if (code < 0)
575
0
                        return code;
576
0
                    return 1;
577
0
                }
578
0
                break;
579
3.86k
            case gs_color_space_index_DeviceRGB:
580
3.86k
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
581
0
                    pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB)
582
3.86k
                    return 0;
583
0
                else {
584
0
                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
585
0
                    if (code < 0)
586
0
                        return code;
587
0
                    return 1;
588
0
                }
589
0
                break;
590
149
            case gs_color_space_index_DeviceCMYK:
591
149
                if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
592
149
                    pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
593
149
                    return 0;
594
0
                else {
595
0
                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
596
0
                    if (code < 0)
597
0
                        return code;
598
0
                    return 1;
599
0
                }
600
0
                break;
601
0
            case gs_color_space_index_CIEA:
602
0
            case gs_color_space_index_CIEABC:
603
0
            case gs_color_space_index_CIEDEF:
604
0
            case gs_color_space_index_CIEDEFG:
605
10
            case gs_color_space_index_Separation:
606
10
                if (pdev->ForOPDFRead) {
607
10
                    switch (pdev->params.ColorConversionStrategy) {
608
0
                        case ccs_ByObjectType:
609
                            /* Object type not implemented yet */
610
0
                        case ccs_UseDeviceIndependentColorForImages:
611
                            /* If only correcting images, then leave unchanged */
612
10
                        case ccs_LeaveColorUnchanged:
613
10
                            if (csi2 == gs_color_space_index_Separation)
614
10
                                return 0;
615
                            /* Fall through and convert CIE to the device space */
616
0
                        default:
617
0
                            switch (pdev->pcm_color_info_index) {
618
0
                                case gs_color_space_index_DeviceGray:
619
0
                                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
620
0
                                    break;
621
0
                                case gs_color_space_index_DeviceRGB:
622
0
                                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
623
0
                                    break;
624
0
                                case gs_color_space_index_DeviceCMYK:
625
0
                                    code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
626
0
                                    break;
627
0
                                default:
628
0
                                    emprintf(pdev->memory, "Unsupported ProcessColorModel.");
629
0
                                    return_error(gs_error_undefined);
630
0
                            }
631
0
                            if (code < 0)
632
0
                                return code;
633
0
                            return 1;
634
0
                            break;
635
10
                    }
636
10
                }
637
0
                else
638
0
                    *pcs_orig = (gs_color_space *)pcs;
639
0
                return 1;
640
0
                break;
641
642
2.07k
            case gs_color_space_index_ICC:
643
                /* Note that if csi is ICC, check to see if this was one of
644
                   the default substitutes that we introduced for DeviceGray,
645
                   DeviceRGB or DeviceCMYK.  If it is, then just write
646
                   the default color.  Depending upon the flavor of PDF,
647
                   or other options, we may want to actually have all
648
                   the colors defined by ICC profiles and not do the following
649
                   substituion of the Device space. */
650
2.07k
                csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
651
652
2.07k
                switch (csi2) {
653
3
                    case gs_color_space_index_DeviceGray:
654
3
                        if (pdev->params.ColorConversionStrategy == ccs_Gray ||
655
3
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
656
3
                            return 0;
657
0
                        break;
658
819
                    case gs_color_space_index_DeviceRGB:
659
819
                        if (pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB ||
660
819
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
661
819
                            return 0;
662
0
                        break;
663
0
                    case gs_color_space_index_DeviceCMYK:
664
0
                        if (pdev->params.ColorConversionStrategy == ccs_CMYK ||
665
0
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
666
0
                            return 0;
667
0
                        break;
668
1.25k
                    default:
669
1.25k
                        break;
670
2.07k
                }
671
                /* Fall through for non-handled cases */
672
1.27k
            case gs_color_space_index_DeviceN:
673
1.27k
            case gs_color_space_index_DevicePixel:
674
1.27k
            case gs_color_space_index_Indexed:
675
1.27k
                switch (pdev->pcm_color_info_index) {
676
0
                    case gs_color_space_index_DeviceGray:
677
0
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
678
0
                        break;
679
1.27k
                    case gs_color_space_index_DeviceRGB:
680
1.27k
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
681
1.27k
                        break;
682
0
                    case gs_color_space_index_DeviceCMYK:
683
0
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
684
0
                        break;
685
0
                    default:
686
0
                        emprintf(pdev->memory, "Unsupported ProcessColorModel.");
687
0
                        return_error(gs_error_undefined);
688
1.27k
                }
689
1.27k
                if (code < 0)
690
0
                    return code;
691
1.27k
                return 1;
692
0
                break;
693
0
            default:
694
0
                return (gs_note_error(gs_error_rangecheck));
695
0
                break;
696
6.62k
        }
697
6.62k
    } else {
698
4.14k
        int strategy = pdev->params.ColorConversionStrategy;
699
700
4.14k
        if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && csi2 == gs_color_space_index_Indexed) {
701
0
            csi = gs_color_space_get_index(pcs->base_space);
702
0
            if (csi == gs_color_space_index_ICC) {
703
0
                csi = gsicc_get_default_type(pcs->base_space->cmm_icc_profile_data);
704
0
            }
705
            /* If its still not a base space, make it the ProcessCOlorModel of the device */
706
0
            if (csi > gs_color_space_index_DeviceCMYK)
707
0
                csi = pdev->pcm_color_info_index;
708
0
            switch(csi) {
709
0
                case gs_color_space_index_DeviceGray:
710
0
                    strategy = ccs_Gray;
711
0
                    break;
712
0
                case gs_color_space_index_DeviceRGB:
713
0
                    strategy = ccs_RGB;
714
0
                    break;
715
0
                case gs_color_space_index_DeviceCMYK:
716
0
                    strategy = ccs_CMYK;
717
0
                    break;
718
0
                default:
719
0
                    break;
720
0
            }
721
0
        }
722
723
4.14k
        switch(strategy) {
724
0
            case ccs_ByObjectType:
725
                /* Object type not implemented yet */
726
0
            case ccs_UseDeviceIndependentColorForImages:
727
                /* If only correcting images, then leave unchanged */
728
4.14k
            case ccs_LeaveColorUnchanged:
729
4.14k
                return 0;
730
0
                break;
731
0
            case ccs_UseDeviceIndependentColor:
732
0
                return 2;
733
0
                break;
734
0
            case ccs_CMYK:
735
0
                switch(csi2) {
736
0
                    case gs_color_space_index_DeviceGray:
737
0
                    case gs_color_space_index_DeviceCMYK:
738
0
                        return 0;
739
0
                        break;
740
0
                    case gs_color_space_index_Separation:
741
0
                        pcs2 = pcs;
742
0
                        while (pcs2->base_space)
743
0
                            pcs2 = pcs2->base_space;
744
0
                        csi = gs_color_space_get_index(pcs2);
745
0
                        if (csi == gs_color_space_index_ICC)
746
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
747
0
                        if (csi == gs_color_space_index_DeviceCMYK)
748
0
                            return 0;
749
0
                        else
750
0
                            return 3;
751
0
                        break;
752
0
                    case gs_color_space_index_DeviceN:
753
0
                        if (pdev->PDFX > 0) {
754
0
                            if (pdev->PDFX < 4) {
755
0
                                *pcs_orig = (gs_color_space *)pcs;
756
0
                                return 1;
757
0
                            }
758
0
                            if (!check_colorants_for_pdfx4(pcs2)){
759
0
                                *pcs_orig = (gs_color_space *)pcs;
760
0
                                return 1;
761
0
                            }
762
0
                        }
763
0
                        pcs2 = pcs;
764
0
                        while (pcs2->base_space)
765
0
                            pcs2 = pcs2->base_space;
766
0
                        csi = gs_color_space_get_index(pcs2);
767
0
                        if (csi == gs_color_space_index_ICC)
768
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
769
0
                        if (csi == gs_color_space_index_DeviceCMYK)
770
0
                            return 0;
771
0
                        else
772
0
                            return 4;
773
0
                        break;
774
0
                    case gs_color_space_index_Indexed:
775
0
                        pcs2 = pcs->base_space;
776
0
                        csi = gs_color_space_get_index(pcs2);
777
0
                        if (csi == gs_color_space_index_ICC)
778
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
779
0
                        switch(csi) {
780
0
                            case gs_color_space_index_DeviceGray:
781
0
                            case gs_color_space_index_DeviceCMYK:
782
0
                                return 0;
783
0
                                break;
784
0
                            case gs_color_space_index_Separation:
785
0
                                pcs2 = pcs;
786
0
                                while (pcs2->base_space)
787
0
                                    pcs2 = pcs2->base_space;
788
0
                                csi = gs_color_space_get_index(pcs2);
789
0
                                if (csi == gs_color_space_index_ICC)
790
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
791
0
                                if (csi == gs_color_space_index_DeviceCMYK)
792
0
                                    return 0;
793
0
                                else
794
0
                                    return 3;
795
0
                                break;
796
0
                            case gs_color_space_index_DeviceN:
797
0
                                pcs2 = pcs;
798
0
                                while (pcs2->base_space)
799
0
                                    pcs2 = pcs2->base_space;
800
0
                                csi = gs_color_space_get_index(pcs2);
801
0
                                if (csi == gs_color_space_index_ICC)
802
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
803
0
                                if (csi == gs_color_space_index_DeviceCMYK)
804
0
                                    return 0;
805
0
                                else
806
0
                                    return 4;
807
0
                                break;
808
0
                            default:
809
0
                                switch (pdev->pcm_color_info_index) {
810
0
                                    case gs_color_space_index_DeviceGray:
811
0
                                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
812
0
                                        break;
813
0
                                    case gs_color_space_index_DeviceRGB:
814
0
                                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
815
0
                                        break;
816
0
                                    case gs_color_space_index_DeviceCMYK:
817
0
                                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
818
0
                                        break;
819
0
                                    default:
820
0
                                        emprintf(pdev->memory, "Unsupported ProcessColorModel.");
821
0
                                        return_error(gs_error_undefined);
822
0
                                }
823
0
                                if (code < 0)
824
0
                                    return code;
825
0
                                return 1;
826
0
                                break;
827
0
                        }
828
0
                        break;
829
0
                    default:
830
0
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceCMYK, cs_value);
831
0
                        if (code < 0)
832
0
                            return code;
833
0
                        return 1;
834
0
                        break;
835
0
                }
836
0
                break;
837
0
            case ccs_Gray:
838
0
                switch(csi2) {
839
0
                    case gs_color_space_index_DeviceGray:
840
0
                        return 0;
841
0
                        break;
842
0
                    case gs_color_space_index_Separation:
843
0
                        pcs2 = pcs;
844
0
                        while (pcs2->base_space)
845
0
                            pcs2 = pcs2->base_space;
846
0
                        csi = gs_color_space_get_index(pcs2);
847
0
                        if (csi == gs_color_space_index_ICC)
848
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
849
0
                        if (csi == gs_color_space_index_DeviceGray)
850
0
                            return 0;
851
0
                        else
852
0
                            return 3;
853
0
                        break;
854
0
                    case gs_color_space_index_DeviceN:
855
0
                        pcs2 = pcs;
856
0
                        while (pcs2->base_space)
857
0
                            pcs2 = pcs2->base_space;
858
0
                        csi = gs_color_space_get_index(pcs2);
859
0
                        if (csi == gs_color_space_index_ICC)
860
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
861
0
                        if (csi == gs_color_space_index_DeviceGray)
862
0
                            return 0;
863
0
                        else
864
0
                            return 4;
865
0
                        break;
866
0
                    case gs_color_space_index_Indexed:
867
0
                        pcs2 = pcs->base_space;
868
0
                        csi = gs_color_space_get_index(pcs2);
869
0
                        if (csi == gs_color_space_index_ICC)
870
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
871
0
                        switch(csi) {
872
0
                            case gs_color_space_index_DeviceGray:
873
0
                                return 0;
874
0
                                break;
875
0
                            case gs_color_space_index_Separation:
876
0
                                pcs2 = pcs;
877
0
                                while (pcs2->base_space)
878
0
                                    pcs2 = pcs2->base_space;
879
0
                                csi = gs_color_space_get_index(pcs2);
880
0
                                if (csi == gs_color_space_index_ICC)
881
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
882
0
                                if (csi == gs_color_space_index_DeviceGray)
883
0
                                    return 0;
884
0
                                else
885
0
                                    return 3;
886
0
                                break;
887
0
                            case gs_color_space_index_DeviceN:
888
0
                                pcs2 = pcs;
889
0
                                while (pcs2->base_space)
890
0
                                    pcs2 = pcs2->base_space;
891
0
                                csi = gs_color_space_get_index(pcs2);
892
0
                                if (csi == gs_color_space_index_ICC)
893
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
894
0
                                if (csi == gs_color_space_index_DeviceGray)
895
0
                                    return 0;
896
0
                                else
897
0
                                    return 4;
898
0
                                break;
899
0
                            default:
900
0
                                code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
901
0
                                if (code < 0)
902
0
                                    return code;
903
0
                                return 1;
904
0
                                break;
905
0
                        }
906
0
                        break;
907
0
                    default:
908
0
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceGray, cs_value);
909
0
                        if (code < 0)
910
0
                            return code;
911
0
                        return 1;
912
0
                        break;
913
0
                }
914
0
                break;
915
0
            case ccs_sRGB:
916
0
            case ccs_RGB:
917
0
                switch(csi2) {
918
0
                    case gs_color_space_index_DeviceGray:
919
0
                    case gs_color_space_index_DeviceRGB:
920
0
                        return 0;
921
0
                        break;
922
0
                    case gs_color_space_index_Separation:
923
0
                        pcs2 = pcs;
924
0
                        while (pcs2->base_space)
925
0
                            pcs2 = pcs2->base_space;
926
0
                        csi = gs_color_space_get_index(pcs2);
927
0
                        if (csi == gs_color_space_index_ICC)
928
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
929
0
                        if (csi == gs_color_space_index_DeviceRGB)
930
0
                            return 0;
931
0
                        else
932
0
                            return 3;
933
0
                        break;
934
0
                    case gs_color_space_index_DeviceN:
935
0
                        pcs2 = pcs;
936
0
                        while (pcs2->base_space)
937
0
                            pcs2 = pcs2->base_space;
938
0
                        csi = gs_color_space_get_index(pcs2);
939
0
                        if (csi == gs_color_space_index_ICC)
940
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
941
0
                        if (csi == gs_color_space_index_DeviceRGB)
942
0
                            return 0;
943
0
                        else
944
0
                            return 4;
945
0
                        break;
946
0
                    case gs_color_space_index_Indexed:
947
0
                        pcs2 = pcs->base_space;
948
0
                        csi = gs_color_space_get_index(pcs2);
949
0
                        if (csi == gs_color_space_index_ICC)
950
0
                            csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
951
0
                        switch(csi) {
952
0
                            case gs_color_space_index_DeviceGray:
953
0
                            case gs_color_space_index_DeviceRGB:
954
0
                                return 0;
955
0
                                break;
956
0
                            case gs_color_space_index_Separation:
957
0
                                pcs2 = pcs;
958
0
                                while (pcs2->base_space)
959
0
                                    pcs2 = pcs2->base_space;
960
0
                                csi = gs_color_space_get_index(pcs2);
961
0
                                if (csi == gs_color_space_index_ICC)
962
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
963
0
                                if (csi == gs_color_space_index_DeviceRGB)
964
0
                                    return 0;
965
0
                                else
966
0
                                    return 3;
967
0
                                break;
968
0
                            case gs_color_space_index_DeviceN:
969
0
                                pcs2 = pcs;
970
0
                                while (pcs2->base_space)
971
0
                                    pcs2 = pcs2->base_space;
972
0
                                csi = gs_color_space_get_index(pcs2);
973
0
                                if (csi == gs_color_space_index_ICC)
974
0
                                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
975
0
                                if (csi == gs_color_space_index_DeviceRGB)
976
0
                                    return 0;
977
0
                                else
978
0
                                    return 4;
979
0
                                break;
980
0
                            default:
981
0
                                code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
982
0
                                if (code < 0)
983
0
                                    return code;
984
0
                                return 1;
985
0
                                break;
986
0
                        }
987
0
                        break;
988
0
                    default:
989
0
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
990
0
                        if (code < 0)
991
0
                            return code;
992
0
                        return 1;
993
0
                        break;
994
0
                }
995
0
                break;
996
0
            default:
997
0
                break;
998
4.14k
        }
999
4.14k
    }
1000
0
    return 0;
1001
10.7k
}
1002
1003
/* Basically, sets up the BBox for Eps2Write case */
1004
static int
1005
pdf_image_handle_eps(gx_device_pdf *pdev, const gs_gstate * pgs,
1006
                     const gs_matrix *pmat, const gs_image_common_t *pic,
1007
                     const gs_int_rect *prect,
1008
                     const gx_clip_path * pcpath)
1009
55.2k
{
1010
55.2k
    int code = 0;
1011
55.2k
    gs_rect sbox, dbox, *Box;
1012
55.2k
    gs_point corners[4];
1013
55.2k
    gs_fixed_rect ibox;
1014
55.2k
    gs_matrix * pmat1 = (gs_matrix *)pmat;
1015
55.2k
    gs_matrix mat;
1016
1017
55.2k
    if (!pdev->Eps2Write)
1018
32.5k
        return 0;
1019
1020
22.6k
    if (!pdev->accumulating_charproc)
1021
21.3k
        Box = &pdev->BBox;
1022
1.29k
    else
1023
1.29k
        Box = &pdev->charproc_BBox;
1024
22.6k
    if (pmat1 == 0)
1025
22.6k
        pmat1 = (gs_matrix *)&ctm_only(pgs);
1026
22.6k
    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
1027
22.6k
        (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
1028
1
        goto exit;
1029
22.6k
    sbox.p.x = prect->p.x;
1030
22.6k
    sbox.p.y = prect->p.y;
1031
22.6k
    sbox.q.x = prect->q.x;
1032
22.6k
    sbox.q.y = prect->q.y;
1033
22.6k
    gs_bbox_transform_only(&sbox, &mat, corners);
1034
22.6k
    gs_points_bbox(corners, &dbox);
1035
22.6k
    ibox.p.x = float2fixed(dbox.p.x);
1036
22.6k
    ibox.p.y = float2fixed(dbox.p.y);
1037
22.6k
    ibox.q.x = float2fixed(dbox.q.x);
1038
22.6k
    ibox.q.y = float2fixed(dbox.q.y);
1039
22.6k
    if (pcpath != NULL &&
1040
21.9k
        !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
1041
21.9k
                                     ibox.q.x, ibox.q.y)
1042
22.6k
        ) {
1043
        /* Let the target do the drawing, but drive two triangles */
1044
        /* through the clipping path to get an accurate bounding box. */
1045
2.60k
        gx_device_clip cdev;
1046
2.60k
        gx_drawing_color devc;
1047
1048
2.60k
        fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
1049
2.60k
        fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
1050
1051
2.60k
        pdev->AccumulatingBBox++;
1052
2.60k
        gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
1053
2.60k
        set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
1054
2.60k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1055
2.60k
                                 float2fixed(corners[1].x) - x0,
1056
2.60k
                                 float2fixed(corners[1].y) - y0,
1057
2.60k
                                 bx2, by2, &devc, lop_default);
1058
2.60k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1059
2.60k
                                 float2fixed(corners[3].x) - x0,
1060
2.60k
                                 float2fixed(corners[3].y) - y0,
1061
2.60k
                                 bx2, by2, &devc, lop_default);
1062
2.60k
        gx_destroy_clip_device_on_stack(&cdev);
1063
2.60k
        pdev->AccumulatingBBox--;
1064
20.0k
    } else {
1065
        /* Just use the bounding box. */
1066
20.0k
        float x0, y0, x1, y1;
1067
20.0k
        x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
1068
20.0k
        y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
1069
20.0k
        x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
1070
20.0k
        y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
1071
20.0k
        if (Box->p.x > x0)
1072
1.16k
            Box->p.x = x0;
1073
20.0k
        if (Box->p.y > y0)
1074
1.42k
            Box->p.y = y0;
1075
20.0k
        if (Box->q.x < x1)
1076
1.82k
            Box->q.x = x1;
1077
20.0k
        if (Box->q.y < y1)
1078
1.97k
            Box->q.y = y1;
1079
20.0k
    }
1080
22.6k
 exit:
1081
22.6k
    return code;
1082
22.6k
}
1083
1084
static int
1085
pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
1086
                      const gs_matrix *pmat, const gs_image_common_t *pic,
1087
                      const gs_int_rect * prect,
1088
                      const gx_drawing_color * pdcolor,
1089
                      const gx_clip_path * pcpath, gs_memory_t * mem,
1090
                      gx_image_enum_common_t ** pinfo,
1091
                      pdf_typed_image_context_t context)
1092
56.6k
{
1093
56.6k
    int code = 0, i;
1094
56.6k
    unsigned int use_fallback  = 0, in_line = 0, is_mask = 0,
1095
56.6k
        force_lossless = 0, convert_to_process_colors = 0;
1096
56.6k
    int width, height;
1097
56.6k
    cos_dict_t *pnamed = 0;
1098
56.6k
    image_union_t *image;
1099
56.6k
    const gs_pixel_image_t *pim;
1100
56.6k
    gs_int_rect rect;
1101
56.6k
    gs_image_format_t format;
1102
56.6k
    gs_color_space *pcs = NULL;
1103
56.6k
    int num_components;
1104
56.6k
    pdf_image_enum *pie = NULL;
1105
56.6k
    const pdf_color_space_names_t *names;
1106
56.6k
    gs_color_space *pcs_orig = NULL;
1107
56.6k
    gs_color_space *pcs_device = NULL;
1108
56.6k
    cos_value_t cs_value;
1109
56.6k
    const gs_range_t *pranges = 0;
1110
1111
56.6k
    image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
1112
56.6k
                       sizeof(image_union_t), "pdf_begin_typed_image(image)");
1113
56.6k
    if (image == 0)
1114
0
        return_error(gs_error_VMerror);
1115
1116
    /*
1117
     * Pop the image name from the NI stack.  We must do this, to keep the
1118
     * stack in sync, even if it turns out we can't handle the image.
1119
     */
1120
56.6k
    {
1121
56.6k
        cos_value_t ni_value;
1122
1123
56.6k
        if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1124
8
            pnamed = (cos_dict_t *)ni_value.contents.object;
1125
56.6k
    }
1126
1127
    /* An initialization for pdf_end_and_do_image :
1128
       We need to delay adding the "Mask" entry into a type 3 image dictionary
1129
       until the mask is completed due to equal image merging. */
1130
56.6k
    pdev->image_mask_id = gs_no_id;
1131
1132
56.6k
    pim = (const gs_pixel_image_t *)pic;
1133
1134
    /* Check for the image types we can handle. */
1135
56.6k
    switch (pic->type->index) {
1136
55.2k
    case 1:
1137
55.2k
        is_mask = ((const gs_image_t *)pic)->ImageMask;
1138
55.2k
        code = setup_type1_image(pdev, pic, pdcolor, image, context);
1139
55.2k
        if (code < 0)
1140
10
            use_fallback = 1;
1141
55.2k
        else
1142
55.2k
            in_line = code;
1143
55.2k
        break;
1144
1145
88
    case 3:
1146
        /* Currently we can't handle images with masks, because we have two
1147
         * image enumerators, and the JPEG passthrough is stored at the device
1148
         * level, not the enumerator level. This means that when we skip the
1149
         * image data (because its handled as JPEG) we also skip the mask data,
1150
         * which is no use at all. FIXME: not sure how but if possible I
1151
         * should fix this. Probably need to store the PassThrough in the
1152
         * enumerator, and then store a pointer to the enumerator in the
1153
         * device in place of the flag, so that when we get JPEG data supplied
1154
         * we know where to send it. Of course, that won't work if we ever end
1155
         * up in the situation where we have two JPEG sources at the same time.....
1156
         * That can probably be handled with some judicious work in the DCTDecode
1157
         * structure, to hold some reference to the particular stream that
1158
         * should get the data. But lets get the simple code working first.
1159
         */
1160
88
        pdev->JPEG_PassThrough = 0;
1161
88
        pdev->JPX_PassThrough = 0;
1162
88
        pdev->image_mask_is_SMask = false;
1163
88
        if (pdev->CompatibilityLevel < 1.2 ||
1164
88
            (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1165
0
                   prect->q.x == ((const gs_image3_t *)pic)->Width &&
1166
0
                   prect->q.y == ((const gs_image3_t *)pic)->Height))) {
1167
0
            use_fallback = 1;
1168
0
            goto exit;
1169
0
        }
1170
88
        code = setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image);
1171
88
        goto exit;
1172
1173
1.28k
    case IMAGE3X_IMAGETYPE:
1174
1.28k
        {
1175
1.28k
            char *OC = pdev->PendingOC;
1176
1177
1.28k
            pdev->JPEG_PassThrough = 0;
1178
1.28k
            pdev->JPX_PassThrough = 0;
1179
1.28k
            if (pdev->CompatibilityLevel < 1.4 ||
1180
1.28k
                (prect && !(prect->p.x == 0 && prect->p.y == 0 &&
1181
0
                           prect->q.x == ((const gs_image3x_t *)pic)->Width &&
1182
0
                           prect->q.y == ((const gs_image3x_t *)pic)->Height))) {
1183
0
                use_fallback = 1;
1184
0
                goto exit;
1185
0
            }
1186
1.28k
            pdev->image_mask_is_SMask = true;
1187
1188
1.28k
            if (pdev->PendingOC)
1189
0
                gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
1190
1.28k
            OC = pdev->PendingOC = NULL;
1191
1.28k
            code = gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
1192
1.28k
                                            prect, pdcolor, pcpath, mem,
1193
1.28k
                                            pdf_image3x_make_mid,
1194
1.28k
                                            pdf_image3x_make_mcde, pinfo, OC);
1195
1.28k
            goto exit;
1196
1.28k
        }
1197
1198
22
    case 4:
1199
        /* If we are colour converting then we may not be able to preserve the
1200
         * type 4 image, if it has a /Mask entry which is a range of colours
1201
         * (chroma-key masking). If its a stencil mask then we can just conver the
1202
         * underlying image and leave the mask alone.
1203
         */
1204
22
        if (pdev->params.ColorConversionStrategy != ccs_LeaveColorUnchanged) {
1205
0
            gs_color_space *pcs2;
1206
0
            int csi = 0;
1207
0
            bool fallback = false;
1208
0
            gs_image4_t *pim4 = (gs_image4_t *)pic;
1209
1210
            /* If the /Mask is chroma-key rather than a stencil */
1211
0
            if (pim4->MaskColor_is_range) {
1212
                /* Find the colour space */
1213
0
                pcs2 = pim->ColorSpace;
1214
0
                csi = gs_color_space_get_index(pcs2);
1215
                /* If its /Indexed, get the base space */
1216
0
                if (csi == gs_color_space_index_Indexed) {
1217
0
                    pcs2 = pim->ColorSpace->base_space;
1218
0
                    csi = gs_color_space_get_index(pcs2);
1219
0
                }
1220
0
                if (csi == gs_color_space_index_ICC)
1221
0
                    csi = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
1222
                /* If the base space matches the target for colour conversion
1223
                 * then no conversion is needed, so we can preserve the type
1224
                 * 4 image.
1225
                 */
1226
0
                switch(csi) {
1227
0
                    case gs_color_space_index_DeviceGray:
1228
0
                        if (pdev->params.ColorConversionStrategy != ccs_Gray)
1229
0
                            fallback = true;
1230
0
                        break;
1231
0
                    case gs_color_space_index_DeviceRGB:
1232
0
                        if (pdev->params.ColorConversionStrategy != ccs_RGB)
1233
0
                            fallback = true;
1234
0
                        break;
1235
0
                    case gs_color_space_index_DeviceCMYK:
1236
0
                        if (pdev->params.ColorConversionStrategy != ccs_CMYK)
1237
0
                            fallback = true;
1238
0
                        break;
1239
0
                    default:
1240
0
                        fallback = true;
1241
0
                        break;
1242
0
                }
1243
0
                if (fallback == true && pdev->CompatibilityLevel > 1.2) {
1244
                    /* We've arrived at the point where we have a chroma-keyed
1245
                     * type 4 image, and the image needs to be converted to a
1246
                     * different space. We can't do that, so fall back to a
1247
                     * default implementation, create a clip path and apply it to
1248
                     * the image.
1249
                     */
1250
0
                    pdev->JPEG_PassThrough = 0;
1251
0
                    pdev->JPX_PassThrough = 0;
1252
0
                    use_fallback = 0;
1253
0
                    code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1254
0
                                                         pcpath, mem,pinfo);
1255
0
                    goto exit;
1256
0
                }
1257
                /* Note that we fall through to the original code, so if we are not
1258
                 * producing at least PDF 1.2 (for image mask support) then we will
1259
                 * fall back further filled to rectangles.
1260
                 */
1261
0
            }
1262
0
        }
1263
22
        pdev->JPEG_PassThrough = 0;
1264
22
        pdev->JPX_PassThrough = 0;
1265
22
        code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
1266
22
                      pcpath, mem, pinfo, context, image, pnamed);
1267
22
        if (code < 0)
1268
0
            use_fallback = 1;
1269
22
        if (code == 0)
1270
0
            goto exit;
1271
        /* No luck.  Masked images require PDF 1.3 or higher. */
1272
22
        if (pdev->CompatibilityLevel < 1.2)
1273
0
            use_fallback = 1;
1274
22
        if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1275
22
            use_fallback = 0;
1276
22
            code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1277
22
                                                 pcpath, mem,pinfo);
1278
22
            goto exit;
1279
22
        }
1280
0
        image[0].type4 = *(const gs_image4_t *)pic;
1281
0
        break;
1282
1283
0
    default:
1284
0
        use_fallback = 1;
1285
0
        break;
1286
56.6k
    }
1287
1288
55.2k
    format = pim->format;
1289
55.2k
    switch (format) {
1290
55.2k
    case gs_image_format_chunky:
1291
55.2k
    case gs_image_format_component_planar:
1292
55.2k
        break;
1293
0
    default:
1294
0
        use_fallback = 1;
1295
55.2k
    }
1296
    /* AR5 on Windows doesn't support 0-size images. Skipping. */
1297
55.2k
    if (pim->Width == 0 || pim->Height == 0)
1298
7
        use_fallback = 1;
1299
    /* PDF doesn't support images with more than 8 bits per component. */
1300
55.2k
    switch (pim->BitsPerComponent) {
1301
43.4k
        case 1:
1302
43.7k
        case 2:
1303
43.7k
        case 4:
1304
55.2k
        case 8:
1305
55.2k
        case 12:
1306
55.2k
        case 16:
1307
55.2k
            break;
1308
0
        default:
1309
0
            code = gs_note_error(gs_error_rangecheck);
1310
0
            goto exit;
1311
55.2k
    }
1312
55.2k
    if (prect)
1313
1.27k
        rect = *prect;
1314
53.9k
    else {
1315
53.9k
        rect.p.x = rect.p.y = 0;
1316
53.9k
        rect.q.x = pim->Width, rect.q.y = pim->Height;
1317
53.9k
    }
1318
55.2k
    if (rect.p.x != 0 || rect.p.y != 0 ||
1319
55.2k
        rect.q.x != pim->Width || rect.q.y != pim->Height ||
1320
55.2k
        (is_mask && pim->CombineWithColor))
1321
0
        use_fallback = 1;
1322
1323
    /* Handle BBox for Eps2Write, if applicable */
1324
55.2k
    code = pdf_image_handle_eps(pdev, pgs, pmat, pic, &rect, pcpath);
1325
55.2k
    if (code < 0) {
1326
1
        use_fallback = 0;
1327
1
        goto exit;
1328
1
    }
1329
1330
55.2k
    if (use_fallback)
1331
16
        goto exit;
1332
1333
55.2k
    pcs = pim->ColorSpace;
1334
55.2k
    rc_increment_cs(pcs);
1335
55.2k
    num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1336
1337
55.2k
    code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
1338
55.2k
    if (code < 0)
1339
0
        goto exit;
1340
55.2k
    if (pdf_must_put_clip_path(pdev, pcpath))
1341
2.15k
        code = pdf_unclip(pdev);
1342
53.0k
    else
1343
53.0k
        code = pdf_open_page(pdev, PDF_IN_STREAM);
1344
55.2k
    if (code < 0)
1345
0
        goto fail_and_fallback;
1346
1347
55.2k
    if (context == PDF_IMAGE_TYPE3_MASK) {
1348
        /*
1349
         * The soft mask for an ImageType 3x image uses a DevicePixel
1350
         * color space, which pdf_color_space() can't handle.  Patch it
1351
         * to DeviceGray here.
1352
         */
1353
        /* {csrc} make sure this gets freed */
1354
1.27k
        rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1355
1.27k
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
1356
1.27k
        if (pcs == NULL)
1357
0
            code = gs_note_error(gs_error_VMerror);
1358
53.9k
    } else if (is_mask)
1359
43.0k
        code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
1360
10.8k
    else
1361
10.8k
        code = pdf_prepare_image(pdev, pgs);
1362
55.2k
    if (code < 0)
1363
138
        goto fail_and_fallback;
1364
1365
55.0k
    pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1366
55.0k
                        "pdf_begin_image");
1367
55.0k
    if (pie == 0) {
1368
0
        code = gs_note_error(gs_error_VMerror);
1369
0
        goto exit;
1370
0
    }
1371
55.0k
    memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1372
55.0k
    *pinfo = (gx_image_enum_common_t *) pie;
1373
55.0k
    gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1374
55.0k
                    ((pdev->CompatibilityLevel >= 1.3) ?
1375
12.5k
                            (context == PDF_IMAGE_TYPE3_MASK ?
1376
1.27k
                            &pdf_image_object_enum_procs :
1377
12.5k
                            &pdf_image_enum_procs) :
1378
55.0k
                            context == PDF_IMAGE_TYPE3_MASK ?
1379
0
                            &pdf_image_object_enum_procs :
1380
42.4k
                            context == PDF_IMAGE_TYPE3_DATA ?
1381
0
                            &pdf_image_object_enum_procs2 :
1382
42.4k
                            &pdf_image_enum_procs),
1383
55.0k
                        (gx_device *)pdev, num_components, format);
1384
55.0k
    pie->memory = mem;
1385
55.0k
    pie->pgs = pgs;
1386
55.0k
    if (pgs != NULL)
1387
55.0k
        pie->pgs_level = pgs->level;
1388
55.0k
    width = rect.q.x - rect.p.x;
1389
55.0k
    pie->width = width;
1390
55.0k
    height = rect.q.y - rect.p.y;
1391
55.0k
    pie->bits_per_pixel =
1392
55.0k
        pim->BitsPerComponent * num_components / pie->num_planes;
1393
55.0k
    pie->rows_left = height;
1394
55.0k
    if (pnamed != 0 || pdev->PendingOC) /* Don't in-line the image if it is named. Or has Optional Content */
1395
20
        in_line = false;
1396
55.0k
    else {
1397
55.0k
        int64_t nbytes = (int64_t)(((int64_t) pie->width * pie->bits_per_pixel + 7) >> 3) *
1398
55.0k
            pie->num_planes * pie->rows_left;
1399
1400
55.0k
        in_line &= (nbytes < pdev->MaxInlineImageSize);
1401
55.0k
    }
1402
55.0k
    pie->initial_colorspace = pdev->pcm_color_info_index;
1403
1404
55.0k
    if (pmat == 0)
1405
52.5k
        pmat = &ctm_only(pgs);
1406
55.0k
    {
1407
55.0k
        gs_matrix mat;
1408
55.0k
        gs_matrix bmat;
1409
55.0k
        int code;
1410
1411
55.0k
        pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1412
55.0k
                               pim->Width, pim->Height, height);
1413
55.0k
        if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1414
55.0k
            (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1415
55.0k
            (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1416
55.0k
            )
1417
0
            goto exit;
1418
        /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1419
55.0k
        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
1420
384
            use_fallback = 1;
1421
384
            goto fail_and_fallback;
1422
384
        }
1423
55.0k
    }
1424
1425
54.6k
    code = pdf_put_clip_path(pdev, pcpath);
1426
54.6k
    if (code < 0)
1427
0
        goto exit;
1428
54.6k
    pdf_image_writer_init(&pie->writer);
1429
    /* Note : Possible values for alt_writer_count are 1,2,3,4.
1430
       1 means no alternative streams.
1431
       2 means the main image stream and a mask stream while converting
1432
               an Image Type 4.
1433
       3 means the main image stream, alternative image compression stream,
1434
               and the compression chooser.
1435
       4 meams 3 and a mask stream while convertingh an Image Type 4.
1436
     */
1437
54.6k
    pie->writer.alt_writer_count = (in_line ||
1438
4.13k
                                    (pim->Width <= 64 && pim->Height <= 64)
1439
54.6k
                                    ? 1 : 2);
1440
54.6k
    if ((image[0].pixel.ColorSpace != NULL &&
1441
12.0k
        image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1442
1.74k
        && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1443
53.8k
        pdev->transfer_not_identity)
1444
819
        force_lossless = true;
1445
1446
54.6k
    if ((image[0].pixel.ColorSpace != NULL && image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed)
1447
52.9k
        || force_lossless)
1448
1.75k
        pie->writer.alt_writer_count = 1;
1449
1450
54.6k
    if (image[0].pixel.ColorSpace != NULL && (image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceGray &&
1451
12.0k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceRGB &&
1452
12.0k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceCMYK &&
1453
12.0k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_Indexed))
1454
10.2k
        names = &pdf_color_space_names;
1455
44.3k
    else
1456
44.3k
        names = (in_line ? &pdf_color_space_names_short : &pdf_color_space_names);
1457
1458
    /* We don't want to change the colour space of a mask, or an SMask (both of which are Gray) */
1459
54.6k
    if (!is_mask) {
1460
12.0k
#if 1
1461
12.0k
        if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1462
10.7k
           convert_to_process_colors = setup_image_colorspace(pdev, &image[0], pcs, &pcs_orig, names, &cs_value);
1463
#else
1464
        if (image[0].pixel.ColorSpace != NULL) {
1465
            if (context != PDF_IMAGE_TYPE3_MASK)
1466
                convert_to_process_colors = setup_image_colorspace(pdev, &image[0], pcs, &pcs_orig, names, &cs_value);
1467
            else {
1468
                if (pdev->PDFA != 0 && pdev->params.ColorConversionStrategy != ccs_Gray)
1469
                {
1470
                    /* A SMask *must* be in DeviceGray (PDF 1.7 reference, page 555), but if we're producing a PDF/A
1471
                     * and not creating a Gray output then we can't write the SMask as DeviceGray!
1472
                     */
1473
                    emprintf(pdev->memory,
1474
                         "\nDetected SMask which must be in DeviceGray, but we are not converting to DeviceGray, reverting to normal PDF output\n");
1475
                    pdev->AbortPDFAX = true;
1476
                    pdev->PDFA = 0;
1477
                }
1478
            }
1479
        }
1480
#endif
1481
1482
12.0k
        if (pim->BitsPerComponent > 8 && convert_to_process_colors) {
1483
0
            use_fallback = 1;
1484
0
            goto fail_and_fallback;
1485
0
        }
1486
12.0k
        if (convert_to_process_colors == 4) {
1487
0
            if (pdev->PDFX == 1) {
1488
0
                convert_to_process_colors = 1;
1489
0
                code = 0;
1490
0
            }
1491
0
            else
1492
0
                code = convert_DeviceN_alternate(pdev, pgs, pcs, NULL, NULL, NULL, NULL, &cs_value, in_line);
1493
0
            if (code < 0)
1494
0
                goto fail_and_fallback;
1495
0
        }
1496
12.0k
        if (convert_to_process_colors == 3) {
1497
0
            code = convert_separation_alternate(pdev, pgs, pcs, NULL, NULL, NULL, NULL, &cs_value, in_line);
1498
0
            if (code < 0)
1499
0
                goto fail_and_fallback;
1500
0
        }
1501
12.0k
        if (convert_to_process_colors == 1) {
1502
1.27k
            code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1503
1.27k
            if (code < 0)
1504
0
                goto fail_and_fallback;
1505
1.27k
            image[0].pixel.ColorSpace = pcs_device;
1506
1.27k
            image[0].pixel.BitsPerComponent = 8;
1507
1.27k
            code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1508
1.27k
                                     in_line, NULL, 0, false);
1509
1.27k
            if (code < 0)
1510
0
                goto fail_and_fallback;
1511
10.7k
        } else {
1512
10.7k
            if (convert_to_process_colors == 2) {
1513
0
                convert_to_process_colors = 0;
1514
0
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1515
0
                                     in_line, NULL, 0, true);
1516
0
                if (code < 0)
1517
0
                    goto fail_and_fallback;
1518
10.7k
            } else {
1519
10.7k
                convert_to_process_colors = 0;
1520
10.7k
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1521
10.7k
                                     in_line, NULL, 0, false);
1522
10.7k
                if (code < 0)
1523
0
                    goto fail_and_fallback;
1524
10.7k
            }
1525
10.7k
        }
1526
12.0k
    }
1527
1528
54.6k
    image[1] = image[0];
1529
1530
54.6k
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1531
1532
54.6k
    code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1533
54.6k
                    height, pnamed, in_line);
1534
54.6k
    if (code < 0)
1535
0
        goto fail_and_fallback;
1536
1537
54.6k
    if (pdev->CompatibilityLevel < 1.5)
1538
42.2k
        pdev->JPX_PassThrough = 0;
1539
1540
54.6k
    if (!convert_to_process_colors)
1541
53.4k
    {
1542
53.4k
        gs_color_space_index csi;
1543
1544
53.4k
        if (pdev->params.TransferFunctionInfo == tfi_Apply && pdev->transfer_not_identity && !is_mask) {
1545
0
            pdev->JPEG_PassThrough = 0;
1546
0
            pdev->JPX_PassThrough = 0;
1547
0
            csi = gs_color_space_get_index(image[0].pixel.ColorSpace);
1548
0
            if (csi == gs_color_space_index_Indexed) {
1549
0
                csi = gs_color_space_get_index(image[0].pixel.ColorSpace->base_space);
1550
0
                if (csi == gs_color_space_index_ICC) {
1551
0
                    csi = gsicc_get_default_type(image[0].pixel.ColorSpace->base_space->cmm_icc_profile_data);
1552
0
                }
1553
0
            } else {
1554
0
                if (csi == gs_color_space_index_ICC) {
1555
0
                    csi = gsicc_get_default_type(image[0].pixel.ColorSpace->cmm_icc_profile_data);
1556
0
                }
1557
0
            }
1558
0
            switch(csi) {
1559
0
                case gs_color_space_index_DevicePixel:
1560
0
                case gs_color_space_index_CIEA:
1561
0
                    convert_to_process_colors = 1;
1562
0
                    pdf_set_process_color_model(pdev, 0);
1563
0
                    break;
1564
0
                case gs_color_space_index_CIEDEF:
1565
0
                case gs_color_space_index_CIEABC:
1566
0
                case gs_color_space_index_DeviceGray:
1567
0
                    convert_to_process_colors = 1;
1568
0
                    pdf_set_process_color_model(pdev, 0);
1569
0
                    break;
1570
0
                case gs_color_space_index_DeviceRGB:
1571
0
                    convert_to_process_colors = 1;
1572
0
                    pdf_set_process_color_model(pdev, 1);
1573
0
                    break;
1574
0
                case gs_color_space_index_CIEDEFG:
1575
0
                case gs_color_space_index_DeviceCMYK:
1576
0
                    convert_to_process_colors = 1;
1577
0
                    pdf_set_process_color_model(pdev, 2);
1578
0
                    break;
1579
0
                default:
1580
0
                    break;
1581
0
            }
1582
0
            if (convert_to_process_colors == 1) {
1583
0
                pcs_orig = image->pixel.ColorSpace;
1584
0
                code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1585
0
                if (code < 0)
1586
0
                    goto fail_and_fallback;
1587
0
                image[0].pixel.ColorSpace = pcs_device;
1588
0
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1589
0
                                         in_line, NULL, 0, false);
1590
0
                if (code < 0)
1591
0
                    goto fail_and_fallback;
1592
0
            }
1593
0
        }
1594
53.4k
    }
1595
    /* If we are not preserving the colour space unchanged, then we can't pass through JPEG */
1596
1.27k
    else
1597
1.27k
        pdev->JPEG_PassThrough = pdev->JPX_PassThrough = 0;
1598
1599
    /* Code below here deals with setting up the multiple data stream writing.
1600
     * We can have up to 4 stream writers, which we keep in an array. We must
1601
     * always have at least one which writes the uncompressed stream. If we
1602
     * are writing compressed streams, we have one for the compressed stream
1603
     * and one for the compression chooser.
1604
     * For type 4 images being converted (for old versions of PDF or for ps2write)
1605
     * we need an additional stream to write a mask, which masks the real
1606
     * image.
1607
     * For colour conversion we will place an additional filter in front of all
1608
     * the streams which does the conversion.
1609
     */
1610
54.6k
    if (in_line) {
1611
50.5k
        pdev->JPEG_PassThrough = 0;
1612
50.5k
        pdev->JPX_PassThrough = 0;
1613
50.5k
        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1614
50.5k
                                             &pie->writer.binary[0],
1615
50.5k
                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
1616
50.5k
    } else {
1617
4.13k
        if (force_lossless) {
1618
            /*
1619
             * Some regrettable PostScript code (such as LanguageLevel 1 output
1620
             * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
1621
             * function to accomplish the equivalent of indexed color.
1622
             * Downsampling (well, only averaging) or JPEG compression are not
1623
             * compatible with this.  Play it safe by using only lossless
1624
             * filters if the transfer function(s) is/are other than the
1625
             * identity and by setting the downsample type to Subsample..
1626
             */
1627
729
            int saved_downsample = pdev->params.ColorImage.DownsampleType;
1628
1629
729
            pdev->params.ColorImage.DownsampleType = ds_Subsample;
1630
729
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1631
729
                                          &pie->writer.binary[0], &image[0].pixel,
1632
729
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1633
729
            pdev->params.ColorImage.DownsampleType = saved_downsample;
1634
3.40k
        } else {
1635
3.40k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1636
3.40k
                                          &pie->writer.binary[0], &image[0].pixel,
1637
3.40k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1638
3.40k
        }
1639
4.13k
    }
1640
1641
54.6k
    if (code < 0)
1642
0
        goto fail_and_fallback;
1643
1644
54.6k
    if (convert_to_process_colors) {
1645
1.27k
        image[0].pixel.ColorSpace = pcs_orig;
1646
1.27k
        image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
1647
1.27k
        code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1648
1.27k
                                              (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
1649
1.27k
        if (code < 0)
1650
0
            goto fail_and_fallback;
1651
1.27k
        image[0].pixel.ColorSpace = pcs_device;
1652
1.27k
    }
1653
1654
54.6k
    if (pdev->JPEG_PassThrough || pdev->JPX_PassThrough) {
1655
452
        pdev->PassThroughWriter = pie->writer.binary[0].strm;
1656
452
        pie->writer.alt_writer_count = 1;
1657
452
    }
1658
54.6k
    pie->JPEG_PassThrough = pdev->JPEG_PassThrough;
1659
54.6k
    pie->JPX_PassThrough = pdev->JPX_PassThrough;
1660
1661
54.6k
    if (pie->writer.alt_writer_count > 1) {
1662
2.87k
        code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1663
2.87k
        if (code < 0)
1664
0
            goto fail_and_fallback;
1665
2.87k
        code = new_setup_image_filters((gx_device_psdf *) pdev,
1666
2.87k
                                  &pie->writer.binary[1], &image[1].pixel,
1667
2.87k
                                  pmat, pgs, force_lossless, in_line, convert_to_process_colors);
1668
2.87k
        if (code == gs_error_rangecheck) {
1669
1670
64
            for (i=1;i < pie->writer.alt_writer_count; i++) {
1671
32
                stream *s = pie->writer.binary[i].strm;
1672
32
                cos_stream_t *pcos = cos_stream_from_pipeline(pie->writer.binary[i].strm);
1673
32
                s_close_filters(&s, NULL);
1674
32
                gs_free_object(pdev->pdf_memory, s, "compressed image stream");
1675
32
                if (pcos == 0L) {
1676
                    /* TODO: Seems like something should be freed here */
1677
0
                    code = gs_note_error(gs_error_ioerror);
1678
0
                    goto exit;
1679
0
                }
1680
32
                pcos->cos_procs->release((cos_object_t *)pcos, "pdf_begin_typed_image_impl");
1681
32
                gs_free_object(pdev->pdf_memory, pcos, "compressed image cos_stream");
1682
32
            }
1683
            /* setup_image_compression rejected the alternative compression. */
1684
32
            pie->writer.alt_writer_count = 1;
1685
32
            memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1686
32
            memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1687
2.84k
        } else if (code) {
1688
0
            goto fail_and_fallback;
1689
2.84k
        } else if (convert_to_process_colors) {
1690
0
            image[1].pixel.ColorSpace = pcs_orig;
1691
0
            image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
1692
0
            code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
1693
0
                                              (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
1694
0
            if (code < 0)
1695
0
                goto fail_and_fallback;
1696
0
            image[1].pixel.ColorSpace = pcs_device;
1697
0
        }
1698
2.87k
    }
1699
1700
112k
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1701
57.5k
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1702
57.5k
                             &image[i].pixel, &cs_value, pie);
1703
57.5k
        if (code < 0)
1704
0
            goto fail_and_fallback;
1705
57.5k
    }
1706
54.6k
    if (pie->writer.alt_writer_count == 2) {
1707
2.84k
        psdf_setup_compression_chooser(&pie->writer.binary[2],
1708
2.84k
             (gx_device_psdf *)pdev, pim->Width, pim->Height,
1709
2.84k
             num_components, pim->BitsPerComponent);
1710
2.84k
        pie->writer.alt_writer_count = 3;
1711
2.84k
    }
1712
54.6k
    if (pic->type->index == 4 && pdev->CompatibilityLevel < 1.3) {
1713
0
        int i;
1714
1715
        /* Create a stream for writing the mask. */
1716
0
        i = pie->writer.alt_writer_count;
1717
0
        gs_image_t_init_mask_adjust((gs_image_t *)&image[i].type1, true, false);
1718
0
        image[i].type1.Width = image[0].pixel.Width;
1719
0
        image[i].type1.Height = image[0].pixel.Height;
1720
        /* Won't use image[2]. */
1721
0
        code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1722
0
                    height, NULL, false);
1723
0
        if (code < 0)
1724
0
            goto fail_and_fallback;
1725
0
        code = psdf_setup_image_filters((gx_device_psdf *) pdev,
1726
0
                                  &pie->writer.binary[i], &image[i].pixel,
1727
0
                                  pmat, pgs, force_lossless, in_line);
1728
0
        if (code < 0)
1729
0
            goto fail_and_fallback;
1730
        /* Bug701972 -- added input_width arg here.  For this case, just passing in the same
1731
         * width as before, so nothing changes.  This is an obscure case that isn't tested
1732
         * on the cluster (note that it requires CompatibilityLevel < 1.3).
1733
         */
1734
0
        psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
1735
0
                                        (gx_device_psdf *)pdev, pim->Width, pim->Height, pim->Width,
1736
0
                                        num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
1737
0
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1738
0
                             &image[i].pixel, &cs_value, pie);
1739
0
        if (code < 0)
1740
0
            goto fail_and_fallback;
1741
0
        ++pie->writer.alt_writer_count;
1742
0
    }
1743
1744
    /* use_fallback = 0, so this will drop through the below labels, doing only the cleanup parts */
1745
54.6k
    code = 0;
1746
1747
    /* This label is used when code < 0 and we want to do the fallback code */
1748
55.2k
 fail_and_fallback:
1749
55.2k
    if (code != 0)
1750
138
        use_fallback = 1;
1751
1752
    /* This label is used either when there's no error and we are just exiting normally
1753
     * (possibly with use_fallback=1), or there is an error but we don't want to do
1754
     * the fallback code.
1755
     */
1756
56.6k
 exit:
1757
    /* Free everything */
1758
56.6k
    rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1759
56.6k
    rc_decrement(pcs_device, "pdf_begin_typed_image(pcs_device)");
1760
56.6k
    gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1761
56.6k
                                      "pdf_begin_typed_image(image)");
1762
1763
    /* Free pie only if there was an error or we are falling back */
1764
56.6k
    if (code < 0 || use_fallback) {
1765
552
        if (pie)
1766
384
            gs_free_object(mem, pie, "pdf_begin_typed_image(pie)");
1767
552
        *pinfo = NULL;
1768
552
    }
1769
    /* Do the fallback */
1770
56.6k
    if (use_fallback) {
1771
538
        pdev->JPEG_PassThrough = 0;
1772
538
        pdev->JPX_PassThrough = 0;
1773
538
        code = gx_default_begin_typed_image
1774
538
            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo);
1775
538
    }
1776
56.6k
    return code;
1777
55.2k
}
1778
1779
int
1780
gdev_pdf_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
1781
                           const gs_matrix *pmat, const gs_image_common_t *pic,
1782
                           const gs_int_rect * prect,
1783
                           const gx_drawing_color * pdcolor,
1784
                           const gx_clip_path * pcpath, gs_memory_t * mem,
1785
                           gx_image_enum_common_t ** pinfo)
1786
54.0k
{
1787
54.0k
    return pdf_begin_typed_image((gx_device_pdf *)dev, pgs, pmat, pic, prect,
1788
54.0k
                                 pdcolor, pcpath, mem, pinfo,
1789
54.0k
                                 PDF_IMAGE_DEFAULT);
1790
54.0k
}
1791
1792
/* ---------------- All images ---------------- */
1793
1794
/* Process the next piece of an image. */
1795
static int
1796
pdf_image_plane_data_alt(gx_image_enum_common_t * info,
1797
                     const gx_image_plane_t * planes, int height,
1798
                     int *rows_used, int alt_writer_index)
1799
3.63M
{
1800
3.63M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1801
3.63M
    int h = height;
1802
3.63M
    int y;
1803
    /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
1804
3.63M
    uint width_bits = pie->width * pie->plane_depths[0];
1805
    /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
1806
3.63M
    uint ignore;
1807
3.63M
    int nplanes = pie->num_planes;
1808
3.63M
    int status = 0;
1809
3.63M
    uint bcount = (width_bits + 7) >> 3;
1810
1811
3.63M
    if (h > pie->rows_left)
1812
41.0k
        h = pie->rows_left;
1813
8.44M
    for (y = 0; y < h; ++y) {
1814
4.81M
        if (nplanes > 1) {
1815
            /*
1816
             * We flip images in blocks, and each block except the last one
1817
             * must contain an integral number of pixels.  The easiest way
1818
             * to meet this condition is for all blocks except the last to
1819
             * be a multiple of 3 source bytes (guaranteeing an integral
1820
             * number of 1/2/4/8/12-bit samples), i.e., 3*nplanes flipped
1821
             * bytes.  This requires a buffer of at least
1822
             * 3*GS_IMAGE_MAX_COMPONENTS bytes.
1823
             */
1824
3.02k
            int pi;
1825
3.02k
            uint count = bcount;
1826
3.02k
            uint offset = 0;
1827
3.02k
#define ROW_BYTES max(200 /*arbitrary*/, 3 * GS_IMAGE_MAX_COMPONENTS)
1828
3.02k
            const byte *bit_planes[GS_IMAGE_MAX_COMPONENTS];
1829
3.02k
            int block_bytes = ROW_BYTES / (3 * nplanes) * 3;
1830
3.02k
            byte row[ROW_BYTES];
1831
1832
12.1k
            for (pi = 0; pi < nplanes; ++pi)
1833
9.07k
                bit_planes[pi] = planes[pi].data + planes[pi].raster * y;
1834
24.2k
            while (count) {
1835
21.1k
                uint flip_count;
1836
21.1k
                uint flipped_count;
1837
1838
21.1k
                if (count > block_bytes) {
1839
18.1k
                    flip_count = block_bytes;
1840
18.1k
                    flipped_count = block_bytes * nplanes;
1841
18.1k
                } else {
1842
3.02k
                    flip_count = count;
1843
3.02k
                    flipped_count =
1844
3.02k
                        (width_bits % (block_bytes * 8) * nplanes + 7) >> 3;
1845
                    /* In case the width of the image is a precise multiple of our block size */
1846
3.02k
                    if (flipped_count == 0)
1847
0
                        flipped_count = block_bytes * nplanes;
1848
3.02k
                }
1849
21.1k
                status = image_flip_planes(row, bit_planes, offset, flip_count,
1850
21.1k
                                           nplanes, pie->plane_depths[0]);
1851
21.1k
                if (status < 0)
1852
0
                    break;
1853
21.1k
                status = sputs(pie->writer.binary[alt_writer_index].strm, row,
1854
21.1k
                               flipped_count, &ignore);
1855
21.1k
                if (status < 0)
1856
0
                    break;
1857
21.1k
                offset += flip_count;
1858
21.1k
                count -= flip_count;
1859
21.1k
            }
1860
4.80M
        } else {
1861
4.80M
            status = sputs(pie->writer.binary[alt_writer_index].strm,
1862
4.80M
                           planes[0].data + planes[0].raster * y, bcount,
1863
4.80M
                           &ignore);
1864
4.80M
        }
1865
4.81M
        if (status < 0)
1866
0
            break;
1867
4.81M
    }
1868
3.63M
    *rows_used = h;
1869
3.63M
    if (status < 0)
1870
0
        return_error(gs_error_ioerror);
1871
3.63M
    return !pie->rows_left;
1872
3.63M
#undef ROW_BYTES
1873
3.63M
}
1874
1875
static int
1876
pdf_image_plane_data(gx_image_enum_common_t * info,
1877
                     const gx_image_plane_t * planes, int height,
1878
                     int *rows_used)
1879
3.53M
{
1880
3.53M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1881
3.53M
    int i;
1882
1883
3.53M
    if (info->pgs != NULL && info->pgs->level < info->pgs_level)
1884
0
        return_error(gs_error_undefinedresult);
1885
1886
3.53M
    if (pie->JPEG_PassThrough || pie->JPX_PassThrough) {
1887
54.9k
        pie->rows_left -= height;
1888
54.9k
        *rows_used = height;
1889
54.9k
        return !pie->rows_left;
1890
54.9k
    }
1891
1892
7.11M
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1893
3.63M
        int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
1894
3.63M
        if (code)
1895
0
            return code;
1896
3.63M
    }
1897
3.47M
    pie->rows_left -= *rows_used;
1898
3.47M
    if (pie->writer.alt_writer_count > 2)
1899
80.1k
        pdf_choose_compression(&pie->writer, false);
1900
1901
3.47M
    return !pie->rows_left;
1902
3.47M
}
1903
1904
static int
1905
use_image_as_pattern(gx_device_pdf *pdev, pdf_resource_t *pres1,
1906
                     const gs_matrix *pmat, gs_id id)
1907
0
{   /* See also dump_image in gdevpdfd.c . */
1908
0
    gs_gstate s;
1909
0
    gs_pattern1_instance_t inst;
1910
0
    cos_value_t v;
1911
0
    const pdf_resource_t *pres;
1912
0
    int code;
1913
1914
0
    memset(&s, 0, sizeof(s));
1915
0
    s.ctm.xx = pmat->xx;
1916
0
    s.ctm.xy = pmat->xy;
1917
0
    s.ctm.yx = pmat->yx;
1918
0
    s.ctm.yy = pmat->yy;
1919
0
    s.ctm.tx = pmat->tx;
1920
0
    s.ctm.ty = pmat->ty;
1921
0
    memset(&inst, 0, sizeof(inst));
1922
0
    inst.saved = (gs_gstate *)&s; /* HACK : will use s.ctm only. */
1923
0
    inst.templat.PaintType = 1;
1924
0
    inst.templat.TilingType = 1;
1925
0
    inst.templat.BBox.p.x = inst.templat.BBox.p.y = 0;
1926
0
    inst.templat.BBox.q.x = 1;
1927
0
    inst.templat.BBox.q.y = 1;
1928
0
    inst.templat.XStep = 2; /* Set 2 times bigger step against artifacts. */
1929
0
    inst.templat.YStep = 2;
1930
1931
0
    {
1932
0
        pattern_accum_param_s param;
1933
0
        param.pinst = (void *)&inst;
1934
0
        param.graphics_state = (void *)&s;
1935
0
        param.pinst_id = inst.id;
1936
1937
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1938
0
            gxdso_pattern_start_accum, &param, sizeof(pattern_accum_param_s));
1939
0
    }
1940
1941
0
    if (code >= 0)
1942
0
        pprinti64d1(pdev->strm, "/R%"PRId64" Do\n", pdf_resource_id(pres1));
1943
0
    pres = pdev->accumulating_substream_resource;
1944
0
    if (pres == NULL)
1945
0
        code = gs_note_error(gs_error_unregistered);
1946
0
    if (code >= 0)
1947
0
        code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres1);
1948
0
    if (code >= 0) {
1949
0
        pattern_accum_param_s param;
1950
0
        param.pinst = (void *)&inst;
1951
0
        param.graphics_state = (void *)&s;
1952
0
        param.pinst_id = inst.id;
1953
1954
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1955
0
            gxdso_pattern_finish_accum, &param, id);
1956
0
    }
1957
0
    if (code >= 0)
1958
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1959
0
            gxdso_pattern_load, &id, sizeof(gs_id));
1960
0
    if (code >= 0) {
1961
0
        stream_puts(pdev->strm, "q ");
1962
0
        code = pdf_cs_Pattern_colored(pdev, &v);
1963
0
    }
1964
0
    if (code >= 0) {
1965
0
        cos_value_write(&v, pdev);
1966
0
        pprinti64d1(pdev->strm, " cs /R%"PRId64" scn ", pdf_resource_id(pres));
1967
0
    }
1968
0
    if (code >= 0) {
1969
        /* The image offset weas broken in gx_begin_image3_generic,
1970
           (see 'origin' in there).
1971
           As a temporary hack use the offset of the image.
1972
           fixme : This isn't generally correct,
1973
           because the mask may be "transpozed" against the image. */
1974
0
        gs_matrix m = pdev->converting_image_matrix;
1975
1976
0
        m.tx = pmat->tx;
1977
0
        m.ty = pmat->ty;
1978
0
        code = pdf_do_image_by_id(pdev, pdev->image_mask_scale,
1979
0
             &m, true, pdev->image_mask_id);
1980
0
        stream_puts(pdev->strm, "Q\n");
1981
0
    }
1982
0
    return code;
1983
0
}
1984
1985
typedef enum {
1986
    USE_AS_MASK,
1987
    USE_AS_IMAGE,
1988
    USE_AS_PATTERN
1989
} pdf_image_usage_t;
1990
1991
/* Close PDF image and do it. */
1992
static int
1993
pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
1994
                     const gs_matrix *mat, gs_id ps_bitmap_id, pdf_image_usage_t do_image)
1995
52.4k
{
1996
52.4k
    int code = 0;
1997
52.4k
    pdf_resource_t *pres = NULL;
1998
1999
    /* In order to identify duplicated images which use the same SMask we must
2000
     * add the SMask entry to the image dictionary before we call pdf_end_write_image
2001
     * because that will hash the dictionaries and streams. If we haven't already
2002
     * added the SMask then the hash will not match any existing image which uses an SMask.
2003
     */
2004
52.4k
    if (do_image == USE_AS_IMAGE) {
2005
51.2k
        if (pdev->image_mask_id != gs_no_id && piw->pres && piw->pres->object) {
2006
1.16k
            char buf[20];
2007
2008
1.16k
            gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->image_mask_id);
2009
1.16k
            code = cos_dict_put_string_copy((cos_dict_t *)piw->pres->object,
2010
1.16k
                    pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
2011
1.16k
            (*(piw->pres->object)).md5_valid = 0;
2012
1.16k
            if (code < 0)
2013
0
                return code;
2014
1.16k
        }
2015
51.2k
    }
2016
2017
52.4k
    code = pdf_end_write_image(pdev, piw);
2018
52.4k
    pres = piw->pres;
2019
2020
52.4k
    switch (code) {
2021
0
    default:
2022
0
        return code; /* error */
2023
48.9k
    case 1:
2024
48.9k
        code = 0;
2025
48.9k
        break;
2026
3.49k
    case 0:
2027
3.49k
        if (do_image == USE_AS_IMAGE) {
2028
2.33k
            if (pdev->image_mask_skip)
2029
0
                code = 0;
2030
2.33k
            else
2031
2.33k
                code = pdf_do_image(pdev, pres, mat, true);
2032
2.33k
        } else if (do_image == USE_AS_MASK) {
2033
            /* Provide data for pdf_do_image_by_id, which will be called through
2034
                use_image_as_pattern during the next call to this function.
2035
                See pdf_do_image about the meaning of 'scale'. */
2036
1.16k
            const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
2037
2038
1.16k
            pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
2039
1.16k
            pdev->image_mask_id = pdf_resource_id(pres);
2040
1.16k
            pdev->converting_image_matrix = *mat;
2041
1.16k
        } else if (do_image == USE_AS_PATTERN)
2042
0
            code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
2043
52.4k
    }
2044
52.4k
    return code;
2045
52.4k
}
2046
2047
/* Clean up by releasing the buffers. */
2048
static int
2049
pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
2050
                         pdf_image_usage_t do_image)
2051
54.6k
{
2052
54.6k
    gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
2053
54.6k
    pdf_image_enum *pie = (pdf_image_enum *)info;
2054
54.6k
    int height = pie->writer.height;
2055
54.6k
    int data_height = height - pie->rows_left;
2056
54.6k
    int code = 0, ecode;
2057
2058
54.6k
    if (pie->writer.pres)
2059
4.13k
        ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
2060
50.5k
    else if (data_height > 0)
2061
48.9k
        pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
2062
54.6k
    if (data_height > 0) {
2063
52.4k
        if (pie->writer.pres) {
2064
3.49k
            code = pdf_complete_image_data(pdev, &pie->writer, data_height,
2065
3.49k
                        pie->width, pie->bits_per_pixel);
2066
3.49k
            if (code < 0)
2067
0
                return code;
2068
3.49k
        }
2069
        /* This closes the stream pointed to by PassThroughWriter
2070
           so we need to NULL that pointer
2071
         */
2072
52.4k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2073
52.4k
        pdev->PassThroughWriter = NULL;
2074
52.4k
        pdev->JPX_PassThrough = false;
2075
52.4k
        pdev->JPEG_PassThrough = false;
2076
        /* The call above possibly decreases pie->writer.alt_writer_count in 2. */
2077
52.4k
        if (code < 0)
2078
1
            return code;
2079
52.4k
        if (pie->writer.alt_writer_count == 2) {
2080
            /* We're converting a type 4 image into an imagemask with a pattern color. */
2081
            /* Since the type 3 image writes the mask first, do so here. */
2082
0
            pdf_image_writer writer = pie->writer;
2083
2084
0
            writer.binary[0] = pie->writer.binary[1];
2085
0
            writer.pres = pie->writer.pres_mask;
2086
0
            writer.alt_writer_count = 1;
2087
0
            memset(&pie->writer.binary[1], 0, sizeof(pie->writer.binary[1]));
2088
0
            pie->writer.alt_writer_count--; /* For GC. */
2089
0
            pie->writer.pres_mask = 0; /* For GC. */
2090
0
            code = pdf_end_image_binary(pdev, &writer, data_height);
2091
0
            if (code < 0)
2092
0
                return code;
2093
0
            code = pdf_end_and_do_image(pdev, &writer, &pie->mat, info->id, USE_AS_MASK);
2094
0
            if (code < 0)
2095
0
                return code;
2096
0
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, USE_AS_PATTERN);
2097
0
        } else
2098
52.4k
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
2099
52.4k
        pie->writer.alt_writer_count--; /* For GC. */
2100
52.4k
    } else {
2101
        /* This closes the stream pointed to by PassThroughWriter
2102
           so we need to NULL that pointer
2103
         */
2104
2.28k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2105
2.28k
        pdev->PassThroughWriter = NULL;
2106
2.28k
        pdev->JPX_PassThrough = false;
2107
2.28k
        pdev->JPEG_PassThrough = false;
2108
2.28k
        code = pdf_end_abort_image(pdev, &pie->writer);
2109
2.28k
        pie->writer.alt_writer_count--; /* For GC. */
2110
2.28k
    }
2111
54.6k
    if (pie->initial_colorspace != pdev->pcm_color_info_index)
2112
0
        pdf_set_process_color_model(pdev, pie->initial_colorspace);
2113
2114
    /* Clean up any outstanding streams before freeing the enumerator */
2115
54.6k
    while (pie->writer.alt_writer_count-- > 0) {
2116
0
        ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
2117
        /* If we are skipping an image (because its clipped out or similar) then we
2118
         * won't have written any data to it. Some filters (notably the DCTEncode filter)
2119
         * throw an error (premature EOD) if we close the filter without writing any data to it.
2120
         * So if we are skipping the image, ignore errors when closing the stream.
2121
         * Unfortunately we don't set pie->skipping until after begin_typed_image()
2122
         * or we could avoid a lot of setup....
2123
         */
2124
0
        if (ecode < 0 && code >= 0 && !pie->skipping) code  = ecode;
2125
0
    }
2126
2127
54.6k
    gx_image_free_enum(&info);
2128
54.6k
    return code;
2129
54.6k
}
2130
2131
/* End a normal image, drawing it. */
2132
static int
2133
pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
2134
53.4k
{
2135
53.4k
    return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
2136
53.4k
}
2137
2138
/* End an image converted with pdf_lcvd_t. */
2139
static int
2140
pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
2141
22
{   pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
2142
22
    int code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
2143
22
    int code1 = gx_image1_end_image(info, draw_last);
2144
22
    int code2 = gs_closedevice((gx_device *)cvd->mask);
2145
22
    int code3 = gs_closedevice((gx_device *)cvd);
2146
2147
22
    gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
2148
22
    gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
2149
22
    return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
2150
22
}
2151
/* ---------------- Type 3/3x images ---------------- */
2152
2153
/*
2154
 * For both types of masked images, we create temporary dummy (null) devices
2155
 * that forward the begin_typed_image call to the implementation above.
2156
 */
2157
static int
2158
pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
2159
2.55k
{
2160
2.55k
    gx_device *fdev;
2161
2.55k
    int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
2162
2163
2.55k
    if (code < 0)
2164
0
        return code;
2165
2.55k
    gx_device_set_target((gx_device_forward *)fdev, tdev);
2166
2.55k
    *pmxdev = fdev;
2167
2.55k
    return 0;
2168
2.55k
}
2169
2170
/* End the mask of an ImageType 3 image, not drawing it. */
2171
static int
2172
pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
2173
1.27k
{
2174
1.27k
    return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
2175
1.27k
}
2176
/* End the data of an ImageType 3 image, converting it into pattern. */
2177
static int
2178
pdf_image_end_image_object2(gx_image_enum_common_t * info, bool draw_last)
2179
0
{
2180
0
    return pdf_image_end_image_data(info, draw_last, USE_AS_PATTERN);
2181
0
}
2182
2183
/* ---------------- Type 3 images ---------------- */
2184
2185
/* Implement the mask image device. */
2186
static dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
2187
static int
2188
pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2189
                    gs_memory_t *mem)
2190
84
{
2191
84
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2192
2193
84
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2194
84
        gs_matrix m;
2195
84
        pdf_lcvd_t *cvd = NULL;
2196
84
        int code;
2197
2198
84
        gs_make_identity(&m);
2199
84
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
2200
84
                                        true, 0, 0, width, height, true);
2201
84
        if (code < 0)
2202
0
            return code;
2203
84
        cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
2204
                                         pdf_image3_make_mcde. The latter will reset it. */
2205
84
        cvd->mask_is_empty = false;
2206
84
        *pmidev = (gx_device *)cvd->mask;
2207
84
        return 0;
2208
84
    } else {
2209
0
        int code = pdf_make_mxd(pmidev, dev, mem);
2210
2211
0
        if (code < 0)
2212
0
            return code;
2213
0
        set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2214
0
        return 0;
2215
0
    }
2216
84
}
2217
static int
2218
pdf_mid_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
2219
                          const gs_matrix *pmat, const gs_image_common_t *pic,
2220
                          const gs_int_rect * prect,
2221
                          const gx_drawing_color * pdcolor,
2222
                          const gx_clip_path * pcpath, gs_memory_t * mem,
2223
                          gx_image_enum_common_t ** pinfo)
2224
1.27k
{
2225
    /* The target of the null device is the pdfwrite device. */
2226
1.27k
    gx_device_pdf *const pdev = (gx_device_pdf *)
2227
1.27k
        ((gx_device_null *)dev)->target;
2228
1.27k
    return pdf_begin_typed_image
2229
1.27k
        (pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
2230
1.27k
         PDF_IMAGE_TYPE3_MASK);
2231
1.27k
}
2232
2233
/* Implement the mask clip device. */
2234
static int
2235
pdf_image3_make_mcde(gx_device *dev, const gs_gstate *pgs,
2236
                     const gs_matrix *pmat, const gs_image_common_t *pic,
2237
                     const gs_int_rect *prect, const gx_drawing_color *pdcolor,
2238
                     const gx_clip_path *pcpath, gs_memory_t *mem,
2239
                     gx_image_enum_common_t **pinfo,
2240
                     gx_device **pmcdev, gx_device *midev,
2241
                     gx_image_enum_common_t *pminfo,
2242
                     const gs_int_point *origin)
2243
84
{
2244
84
    int code;
2245
84
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2246
2247
84
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2248
        /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
2249
84
        pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
2250
2251
84
        ((gx_device_memory *)midev)->target = NULL;
2252
84
        cvd->m = pdev->converting_image_matrix;
2253
84
        cvd->mdev.mapped_x = origin->x;
2254
84
        cvd->mdev.mapped_y = origin->y;
2255
84
        cvd->mdev.width += origin->x;
2256
84
        cvd->mdev.height += origin->y;
2257
84
        *pmcdev = (gx_device *)&cvd->mdev;
2258
84
        code = gx_default_begin_typed_image
2259
84
            ((gx_device *)&cvd->mdev, pgs, pmat, pic, prect, pdcolor, NULL, mem,
2260
84
            pinfo);
2261
84
        if (code < 0)
2262
0
            return code;
2263
84
    } else {
2264
0
        code = pdf_make_mxd(pmcdev, midev, mem);
2265
0
        if (code < 0)
2266
0
            return code;
2267
0
        code = pdf_begin_typed_image
2268
0
            ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2269
0
            pinfo, PDF_IMAGE_TYPE3_DATA);
2270
0
        if (code < 0) {
2271
0
            gx_device_set_target((gx_device_forward *)(*pmcdev), NULL);
2272
0
            gs_closedevice((*pmcdev));
2273
0
            gs_free_object(mem, (*pmcdev), "pdf_image3_make_mcde(*pmcdev)");
2274
0
            *pmcdev = NULL;
2275
0
            return code;
2276
0
        }
2277
0
    }
2278
    /* Due to equal image merging, we delay the adding of the "Mask" entry into
2279
       a type 3 image dictionary until the mask is completed.
2280
       Will do in pdf_end_and_do_image.*/
2281
84
    return 0;
2282
84
}
2283
2284
/* ---------------- Type 3x images ---------------- */
2285
2286
/* Implement the mask image device. */
2287
static int
2288
pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2289
                     int depth, gs_memory_t *mem)
2290
1.27k
{
2291
1.27k
    int code = pdf_make_mxd(pmidev, dev, mem);
2292
2293
1.27k
    if (code < 0)
2294
0
        return code;
2295
1.27k
    set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2296
1.27k
    return 0;
2297
1.27k
}
2298
2299
/* Implement the mask clip device. */
2300
static int
2301
pdf_image3x_make_mcde(gx_device *dev, const gs_gstate *pgs,
2302
                      const gs_matrix *pmat, const gs_image_common_t *pic,
2303
                      const gs_int_rect *prect,
2304
                      const gx_drawing_color *pdcolor,
2305
                      const gx_clip_path *pcpath, gs_memory_t *mem,
2306
                      gx_image_enum_common_t **pinfo,
2307
                      gx_device **pmcdev, gx_device *midev[2],
2308
                      gx_image_enum_common_t *pminfo[2],
2309
                      const gs_int_point origin[2],
2310
                      const gs_image3x_t *pim)
2311
1.27k
{
2312
1.27k
    int code;
2313
1.27k
    pdf_image_enum *pmie;
2314
1.27k
    int i;
2315
1.27k
    const gs_image3x_mask_t *pixm;
2316
1.27k
    gx_device_pdf *pdf_dev = (gx_device_pdf *)dev;
2317
2318
1.27k
    if (midev[0]) {
2319
1.27k
        if (midev[1])
2320
0
            return_error(gs_error_rangecheck);
2321
1.27k
        i = 0, pixm = &pim->Opacity;
2322
1.27k
    } else if (midev[1])
2323
2
        i = 1, pixm = &pim->Shape;
2324
0
    else
2325
0
        return_error(gs_error_rangecheck);
2326
1.27k
    code = pdf_make_mxd(pmcdev, midev[i], mem);
2327
1.27k
    if (code < 0)
2328
0
        return code;
2329
2330
1.27k
    if (pminfo[0] != NULL)
2331
1.27k
        pdf_dev->PendingOC = pminfo[0]->OC;
2332
2
    else
2333
2
        pdf_dev->PendingOC = 0;
2334
2335
1.27k
    code = pdf_begin_typed_image
2336
1.27k
        ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2337
1.27k
         pinfo, PDF_IMAGE_TYPE3_DATA);
2338
1.27k
    pdf_dev->PendingOC = 0;
2339
1.27k
    if (code < 0) {
2340
0
        rc_decrement(*pmcdev, "pdf_image3x_make_mcde");
2341
0
        return code;
2342
0
    }
2343
1.27k
    if ((*pinfo)->procs != &pdf_image_enum_procs) {
2344
        /* We couldn't handle the image.  Bail out. */
2345
0
        gx_image_end(*pinfo, false);
2346
0
        gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
2347
0
        return_error(gs_error_rangecheck);
2348
0
    }
2349
1.27k
    pmie = (pdf_image_enum *)pminfo[i];
2350
1.27k
    if (pmie->writer.alt_writer_count == 3) {
2351
1.24k
        cos_stream_t *s;
2352
2353
1.24k
        s = cos_stream_from_pipeline(pmie->writer.binary[1].strm);
2354
1.24k
        s_close_filters(&pmie->writer.binary[1].strm, pmie->writer.binary[1].target);
2355
1.24k
        s->cos_procs->release((cos_object_t *)s, "pdf_image_choose_filter");
2356
1.24k
        s->written = 1;
2357
1.24k
        s_close_filters(&pmie->writer.binary[2].strm, pmie->writer.binary[2].target);
2358
1.24k
        pmie->writer.binary[1].strm = pmie->writer.binary[2].strm = 0; /* for GC */
2359
1.24k
        pmie->writer.binary[1].target = pmie->writer.binary[2].target = 0;
2360
1.24k
        pmie->writer.alt_writer_count = 1;
2361
1.24k
    }
2362
    /*
2363
     * Add the SMask entry to the image dictionary, and, if needed,
2364
     * the Matte entry to the mask dictionary.
2365
     */
2366
1.27k
    if (pixm->has_Matte) {
2367
1
        gx_device_pdf *pdev = (gx_device_pdf *)dev;
2368
1
        int DoMatte = 0, num_components =
2369
1
            gs_color_space_num_components(pim->ColorSpace);
2370
2371
1
        switch (pdev->params.ColorConversionStrategy) {
2372
1
            case ccs_LeaveColorUnchanged:
2373
1
                DoMatte = 1;
2374
1
                break;
2375
0
            case ccs_RGB:
2376
0
            case ccs_sRGB:
2377
0
                if (num_components == 3)
2378
0
                    DoMatte = 1;
2379
0
                else
2380
0
                    DoMatte = 0;
2381
0
                break;
2382
0
            case ccs_CMYK:
2383
0
                if (num_components == 4)
2384
0
                    DoMatte = 1;
2385
0
                else
2386
0
                    DoMatte = 0;
2387
0
                break;
2388
0
            case ccs_Gray:
2389
0
                if (num_components == 1)
2390
0
                    DoMatte = 1;
2391
0
                else
2392
0
                    DoMatte = 0;
2393
0
                break;
2394
0
            case ccs_UseDeviceIndependentColor:
2395
0
            case ccs_UseDeviceIndependentColorForImages:
2396
0
            case ccs_ByObjectType:
2397
0
            default:
2398
0
                DoMatte = 0;
2399
0
                break;
2400
1
        }
2401
2402
1
        if (DoMatte) {
2403
1
            int code;
2404
2405
1
            code = cos_dict_put_c_key_floats((gx_device_pdf *)dev,
2406
1
                                    (cos_dict_t *)pmie->writer.pres->object,
2407
1
                                    "/Matte", pixm->Matte,
2408
1
                                    num_components);
2409
1
            if (code < 0)
2410
0
                return code;
2411
1
        }
2412
1
    }
2413
/* Don't put SMask here because pmie->writer.pres->object may be substituted
2414
 * after the image stream is accummulated. pdf_end_and_do_image will set
2415
 * SMask with the right value. Bug 690345.
2416
 */
2417
1.27k
    return 0;
2418
1.27k
}
2419
2420
pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
2421
8.35k
{
2422
8.35k
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
2423
2424
8.35k
    return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
2425
8.35k
}
2426
2427
static int
2428
check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
2429
968
{
2430
968
    pdf_pattern_t *ppat0 = (pdf_pattern_t *)pres0;
2431
968
    pdf_pattern_t *ppat1 = (pdf_pattern_t *)pres1;
2432
2433
968
    return (ppat0->substitute == NULL && ppat1->substitute == NULL);
2434
968
}
2435
2436
static int
2437
check_unsubstituted1(gx_device_pdf * pdev, pdf_resource_t *pres0)
2438
0
{
2439
0
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
2440
2441
0
    return ppat->substitute != NULL;
2442
0
}
2443
2444
static int reset_gstate_for_pattern(gx_device_pdf * pdev, gs_gstate *destination, gs_gstate *source)
2445
5.06k
{
2446
5.06k
    if (pdev->vg_initial_set) {
2447
5.06k
        destination->strokeconstantalpha = source->strokeconstantalpha;
2448
5.06k
        source->strokeconstantalpha = pdev->vg_initial.strokeconstantalpha;
2449
5.06k
        destination->fillconstantalpha = source->fillconstantalpha;
2450
5.06k
        source->fillconstantalpha = pdev->vg_initial.fillconstantalpha;
2451
5.06k
        if (destination->set_transfer.red != NULL)
2452
0
            destination->set_transfer.red->id = (source->set_transfer.red != NULL ? source->set_transfer.red->id : 0);
2453
5.06k
        if (destination->set_transfer.green != NULL)
2454
0
            destination->set_transfer.green->id = (source->set_transfer.green != NULL ? source->set_transfer.green->id : 0);
2455
5.06k
        if (destination->set_transfer.blue != NULL)
2456
0
            destination->set_transfer.blue->id = (source->set_transfer.blue != NULL ? source->set_transfer.blue->id : 0);
2457
5.06k
        if (destination->set_transfer.gray != NULL)
2458
2.53k
            destination->set_transfer.gray->id = (source->set_transfer.gray != NULL ? source->set_transfer.gray->id : 0);
2459
5.06k
        if (source->set_transfer.red != NULL)
2460
0
            source->set_transfer.red->id = pdev->vg_initial.transfer_ids[0];
2461
5.06k
        if (source->set_transfer.green != NULL)
2462
0
            source->set_transfer.green->id = pdev->vg_initial.transfer_ids[1];
2463
5.06k
        if (source->set_transfer.blue != NULL)
2464
0
            source->set_transfer.blue->id = pdev->vg_initial.transfer_ids[2];
2465
5.06k
        if (source->set_transfer.gray != NULL)
2466
2.53k
            source->set_transfer.gray->id = pdev->vg_initial.transfer_ids[3];
2467
5.06k
        destination->alphaisshape = source->alphaisshape;
2468
5.06k
        source->alphaisshape = pdev->vg_initial.alphaisshape;
2469
5.06k
        destination->blend_mode = source->blend_mode;
2470
5.06k
        source->blend_mode = pdev->vg_initial.blend_mode;
2471
5.06k
        if (destination->black_generation != NULL)
2472
2.53k
            destination->black_generation->id = (source->black_generation != NULL ? source->black_generation->id : 0);
2473
5.06k
        if (source->black_generation != NULL)
2474
2.53k
            source->black_generation->id = pdev->vg_initial.black_generation_id;
2475
5.06k
        if (destination->undercolor_removal != NULL)
2476
2.53k
            destination->undercolor_removal->id = (source->undercolor_removal != NULL ? source->undercolor_removal->id : 0);
2477
5.06k
        if (source->undercolor_removal != NULL)
2478
2.53k
            source->undercolor_removal->id = pdev->vg_initial.undercolor_removal_id;
2479
5.06k
        destination->overprint_mode = source->overprint_mode;
2480
5.06k
        source->overprint_mode = pdev->vg_initial.overprint_mode;
2481
5.06k
        destination->flatness = source->flatness;
2482
5.06k
        source->flatness = pdev->vg_initial.flatness;
2483
5.06k
        destination->smoothness = source->smoothness;
2484
5.06k
        source->smoothness = pdev->vg_initial.smoothness;
2485
5.06k
        destination->flatness = source->flatness;
2486
5.06k
        source->flatness = pdev->vg_initial.flatness;
2487
5.06k
        destination->text_knockout = source->text_knockout;
2488
5.06k
        source->text_knockout = pdev->vg_initial.text_knockout;
2489
5.06k
        destination->stroke_adjust = source->stroke_adjust;
2490
5.06k
        source->stroke_adjust = pdev->vg_initial.stroke_adjust;
2491
5.06k
        destination->line_params.half_width = source->line_params.half_width;
2492
5.06k
        source->line_params.half_width = pdev->vg_initial.line_params.half_width;
2493
5.06k
        destination->line_params.start_cap = source->line_params.start_cap;
2494
5.06k
        source->line_params.start_cap = pdev->vg_initial.line_params.start_cap;
2495
5.06k
        destination->line_params.end_cap = source->line_params.end_cap;
2496
5.06k
        source->line_params.end_cap = pdev->vg_initial.line_params.end_cap;
2497
5.06k
        destination->line_params.dash_cap = source->line_params.dash_cap;
2498
5.06k
        source->line_params.dash_cap = pdev->vg_initial.line_params.dash_cap;
2499
5.06k
        destination->line_params.join = source->line_params.join;
2500
5.06k
        source->line_params.join = pdev->vg_initial.line_params.join;
2501
5.06k
        destination->line_params.curve_join = source->line_params.curve_join;
2502
5.06k
        source->line_params.curve_join = pdev->vg_initial.line_params.curve_join;
2503
5.06k
        destination->line_params.miter_limit = source->line_params.miter_limit;
2504
5.06k
        source->line_params.miter_limit = pdev->vg_initial.line_params.miter_limit;
2505
5.06k
        destination->line_params.miter_check = source->line_params.miter_check;
2506
5.06k
        source->line_params.miter_check = pdev->vg_initial.line_params.miter_check;
2507
5.06k
        destination->line_params.dot_length = source->line_params.dot_length;
2508
5.06k
        source->line_params.dot_length = pdev->vg_initial.line_params.dot_length;
2509
5.06k
        destination->line_params.dot_length_absolute = source->line_params.dot_length_absolute;
2510
5.06k
        source->line_params.dot_length_absolute = pdev->vg_initial.line_params.dot_length_absolute;
2511
5.06k
        destination->line_params.dot_orientation = source->line_params.dot_orientation;
2512
5.06k
        source->line_params.dot_orientation = pdev->vg_initial.line_params.dot_orientation;
2513
5.06k
        if (destination->line_params.dash.pattern != NULL && destination->line_params.dash.pattern != source->line_params.dash.pattern)
2514
0
            gs_free_object(destination->memory, destination->line_params.dash.pattern, "free dash assigned during pattern accumulation");
2515
5.06k
        memcpy(&destination->line_params.dash, &source->line_params.dash, sizeof(source->line_params.dash));
2516
5.06k
        memcpy(&source->line_params.dash, &pdev->vg_initial.line_params.dash, sizeof(source->line_params.dash));
2517
5.06k
    }
2518
5.06k
    return 0;
2519
5.06k
}
2520
2521
/*
2522
   The device specific operations - just pattern management.
2523
   See gxdevcli.h about return codes.
2524
 */
2525
int
2526
gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
2527
67.7M
{
2528
67.7M
    gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
2529
67.7M
    int code=0, force_CTM_change=0;
2530
67.7M
    pdf_resource_t *pres, *pres1;
2531
67.7M
    gx_bitmap_id id = (gx_bitmap_id)size;
2532
2533
67.7M
    switch (dev_spec_op) {
2534
52.2k
        case gxdso_skip_icc_component_validation:
2535
52.2k
            return 1;
2536
10.7k
        case gxdso_supports_pattern_transparency:
2537
10.7k
            return 1;
2538
2.76k
        case gxdso_pattern_can_accum:
2539
2.76k
            return 1;
2540
2.52k
        case gxdso_pdf_form_name:
2541
2.52k
            if (pdev->PDFFormName) {
2542
0
                gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2543
0
            }
2544
2.52k
            pdev->PDFFormName = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, size + 1, "Name of Form for pdfmark");
2545
2.52k
            if (pdev->PDFFormName == NULL)
2546
0
                return_error(gs_error_VMerror);
2547
2.52k
            memset(pdev->PDFFormName, 0x00, size + 1);
2548
2.52k
            memcpy(pdev->PDFFormName, data, size);
2549
2.52k
            return 0;
2550
0
        case gxdso_pdf_last_form_ID:
2551
0
            {
2552
0
            int *i = (int *)data;
2553
0
            *i = pdev->LastFormID;
2554
0
            }
2555
0
            return 0;
2556
2.52k
        case gxdso_form_begin:
2557
2.52k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 0) && pdev->PatternDepth == 0) {
2558
2.52k
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2559
2.52k
                float arry[6];
2560
2.52k
                cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
2561
2562
                /* Make sure the document and page stream are open */
2563
2.52k
                code = pdfwrite_pdf_open_document(pdev);
2564
2.52k
                if (code < 0)
2565
0
                    return code;
2566
2.52k
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2567
2.52k
                if (code < 0)
2568
0
                    return code;
2569
2.52k
                if (!pdev->PDFFormName) {
2570
                    /* Put any extant clip out before we start the form */
2571
0
                    code = pdf_put_clip_path(pdev, tmplate->pcpath);
2572
0
                    if (code < 0)
2573
0
                        return code;
2574
                    /* Set the CTM to be the one passed in from the interpreter,
2575
                     * this allows us to spot forms even when translation/rotation takes place
2576
                     * as we remove the CTN from the form stream before capture
2577
                     */
2578
0
                    pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2579
0
                             tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2580
0
                }
2581
2582
                /* start capturing the form stream */
2583
2.52k
                code = pdf_enter_substream(pdev, resourceXObject, id, &pres, false,
2584
2.52k
                        pdev->CompressStreams);
2585
2.52k
                if (code < 0)
2586
0
                    return code;
2587
2.52k
                pcd = cos_stream_dict((cos_stream_t *)pres->object);
2588
2.52k
                pcd_Resources = cos_dict_alloc(pdev, "pdf_form(Resources)");
2589
2.52k
                if (pcd == NULL || pcd_Resources == NULL)
2590
0
                    return_error(gs_error_VMerror);
2591
2.52k
                code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
2592
2.52k
                if (code >= 0)
2593
2.52k
                    code = cos_dict_put_c_strings(pcd, "/Subtype", "/Form");
2594
2.52k
                if (code >= 0)
2595
2.52k
                    code = cos_dict_put_c_strings(pcd, "/FormType", "1");
2596
2.52k
                if (code >= 0)
2597
2.52k
                    code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
2598
2599
2.52k
                if (pdev->PDFFormName) {
2600
                    /* This is not (I think) required when executing PS forms, because the
2601
                     * CTM is written out before we execute the Form. It *is* required for
2602
                     * PDF Appearance Forms, because the Form is written directly from the
2603
                     * outer context, not from the page, so we don't emit the CTM first.
2604
                     * We want to alter the Form BBox to take any required rotation and scaling
2605
                     * (from FitPage and /Rotate) into account so that the form appearance is
2606
                     * properly scaled and rotated.
2607
                     */
2608
2.52k
                    gs_rect bbox_out;
2609
2.52k
                    gs_matrix cmat, new_mat = tmplate->CTM;
2610
2611
                    /* We don't want anything left over from the page content stream, or other
2612
                     * annotation appearances, to affect whether or not we emit any graphics
2613
                     * state, so reset the state here to the defaults.
2614
                     */
2615
2.52k
                    pdf_viewer_state_from_gs_gstate(pdev, tmplate->pgs, NULL);
2616
                    /* For PDF Appearance streams at least, the Form BBox is modified by the
2617
                     * Form Matrix.
2618
                     */
2619
2.52k
                    code = gs_matrix_multiply(&tmplate->form_matrix, &tmplate->CTM, &cmat);
2620
2.52k
                    if (code < 0)
2621
0
                        return code;
2622
2.52k
                    code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2623
2.52k
                    if (code < 0)
2624
0
                        return code;
2625
2626
                    /* Check the BBox is on the page. Modify it if it is not (this can happen
2627
                     * if the MediaBox does not have bottom left at 0,0)
2628
                     */
2629
2.52k
                    cmat.xx = cmat.yy = 1.0f;
2630
2.52k
                    cmat.xy = cmat.yx = cmat.tx = cmat.ty = 0.0f;
2631
2.52k
                    if(bbox_out.q.x - bbox_out.p.x > pdev->width) {
2632
0
                        cmat.xx = pdev->width / (bbox_out.q.x - bbox_out.p.x);
2633
0
                        bbox_out.q.x = bbox_out.p.x + ((bbox_out.q.x - bbox_out.p.x) * cmat.xx);
2634
0
                        force_CTM_change = 1;
2635
0
                    }
2636
2.52k
                    if(bbox_out.q.y - bbox_out.p.y > pdev->height) {
2637
0
                        cmat.yy = pdev->height / (bbox_out.q.y - bbox_out.p.y);
2638
0
                        bbox_out.q.y = bbox_out.p.y + ((bbox_out.q.y - bbox_out.p.y) * cmat.yy);
2639
0
                        force_CTM_change = 1;
2640
0
                    }
2641
2642
2.52k
                    if (bbox_out.p.x < 0) {
2643
0
                        cmat.tx = bbox_out.p.x * -1;
2644
0
                        bbox_out.q.x += cmat.tx;
2645
0
                        force_CTM_change = 1;
2646
0
                    }
2647
2.52k
                    if (floor(bbox_out.q.x) > pdev->width) {
2648
0
                        cmat.tx -= bbox_out.p.x;
2649
0
                        bbox_out.q.x -= bbox_out.p.x;
2650
0
                        bbox_out.p.x = 0;
2651
0
                        force_CTM_change = 1;
2652
0
                    }
2653
2.52k
                    if (bbox_out.p.y < 0) {
2654
0
                        cmat.ty = bbox_out.p.y * -1;
2655
0
                        bbox_out.q.y += cmat.ty;
2656
0
                        force_CTM_change = 1;
2657
0
                    }
2658
2.52k
                    if (floor(bbox_out.q.y) > pdev->height) {
2659
0
                        cmat.ty += pdev->height - bbox_out.q.y;
2660
0
                        force_CTM_change = 1;
2661
0
                    }
2662
2663
2.52k
                    if (force_CTM_change) {
2664
0
                        code = gs_matrix_multiply(&tmplate->CTM, &cmat, &new_mat);
2665
0
                        if (code < 0)
2666
0
                            return code;
2667
0
                        code = gs_matrix_multiply(&tmplate->form_matrix, &new_mat, &cmat);
2668
0
                        if (code < 0)
2669
0
                            return code;
2670
0
                        code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2671
0
                        if (code < 0)
2672
0
                            return code;
2673
0
                        tmplate->CTM = cmat;
2674
0
                    }
2675
2.52k
                    arry[0] = bbox_out.p.x;
2676
2.52k
                    arry[1] = bbox_out.p.y;
2677
2.52k
                    arry[2] = bbox_out.q.x;
2678
2.52k
                    arry[3] = bbox_out.q.y;
2679
2.52k
                    if (code >= 0)
2680
2.52k
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2681
2.52k
                    if (code < 0)
2682
0
                        return code;
2683
2684
                    /* Note that we will apply the CTM to the form, and the Form Matrix. To prevcent
2685
                     * us applying the Matrix twice, we need to set it to the identity in the Form
2686
                     * dictionary. I'm not sure why we don't need to do that for PostScript Forms.
2687
                     */
2688
2.52k
                    arry[0] = arry[3] = 1.0f;
2689
2.52k
                    arry[1] = arry[2] = arry[4] = arry[5] = 0.0f;
2690
2.52k
                } else {
2691
0
                    arry[0] = tmplate->BBox.p.x;
2692
0
                    arry[1] = tmplate->BBox.p.y;
2693
0
                    arry[2] = tmplate->BBox.q.x;
2694
0
                    arry[3] = tmplate->BBox.q.y;
2695
0
                    if (code >= 0)
2696
0
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2697
0
                    if (code < 0)
2698
0
                        return code;
2699
2700
0
                    arry[0] = tmplate->form_matrix.xx;
2701
0
                    arry[1] = tmplate->form_matrix.xy;
2702
0
                    arry[2] = tmplate->form_matrix.yx;
2703
0
                    arry[3] = tmplate->form_matrix.yy;
2704
0
                    arry[4] = tmplate->form_matrix.tx;
2705
0
                    arry[5] = tmplate->form_matrix.ty;
2706
2707
0
                    pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2708
0
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2709
0
                }
2710
2711
2.52k
                code = cos_dict_put_c_key_floats(pdev, pcd, "/Matrix", arry, 6);
2712
2.52k
                if (code < 0)
2713
0
                    return code;
2714
2715
                /* We'll return this to the interpreter and have it set
2716
                 * as the CTM, so that we remove the prior CTM before capturing the form.
2717
                 * This is safe because forms are always run inside a gsave/grestore, so
2718
                 * CTM will be put back for us.
2719
                 */
2720
2.52k
                if (!pdev->PDFFormName) {
2721
0
                    tmplate->CTM.xx = pdev->HWResolution[0] / 72;
2722
0
                    tmplate->CTM.xy = 0.0;
2723
0
                    tmplate->CTM.yx = 0.0;
2724
0
                    tmplate->CTM.yy = pdev->HWResolution[0] / 72;
2725
0
                    tmplate->CTM.tx = 0.0;
2726
0
                    tmplate->CTM.ty = 0.0;
2727
2728
0
                    pdev->substream_Resources = pcd_Resources;
2729
0
                    pres->rid = id;
2730
0
                    if (code >= 0)
2731
0
                        pdev->HighLevelForm++;
2732
0
                    return 1;
2733
2.52k
                } else {
2734
                    /* For PDF Appearance streams (Forms) we *must* apply the
2735
                     * CTM. This is because if the PDF has a non-zero Rotate key
2736
                     * we bake that rotation into the CTM. If we didn't apply that
2737
                     * then the annotation wouldn't get rotated :-(
2738
                     */
2739
2.52k
                    pdev->substream_Resources = pcd_Resources;
2740
2.52k
                    pres->rid = id;
2741
2.52k
                    if (code >= 0)
2742
2.52k
                        pdev->HighLevelForm++;
2743
2.52k
                    return force_CTM_change;
2744
2.52k
                }
2745
2.52k
            }
2746
0
            return code;
2747
2.52k
        case gxdso_form_end:
2748
            /* This test must be the same as the one in gxdso_form_begin, above */
2749
2.52k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 1) && pdev->PatternDepth == 0) {
2750
2.52k
                if (pdev->CompatibilityLevel <= 1.7) {
2751
2.52k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2752
2.52k
                    if (code < 0)
2753
0
                        return code;
2754
2.52k
                }
2755
2.52k
                pres = pres1 = pdev->accumulating_substream_resource;
2756
2.52k
                if (pres == NULL)
2757
0
                    return_error(gs_error_unregistered);
2758
2.52k
                code = pdf_exit_substream(pdev);
2759
2.52k
                if (code < 0)
2760
0
                    return code;
2761
2.52k
                code = pdf_find_same_resource(pdev, resourceXObject, &pres, check_unsubstituted2);
2762
2.52k
                if (code < 0)
2763
0
                    return code;
2764
2.52k
                if (code > 0) {
2765
0
                    code = pdf_cancel_resource(pdev, pres1, resourceXObject);
2766
0
                    if (code < 0)
2767
0
                        return code;
2768
0
                    pres->where_used |= pdev->used_mask;
2769
2.52k
                } else if (pres->object->id < 0)
2770
2.52k
                    pdf_reserve_object_id(pdev, pres, 0);
2771
2.52k
                pdev->LastFormID = pdf_resource_id(pres);
2772
2.52k
                pdev->HighLevelForm--;
2773
2.52k
                if (pdev->accumulating_substream_resource) {
2774
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2775
0
                    if (code < 0)
2776
0
                        return code;
2777
0
                }
2778
2.52k
                if (pdev->PDFFormName) {
2779
2.52k
                    cos_value_t value;
2780
2781
2.52k
                    code = cos_dict_put(pdev->local_named_objects, (const byte *)pdev->PDFFormName,
2782
2.52k
                        strlen(pdev->PDFFormName), cos_object_value(&value, pres->object));
2783
2784
2.52k
                    if (code < 0)
2785
0
                        return code;
2786
2.52k
                    pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
2787
2.52k
                    pres->object = NULL;
2788
2.52k
                    gs_free_object(pdev->pdf_memory, pres, "free redundant resource");
2789
2790
2.52k
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2791
2.52k
                    pdev->PDFFormName = 0x00;
2792
2.52k
                } else {
2793
0
                    pprinti64d1(pdev->strm, "/R%"PRId64" Do Q\n", pdf_resource_id(pres));
2794
0
                }
2795
2.52k
            }
2796
2.52k
            return 0;
2797
2.52k
        case gxdso_get_form_ID:
2798
2.52k
            {
2799
2.52k
                int *ID = data;
2800
2.52k
                *ID = pdev->LastFormID;
2801
2.52k
            }
2802
2.52k
            return 0;
2803
0
        case gxdso_repeat_form:
2804
0
            {
2805
0
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2806
2807
                /* Make sure the document and page stream are open */
2808
0
                code = pdfwrite_pdf_open_document(pdev);
2809
0
                if (code < 0)
2810
0
                    return code;
2811
0
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2812
0
                if (code < 0)
2813
0
                    return code;
2814
                /* Put any extant clip out before we start the form */
2815
0
                code = pdf_put_clip_path(pdev, tmplate->pcpath);
2816
0
                if (code < 0)
2817
0
                    return code;
2818
                /* Set the CTM to be the one passed in from the interpreter,
2819
                 * this allows us to spot forms even when translation/rotation takes place
2820
                 * as we remove the CTN from the form stream before capture
2821
                 */
2822
0
                pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2823
0
                         tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2824
0
                pprintld1(pdev->strm, "/R%ld Do Q\n", tmplate->FormID);
2825
0
                pres = pdf_find_resource_by_resource_id(pdev, resourceXObject, tmplate->FormID);
2826
0
                if (pres == NULL)
2827
0
                    return_error(gs_error_undefined);
2828
0
                pres->where_used |= pdev->used_mask;
2829
0
                if (pdev->accumulating_substream_resource) {
2830
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2831
0
                    if (code < 0)
2832
0
                        return code;
2833
0
                }
2834
0
            }
2835
0
            return 0;
2836
2.53k
        case gxdso_pattern_start_accum:
2837
2.53k
            {
2838
2.53k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2839
2.53k
                gs_pattern1_instance_t *pinst = param->pinst;
2840
2.53k
                gs_gstate *pgs = param->graphics_state;
2841
2842
2.53k
                code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
2843
2.53k
                if (code < 0)
2844
0
                    return code;
2845
2.53k
                if (pdev->context == PDF_IN_NONE) {
2846
93
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
2847
93
                    if (code < 0)
2848
0
                        return code;
2849
93
                }
2850
2.53k
                code = pdf_prepare_fill_stroke(pdev, (gs_gstate *)pgs, false);
2851
2.53k
                if (code < 0)
2852
0
                    return code;
2853
2.53k
                if (pdev->PatternDepth == 0 && pdev->initial_pattern_states != NULL) {
2854
0
                    int pdepth = 0;
2855
2856
0
                    while (pdev->initial_pattern_states[pdepth] != 0x00) {
2857
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdepth], "Freeing dangling pattern state");
2858
0
                        pdev->initial_pattern_states[pdepth] = NULL;
2859
0
                        pdepth++;
2860
0
                    }
2861
0
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state stack");
2862
0
                }
2863
2864
2.53k
                {
2865
2.53k
                    gs_gstate **new_states;
2866
2.53k
                    int pdepth;
2867
2868
2.53k
                    new_states = (gs_gstate **)gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, sizeof(gs_gstate *) * (pdev->PatternDepth + 2), "pattern initial graphics state stack");
2869
2.53k
                    if (new_states == NULL)
2870
0
                        return_error(gs_error_VMerror);
2871
2.53k
                    memset(new_states, 0x00, sizeof(gs_gstate *) * (pdev->PatternDepth + 2));
2872
2.53k
                    for (pdepth = 0; pdepth < pdev->PatternDepth;pdepth++)
2873
6
                        new_states[pdepth] = pdev->initial_pattern_states[pdepth];
2874
2.53k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing old pattern state stack");
2875
2.53k
                    pdev->initial_pattern_states = new_states;
2876
2.53k
                }
2877
2.53k
                pdev->initial_pattern_states[pdev->PatternDepth] = (gs_gstate *)gs_alloc_struct(pdev->pdf_memory, gs_gstate, &st_gs_gstate, "gdev_pdf_dev_spec_op");
2878
2.53k
                if (pdev->initial_pattern_states[pdev->PatternDepth] == NULL)
2879
0
                    return code;
2880
2.53k
                memset(pdev->initial_pattern_states[pdev->PatternDepth], 0x00, sizeof(gs_gstate));
2881
2.53k
                pdev->initial_pattern_states[pdev->PatternDepth]->memory = pdev->pdf_memory;
2882
2883
2.53k
                reset_gstate_for_pattern(pdev, pdev->initial_pattern_states[pdev->PatternDepth], pgs);
2884
2.53k
                code = pdf_enter_substream(pdev, resourcePattern, pinst->id, &pres, false,
2885
2.53k
                        pdev->CompressStreams);
2886
2.53k
                if (code < 0) {
2887
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2888
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2889
0
                    return code;
2890
0
                }
2891
2892
                /* We have started a new substream, to avoid confusing the 'saved viewer state'
2893
                 * (the stack of pdfwrite's saved copies of graophics states) we need to reset the
2894
                 * soft_mask_id, which is the ID of the SMask we have already created in the pdfwrite
2895
                 * output. The gsave/grestore round the spec_op to start and finish the pattern
2896
                 * accumulator (see pattern_paint_prepare and pattern_paint_finish) will ensure that
2897
                 * the ID is restored when we finish capturing the pattern.
2898
                 */
2899
2.53k
                pdev->state.soft_mask_id = pgs->soft_mask_id;
2900
2.53k
                pres->rid = pinst->id;
2901
2.53k
                code = pdf_store_pattern1_params(pdev, pres, pinst);
2902
2.53k
                if (code < 0) {
2903
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2904
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2905
0
                    return code;
2906
0
                }
2907
                /* Scale the coordinate system, because object handlers assume so. See none_to_stream. */
2908
2.53k
                pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2909
2.53k
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2910
2.53k
                pdev->PatternDepth++;
2911
2.53k
                pdev->PatternsSinceForm++;
2912
2.53k
            }
2913
0
            return 1;
2914
2.53k
        case gxdso_pattern_finish_accum:
2915
2.53k
            {
2916
2.53k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2917
2.53k
                gs_gstate *pgs = param->graphics_state;
2918
2919
2.53k
                if (pdev->CompatibilityLevel <= 1.7) {
2920
2.53k
                    if (pdev->substream_Resources == NULL) {
2921
0
                        pdev->substream_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
2922
0
                        if (pdev->substream_Resources == NULL)
2923
0
                            return_error(gs_error_VMerror);
2924
0
                    }
2925
2.53k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2926
2.53k
                    if (code < 0) {
2927
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2928
0
                        pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2929
0
                        return code;
2930
0
                    }
2931
2.53k
                }
2932
2.53k
                pres = pres1 = pdev->accumulating_substream_resource;
2933
2.53k
                if (pres == NULL)
2934
0
                    code = gs_note_error(gs_error_unregistered);
2935
2.53k
                else
2936
2.53k
                    code = pdf_exit_substream(pdev);
2937
2.53k
                if (code < 0) {
2938
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2939
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2940
0
                    return code;
2941
0
                }
2942
2.53k
                if (pdev->substituted_pattern_count > 300 &&
2943
0
                        pdev->substituted_pattern_drop_page != pdev->next_page) { /* arbitrary */
2944
0
                    pdf_drop_resources(pdev, resourcePattern, check_unsubstituted1);
2945
0
                    pdev->substituted_pattern_count = 0;
2946
0
                    pdev->substituted_pattern_drop_page = pdev->next_page;
2947
0
                }
2948
2.53k
                code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
2949
2.53k
                if (code < 0) {
2950
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2951
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2952
0
                    return code;
2953
0
                }
2954
2.53k
                if (code > 0) {
2955
968
                    pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
2956
2957
968
                    code = pdf_cancel_resource(pdev, pres1, resourcePattern);
2958
968
                    if (code < 0) {
2959
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2960
0
                        pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2961
0
                        return code;
2962
0
                    }
2963
                    /* Do not remove pres1, because it keeps the substitution. */
2964
968
                    ppat->substitute = (pdf_pattern_t *)pres;
2965
968
                    pres->where_used |= pdev->used_mask;
2966
968
                    pdev->substituted_pattern_count++;
2967
1.56k
                } else if (pres->object->id < 0)
2968
1.56k
                    pdf_reserve_object_id(pdev, pres, 0);
2969
2.53k
                reset_gstate_for_pattern(pdev, pgs, pdev->initial_pattern_states[pdev->PatternDepth - 1]);
2970
2.53k
                gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth - 1], "Freeing dangling pattern state");
2971
2.53k
                pdev->initial_pattern_states[pdev->PatternDepth - 1] = NULL;
2972
2.53k
                if (pdev->PatternDepth == 1) {
2973
2.52k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state");
2974
2.52k
                    pdev->initial_pattern_states = NULL;
2975
2.52k
                }
2976
2977
2.53k
                pdev->PatternDepth--;
2978
2.53k
                pdev->PatternsSinceForm--;
2979
2.53k
            }
2980
0
            return 1;
2981
6.11k
        case gxdso_pattern_load:
2982
6.11k
            pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, *((gx_bitmap_id *)data));
2983
6.11k
            if (pres == 0)
2984
2.52k
                return 0;
2985
3.58k
            pres = pdf_substitute_pattern(pres);
2986
3.58k
            pres->where_used |= pdev->used_mask;
2987
3.58k
            code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
2988
3.58k
            if (code < 0)
2989
0
                return code;
2990
3.58k
            return 1;
2991
9.96k
        case gxdso_pattern_shading_area:
2992
9.96k
            return 0;
2993
62.5k
        case gxdso_pattern_is_cpath_accum:
2994
62.5k
            return 0;
2995
1.11k
        case gxdso_pattern_shfill_doesnt_need_path:
2996
1.11k
            return 0; /* gdev_pdf_fill_path still does need a path. */
2997
1
        case gxdso_pattern_handles_clip_path:
2998
            /* This is important when the default implementation of
2999
               of fill_path is called due to a failure in setcolor
3000
               or so, for example when a shading is incorrect.
3001
               The test case is the unfixed (buggy) Genoa test 446-01.ps .
3002
               In this case pdfwrite converts the object into rectangles,
3003
               and the clipping device has to be set up. */
3004
1
            return 0;
3005
9.46k
        case gxdso_supports_hlcolor:
3006
            /* This is used due to some aliasing between the rect_hl color
3007
               filling used by pdfwrite vs. that used by the planar device
3008
               which is actually a devn vs. the pattern type for pdfwrite.
3009
               We use this to distingush between the two */
3010
9.46k
            return 1;
3011
0
        case gxdso_needs_invariant_palette:
3012
            /* Indicates that it is not permissible to change /Indexed colour space
3013
             * palette entries after the colour space has been set.
3014
             */
3015
0
            return 1;
3016
2.17k
        case gxdso_JPEG_passthrough_query:
3017
2.17k
            pdev->JPEG_PassThrough = pdev->params.PassThroughJPEGImages;
3018
2.17k
            return 1;
3019
0
            break;
3020
0
        case gxdso_set_JPEG_PassThrough:
3021
0
            pdev->params.PassThroughJPEGImages = *((bool *)data);
3022
0
            if (*((bool *)data) == 0 && pdev->JPEG_PassThrough)
3023
0
                pdev->JPEG_PassThrough = 0;
3024
0
            return 0;
3025
0
            break;
3026
2.16k
        case gxdso_JPEG_passthrough_begin:
3027
2.16k
            return 0;
3028
0
            break;
3029
187k
        case gxdso_JPEG_passthrough_data:
3030
187k
            if (pdev->JPEG_PassThrough && pdev->PassThroughWriter)
3031
44.7k
            {
3032
44.7k
                uint ignore;
3033
44.7k
                if (sputs(pdev->PassThroughWriter,
3034
44.7k
                           data, size,
3035
44.7k
                           &ignore) < 0)
3036
0
                           return_error(gs_error_ioerror);
3037
44.7k
            }
3038
187k
            return 0;
3039
0
            break;
3040
2.03k
        case gxdso_JPEG_passthrough_end:
3041
2.03k
            pdev->JPEG_PassThrough = 0;
3042
2.03k
            pdev->PassThroughWriter = 0;
3043
2.03k
            return 0;
3044
0
            break;
3045
1.82k
        case gxdso_JPX_passthrough_query:
3046
1.82k
            pdev->JPX_PassThrough = pdev->params.PassThroughJPXImages;
3047
1.82k
            return 1;
3048
0
            break;
3049
0
        case gxdso_set_JPX_PassThrough:
3050
0
            pdev->params.PassThroughJPXImages = *((bool *)data);
3051
0
            if (*((bool *)data) == 0 && pdev->JPX_PassThrough)
3052
0
                pdev->JPX_PassThrough = 0;
3053
0
            return 0;
3054
0
            break;
3055
1.66k
        case gxdso_JPX_passthrough_begin:
3056
1.66k
            return 0;
3057
0
            break;
3058
114k
        case gxdso_JPX_passthrough_data:
3059
114k
            if (pdev->JPX_PassThrough && pdev->PassThroughWriter)
3060
20.9k
            {
3061
20.9k
                uint ignore;
3062
20.9k
                if (sputs(pdev->PassThroughWriter,
3063
20.9k
                           data, size,
3064
20.9k
                           &ignore) < 0)
3065
0
                           return_error(gs_error_ioerror);
3066
20.9k
            }
3067
114k
            return 0;
3068
0
            break;
3069
1.82k
        case gxdso_JPX_passthrough_end:
3070
1.82k
            pdev->JPX_PassThrough = 0;
3071
1.82k
            pdev->PassThroughWriter = 0;
3072
1.82k
            return 0;
3073
0
            break;
3074
3075
0
        case gxdso_event_info:
3076
0
            {
3077
0
                dev_param_req_t *request = (dev_param_req_t *)data;
3078
0
                if (memcmp(request->Param, "SubstitutedFont", 15) == 0 && (pdev->PDFA || pdev->PDFX)) {
3079
0
                    switch (pdev->PDFACompatibilityPolicy) {
3080
0
                        case 0:
3081
0
                        case 1:
3082
0
                            emprintf(pdev->memory,
3083
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, reverting to normal PDF output!\n");
3084
0
                            pdev->AbortPDFAX = true;
3085
0
                            pdev->PDFX = 0;
3086
0
                            pdev->PDFA = 0;
3087
0
                            break;
3088
0
                        case 2:
3089
0
                            emprintf(pdev->memory,
3090
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, aborting conversion!\n");
3091
0
                            pdev->AbortPDFAX = true;
3092
0
                            pdev->PDFX = 0;
3093
0
                            pdev->PDFA = 0;
3094
0
                            return gs_note_error(gs_error_unknownerror);
3095
0
                            break;
3096
0
                        default:
3097
0
                            emprintf(pdev->memory,
3098
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, unknown PDFACompatibilityPolicy, reverting to normal PDF output!\n");
3099
0
                            pdev->AbortPDFAX = true;
3100
0
                            pdev->PDFX = 0;
3101
0
                            pdev->PDFA = 0;
3102
0
                            break;
3103
0
                    }
3104
0
                }
3105
0
                return 0;
3106
0
            }
3107
0
            break;
3108
4.19M
        case gxdso_in_smask_construction:
3109
4.19M
            return pdev->smask_construction;
3110
15
        case gxdso_pending_optional_content:
3111
15
            if (pdev->CompatibilityLevel < 1.4999) {
3112
0
                if (pdev->PDFA) {
3113
0
                    switch (pdev->PDFACompatibilityPolicy) {
3114
0
                        case 0:
3115
0
                            emprintf(pdev->memory,
3116
0
                                     "Optional Content not valid in this version of PDF, reverting to normal PDF output\n");
3117
0
                            pdev->AbortPDFAX = true;
3118
0
                            pdev->PDFA = 0;
3119
0
                            break;
3120
0
                        case 1:
3121
0
                            emprintf(pdev->memory,
3122
0
                                     "Optional Content not valid in this version of PDF. Dropping feature to preserve PDF/A compatibility\n");
3123
0
                            break;
3124
0
                        case 2:
3125
0
                            emprintf(pdev->memory,
3126
0
                                     "Optional Content not valid in this version of PDF,  aborting conversion\n");
3127
0
                            return_error (gs_error_typecheck);
3128
0
                            break;
3129
0
                        default:
3130
0
                            emprintf(pdev->memory,
3131
0
                                     "Optional Content not valid in this version of PDF, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
3132
0
                            pdev->AbortPDFAX = true;
3133
0
                            pdev->PDFA = 0;
3134
0
                            break;
3135
0
                    }
3136
0
                } else {
3137
0
                    emprintf(pdev->memory,
3138
0
                             "Optional Content not valid in this version of PDF. Dropping feature to preserve compatibility\n");
3139
0
                }
3140
0
            } else
3141
15
            {
3142
15
                char *object = data;
3143
15
                if (pdev->PendingOC)
3144
0
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
3145
15
                pdev->PendingOC = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, strlen(object) + 1, "");
3146
15
                if (pdev->PendingOC == NULL)
3147
0
                    return_error(gs_error_VMerror);
3148
15
                memcpy(pdev->PendingOC, object, strlen(object) + 1);
3149
15
            }
3150
15
            return 0;
3151
0
            break;
3152
72
        case gxdso_hilevel_text_clip:
3153
72
            if (data == 0 && !pdev->accumulating_charproc) {
3154
                /* We are exiting a text render mode 'clip' by grestoring back to
3155
                 *  a time when the clip wasn't active.
3156
                 * First, check if we have a clip (this should always be true).
3157
                 */
3158
70
                if (pdev->clipped_text_pending) {
3159
                    /* Get back to the content stream. This will (amongst other things) flush
3160
                     * any pending text.
3161
                     */
3162
0
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
3163
0
                    if (code < 0)
3164
0
                        return code;
3165
                    /* Reset the pending state */
3166
0
                    pdev->clipped_text_pending = 0;
3167
                    /* Restore to our saved state */
3168
3169
                    /* The saved state in this case is the dpeth of the saved gstate stack at the time we
3170
                     * started the text clipping. Note; we cannot restore back past the 'bottom' of the
3171
                     * stack, which is why we alter vgstack_bottom here, rather than just using the saved
3172
                     * level in the loop below.
3173
                     */
3174
0
                    if (pdev->vgstack_bottom)
3175
0
                        pdev->vgstack_bottom = pdev->saved_vgstack_depth_for_textclip;
3176
3177
0
                    while (pdev->vgstack_depth > pdev->vgstack_bottom) {
3178
0
                        code = pdf_restore_viewer_state(pdev, pdev->strm);
3179
0
                        if (code < 0)
3180
0
                            return code;
3181
0
                    }
3182
3183
0
                    pdev->vgstack_bottom = pdev->saved_vgstack_bottom_for_textclip;
3184
0
                    pdf_reset_text(pdev); /* because of Q */
3185
0
                }
3186
70
            } else {
3187
2
                if (!pdev->accumulating_charproc) {
3188
2
                    gs_gstate *pgs = (gs_gstate *)data;
3189
                    /* We are starting text in a clip mode
3190
                     * First make sure we aren't already in a clip mode (this should never be true)
3191
                     */
3192
2
                    if (!pdev->clipped_text_pending) {
3193
                        /* Return to the content stream, this will (amongst other things) flush
3194
                         * any pending text.
3195
                         */
3196
2
                        code = pdf_open_page(pdev, PDF_IN_STREAM);
3197
2
                        if (code < 0)
3198
0
                            return code;
3199
3200
2
                        if (pdf_must_put_clip_path(pdev, pgs->clip_path)) {
3201
0
                           code = pdf_unclip(pdev);
3202
0
                            if (code < 0)
3203
0
                                return code;
3204
0
                            code = pdf_put_clip_path(pdev, pgs->clip_path);
3205
0
                            if (code < 0)
3206
0
                                return code;
3207
0
                        }
3208
3209
2
                        pdev->saved_vgstack_depth_for_textclip = pdev->vgstack_depth;
3210
3211
                        /* Save the current graphics state (or at least that bit which we track) so
3212
                         * that we can put it back later.
3213
                         */
3214
2
                        code = pdf_save_viewer_state(pdev, pdev->strm);
3215
2
                        if (code < 0)
3216
0
                            return code;
3217
2
                        pdev->clipped_text_pending = 1;
3218
3219
                        /* Save the current 'bottom' of the saved gstate stack, we need to
3220
                         * restore back to this state when we exit the graphics state
3221
                         * with a text rendering mode involving a clip.
3222
                         */
3223
2
                        pdev->saved_vgstack_bottom_for_textclip = pdev->vgstack_bottom;
3224
                        /* And push the bottom of the stack up until it is where we are now.
3225
                         * This is because clip paths, images, and possibly other constructs
3226
                         * will emit a clip path if the 'depth - bottom' is not zero, to create
3227
                         * a clip path. We want to make sure that it doesn't try to restore back
3228
                         * to a point before we established the text clip.
3229
                         */
3230
2
                        pdev->vgstack_bottom = pdev->vgstack_depth;
3231
2
                    }
3232
2
                }
3233
2
            }
3234
72
            break;
3235
1.92M
        case gxdso_get_dev_param:
3236
1.92M
            {
3237
1.92M
                int code;
3238
1.92M
                dev_param_req_t *request = (dev_param_req_t *)data;
3239
1.92M
                code = gdev_pdf_get_param(pdev1, request->Param, request->list);
3240
1.92M
                if (code != gs_error_undefined)
3241
1.87M
                    return code;
3242
1.92M
            }
3243
            /* Fall through */
3244
67.7M
    }
3245
61.2M
    return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size);
3246
67.7M
}