Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/devices/vector/gdevpdfi.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
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
97.6k
{
118
97.6k
    return true;
119
97.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
28
{
143
28
    if (pim4->BitsPerComponent == 1 &&
144
28
        pim4->ColorSpace->type->num_components(pim4->ColorSpace) == 1 &&
145
28
        (pim4->MaskColor_is_range ?
146
0
         pim4->MaskColor[0] | pim4->MaskColor[1] :
147
0
         pim4->MaskColor[0]) <= 1
148
28
        ) {
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
28
    return -1;     /* arbitrary <0 */
225
28
}
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
117k
{
231
232
117k
    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
117k
    return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
247
117k
}
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
3.07k
{
254
3.07k
    gs_color_space *cs;
255
3.07k
    gs_memory_t *mem = pdev->v_memory;
256
257
3.07k
    switch (output_cspace_index) {
258
0
        case gs_color_space_index_DeviceGray:
259
0
            cs = gs_cspace_new_DeviceGray(mem);
260
0
            break;
261
3.07k
        case gs_color_space_index_DeviceRGB:
262
3.07k
            cs = gs_cspace_new_DeviceRGB(mem);
263
3.07k
            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
3.07k
    }
275
276
3.07k
    if (cs == NULL)
277
0
        return_error(gs_error_VMerror);
278
279
3.07k
    *ppcs = cs;
280
3.07k
    return 0;
281
3.07k
}
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
107k
{
318
107k
    const gs_image_t *pim1 = (const gs_image_t *)pic;
319
320
107k
    if (pim1->Alpha != gs_image_alpha_none)
321
0
        return -1;
322
107k
    if (pim1->ImageMask) {
323
        /* If parameters are invalid, use the fallback implementation. */
324
78.4k
        if (!(gx_dc_is_pattern1_color(pdcolor)))
325
77.9k
            if (pim1->BitsPerComponent != 1 ||
326
77.9k
                !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
327
77.9k
                  (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
328
77.9k
                )
329
12
                return -1;
330
78.4k
    }
331
107k
    image[0].type1 = *pim1;
332
    /* If we can write in-line then make it so */
333
107k
    return (context == PDF_IMAGE_DEFAULT &&
334
107k
        can_write_image_in_line(pdev, pim1));
335
107k
}
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
126
{
345
126
    const gs_image3_t *pim3 = (const gs_image3_t *)pic;
346
126
    gs_image3_t pim3a;
347
126
    const gs_image_common_t *pic1 = pic;
348
126
    gs_matrix m, mi;
349
126
    const gs_matrix *pmat1 = pmat;
350
126
    int code;
351
352
126
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
353
92
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
354
92
        if (code < 0)
355
0
            return code;
356
92
        if (pdf_must_put_clip_path(pdev, pcpath))
357
22
            code = pdf_unclip(pdev);
358
70
        else
359
70
            code = pdf_open_page(pdev, PDF_IN_STREAM);
360
92
        if (code < 0)
361
0
            return code;
362
92
        code = pdf_put_clip_path(pdev, pcpath);
363
92
        if (code < 0)
364
0
            return code;
365
92
        gs_make_identity(&m);
366
92
        pmat1 = &m;
367
92
        m.tx = floor(pgs->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
368
92
        m.ty = floor(pgs->ctm.ty + 0.5);
369
92
        pim3a = *pim3;
370
92
        code = gs_matrix_invert(&pim3a.ImageMatrix, &mi);
371
92
        if (code < 0)
372
1
            return code;
373
91
        gs_make_identity(&pim3a.ImageMatrix);
374
91
        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
91
        if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
381
15
            int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
382
383
15
            gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
384
15
            gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
385
15
        }
386
91
        gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
387
91
        pim3a.imagematrices_are_untrustworthy = 1;
388
91
        pic1 = (gs_image_common_t *)&pim3a;
389
        /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
390
91
        gs_matrix_multiply(&mi, &ctm_only(pgs), &pdev->converting_image_matrix);
391
91
    }
392
    /*
393
     * We handle ImageType 3 images in a completely different way:
394
     * the default implementation sets up the enumerator.
395
     */
396
125
    return gx_begin_image3_generic((gx_device *)pdev, pgs, pmat1, pic1,
397
125
                                   prect, pdcolor, pcpath, mem,
398
125
                                   pdf_image3_make_mid,
399
125
                                   pdf_image3_make_mcde, pinfo);
400
126
}
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
28
{
411
    /* Try to convert the image to a plain masked image. */
412
28
    gx_drawing_color icolor;
413
28
    int code = 1;
414
415
28
    pdev->image_mask_is_SMask = false;
416
28
    if (pdf_convert_image4_to_image1(pdev, pgs, pdcolor,
417
28
                                     (const gs_image4_t *)pic,
418
28
                                     &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
28
    return code;
445
28
}
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
25
{
454
25
        gs_matrix m, m1, mi;
455
25
        gs_image4_t pi4 = *(const gs_image4_t *)pic;
456
25
        int code;
457
25
        pdf_lcvd_t *cvd = NULL;
458
459
25
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
460
25
        if (code < 0)
461
0
            return code;
462
25
        if (pdf_must_put_clip_path(pdev, pcpath))
463
24
            code = pdf_unclip(pdev);
464
1
        else
465
1
            code = pdf_open_page(pdev, PDF_IN_STREAM);
466
25
        if (code < 0)
467
0
            return code;
468
25
        code = pdf_put_clip_path(pdev, pcpath);
469
25
        if (code < 0)
470
0
            return code;
471
25
        gs_make_identity(&m1);
472
25
        code = gs_matrix_invert(&pic->ImageMatrix, &mi);
473
25
        if (code < 0)
474
0
            return code;
475
25
        gs_matrix_multiply(&mi, &ctm_only(pgs), &m);
476
25
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
477
25
                             true, 0, 0, pi4.Width, pi4.Height, false);
478
25
        if (code < 0)
479
0
            return code;
480
25
        cvd->mdev.is_open = true; /* fixme: same as above. */
481
25
        cvd->mask->is_open = true; /* fixme: same as above. */
482
25
        cvd->mask_is_empty = false;
483
25
        code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
484
25
                    0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
485
25
        if (code < 0)
486
0
            return code;
487
25
        gx_device_retain((gx_device *)cvd, true);
488
25
        gx_device_retain((gx_device *)cvd->mask, true);
489
25
        gs_make_identity(&pi4.ImageMatrix);
490
25
        code = gx_default_begin_typed_image((gx_device *)cvd,
491
25
            pgs, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
492
25
        if (code < 0)
493
0
            return code;
494
25
        (*pinfo)->procs = &pdf_image_cvd_enum_procs;
495
25
        return 0;
496
25
}
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.53k
{
501
1.53k
    int code;
502
1.53k
    gs_color_space *pcs_device = NULL;
503
504
1.53k
    cos_c_string_value(cs_value, sname);
505
1.53k
    *pcs_orig = image->pixel.ColorSpace;
506
1.53k
    code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
507
1.53k
    if (code < 0)
508
0
        return code;
509
1.53k
    image->pixel.ColorSpace = pcs_device;
510
1.53k
    return 0;
511
1.53k
}
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
24.1k
{
547
24.1k
    int code=0;
548
24.1k
    gs_color_space_index csi;
549
24.1k
    gs_color_space_index csi2;
550
24.1k
    const gs_color_space *pcs2 = pcs;
551
552
24.1k
    csi = csi2 = gs_color_space_get_index(pcs);
553
24.1k
    if (csi == gs_color_space_index_ICC) {
554
21.3k
        csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
555
21.3k
    }
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
24.1k
    if (pdev->CompatibilityLevel <= 1.2) {
559
560
        /* If we have an /Indexed space, we need to look at the base space */
561
9.98k
        if (csi2 == gs_color_space_index_Indexed) {
562
1.53k
            pcs2 = pcs->base_space;
563
1.53k
            csi2 = gs_color_space_get_index(pcs2);
564
1.53k
        }
565
566
9.98k
        switch (csi2) {
567
632
            case gs_color_space_index_DeviceGray:
568
632
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
569
632
                    pdev->params.ColorConversionStrategy == ccs_Gray) {
570
632
                    return 0;
571
632
                }
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
6.34k
            case gs_color_space_index_DeviceRGB:
580
6.34k
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
581
6.34k
                    pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB)
582
6.34k
                    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
165
            case gs_color_space_index_DeviceCMYK:
591
165
                if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
592
165
                    pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
593
165
                    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.81k
            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.81k
                csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
651
652
2.81k
                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
1.29k
                    case gs_color_space_index_DeviceRGB:
659
1.29k
                        if (pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB ||
660
1.29k
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
661
1.29k
                            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.51k
                    default:
669
1.51k
                        break;
670
2.81k
                }
671
                /* Fall through for non-handled cases */
672
1.53k
            case gs_color_space_index_DeviceN:
673
1.53k
            case gs_color_space_index_DevicePixel:
674
1.53k
            case gs_color_space_index_Indexed:
675
1.53k
                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.53k
                    case gs_color_space_index_DeviceRGB:
680
1.53k
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
681
1.53k
                        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.53k
                }
689
1.53k
                if (code < 0)
690
0
                    return code;
691
1.53k
                return 1;
692
0
                break;
693
0
            default:
694
0
                return (gs_note_error(gs_error_rangecheck));
695
0
                break;
696
9.98k
        }
697
14.2k
    } else {
698
14.2k
        int strategy = pdev->params.ColorConversionStrategy;
699
700
14.2k
        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
14.2k
        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
14.2k
            case ccs_LeaveColorUnchanged:
729
14.2k
                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
14.2k
        }
999
14.2k
    }
1000
0
    return 0;
1001
24.1k
}
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
107k
{
1010
107k
    int code = 0;
1011
107k
    gs_rect sbox, dbox, *Box;
1012
107k
    gs_point corners[4];
1013
107k
    gs_fixed_rect ibox;
1014
107k
    gs_matrix * pmat1 = (gs_matrix *)pmat;
1015
107k
    gs_matrix mat;
1016
1017
107k
    if (!pdev->Eps2Write)
1018
79.6k
        return 0;
1019
1020
28.2k
    if (!pdev->accumulating_charproc)
1021
27.0k
        Box = &pdev->BBox;
1022
1.19k
    else
1023
1.19k
        Box = &pdev->charproc_BBox;
1024
28.2k
    if (pmat1 == 0)
1025
28.2k
        pmat1 = (gs_matrix *)&ctm_only(pgs);
1026
28.2k
    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
1027
28.2k
        (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
1028
1
        goto exit;
1029
28.2k
    sbox.p.x = prect->p.x;
1030
28.2k
    sbox.p.y = prect->p.y;
1031
28.2k
    sbox.q.x = prect->q.x;
1032
28.2k
    sbox.q.y = prect->q.y;
1033
28.2k
    gs_bbox_transform_only(&sbox, &mat, corners);
1034
28.2k
    gs_points_bbox(corners, &dbox);
1035
28.2k
    ibox.p.x = float2fixed(dbox.p.x);
1036
28.2k
    ibox.p.y = float2fixed(dbox.p.y);
1037
28.2k
    ibox.q.x = float2fixed(dbox.q.x);
1038
28.2k
    ibox.q.y = float2fixed(dbox.q.y);
1039
28.2k
    if (pcpath != NULL &&
1040
28.2k
        !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
1041
26.7k
                                     ibox.q.x, ibox.q.y)
1042
28.2k
        ) {
1043
        /* Let the target do the drawing, but drive two triangles */
1044
        /* through the clipping path to get an accurate bounding box. */
1045
2.69k
        gx_device_clip cdev;
1046
2.69k
        gx_drawing_color devc;
1047
1048
2.69k
        fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
1049
2.69k
        fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
1050
1051
2.69k
        pdev->AccumulatingBBox++;
1052
2.69k
        gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
1053
2.69k
        set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
1054
2.69k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1055
2.69k
                                 float2fixed(corners[1].x) - x0,
1056
2.69k
                                 float2fixed(corners[1].y) - y0,
1057
2.69k
                                 bx2, by2, &devc, lop_default);
1058
2.69k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1059
2.69k
                                 float2fixed(corners[3].x) - x0,
1060
2.69k
                                 float2fixed(corners[3].y) - y0,
1061
2.69k
                                 bx2, by2, &devc, lop_default);
1062
2.69k
        gx_destroy_clip_device_on_stack(&cdev);
1063
2.69k
        pdev->AccumulatingBBox--;
1064
25.5k
    } else {
1065
        /* Just use the bounding box. */
1066
25.5k
        float x0, y0, x1, y1;
1067
25.5k
        x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
1068
25.5k
        y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
1069
25.5k
        x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
1070
25.5k
        y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
1071
25.5k
        if (Box->p.x > x0)
1072
1.89k
            Box->p.x = x0;
1073
25.5k
        if (Box->p.y > y0)
1074
2.17k
            Box->p.y = y0;
1075
25.5k
        if (Box->q.x < x1)
1076
2.63k
            Box->q.x = x1;
1077
25.5k
        if (Box->q.y < y1)
1078
2.81k
            Box->q.y = y1;
1079
25.5k
    }
1080
28.2k
 exit:
1081
28.2k
    return code;
1082
28.2k
}
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
113k
{
1093
113k
    int code = 0, i;
1094
113k
    unsigned int use_fallback  = 0, in_line = 0, is_mask = 0,
1095
113k
        force_lossless = 0, convert_to_process_colors = 0;
1096
113k
    int width, height;
1097
113k
    cos_dict_t *pnamed = 0;
1098
113k
    image_union_t *image;
1099
113k
    const gs_pixel_image_t *pim;
1100
113k
    gs_int_rect rect;
1101
113k
    gs_image_format_t format;
1102
113k
    gs_color_space *pcs = NULL;
1103
113k
    int num_components;
1104
113k
    pdf_image_enum *pie = NULL;
1105
113k
    const pdf_color_space_names_t *names;
1106
113k
    gs_color_space *pcs_orig = NULL;
1107
113k
    gs_color_space *pcs_device = NULL;
1108
113k
    cos_value_t cs_value;
1109
113k
    const gs_range_t *pranges = 0;
1110
1111
113k
    image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
1112
113k
                       sizeof(image_union_t), "pdf_begin_typed_image(image)");
1113
113k
    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
113k
    {
1121
113k
        cos_value_t ni_value;
1122
1123
113k
        if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1124
6
            pnamed = (cos_dict_t *)ni_value.contents.object;
1125
113k
    }
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
113k
    pdev->image_mask_id = gs_no_id;
1131
1132
113k
    pim = (const gs_pixel_image_t *)pic;
1133
1134
    /* Check for the image types we can handle. */
1135
113k
    switch (pic->type->index) {
1136
107k
    case 1:
1137
107k
        is_mask = ((const gs_image_t *)pic)->ImageMask;
1138
107k
        code = setup_type1_image(pdev, pic, pdcolor, image, context);
1139
107k
        if (code < 0)
1140
12
            use_fallback = 1;
1141
107k
        else
1142
107k
            in_line = code;
1143
107k
        break;
1144
1145
126
    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
126
        pdev->JPEG_PassThrough = 0;
1161
126
        pdev->JPX_PassThrough = 0;
1162
126
        pdev->image_mask_is_SMask = false;
1163
126
        if (pdev->CompatibilityLevel < 1.2 ||
1164
126
            (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
126
        code = setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image);
1171
126
        goto exit;
1172
1173
5.07k
    case IMAGE3X_IMAGETYPE:
1174
5.07k
        {
1175
5.07k
            char *OC = pdev->PendingOC;
1176
1177
5.07k
            pdev->JPEG_PassThrough = 0;
1178
5.07k
            pdev->JPX_PassThrough = 0;
1179
5.07k
            if (pdev->CompatibilityLevel < 1.4 ||
1180
5.07k
                (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
5.07k
            pdev->image_mask_is_SMask = true;
1187
1188
5.07k
            if (pdev->PendingOC)
1189
3
                gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
1190
5.07k
            OC = pdev->PendingOC = NULL;
1191
5.07k
            code = gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
1192
5.07k
                                            prect, pdcolor, pcpath, mem,
1193
5.07k
                                            pdf_image3x_make_mid,
1194
5.07k
                                            pdf_image3x_make_mcde, pinfo, OC);
1195
5.07k
            goto exit;
1196
5.07k
        }
1197
1198
28
    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
28
        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
28
        pdev->JPEG_PassThrough = 0;
1264
28
        pdev->JPX_PassThrough = 0;
1265
28
        code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
1266
28
                      pcpath, mem, pinfo, context, image, pnamed);
1267
28
        if (code < 0)
1268
0
            use_fallback = 1;
1269
28
        if (code == 0)
1270
0
            goto exit;
1271
        /* No luck.  Masked images require PDF 1.3 or higher. */
1272
28
        if (pdev->CompatibilityLevel < 1.2)
1273
0
            use_fallback = 1;
1274
28
        if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1275
25
            use_fallback = 0;
1276
25
            code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1277
25
                                                 pcpath, mem,pinfo);
1278
25
            goto exit;
1279
25
        }
1280
3
        image[0].type4 = *(const gs_image4_t *)pic;
1281
3
        break;
1282
1283
0
    default:
1284
0
        use_fallback = 1;
1285
0
        break;
1286
113k
    }
1287
1288
107k
    format = pim->format;
1289
107k
    switch (format) {
1290
107k
    case gs_image_format_chunky:
1291
107k
    case gs_image_format_component_planar:
1292
107k
        break;
1293
0
    default:
1294
0
        use_fallback = 1;
1295
107k
    }
1296
    /* AR5 on Windows doesn't support 0-size images. Skipping. */
1297
107k
    if (pim->Width == 0 || pim->Height == 0)
1298
11
        use_fallback = 1;
1299
    /* PDF doesn't support images with more than 8 bits per component. */
1300
107k
    switch (pim->BitsPerComponent) {
1301
79.3k
        case 1:
1302
79.6k
        case 2:
1303
79.7k
        case 4:
1304
107k
        case 8:
1305
107k
        case 12:
1306
107k
        case 16:
1307
107k
            break;
1308
0
        default:
1309
0
            code = gs_note_error(gs_error_rangecheck);
1310
0
            goto exit;
1311
107k
    }
1312
107k
    if (prect)
1313
5.10k
        rect = *prect;
1314
102k
    else {
1315
102k
        rect.p.x = rect.p.y = 0;
1316
102k
        rect.q.x = pim->Width, rect.q.y = pim->Height;
1317
102k
    }
1318
107k
    if (rect.p.x != 0 || rect.p.y != 0 ||
1319
107k
        rect.q.x != pim->Width || rect.q.y != pim->Height ||
1320
107k
        (is_mask && pim->CombineWithColor))
1321
0
        use_fallback = 1;
1322
1323
    /* Handle BBox for Eps2Write, if applicable */
1324
107k
    code = pdf_image_handle_eps(pdev, pgs, pmat, pic, &rect, pcpath);
1325
107k
    if (code < 0) {
1326
1
        use_fallback = 0;
1327
1
        goto exit;
1328
1
    }
1329
1330
107k
    if (use_fallback)
1331
22
        goto exit;
1332
1333
107k
    pcs = pim->ColorSpace;
1334
107k
    rc_increment_cs(pcs);
1335
107k
    num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1336
1337
107k
    code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
1338
107k
    if (code < 0)
1339
0
        goto exit;
1340
107k
    if (pdf_must_put_clip_path(pdev, pcpath))
1341
9.91k
        code = pdf_unclip(pdev);
1342
97.9k
    else
1343
97.9k
        code = pdf_open_page(pdev, PDF_IN_STREAM);
1344
107k
    if (code < 0)
1345
0
        goto fail_and_fallback;
1346
1347
107k
    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
5.10k
        rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1355
5.10k
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
1356
5.10k
        if (pcs == NULL)
1357
0
            code = gs_note_error(gs_error_VMerror);
1358
102k
    } else if (is_mask)
1359
78.4k
        code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
1360
24.3k
    else
1361
24.3k
        code = pdf_prepare_image(pdev, pgs);
1362
107k
    if (code < 0)
1363
242
        goto fail_and_fallback;
1364
1365
107k
    pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1366
107k
                        "pdf_begin_image");
1367
107k
    if (pie == 0) {
1368
0
        code = gs_note_error(gs_error_VMerror);
1369
0
        goto exit;
1370
0
    }
1371
107k
    memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1372
107k
    *pinfo = (gx_image_enum_common_t *) pie;
1373
107k
    gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1374
107k
                    ((pdev->CompatibilityLevel >= 1.3) ?
1375
50.9k
                            (context == PDF_IMAGE_TYPE3_MASK ?
1376
5.10k
                            &pdf_image_object_enum_procs :
1377
50.9k
                            &pdf_image_enum_procs) :
1378
107k
                            context == PDF_IMAGE_TYPE3_MASK ?
1379
0
                            &pdf_image_object_enum_procs :
1380
56.6k
                            context == PDF_IMAGE_TYPE3_DATA ?
1381
0
                            &pdf_image_object_enum_procs2 :
1382
56.6k
                            &pdf_image_enum_procs),
1383
107k
                        (gx_device *)pdev, num_components, format);
1384
107k
    pie->memory = mem;
1385
107k
    pie->pgs = pgs;
1386
107k
    if (pgs != NULL)
1387
107k
        pie->pgs_level = pgs->level;
1388
107k
    width = rect.q.x - rect.p.x;
1389
107k
    pie->width = width;
1390
107k
    height = rect.q.y - rect.p.y;
1391
107k
    pie->bits_per_pixel =
1392
107k
        pim->BitsPerComponent * num_components / pie->num_planes;
1393
107k
    pie->rows_left = height;
1394
107k
    if (pnamed != 0 || pdev->PendingOC) /* Don't in-line the image if it is named. Or has Optional Content */
1395
25
        in_line = false;
1396
107k
    else {
1397
107k
        int64_t nbytes = (int64_t)(((int64_t) pie->width * pie->bits_per_pixel + 7) >> 3) *
1398
107k
            pie->num_planes * pie->rows_left;
1399
1400
107k
        in_line &= (nbytes < pdev->MaxInlineImageSize);
1401
107k
    }
1402
107k
    pie->initial_colorspace = pdev->pcm_color_info_index;
1403
1404
107k
    if (pmat == 0)
1405
97.4k
        pmat = &ctm_only(pgs);
1406
107k
    {
1407
107k
        gs_matrix mat;
1408
107k
        gs_matrix bmat;
1409
107k
        int code;
1410
1411
107k
        pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1412
107k
                               pim->Width, pim->Height, height);
1413
107k
        if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1414
107k
            (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1415
107k
            (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1416
107k
            )
1417
1
            goto exit;
1418
        /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1419
107k
        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
1420
621
            use_fallback = 1;
1421
621
            goto fail_and_fallback;
1422
621
        }
1423
107k
    }
1424
1425
106k
    code = pdf_put_clip_path(pdev, pcpath);
1426
106k
    if (code < 0)
1427
0
        goto exit;
1428
106k
    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
106k
    pie->writer.alt_writer_count = (in_line ||
1438
106k
                                    (pim->Width <= 64 && pim->Height <= 64)
1439
106k
                                    ? 1 : 2);
1440
106k
    if ((image[0].pixel.ColorSpace != NULL &&
1441
106k
        image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1442
106k
        && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1443
106k
        pdev->transfer_not_identity)
1444
1.27k
        force_lossless = true;
1445
1446
106k
    if ((image[0].pixel.ColorSpace != NULL && image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed)
1447
106k
        || force_lossless)
1448
2.80k
        pie->writer.alt_writer_count = 1;
1449
1450
106k
    if (image[0].pixel.ColorSpace != NULL && (image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceGray &&
1451
29.2k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceRGB &&
1452
29.2k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceCMYK &&
1453
29.2k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_Indexed))
1454
26.4k
        names = &pdf_color_space_names;
1455
80.5k
    else
1456
80.5k
        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
106k
    if (!is_mask) {
1460
29.2k
#if 1
1461
29.2k
        if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1462
24.1k
           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
29.2k
        if (pim->BitsPerComponent > 8 && convert_to_process_colors) {
1483
0
            use_fallback = 1;
1484
0
            goto fail_and_fallback;
1485
0
        }
1486
29.2k
        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
29.2k
        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
29.2k
        if (convert_to_process_colors == 1) {
1502
1.53k
            code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1503
1.53k
            if (code < 0)
1504
0
                goto fail_and_fallback;
1505
1.53k
            image[0].pixel.ColorSpace = pcs_device;
1506
1.53k
            image[0].pixel.BitsPerComponent = 8;
1507
1.53k
            code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1508
1.53k
                                     in_line, NULL, 0, false);
1509
1.53k
            if (code < 0)
1510
0
                goto fail_and_fallback;
1511
27.7k
        } else {
1512
27.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
27.7k
            } else {
1519
27.7k
                convert_to_process_colors = 0;
1520
27.7k
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1521
27.7k
                                     in_line, NULL, 0, false);
1522
27.7k
                if (code < 0)
1523
0
                    goto fail_and_fallback;
1524
27.7k
            }
1525
27.7k
        }
1526
29.2k
    }
1527
1528
106k
    image[1] = image[0];
1529
1530
106k
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1531
1532
106k
    code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1533
106k
                    height, pnamed, in_line);
1534
106k
    if (code < 0)
1535
0
        goto fail_and_fallback;
1536
1537
106k
    if (pdev->CompatibilityLevel < 1.5)
1538
56.4k
        pdev->JPX_PassThrough = 0;
1539
1540
106k
    if (!convert_to_process_colors)
1541
105k
    {
1542
105k
        gs_color_space_index csi;
1543
1544
105k
        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
105k
    }
1595
    /* If we are not preserving the colour space unchanged, then we can't pass through JPEG */
1596
1.53k
    else
1597
1.53k
        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
106k
    if (in_line) {
1611
89.7k
        pdev->JPEG_PassThrough = 0;
1612
89.7k
        pdev->JPX_PassThrough = 0;
1613
89.7k
        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1614
89.7k
                                             &pie->writer.binary[0],
1615
89.7k
                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
1616
89.7k
    } else {
1617
17.2k
        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
1.05k
            int saved_downsample = pdev->params.ColorImage.DownsampleType;
1628
1629
1.05k
            pdev->params.ColorImage.DownsampleType = ds_Subsample;
1630
1.05k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1631
1.05k
                                          &pie->writer.binary[0], &image[0].pixel,
1632
1.05k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1633
1.05k
            pdev->params.ColorImage.DownsampleType = saved_downsample;
1634
16.1k
        } else {
1635
16.1k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1636
16.1k
                                          &pie->writer.binary[0], &image[0].pixel,
1637
16.1k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1638
16.1k
        }
1639
17.2k
    }
1640
1641
106k
    if (code < 0)
1642
0
        goto fail_and_fallback;
1643
1644
106k
    if (convert_to_process_colors) {
1645
1.53k
        image[0].pixel.ColorSpace = pcs_orig;
1646
1.53k
        image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
1647
1.53k
        code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1648
1.53k
                                              (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
1649
1.53k
        if (code < 0)
1650
0
            goto fail_and_fallback;
1651
1.53k
        image[0].pixel.ColorSpace = pcs_device;
1652
1.53k
    }
1653
1654
106k
    if (pdev->JPEG_PassThrough || pdev->JPX_PassThrough) {
1655
/*        if (pie->writer.alt_writer_count > 1) {
1656
            s_close_filters(&pie->writer.binary[0].strm, uncompressed);
1657
            memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1658
            memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1659
        }*/
1660
4.85k
        pdev->PassThroughWriter = pie->writer.binary[0].strm;
1661
4.85k
        pie->writer.alt_writer_count = 1;
1662
4.85k
    }
1663
106k
    pie->JPEG_PassThrough = pdev->JPEG_PassThrough;
1664
106k
    pie->JPX_PassThrough = pdev->JPX_PassThrough;
1665
1666
106k
    if (pie->writer.alt_writer_count > 1) {
1667
10.7k
        code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1668
10.7k
        if (code < 0)
1669
0
            goto fail_and_fallback;
1670
10.7k
        code = new_setup_image_filters((gx_device_psdf *) pdev,
1671
10.7k
                                  &pie->writer.binary[1], &image[1].pixel,
1672
10.7k
                                  pmat, pgs, force_lossless, in_line, convert_to_process_colors);
1673
10.7k
        if (code == gs_error_rangecheck) {
1674
1675
0
            for (i=1;i < pie->writer.alt_writer_count; i++) {
1676
0
                stream *s = pie->writer.binary[i].strm;
1677
0
                cos_stream_t *pcos = cos_stream_from_pipeline(pie->writer.binary[i].strm);
1678
0
                s_close_filters(&s, NULL);
1679
0
                gs_free_object(pdev->pdf_memory, s, "compressed image stream");
1680
0
                if (pcos == 0L) {
1681
                    /* TODO: Seems like something should be freed here */
1682
0
                    code = gs_note_error(gs_error_ioerror);
1683
0
                    goto exit;
1684
0
                }
1685
0
                pcos->cos_procs->release((cos_object_t *)pcos, "pdf_begin_typed_image_impl");
1686
0
                gs_free_object(pdev->pdf_memory, pcos, "compressed image cos_stream");
1687
0
            }
1688
            /* setup_image_compression rejected the alternative compression. */
1689
0
            pie->writer.alt_writer_count = 1;
1690
0
            memset(pie->writer.binary + 1, 0, sizeof(pie->writer.binary[1]));
1691
0
            memset(pie->writer.binary + 2, 0, sizeof(pie->writer.binary[1]));
1692
10.7k
        } else if (code) {
1693
0
            goto fail_and_fallback;
1694
10.7k
        } else if (convert_to_process_colors) {
1695
0
            image[1].pixel.ColorSpace = pcs_orig;
1696
0
            image[1].pixel.BitsPerComponent = pim->BitsPerComponent;
1697
0
            code = psdf_setup_image_colors_filter(&pie->writer.binary[1],
1698
0
                                              (gx_device_psdf *)pdev, pim, &image[1].pixel, pgs);
1699
0
            if (code < 0)
1700
0
                goto fail_and_fallback;
1701
0
            image[1].pixel.ColorSpace = pcs_device;
1702
0
        }
1703
10.7k
    }
1704
1705
224k
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1706
117k
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1707
117k
                             &image[i].pixel, &cs_value, pie);
1708
117k
        if (code < 0)
1709
0
            goto fail_and_fallback;
1710
117k
    }
1711
106k
    if (pie->writer.alt_writer_count == 2) {
1712
10.7k
        psdf_setup_compression_chooser(&pie->writer.binary[2],
1713
10.7k
             (gx_device_psdf *)pdev, pim->Width, pim->Height,
1714
10.7k
             num_components, pim->BitsPerComponent);
1715
10.7k
        pie->writer.alt_writer_count = 3;
1716
10.7k
    }
1717
106k
    if (pic->type->index == 4 && pdev->CompatibilityLevel < 1.3) {
1718
0
        int i;
1719
1720
        /* Create a stream for writing the mask. */
1721
0
        i = pie->writer.alt_writer_count;
1722
0
        gs_image_t_init_mask_adjust((gs_image_t *)&image[i].type1, true, false);
1723
0
        image[i].type1.Width = image[0].pixel.Width;
1724
0
        image[i].type1.Height = image[0].pixel.Height;
1725
        /* Won't use image[2]. */
1726
0
        code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1727
0
                    height, NULL, false);
1728
0
        if (code < 0)
1729
0
            goto fail_and_fallback;
1730
0
        code = psdf_setup_image_filters((gx_device_psdf *) pdev,
1731
0
                                  &pie->writer.binary[i], &image[i].pixel,
1732
0
                                  pmat, pgs, force_lossless, in_line);
1733
0
        if (code < 0)
1734
0
            goto fail_and_fallback;
1735
        /* Bug701972 -- added input_width arg here.  For this case, just passing in the same
1736
         * width as before, so nothing changes.  This is an obscure case that isn't tested
1737
         * on the cluster (note that it requires CompatibilityLevel < 1.3).
1738
         */
1739
0
        psdf_setup_image_to_mask_filter(&pie->writer.binary[i],
1740
0
                                        (gx_device_psdf *)pdev, pim->Width, pim->Height, pim->Width,
1741
0
                                        num_components, pim->BitsPerComponent, image[i].type4.MaskColor);
1742
0
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1743
0
                             &image[i].pixel, &cs_value, pie);
1744
0
        if (code < 0)
1745
0
            goto fail_and_fallback;
1746
0
        ++pie->writer.alt_writer_count;
1747
0
    }
1748
1749
    /* use_fallback = 0, so this will drop through the below labels, doing only the cleanup parts */
1750
106k
    code = 0;
1751
1752
    /* This label is used when code < 0 and we want to do the fallback code */
1753
107k
 fail_and_fallback:
1754
107k
    if (code != 0)
1755
242
        use_fallback = 1;
1756
1757
    /* This label is used either when there's no error and we are just exiting normally
1758
     * (possibly with use_fallback=1), or there is an error but we don't want to do
1759
     * the fallback code.
1760
     */
1761
113k
 exit:
1762
    /* Free everything */
1763
113k
    rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1764
113k
    rc_decrement(pcs_device, "pdf_begin_typed_image(pcs_device)");
1765
113k
    gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1766
113k
                                      "pdf_begin_typed_image(image)");
1767
1768
    /* Free pie only if there was an error or we are falling back */
1769
113k
    if (code < 0 || use_fallback) {
1770
911
        if (pie)
1771
621
            gs_free_object(mem, pie, "pdf_begin_typed_image(pie)");
1772
911
        *pinfo = NULL;
1773
911
    }
1774
    /* Do the fallback */
1775
113k
    if (use_fallback) {
1776
885
        pdev->JPEG_PassThrough = 0;
1777
885
        pdev->JPX_PassThrough = 0;
1778
885
        code = gx_default_begin_typed_image
1779
885
            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo);
1780
885
    }
1781
113k
    return code;
1782
107k
}
1783
1784
int
1785
gdev_pdf_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
1786
                           const gs_matrix *pmat, const gs_image_common_t *pic,
1787
                           const gs_int_rect * prect,
1788
                           const gx_drawing_color * pdcolor,
1789
                           const gx_clip_path * pcpath, gs_memory_t * mem,
1790
                           gx_image_enum_common_t ** pinfo)
1791
102k
{
1792
102k
    return pdf_begin_typed_image((gx_device_pdf *)dev, pgs, pmat, pic, prect,
1793
102k
                                 pdcolor, pcpath, mem, pinfo,
1794
102k
                                 PDF_IMAGE_DEFAULT);
1795
102k
}
1796
1797
/* ---------------- All images ---------------- */
1798
1799
/* Process the next piece of an image. */
1800
static int
1801
pdf_image_plane_data_alt(gx_image_enum_common_t * info,
1802
                     const gx_image_plane_t * planes, int height,
1803
                     int *rows_used, int alt_writer_index)
1804
10.8M
{
1805
10.8M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1806
10.8M
    int h = height;
1807
10.8M
    int y;
1808
    /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
1809
10.8M
    uint width_bits = pie->width * pie->plane_depths[0];
1810
    /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
1811
10.8M
    uint ignore;
1812
10.8M
    int nplanes = pie->num_planes;
1813
10.8M
    int status = 0;
1814
10.8M
    uint bcount = (width_bits + 7) >> 3;
1815
1816
10.8M
    if (h > pie->rows_left)
1817
72.7k
        h = pie->rows_left;
1818
23.8M
    for (y = 0; y < h; ++y) {
1819
13.0M
        if (nplanes > 1) {
1820
            /*
1821
             * We flip images in blocks, and each block except the last one
1822
             * must contain an integral number of pixels.  The easiest way
1823
             * to meet this condition is for all blocks except the last to
1824
             * be a multiple of 3 source bytes (guaranteeing an integral
1825
             * number of 1/2/4/8/12-bit samples), i.e., 3*nplanes flipped
1826
             * bytes.  This requires a buffer of at least
1827
             * 3*GS_IMAGE_MAX_COMPONENTS bytes.
1828
             */
1829
2.18k
            int pi;
1830
2.18k
            uint count = bcount;
1831
2.18k
            uint offset = 0;
1832
2.18k
#define ROW_BYTES max(200 /*arbitrary*/, 3 * GS_IMAGE_MAX_COMPONENTS)
1833
2.18k
            const byte *bit_planes[GS_IMAGE_MAX_COMPONENTS];
1834
2.18k
            int block_bytes = ROW_BYTES / (3 * nplanes) * 3;
1835
2.18k
            byte row[ROW_BYTES];
1836
1837
8.74k
            for (pi = 0; pi < nplanes; ++pi)
1838
6.55k
                bit_planes[pi] = planes[pi].data + planes[pi].raster * y;
1839
17.4k
            while (count) {
1840
15.3k
                uint flip_count;
1841
15.3k
                uint flipped_count;
1842
1843
15.3k
                if (count > block_bytes) {
1844
13.1k
                    flip_count = block_bytes;
1845
13.1k
                    flipped_count = block_bytes * nplanes;
1846
13.1k
                } else {
1847
2.18k
                    flip_count = count;
1848
2.18k
                    flipped_count =
1849
2.18k
                        (width_bits % (block_bytes * 8) * nplanes + 7) >> 3;
1850
                    /* In case the width of the image is a precise multiple of our block size */
1851
2.18k
                    if (flipped_count == 0)
1852
0
                        flipped_count = block_bytes * nplanes;
1853
2.18k
                }
1854
15.3k
                status = image_flip_planes(row, bit_planes, offset, flip_count,
1855
15.3k
                                           nplanes, pie->plane_depths[0]);
1856
15.3k
                if (status < 0)
1857
0
                    break;
1858
15.3k
                status = sputs(pie->writer.binary[alt_writer_index].strm, row,
1859
15.3k
                               flipped_count, &ignore);
1860
15.3k
                if (status < 0)
1861
0
                    break;
1862
15.3k
                offset += flip_count;
1863
15.3k
                count -= flip_count;
1864
15.3k
            }
1865
13.0M
        } else {
1866
13.0M
            status = sputs(pie->writer.binary[alt_writer_index].strm,
1867
13.0M
                           planes[0].data + planes[0].raster * y, bcount,
1868
13.0M
                           &ignore);
1869
13.0M
        }
1870
13.0M
        if (status < 0)
1871
0
            break;
1872
13.0M
    }
1873
10.8M
    *rows_used = h;
1874
10.8M
    if (status < 0)
1875
0
        return_error(gs_error_ioerror);
1876
10.8M
    return !pie->rows_left;
1877
10.8M
#undef ROW_BYTES
1878
10.8M
}
1879
1880
static int
1881
pdf_image_plane_data(gx_image_enum_common_t * info,
1882
                     const gx_image_plane_t * planes, int height,
1883
                     int *rows_used)
1884
9.41M
{
1885
9.41M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1886
9.41M
    int i;
1887
1888
9.41M
    if (info->pgs != NULL && info->pgs->level < info->pgs_level)
1889
1
        return_error(gs_error_undefinedresult);
1890
1891
9.41M
    if (pie->JPEG_PassThrough || pie->JPX_PassThrough) {
1892
303k
        pie->rows_left -= height;
1893
303k
        *rows_used = height;
1894
303k
        return !pie->rows_left;
1895
303k
    }
1896
1897
19.9M
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1898
10.8M
        int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
1899
10.8M
        if (code)
1900
0
            return code;
1901
10.8M
    }
1902
9.11M
    pie->rows_left -= *rows_used;
1903
9.11M
    if (pie->writer.alt_writer_count > 2)
1904
861k
        pdf_choose_compression(&pie->writer, false);
1905
1906
9.11M
    return !pie->rows_left;
1907
9.11M
}
1908
1909
static int
1910
use_image_as_pattern(gx_device_pdf *pdev, pdf_resource_t *pres1,
1911
                     const gs_matrix *pmat, gs_id id)
1912
0
{   /* See also dump_image in gdevpdfd.c . */
1913
0
    gs_gstate s;
1914
0
    gs_pattern1_instance_t inst;
1915
0
    cos_value_t v;
1916
0
    const pdf_resource_t *pres;
1917
0
    int code;
1918
1919
0
    memset(&s, 0, sizeof(s));
1920
0
    s.ctm.xx = pmat->xx;
1921
0
    s.ctm.xy = pmat->xy;
1922
0
    s.ctm.yx = pmat->yx;
1923
0
    s.ctm.yy = pmat->yy;
1924
0
    s.ctm.tx = pmat->tx;
1925
0
    s.ctm.ty = pmat->ty;
1926
0
    memset(&inst, 0, sizeof(inst));
1927
0
    inst.saved = (gs_gstate *)&s; /* HACK : will use s.ctm only. */
1928
0
    inst.templat.PaintType = 1;
1929
0
    inst.templat.TilingType = 1;
1930
0
    inst.templat.BBox.p.x = inst.templat.BBox.p.y = 0;
1931
0
    inst.templat.BBox.q.x = 1;
1932
0
    inst.templat.BBox.q.y = 1;
1933
0
    inst.templat.XStep = 2; /* Set 2 times bigger step against artifacts. */
1934
0
    inst.templat.YStep = 2;
1935
1936
0
    {
1937
0
        pattern_accum_param_s param;
1938
0
        param.pinst = (void *)&inst;
1939
0
        param.graphics_state = (void *)&s;
1940
0
        param.pinst_id = inst.id;
1941
1942
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1943
0
            gxdso_pattern_start_accum, &param, sizeof(pattern_accum_param_s));
1944
0
    }
1945
1946
0
    if (code >= 0)
1947
0
        pprinti64d1(pdev->strm, "/R%"PRId64" Do\n", pdf_resource_id(pres1));
1948
0
    pres = pdev->accumulating_substream_resource;
1949
0
    if (pres == NULL)
1950
0
        code = gs_note_error(gs_error_unregistered);
1951
0
    if (code >= 0)
1952
0
        code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres1);
1953
0
    if (code >= 0) {
1954
0
        pattern_accum_param_s param;
1955
0
        param.pinst = (void *)&inst;
1956
0
        param.graphics_state = (void *)&s;
1957
0
        param.pinst_id = inst.id;
1958
1959
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1960
0
            gxdso_pattern_finish_accum, &param, id);
1961
0
    }
1962
0
    if (code >= 0)
1963
0
        code = (*dev_proc(pdev, dev_spec_op))((gx_device *)pdev,
1964
0
            gxdso_pattern_load, &id, sizeof(gs_id));
1965
0
    if (code >= 0) {
1966
0
        stream_puts(pdev->strm, "q ");
1967
0
        code = pdf_cs_Pattern_colored(pdev, &v);
1968
0
    }
1969
0
    if (code >= 0) {
1970
0
        cos_value_write(&v, pdev);
1971
0
        pprinti64d1(pdev->strm, " cs /R%"PRId64" scn ", pdf_resource_id(pres));
1972
0
    }
1973
0
    if (code >= 0) {
1974
        /* The image offset weas broken in gx_begin_image3_generic,
1975
           (see 'origin' in there).
1976
           As a temporary hack use the offset of the image.
1977
           fixme : This isn't generally correct,
1978
           because the mask may be "transpozed" against the image. */
1979
0
        gs_matrix m = pdev->converting_image_matrix;
1980
1981
0
        m.tx = pmat->tx;
1982
0
        m.ty = pmat->ty;
1983
0
        code = pdf_do_image_by_id(pdev, pdev->image_mask_scale,
1984
0
             &m, true, pdev->image_mask_id);
1985
0
        stream_puts(pdev->strm, "Q\n");
1986
0
    }
1987
0
    return code;
1988
0
}
1989
1990
typedef enum {
1991
    USE_AS_MASK,
1992
    USE_AS_IMAGE,
1993
    USE_AS_PATTERN
1994
} pdf_image_usage_t;
1995
1996
/* Close PDF image and do it. */
1997
static int
1998
pdf_end_and_do_image(gx_device_pdf *pdev, pdf_image_writer *piw,
1999
                     const gs_matrix *mat, gs_id ps_bitmap_id, pdf_image_usage_t do_image)
2000
102k
{
2001
102k
    int code = 0;
2002
102k
    pdf_resource_t *pres = NULL;
2003
2004
    /* In order to identify duplicated images which use the same SMask we must
2005
     * add the SMask entry to the image dictionary before we call pdf_end_write_image
2006
     * because that will hash the dictionaries and streams. If we haven't already
2007
     * added the SMask then the hash will not match any existing image which uses an SMask.
2008
     */
2009
102k
    if (do_image == USE_AS_IMAGE) {
2010
97.9k
        if (pdev->image_mask_id != gs_no_id && piw->pres && piw->pres->object) {
2011
4.78k
            char buf[20];
2012
2013
4.78k
            gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->image_mask_id);
2014
4.78k
            code = cos_dict_put_string_copy((cos_dict_t *)piw->pres->object,
2015
4.78k
                    pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
2016
4.78k
            (*(piw->pres->object)).md5_valid = 0;
2017
4.78k
            if (code < 0)
2018
0
                return code;
2019
4.78k
        }
2020
97.9k
    }
2021
2022
102k
    code = pdf_end_write_image(pdev, piw);
2023
102k
    pres = piw->pres;
2024
2025
102k
    switch (code) {
2026
0
    default:
2027
0
        return code; /* error */
2028
87.8k
    case 1:
2029
87.8k
        code = 0;
2030
87.8k
        break;
2031
14.8k
    case 0:
2032
14.8k
        if (do_image == USE_AS_IMAGE) {
2033
10.0k
            if (pdev->image_mask_skip)
2034
0
                code = 0;
2035
10.0k
            else
2036
10.0k
                code = pdf_do_image(pdev, pres, mat, true);
2037
10.0k
        } else if (do_image == USE_AS_MASK) {
2038
            /* Provide data for pdf_do_image_by_id, which will be called through
2039
                use_image_as_pattern during the next call to this function.
2040
                See pdf_do_image about the meaning of 'scale'. */
2041
4.78k
            const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
2042
2043
4.78k
            pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
2044
4.78k
            pdev->image_mask_id = pdf_resource_id(pres);
2045
4.78k
            pdev->converting_image_matrix = *mat;
2046
4.78k
        } else if (do_image == USE_AS_PATTERN)
2047
0
            code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
2048
102k
    }
2049
102k
    return code;
2050
102k
}
2051
2052
/* Clean up by releasing the buffers. */
2053
static int
2054
pdf_image_end_image_data(gx_image_enum_common_t * info, bool draw_last,
2055
                         pdf_image_usage_t do_image)
2056
106k
{
2057
106k
    gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
2058
106k
    pdf_image_enum *pie = (pdf_image_enum *)info;
2059
106k
    int height = pie->writer.height;
2060
106k
    int data_height = height - pie->rows_left;
2061
106k
    int code = 0, ecode;
2062
2063
106k
    if (pie->writer.pres)
2064
17.2k
        ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
2065
89.7k
    else if (data_height > 0)
2066
87.8k
        pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
2067
106k
    if (data_height > 0) {
2068
102k
        if (pie->writer.pres) {
2069
14.8k
            code = pdf_complete_image_data(pdev, &pie->writer, data_height,
2070
14.8k
                        pie->width, pie->bits_per_pixel);
2071
14.8k
            if (code < 0)
2072
0
                return code;
2073
14.8k
        }
2074
102k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2075
        /* The call above possibly decreases pie->writer.alt_writer_count in 2. */
2076
102k
        if (code < 0)
2077
0
            return code;
2078
102k
        if (pie->writer.alt_writer_count == 2) {
2079
            /* We're converting a type 4 image into an imagemask with a pattern color. */
2080
            /* Since the type 3 image writes the mask first, do so here. */
2081
0
            pdf_image_writer writer = pie->writer;
2082
2083
0
            writer.binary[0] = pie->writer.binary[1];
2084
0
            writer.pres = pie->writer.pres_mask;
2085
0
            writer.alt_writer_count = 1;
2086
0
            memset(&pie->writer.binary[1], 0, sizeof(pie->writer.binary[1]));
2087
0
            pie->writer.alt_writer_count--; /* For GC. */
2088
0
            pie->writer.pres_mask = 0; /* For GC. */
2089
0
            code = pdf_end_image_binary(pdev, &writer, data_height);
2090
0
            if (code < 0)
2091
0
                return code;
2092
0
            code = pdf_end_and_do_image(pdev, &writer, &pie->mat, info->id, USE_AS_MASK);
2093
0
            if (code < 0)
2094
0
                return code;
2095
0
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, USE_AS_PATTERN);
2096
0
        } else
2097
102k
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
2098
102k
        pie->writer.alt_writer_count--; /* For GC. */
2099
102k
    } else {
2100
4.27k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2101
4.27k
        code = pdf_end_abort_image(pdev, &pie->writer);
2102
4.27k
        pie->writer.alt_writer_count--; /* For GC. */
2103
4.27k
    }
2104
106k
    if (pie->initial_colorspace != pdev->pcm_color_info_index)
2105
0
        pdf_set_process_color_model(pdev, pie->initial_colorspace);
2106
2107
    /* Clean up any outstanding streams before freeing the enumerator */
2108
106k
    while (pie->writer.alt_writer_count-- > 0) {
2109
0
        ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
2110
        /* If we are skipping an image (because its clipped out or similar) then we
2111
         * won't have written any data to it. Some filters (notably the DCTEncode filter)
2112
         * throw an error (premature EOD) if we close the filter without writing any data to it.
2113
         * So if we are skipping the image, ignore errors when closing the stream.
2114
         * Unfortunately we don't set pie->skipping until after begin_typed_image()
2115
         * or we could avoid a lot of setup....
2116
         */
2117
0
        if (ecode < 0 && code >= 0 && !pie->skipping) code  = ecode;
2118
0
    }
2119
2120
106k
    gx_image_free_enum(&info);
2121
106k
    return code;
2122
106k
}
2123
2124
/* End a normal image, drawing it. */
2125
static int
2126
pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
2127
101k
{
2128
101k
    return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
2129
101k
}
2130
2131
/* End an image converted with pdf_lcvd_t. */
2132
static int
2133
pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
2134
25
{   pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
2135
25
    int code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
2136
25
    int code1 = gx_image1_end_image(info, draw_last);
2137
25
    int code2 = gs_closedevice((gx_device *)cvd->mask);
2138
25
    int code3 = gs_closedevice((gx_device *)cvd);
2139
2140
25
    gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
2141
25
    gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
2142
25
    return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
2143
25
}
2144
/* ---------------- Type 3/3x images ---------------- */
2145
2146
/*
2147
 * For both types of masked images, we create temporary dummy (null) devices
2148
 * that forward the begin_typed_image call to the implementation above.
2149
 */
2150
static int
2151
pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
2152
10.2k
{
2153
10.2k
    gx_device *fdev;
2154
10.2k
    int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
2155
2156
10.2k
    if (code < 0)
2157
0
        return code;
2158
10.2k
    gx_device_set_target((gx_device_forward *)fdev, tdev);
2159
10.2k
    *pmxdev = fdev;
2160
10.2k
    return 0;
2161
10.2k
}
2162
2163
/* End the mask of an ImageType 3 image, not drawing it. */
2164
static int
2165
pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
2166
5.09k
{
2167
5.09k
    return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
2168
5.09k
}
2169
/* End the data of an ImageType 3 image, converting it into pattern. */
2170
static int
2171
pdf_image_end_image_object2(gx_image_enum_common_t * info, bool draw_last)
2172
0
{
2173
0
    return pdf_image_end_image_data(info, draw_last, USE_AS_PATTERN);
2174
0
}
2175
2176
/* ---------------- Type 3 images ---------------- */
2177
2178
/* Implement the mask image device. */
2179
static dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
2180
static int
2181
pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2182
                    gs_memory_t *mem)
2183
121
{
2184
121
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2185
2186
121
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2187
87
        gs_matrix m;
2188
87
        pdf_lcvd_t *cvd = NULL;
2189
87
        int code;
2190
2191
87
        gs_make_identity(&m);
2192
87
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
2193
87
                                        true, 0, 0, width, height, true);
2194
87
        if (code < 0)
2195
0
            return code;
2196
87
        cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
2197
                                         pdf_image3_make_mcde. The latter will reset it. */
2198
87
        cvd->mask_is_empty = false;
2199
87
        *pmidev = (gx_device *)cvd->mask;
2200
87
        return 0;
2201
87
    } else {
2202
34
        int code = pdf_make_mxd(pmidev, dev, mem);
2203
2204
34
        if (code < 0)
2205
0
            return code;
2206
34
        set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2207
34
        return 0;
2208
34
    }
2209
121
}
2210
static int
2211
pdf_mid_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
2212
                          const gs_matrix *pmat, const gs_image_common_t *pic,
2213
                          const gs_int_rect * prect,
2214
                          const gx_drawing_color * pdcolor,
2215
                          const gx_clip_path * pcpath, gs_memory_t * mem,
2216
                          gx_image_enum_common_t ** pinfo)
2217
5.10k
{
2218
    /* The target of the null device is the pdfwrite device. */
2219
5.10k
    gx_device_pdf *const pdev = (gx_device_pdf *)
2220
5.10k
        ((gx_device_null *)dev)->target;
2221
5.10k
    return pdf_begin_typed_image
2222
5.10k
        (pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
2223
5.10k
         PDF_IMAGE_TYPE3_MASK);
2224
5.10k
}
2225
2226
/* Implement the mask clip device. */
2227
static int
2228
pdf_image3_make_mcde(gx_device *dev, const gs_gstate *pgs,
2229
                     const gs_matrix *pmat, const gs_image_common_t *pic,
2230
                     const gs_int_rect *prect, const gx_drawing_color *pdcolor,
2231
                     const gx_clip_path *pcpath, gs_memory_t *mem,
2232
                     gx_image_enum_common_t **pinfo,
2233
                     gx_device **pmcdev, gx_device *midev,
2234
                     gx_image_enum_common_t *pminfo,
2235
                     const gs_int_point *origin)
2236
121
{
2237
121
    int code;
2238
121
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2239
2240
121
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2241
        /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
2242
87
        pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
2243
2244
87
        ((gx_device_memory *)midev)->target = NULL;
2245
87
        cvd->m = pdev->converting_image_matrix;
2246
87
        cvd->mdev.mapped_x = origin->x;
2247
87
        cvd->mdev.mapped_y = origin->y;
2248
87
        cvd->mdev.width += origin->x;
2249
87
        cvd->mdev.height += origin->y;
2250
87
        *pmcdev = (gx_device *)&cvd->mdev;
2251
87
        code = gx_default_begin_typed_image
2252
87
            ((gx_device *)&cvd->mdev, pgs, pmat, pic, prect, pdcolor, NULL, mem,
2253
87
            pinfo);
2254
87
        if (code < 0)
2255
0
            return code;
2256
87
    } else {
2257
34
        code = pdf_make_mxd(pmcdev, midev, mem);
2258
34
        if (code < 0)
2259
0
            return code;
2260
34
        code = pdf_begin_typed_image
2261
34
            ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2262
34
            pinfo, PDF_IMAGE_TYPE3_DATA);
2263
34
        if (code < 0) {
2264
0
            gx_device_set_target((gx_device_forward *)(*pmcdev), NULL);
2265
0
            gs_closedevice((*pmcdev));
2266
0
            gs_free_object(mem, (*pmcdev), "pdf_image3_make_mcde(*pmcdev)");
2267
0
            *pmcdev = NULL;
2268
0
            return code;
2269
0
        }
2270
34
    }
2271
    /* Due to equal image merging, we delay the adding of the "Mask" entry into
2272
       a type 3 image dictionary until the mask is completed.
2273
       Will do in pdf_end_and_do_image.*/
2274
121
    return 0;
2275
121
}
2276
2277
/* ---------------- Type 3x images ---------------- */
2278
2279
/* Implement the mask image device. */
2280
static int
2281
pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2282
                     int depth, gs_memory_t *mem)
2283
5.06k
{
2284
5.06k
    int code = pdf_make_mxd(pmidev, dev, mem);
2285
2286
5.06k
    if (code < 0)
2287
0
        return code;
2288
5.06k
    set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2289
5.06k
    return 0;
2290
5.06k
}
2291
2292
/* Implement the mask clip device. */
2293
static int
2294
pdf_image3x_make_mcde(gx_device *dev, const gs_gstate *pgs,
2295
                      const gs_matrix *pmat, const gs_image_common_t *pic,
2296
                      const gs_int_rect *prect,
2297
                      const gx_drawing_color *pdcolor,
2298
                      const gx_clip_path *pcpath, gs_memory_t *mem,
2299
                      gx_image_enum_common_t **pinfo,
2300
                      gx_device **pmcdev, gx_device *midev[2],
2301
                      gx_image_enum_common_t *pminfo[2],
2302
                      const gs_int_point origin[2],
2303
                      const gs_image3x_t *pim)
2304
5.06k
{
2305
5.06k
    int code;
2306
5.06k
    pdf_image_enum *pmie;
2307
5.06k
    int i;
2308
5.06k
    const gs_image3x_mask_t *pixm;
2309
5.06k
    gx_device_pdf *pdf_dev = (gx_device_pdf *)dev;
2310
2311
5.06k
    if (midev[0]) {
2312
5.05k
        if (midev[1])
2313
0
            return_error(gs_error_rangecheck);
2314
5.05k
        i = 0, pixm = &pim->Opacity;
2315
5.05k
    } else if (midev[1])
2316
9
        i = 1, pixm = &pim->Shape;
2317
0
    else
2318
0
        return_error(gs_error_rangecheck);
2319
5.06k
    code = pdf_make_mxd(pmcdev, midev[i], mem);
2320
5.06k
    if (code < 0)
2321
0
        return code;
2322
2323
5.06k
    if (pminfo[0] != NULL)
2324
5.05k
        pdf_dev->PendingOC = pminfo[0]->OC;
2325
9
    else
2326
9
        pdf_dev->PendingOC = 0;
2327
2328
5.06k
    code = pdf_begin_typed_image
2329
5.06k
        ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2330
5.06k
         pinfo, PDF_IMAGE_TYPE3_DATA);
2331
5.06k
    pdf_dev->PendingOC = 0;
2332
5.06k
    if (code < 0) {
2333
0
        rc_decrement(*pmcdev, "pdf_image3x_make_mcde");
2334
0
        return code;
2335
0
    }
2336
5.06k
    if ((*pinfo)->procs != &pdf_image_enum_procs) {
2337
        /* We couldn't handle the image.  Bail out. */
2338
8
        gx_image_end(*pinfo, false);
2339
8
        gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
2340
8
        return_error(gs_error_rangecheck);
2341
8
    }
2342
5.05k
    pmie = (pdf_image_enum *)pminfo[i];
2343
    /*
2344
     * Add the SMask entry to the image dictionary, and, if needed,
2345
     * the Matte entry to the mask dictionary.
2346
     */
2347
5.05k
    if (pixm->has_Matte) {
2348
4
        gx_device_pdf *pdev = (gx_device_pdf *)dev;
2349
4
        int DoMatte = 0, num_components =
2350
4
            gs_color_space_num_components(pim->ColorSpace);
2351
2352
4
        switch (pdev->params.ColorConversionStrategy) {
2353
4
            case ccs_LeaveColorUnchanged:
2354
4
                DoMatte = 1;
2355
4
                break;
2356
0
            case ccs_RGB:
2357
0
            case ccs_sRGB:
2358
0
                if (num_components == 3)
2359
0
                    DoMatte = 1;
2360
0
                else
2361
0
                    DoMatte = 0;
2362
0
                break;
2363
0
            case ccs_CMYK:
2364
0
                if (num_components == 4)
2365
0
                    DoMatte = 1;
2366
0
                else
2367
0
                    DoMatte = 0;
2368
0
                break;
2369
0
            case ccs_Gray:
2370
0
                if (num_components == 1)
2371
0
                    DoMatte = 1;
2372
0
                else
2373
0
                    DoMatte = 0;
2374
0
                break;
2375
0
            case ccs_UseDeviceIndependentColor:
2376
0
            case ccs_UseDeviceIndependentColorForImages:
2377
0
            case ccs_ByObjectType:
2378
0
            default:
2379
0
                DoMatte = 0;
2380
0
                break;
2381
4
        }
2382
2383
4
        if (DoMatte) {
2384
4
            code = cos_dict_put_c_key_floats((gx_device_pdf *)dev,
2385
4
                                    (cos_dict_t *)pmie->writer.pres->object,
2386
4
                                    "/Matte", pixm->Matte,
2387
4
                                    num_components);
2388
4
            if (code < 0)
2389
0
                return code;
2390
4
        }
2391
4
    }
2392
/* Don't put SMask here because pmie->writer.pres->object may be substituted
2393
 * after the image stream is accummulated. pdf_end_and_do_image will set
2394
 * SMask with the right value. Bug 690345.
2395
 */
2396
5.05k
    return 0;
2397
5.05k
}
2398
2399
pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
2400
15.2k
{
2401
15.2k
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
2402
2403
15.2k
    return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
2404
15.2k
}
2405
2406
static int
2407
check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
2408
1.53k
{
2409
1.53k
    pdf_pattern_t *ppat0 = (pdf_pattern_t *)pres0;
2410
1.53k
    pdf_pattern_t *ppat1 = (pdf_pattern_t *)pres1;
2411
2412
1.53k
    return (ppat0->substitute == NULL && ppat1->substitute == NULL);
2413
1.53k
}
2414
2415
static int
2416
check_unsubstituted1(gx_device_pdf * pdev, pdf_resource_t *pres0)
2417
0
{
2418
0
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
2419
2420
0
    return ppat->substitute != NULL;
2421
0
}
2422
2423
static int reset_gstate_for_pattern(gx_device_pdf * pdev, gs_gstate *destination, gs_gstate *source)
2424
11.3k
{
2425
11.3k
    if (pdev->vg_initial_set) {
2426
11.3k
        destination->strokeconstantalpha = source->strokeconstantalpha;
2427
11.3k
        source->strokeconstantalpha = pdev->vg_initial.strokeconstantalpha;
2428
11.3k
        destination->fillconstantalpha = source->fillconstantalpha;
2429
11.3k
        source->fillconstantalpha = pdev->vg_initial.fillconstantalpha;
2430
11.3k
        if (destination->set_transfer.red != NULL)
2431
0
            destination->set_transfer.red->id = (source->set_transfer.red != NULL ? source->set_transfer.red->id : 0);
2432
11.3k
        if (destination->set_transfer.green != NULL)
2433
0
            destination->set_transfer.green->id = (source->set_transfer.green != NULL ? source->set_transfer.green->id : 0);
2434
11.3k
        if (destination->set_transfer.blue != NULL)
2435
0
            destination->set_transfer.blue->id = (source->set_transfer.blue != NULL ? source->set_transfer.blue->id : 0);
2436
11.3k
        if (destination->set_transfer.gray != NULL)
2437
5.68k
            destination->set_transfer.gray->id = (source->set_transfer.gray != NULL ? source->set_transfer.gray->id : 0);
2438
11.3k
        if (source->set_transfer.red != NULL)
2439
0
            source->set_transfer.red->id = pdev->vg_initial.transfer_ids[0];
2440
11.3k
        if (source->set_transfer.green != NULL)
2441
0
            source->set_transfer.green->id = pdev->vg_initial.transfer_ids[1];
2442
11.3k
        if (source->set_transfer.blue != NULL)
2443
0
            source->set_transfer.blue->id = pdev->vg_initial.transfer_ids[2];
2444
11.3k
        if (source->set_transfer.gray != NULL)
2445
5.68k
            source->set_transfer.gray->id = pdev->vg_initial.transfer_ids[3];
2446
11.3k
        destination->alphaisshape = source->alphaisshape;
2447
11.3k
        source->alphaisshape = pdev->vg_initial.alphaisshape;
2448
11.3k
        destination->blend_mode = source->blend_mode;
2449
11.3k
        source->blend_mode = pdev->vg_initial.blend_mode;
2450
11.3k
        if (destination->black_generation != NULL)
2451
5.68k
            destination->black_generation->id = (source->black_generation != NULL ? source->black_generation->id : 0);
2452
11.3k
        if (source->black_generation != NULL)
2453
5.68k
            source->black_generation->id = pdev->vg_initial.black_generation_id;
2454
11.3k
        if (destination->undercolor_removal != NULL)
2455
5.68k
            destination->undercolor_removal->id = (source->undercolor_removal != NULL ? source->undercolor_removal->id : 0);
2456
11.3k
        if (source->undercolor_removal != NULL)
2457
5.68k
            source->undercolor_removal->id = pdev->vg_initial.undercolor_removal_id;
2458
11.3k
        destination->overprint_mode = source->overprint_mode;
2459
11.3k
        source->overprint_mode = pdev->vg_initial.overprint_mode;
2460
11.3k
        destination->flatness = source->flatness;
2461
11.3k
        source->flatness = pdev->vg_initial.flatness;
2462
11.3k
        destination->smoothness = source->smoothness;
2463
11.3k
        source->smoothness = pdev->vg_initial.smoothness;
2464
11.3k
        destination->flatness = source->flatness;
2465
11.3k
        source->flatness = pdev->vg_initial.flatness;
2466
11.3k
        destination->text_knockout = source->text_knockout;
2467
11.3k
        source->text_knockout = pdev->vg_initial.text_knockout;
2468
11.3k
        destination->stroke_adjust = source->stroke_adjust;
2469
11.3k
        source->stroke_adjust = pdev->vg_initial.stroke_adjust;
2470
11.3k
        destination->line_params.half_width = source->line_params.half_width;
2471
11.3k
        source->line_params.half_width = pdev->vg_initial.line_params.half_width;
2472
11.3k
        destination->line_params.start_cap = source->line_params.start_cap;
2473
11.3k
        source->line_params.start_cap = pdev->vg_initial.line_params.start_cap;
2474
11.3k
        destination->line_params.end_cap = source->line_params.end_cap;
2475
11.3k
        source->line_params.end_cap = pdev->vg_initial.line_params.end_cap;
2476
11.3k
        destination->line_params.dash_cap = source->line_params.dash_cap;
2477
11.3k
        source->line_params.dash_cap = pdev->vg_initial.line_params.dash_cap;
2478
11.3k
        destination->line_params.join = source->line_params.join;
2479
11.3k
        source->line_params.join = pdev->vg_initial.line_params.join;
2480
11.3k
        destination->line_params.curve_join = source->line_params.curve_join;
2481
11.3k
        source->line_params.curve_join = pdev->vg_initial.line_params.curve_join;
2482
11.3k
        destination->line_params.miter_limit = source->line_params.miter_limit;
2483
11.3k
        source->line_params.miter_limit = pdev->vg_initial.line_params.miter_limit;
2484
11.3k
        destination->line_params.miter_check = source->line_params.miter_check;
2485
11.3k
        source->line_params.miter_check = pdev->vg_initial.line_params.miter_check;
2486
11.3k
        destination->line_params.dot_length = source->line_params.dot_length;
2487
11.3k
        source->line_params.dot_length = pdev->vg_initial.line_params.dot_length;
2488
11.3k
        destination->line_params.dot_length_absolute = source->line_params.dot_length_absolute;
2489
11.3k
        source->line_params.dot_length_absolute = pdev->vg_initial.line_params.dot_length_absolute;
2490
11.3k
        destination->line_params.dot_orientation = source->line_params.dot_orientation;
2491
11.3k
        source->line_params.dot_orientation = pdev->vg_initial.line_params.dot_orientation;
2492
11.3k
        if (destination->line_params.dash.pattern != NULL && destination->line_params.dash.pattern != source->line_params.dash.pattern)
2493
0
            gs_free_object(destination->memory, destination->line_params.dash.pattern, "free dash assigned during pattern accumulation");
2494
11.3k
        memcpy(&destination->line_params.dash, &source->line_params.dash, sizeof(source->line_params.dash));
2495
11.3k
        memcpy(&source->line_params.dash, &pdev->vg_initial.line_params.dash, sizeof(source->line_params.dash));
2496
11.3k
    }
2497
11.3k
    return 0;
2498
11.3k
}
2499
2500
/*
2501
   The device specific operations - just pattern management.
2502
   See gxdevcli.h about return codes.
2503
 */
2504
int
2505
gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
2506
166M
{
2507
166M
    gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
2508
166M
    int code=0, force_CTM_change=0;
2509
166M
    pdf_resource_t *pres, *pres1;
2510
166M
    gx_bitmap_id id = (gx_bitmap_id)size;
2511
2512
166M
    switch (dev_spec_op) {
2513
81.7k
        case gxdso_skip_icc_component_validation:
2514
81.7k
            return 1;
2515
17.1k
        case gxdso_supports_pattern_transparency:
2516
17.1k
            return 1;
2517
6.17k
        case gxdso_pattern_can_accum:
2518
6.17k
            return 1;
2519
16.8k
        case gxdso_pdf_form_name:
2520
16.8k
            if (pdev->PDFFormName) {
2521
3
                gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2522
3
            }
2523
16.8k
            pdev->PDFFormName = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, size + 1, "Name of Form for pdfmark");
2524
16.8k
            if (pdev->PDFFormName == NULL)
2525
0
                return_error(gs_error_VMerror);
2526
16.8k
            memset(pdev->PDFFormName, 0x00, size + 1);
2527
16.8k
            memcpy(pdev->PDFFormName, data, size);
2528
16.8k
            return 0;
2529
0
        case gxdso_pdf_last_form_ID:
2530
0
            {
2531
0
            int *i = (int *)data;
2532
0
            *i = pdev->LastFormID;
2533
0
            }
2534
0
            return 0;
2535
16.8k
        case gxdso_form_begin:
2536
16.8k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 0) && pdev->PatternDepth == 0) {
2537
16.8k
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2538
16.8k
                float arry[6];
2539
16.8k
                cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
2540
2541
                /* Make sure the document and page stream are open */
2542
16.8k
                code = pdfwrite_pdf_open_document(pdev);
2543
16.8k
                if (code < 0)
2544
0
                    return code;
2545
16.8k
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2546
16.8k
                if (code < 0)
2547
0
                    return code;
2548
16.8k
                if (!pdev->PDFFormName) {
2549
                    /* Put any extant clip out before we start the form */
2550
0
                    code = pdf_put_clip_path(pdev, tmplate->pcpath);
2551
0
                    if (code < 0)
2552
0
                        return code;
2553
                    /* Set the CTM to be the one passed in from the interpreter,
2554
                     * this allows us to spot forms even when translation/rotation takes place
2555
                     * as we remove the CTN from the form stream before capture
2556
                     */
2557
0
                    pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2558
0
                             tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2559
0
                }
2560
2561
                /* start capturing the form stream */
2562
16.8k
                code = pdf_enter_substream(pdev, resourceXObject, id, &pres, false,
2563
16.8k
                        pdev->CompressStreams);
2564
16.8k
                if (code < 0)
2565
0
                    return code;
2566
16.8k
                pcd = cos_stream_dict((cos_stream_t *)pres->object);
2567
16.8k
                pcd_Resources = cos_dict_alloc(pdev, "pdf_form(Resources)");
2568
16.8k
                if (pcd == NULL || pcd_Resources == NULL)
2569
0
                    return_error(gs_error_VMerror);
2570
16.8k
                code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
2571
16.8k
                if (code >= 0)
2572
16.8k
                    code = cos_dict_put_c_strings(pcd, "/Subtype", "/Form");
2573
16.8k
                if (code >= 0)
2574
16.8k
                    code = cos_dict_put_c_strings(pcd, "/FormType", "1");
2575
16.8k
                if (code >= 0)
2576
16.8k
                    code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
2577
2578
16.8k
                if (pdev->PDFFormName) {
2579
                    /* This is not (I think) required when executing PS forms, because the
2580
                     * CTM is written out before we execute the Form. It *is* required for
2581
                     * PDF Appearance Forms, because the Form is written directly from the
2582
                     * outer context, not from the page, so we don't emit the CTM first.
2583
                     * We want to alter the Form BBox to take any required rotation and scaling
2584
                     * (from FitPage and /Rotate) into account so that the form appearance is
2585
                     * properly scaled and rotated.
2586
                     */
2587
16.8k
                    gs_rect bbox_out;
2588
16.8k
                    gs_matrix cmat, new_mat = tmplate->CTM;
2589
2590
                    /* We don't want anything left over from the page content stream, or other
2591
                     * annotation appearances, to affect whether or not we emit any graphics
2592
                     * state, so reset the state here to the defaults.
2593
                     */
2594
16.8k
                    pdf_viewer_state_from_gs_gstate(pdev, tmplate->pgs, NULL);
2595
                    /* For PDF Appearance streams at least, the Form BBox is modified by the
2596
                     * Form Matrix.
2597
                     */
2598
16.8k
                    code = gs_matrix_multiply(&tmplate->form_matrix, &tmplate->CTM, &cmat);
2599
16.8k
                    if (code < 0)
2600
0
                        return code;
2601
16.8k
                    code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2602
16.8k
                    if (code < 0)
2603
0
                        return code;
2604
2605
                    /* Check the BBox is on the page. Modify it if it is not (this can happen
2606
                     * if the MediaBox does not have bottom left at 0,0)
2607
                     */
2608
16.8k
                    cmat.xx = cmat.yy = 1.0f;
2609
16.8k
                    cmat.xy = cmat.yx = cmat.tx = cmat.ty = 0.0f;
2610
16.8k
                    if(bbox_out.q.x - bbox_out.p.x > pdev->width) {
2611
1
                        cmat.xx = pdev->width / (bbox_out.q.x - bbox_out.p.x);
2612
1
                        bbox_out.q.x = bbox_out.p.x + ((bbox_out.q.x - bbox_out.p.x) * cmat.xx);
2613
1
                        force_CTM_change = 1;
2614
1
                    }
2615
16.8k
                    if(bbox_out.q.y - bbox_out.p.y > pdev->height) {
2616
1
                        cmat.yy = pdev->height / (bbox_out.q.y - bbox_out.p.y);
2617
1
                        bbox_out.q.y = bbox_out.p.y + ((bbox_out.q.y - bbox_out.p.y) * cmat.yy);
2618
1
                        force_CTM_change = 1;
2619
1
                    }
2620
2621
16.8k
                    if (bbox_out.p.x < 0) {
2622
2
                        cmat.tx = bbox_out.p.x * -1;
2623
2
                        bbox_out.q.x += cmat.tx;
2624
2
                        force_CTM_change = 1;
2625
2
                    }
2626
16.8k
                    if (floor(bbox_out.q.x) > pdev->width) {
2627
0
                        cmat.tx -= bbox_out.p.x;
2628
0
                        bbox_out.q.x -= bbox_out.p.x;
2629
0
                        bbox_out.p.x = 0;
2630
0
                        force_CTM_change = 1;
2631
0
                    }
2632
16.8k
                    if (bbox_out.p.y < 0) {
2633
5
                        cmat.ty = bbox_out.p.y * -1;
2634
5
                        bbox_out.q.y += cmat.ty;
2635
5
                        force_CTM_change = 1;
2636
5
                    }
2637
16.8k
                    if (floor(bbox_out.q.y) > pdev->height) {
2638
1
                        cmat.ty += pdev->height - bbox_out.q.y;
2639
1
                        force_CTM_change = 1;
2640
1
                    }
2641
2642
16.8k
                    if (force_CTM_change) {
2643
7
                        code = gs_matrix_multiply(&tmplate->CTM, &cmat, &new_mat);
2644
7
                        if (code < 0)
2645
0
                            return code;
2646
7
                        code = gs_matrix_multiply(&tmplate->form_matrix, &new_mat, &cmat);
2647
7
                        if (code < 0)
2648
0
                            return code;
2649
7
                        code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2650
7
                        if (code < 0)
2651
0
                            return code;
2652
7
                        tmplate->CTM = cmat;
2653
7
                    }
2654
16.8k
                    arry[0] = bbox_out.p.x;
2655
16.8k
                    arry[1] = bbox_out.p.y;
2656
16.8k
                    arry[2] = bbox_out.q.x;
2657
16.8k
                    arry[3] = bbox_out.q.y;
2658
16.8k
                    if (code >= 0)
2659
16.8k
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2660
16.8k
                    if (code < 0)
2661
0
                        return code;
2662
2663
                    /* Note that we will apply the CTM to the form, and the Form Matrix. To prevcent
2664
                     * us applying the Matrix twice, we need to set it to the identity in the Form
2665
                     * dictionary. I'm not sure why we don't need to do that for PostScript Forms.
2666
                     */
2667
16.8k
                    arry[0] = arry[3] = 1.0f;
2668
16.8k
                    arry[1] = arry[2] = arry[4] = arry[5] = 0.0f;
2669
16.8k
                } else {
2670
0
                    arry[0] = tmplate->BBox.p.x;
2671
0
                    arry[1] = tmplate->BBox.p.y;
2672
0
                    arry[2] = tmplate->BBox.q.x;
2673
0
                    arry[3] = tmplate->BBox.q.y;
2674
0
                    if (code >= 0)
2675
0
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2676
0
                    if (code < 0)
2677
0
                        return code;
2678
2679
0
                    arry[0] = tmplate->form_matrix.xx;
2680
0
                    arry[1] = tmplate->form_matrix.xy;
2681
0
                    arry[2] = tmplate->form_matrix.yx;
2682
0
                    arry[3] = tmplate->form_matrix.yy;
2683
0
                    arry[4] = tmplate->form_matrix.tx;
2684
0
                    arry[5] = tmplate->form_matrix.ty;
2685
2686
0
                    pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2687
0
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2688
0
                }
2689
2690
16.8k
                code = cos_dict_put_c_key_floats(pdev, pcd, "/Matrix", arry, 6);
2691
16.8k
                if (code < 0)
2692
0
                    return code;
2693
2694
                /* We'll return this to the interpreter and have it set
2695
                 * as the CTM, so that we remove the prior CTM before capturing the form.
2696
                 * This is safe because forms are always run inside a gsave/grestore, so
2697
                 * CTM will be put back for us.
2698
                 */
2699
16.8k
                if (!pdev->PDFFormName) {
2700
0
                    tmplate->CTM.xx = pdev->HWResolution[0] / 72;
2701
0
                    tmplate->CTM.xy = 0.0;
2702
0
                    tmplate->CTM.yx = 0.0;
2703
0
                    tmplate->CTM.yy = pdev->HWResolution[0] / 72;
2704
0
                    tmplate->CTM.tx = 0.0;
2705
0
                    tmplate->CTM.ty = 0.0;
2706
2707
0
                    pdev->substream_Resources = pcd_Resources;
2708
0
                    pres->rid = id;
2709
0
                    if (code >= 0)
2710
0
                        pdev->HighLevelForm++;
2711
0
                    return 1;
2712
16.8k
                } else {
2713
                    /* For PDF Appearance streams (Forms) we *must* apply the
2714
                     * CTM. This is because if the PDF has a non-zero Rotate key
2715
                     * we bake that rotation into the CTM. If we didn't apply that
2716
                     * then the annotation wouldn't get rotated :-(
2717
                     */
2718
16.8k
                    pdev->substream_Resources = pcd_Resources;
2719
16.8k
                    pres->rid = id;
2720
16.8k
                    if (code >= 0)
2721
16.8k
                        pdev->HighLevelForm++;
2722
16.8k
                    return force_CTM_change;
2723
16.8k
                }
2724
16.8k
            }
2725
0
            return code;
2726
16.8k
        case gxdso_form_end:
2727
            /* This test must be the same as the one in gxdso_form_begin, above */
2728
16.8k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 1) && pdev->PatternDepth == 0) {
2729
16.8k
                if (pdev->CompatibilityLevel <= 1.7) {
2730
16.8k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2731
16.8k
                    if (code < 0)
2732
0
                        return code;
2733
16.8k
                }
2734
16.8k
                pres = pres1 = pdev->accumulating_substream_resource;
2735
16.8k
                if (pres == NULL)
2736
0
                    return_error(gs_error_unregistered);
2737
16.8k
                code = pdf_exit_substream(pdev);
2738
16.8k
                if (code < 0)
2739
0
                    return code;
2740
16.8k
                code = pdf_find_same_resource(pdev, resourceXObject, &pres, check_unsubstituted2);
2741
16.8k
                if (code < 0)
2742
0
                    return code;
2743
16.8k
                if (code > 0) {
2744
0
                    code = pdf_cancel_resource(pdev, pres1, resourceXObject);
2745
0
                    if (code < 0)
2746
0
                        return code;
2747
0
                    pres->where_used |= pdev->used_mask;
2748
16.8k
                } else if (pres->object->id < 0)
2749
16.8k
                    pdf_reserve_object_id(pdev, pres, 0);
2750
16.8k
                pdev->LastFormID = pdf_resource_id(pres);
2751
16.8k
                pdev->HighLevelForm--;
2752
16.8k
                if (pdev->accumulating_substream_resource) {
2753
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2754
0
                    if (code < 0)
2755
0
                        return code;
2756
0
                }
2757
16.8k
                if (pdev->PDFFormName) {
2758
16.8k
                    cos_value_t value;
2759
2760
16.8k
                    code = cos_dict_put(pdev->local_named_objects, (const byte *)pdev->PDFFormName,
2761
16.8k
                        strlen(pdev->PDFFormName), cos_object_value(&value, pres->object));
2762
2763
16.8k
                    if (code < 0)
2764
0
                        return code;
2765
16.8k
                    pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
2766
16.8k
                    pres->object = NULL;
2767
16.8k
                    gs_free_object(pdev->pdf_memory, pres, "free redundant resource");
2768
2769
16.8k
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2770
16.8k
                    pdev->PDFFormName = 0x00;
2771
16.8k
                } else {
2772
0
                    pprinti64d1(pdev->strm, "/R%"PRId64" Do Q\n", pdf_resource_id(pres));
2773
0
                }
2774
16.8k
            }
2775
16.8k
            return 0;
2776
16.8k
        case gxdso_get_form_ID:
2777
16.8k
            {
2778
16.8k
                int *ID = data;
2779
16.8k
                *ID = pdev->LastFormID;
2780
16.8k
            }
2781
16.8k
            return 0;
2782
0
        case gxdso_repeat_form:
2783
0
            {
2784
0
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2785
2786
                /* Make sure the document and page stream are open */
2787
0
                code = pdfwrite_pdf_open_document(pdev);
2788
0
                if (code < 0)
2789
0
                    return code;
2790
0
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2791
0
                if (code < 0)
2792
0
                    return code;
2793
                /* Put any extant clip out before we start the form */
2794
0
                code = pdf_put_clip_path(pdev, tmplate->pcpath);
2795
0
                if (code < 0)
2796
0
                    return code;
2797
                /* Set the CTM to be the one passed in from the interpreter,
2798
                 * this allows us to spot forms even when translation/rotation takes place
2799
                 * as we remove the CTN from the form stream before capture
2800
                 */
2801
0
                pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2802
0
                         tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2803
0
                pprintld1(pdev->strm, "/R%ld Do Q\n", tmplate->FormID);
2804
0
                pres = pdf_find_resource_by_resource_id(pdev, resourceXObject, tmplate->FormID);
2805
0
                if (pres == NULL)
2806
0
                    return_error(gs_error_undefined);
2807
0
                pres->where_used |= pdev->used_mask;
2808
0
                if (pdev->accumulating_substream_resource) {
2809
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2810
0
                    if (code < 0)
2811
0
                        return code;
2812
0
                }
2813
0
            }
2814
0
            return 0;
2815
5.68k
        case gxdso_pattern_start_accum:
2816
5.68k
            {
2817
5.68k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2818
5.68k
                gs_pattern1_instance_t *pinst = param->pinst;
2819
5.68k
                gs_gstate *pgs = param->graphics_state;
2820
2821
5.68k
                code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
2822
5.68k
                if (code < 0)
2823
0
                    return code;
2824
5.68k
                if (pdev->context == PDF_IN_NONE) {
2825
150
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
2826
150
                    if (code < 0)
2827
0
                        return code;
2828
150
                }
2829
5.68k
                code = pdf_prepare_fill_stroke(pdev, (gs_gstate *)pgs, false);
2830
5.68k
                if (code < 0)
2831
0
                    return code;
2832
5.68k
                if (pdev->PatternDepth == 0 && pdev->initial_pattern_states != NULL) {
2833
0
                    int pdepth = 0;
2834
2835
0
                    while (pdev->initial_pattern_states[pdepth] != 0x00) {
2836
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdepth], "Freeing dangling pattern state");
2837
0
                        pdev->initial_pattern_states[pdepth] = NULL;
2838
0
                        pdepth++;
2839
0
                    }
2840
0
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state stack");
2841
0
                }
2842
2843
5.68k
                {
2844
5.68k
                    gs_gstate **new_states;
2845
5.68k
                    int pdepth;
2846
2847
5.68k
                    new_states = (gs_gstate **)gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, sizeof(gs_gstate *) * (pdev->PatternDepth + 2), "pattern initial graphics state stack");
2848
5.68k
                    if (new_states == NULL)
2849
0
                        return_error(gs_error_VMerror);
2850
5.68k
                    memset(new_states, 0x00, sizeof(gs_gstate *) * (pdev->PatternDepth + 2));
2851
5.69k
                    for (pdepth = 0; pdepth < pdev->PatternDepth;pdepth++)
2852
10
                        new_states[pdepth] = pdev->initial_pattern_states[pdepth];
2853
5.68k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing old pattern state stack");
2854
5.68k
                    pdev->initial_pattern_states = new_states;
2855
5.68k
                }
2856
5.68k
                pdev->initial_pattern_states[pdev->PatternDepth] = (gs_gstate *)gs_alloc_struct(pdev->pdf_memory, gs_gstate, &st_gs_gstate, "gdev_pdf_dev_spec_op");
2857
5.68k
                if (pdev->initial_pattern_states[pdev->PatternDepth] == NULL)
2858
0
                    return code;
2859
5.68k
                memset(pdev->initial_pattern_states[pdev->PatternDepth], 0x00, sizeof(gs_gstate));
2860
5.68k
                pdev->initial_pattern_states[pdev->PatternDepth]->memory = pdev->pdf_memory;
2861
2862
5.68k
                reset_gstate_for_pattern(pdev, pdev->initial_pattern_states[pdev->PatternDepth], pgs);
2863
5.68k
                code = pdf_enter_substream(pdev, resourcePattern, pinst->id, &pres, false,
2864
5.68k
                        pdev->CompressStreams);
2865
5.68k
                if (code < 0) {
2866
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2867
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2868
0
                    return code;
2869
0
                }
2870
2871
                /* We have started a new substream, to avoid confusing the 'saved viewer state'
2872
                 * (the stack of pdfwrite's saved copies of graophics states) we need to reset the
2873
                 * soft_mask_id, which is the ID of the SMask we have already created in the pdfwrite
2874
                 * output. The gsave/grestore round the spec_op to start and finish the pattern
2875
                 * accumulator (see pattern_paint_prepare and pattern_paint_finish) will ensure that
2876
                 * the ID is restored when we finish capturing the pattern.
2877
                 */
2878
5.68k
                pdev->state.soft_mask_id = pgs->soft_mask_id;
2879
5.68k
                pres->rid = pinst->id;
2880
5.68k
                code = pdf_store_pattern1_params(pdev, pres, pinst);
2881
5.68k
                if (code < 0) {
2882
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2883
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2884
0
                    return code;
2885
0
                }
2886
                /* Scale the coordinate system, because object handlers assume so. See none_to_stream. */
2887
5.68k
                pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2888
5.68k
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2889
5.68k
                pdev->PatternDepth++;
2890
5.68k
                pdev->PatternsSinceForm++;
2891
5.68k
            }
2892
0
            return 1;
2893
5.68k
        case gxdso_pattern_finish_accum:
2894
5.68k
            {
2895
5.68k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2896
5.68k
                gs_gstate *pgs = param->graphics_state;
2897
2898
5.68k
                if (pdev->CompatibilityLevel <= 1.7) {
2899
5.68k
                    if (pdev->substream_Resources == NULL) {
2900
0
                        pdev->substream_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
2901
0
                        if (pdev->substream_Resources == NULL)
2902
0
                            return_error(gs_error_VMerror);
2903
0
                    }
2904
5.68k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2905
5.68k
                    if (code < 0) {
2906
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2907
0
                        pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2908
0
                        return code;
2909
0
                    }
2910
5.68k
                }
2911
5.68k
                pres = pres1 = pdev->accumulating_substream_resource;
2912
5.68k
                if (pres == NULL)
2913
0
                    code = gs_note_error(gs_error_unregistered);
2914
5.68k
                else
2915
5.68k
                    code = pdf_exit_substream(pdev);
2916
5.68k
                if (code < 0) {
2917
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2918
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2919
0
                    return code;
2920
0
                }
2921
5.68k
                if (pdev->substituted_pattern_count > 300 &&
2922
5.68k
                        pdev->substituted_pattern_drop_page != pdev->next_page) { /* arbitrary */
2923
0
                    pdf_drop_resources(pdev, resourcePattern, check_unsubstituted1);
2924
0
                    pdev->substituted_pattern_count = 0;
2925
0
                    pdev->substituted_pattern_drop_page = pdev->next_page;
2926
0
                }
2927
5.68k
                code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
2928
5.68k
                if (code < 0) {
2929
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2930
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2931
0
                    return code;
2932
0
                }
2933
5.68k
                if (code > 0) {
2934
1.53k
                    pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
2935
2936
1.53k
                    code = pdf_cancel_resource(pdev, pres1, resourcePattern);
2937
1.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
                    /* Do not remove pres1, because it keeps the substitution. */
2943
1.53k
                    ppat->substitute = (pdf_pattern_t *)pres;
2944
1.53k
                    pres->where_used |= pdev->used_mask;
2945
1.53k
                    pdev->substituted_pattern_count++;
2946
4.15k
                } else if (pres->object->id < 0)
2947
4.15k
                    pdf_reserve_object_id(pdev, pres, 0);
2948
5.68k
                reset_gstate_for_pattern(pdev, pgs, pdev->initial_pattern_states[pdev->PatternDepth - 1]);
2949
5.68k
                gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth - 1], "Freeing dangling pattern state");
2950
5.68k
                pdev->initial_pattern_states[pdev->PatternDepth - 1] = NULL;
2951
5.68k
                if (pdev->PatternDepth == 1) {
2952
5.67k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state");
2953
5.67k
                    pdev->initial_pattern_states = NULL;
2954
5.67k
                }
2955
2956
5.68k
                pdev->PatternDepth--;
2957
5.68k
                pdev->PatternsSinceForm--;
2958
5.68k
            }
2959
0
            return 1;
2960
12.8k
        case gxdso_pattern_load:
2961
12.8k
            pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, *((gx_bitmap_id *)data));
2962
12.8k
            if (pres == 0)
2963
5.68k
                return 0;
2964
7.19k
            pres = pdf_substitute_pattern(pres);
2965
7.19k
            pres->where_used |= pdev->used_mask;
2966
7.19k
            code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
2967
7.19k
            if (code < 0)
2968
0
                return code;
2969
7.19k
            return 1;
2970
174k
        case gxdso_pattern_shading_area:
2971
174k
            return 0;
2972
274k
        case gxdso_pattern_is_cpath_accum:
2973
274k
            return 0;
2974
16.4k
        case gxdso_pattern_shfill_doesnt_need_path:
2975
16.4k
            return 0; /* gdev_pdf_fill_path still does need a path. */
2976
5
        case gxdso_pattern_handles_clip_path:
2977
            /* This is important when the default implementation of
2978
               of fill_path is called due to a failure in setcolor
2979
               or so, for example when a shading is incorrect.
2980
               The test case is the unfixed (buggy) Genoa test 446-01.ps .
2981
               In this case pdfwrite converts the object into rectangles,
2982
               and the clipping device has to be set up. */
2983
5
            return 0;
2984
12.6k
        case gxdso_supports_hlcolor:
2985
            /* This is used due to some aliasing between the rect_hl color
2986
               filling used by pdfwrite vs. that used by the planar device
2987
               which is actually a devn vs. the pattern type for pdfwrite.
2988
               We use this to distingush between the two */
2989
12.6k
            return 1;
2990
0
        case gxdso_needs_invariant_palette:
2991
            /* Indicates that it is not permissible to change /Indexed colour space
2992
             * palette entries after the colour space has been set.
2993
             */
2994
0
            return 1;
2995
6.67k
        case gxdso_JPEG_passthrough_query:
2996
6.67k
            pdev->JPEG_PassThrough = pdev->params.PassThroughJPEGImages;
2997
6.67k
            return 1;
2998
0
            break;
2999
6.65k
        case gxdso_JPEG_passthrough_begin:
3000
6.65k
            return 0;
3001
0
            break;
3002
528k
        case gxdso_JPEG_passthrough_data:
3003
528k
            if (pdev->JPEG_PassThrough && pdev->PassThroughWriter)
3004
283k
            {
3005
283k
                uint ignore;
3006
283k
                if (sputs(pdev->PassThroughWriter,
3007
283k
                           data, size,
3008
283k
                           &ignore) < 0)
3009
0
                           return_error(gs_error_ioerror);
3010
283k
            }
3011
528k
            return 0;
3012
0
            break;
3013
6.67k
        case gxdso_JPEG_passthrough_end:
3014
6.67k
            pdev->JPEG_PassThrough = 0;
3015
6.67k
            pdev->PassThroughWriter = 0;
3016
6.67k
            return 0;
3017
0
            break;
3018
3.54k
        case gxdso_JPX_passthrough_query:
3019
3.54k
            pdev->JPX_PassThrough = pdev->params.PassThroughJPXImages;
3020
3.54k
            return 1;
3021
0
            break;
3022
3.31k
        case gxdso_JPX_passthrough_begin:
3023
3.31k
            return 0;
3024
0
            break;
3025
170k
        case gxdso_JPX_passthrough_data:
3026
170k
            if (pdev->JPX_PassThrough && pdev->PassThroughWriter)
3027
59.2k
            {
3028
59.2k
                uint ignore;
3029
59.2k
                if (sputs(pdev->PassThroughWriter,
3030
59.2k
                           data, size,
3031
59.2k
                           &ignore) < 0)
3032
0
                           return_error(gs_error_ioerror);
3033
59.2k
            }
3034
170k
            return 0;
3035
0
            break;
3036
3.31k
        case gxdso_JPX_passthrough_end:
3037
3.31k
            pdev->JPX_PassThrough = 0;
3038
3.31k
            pdev->PassThroughWriter = 0;
3039
3.31k
            return 0;
3040
0
            break;
3041
0
        case gxdso_event_info:
3042
0
            {
3043
0
                dev_param_req_t *request = (dev_param_req_t *)data;
3044
0
                if (memcmp(request->Param, "SubstitutedFont", 15) == 0 && (pdev->PDFA || pdev->PDFX)) {
3045
0
                    switch (pdev->PDFACompatibilityPolicy) {
3046
0
                        case 0:
3047
0
                        case 1:
3048
0
                            emprintf(pdev->memory,
3049
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");
3050
0
                            pdev->AbortPDFAX = true;
3051
0
                            pdev->PDFX = 0;
3052
0
                            pdev->PDFA = 0;
3053
0
                            break;
3054
0
                        case 2:
3055
0
                            emprintf(pdev->memory,
3056
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, aborting conversion!\n");
3057
0
                            pdev->AbortPDFAX = true;
3058
0
                            pdev->PDFX = 0;
3059
0
                            pdev->PDFA = 0;
3060
0
                            return gs_note_error(gs_error_unknownerror);
3061
0
                            break;
3062
0
                        default:
3063
0
                            emprintf(pdev->memory,
3064
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");
3065
0
                            pdev->AbortPDFAX = true;
3066
0
                            pdev->PDFX = 0;
3067
0
                            pdev->PDFA = 0;
3068
0
                            break;
3069
0
                    }
3070
0
                }
3071
0
                return 0;
3072
0
            }
3073
0
            break;
3074
9.70M
        case gxdso_in_smask_construction:
3075
9.70M
            return pdev->smask_construction;
3076
81
        case gxdso_pending_optional_content:
3077
81
            if (pdev->CompatibilityLevel < 1.4999) {
3078
0
                if (pdev->PDFA) {
3079
0
                    switch (pdev->PDFACompatibilityPolicy) {
3080
0
                        case 0:
3081
0
                            emprintf(pdev->memory,
3082
0
                                     "Optional Content not valid in this version of PDF, reverting to normal PDF output\n");
3083
0
                            pdev->AbortPDFAX = true;
3084
0
                            pdev->PDFA = 0;
3085
0
                            break;
3086
0
                        case 1:
3087
0
                            emprintf(pdev->memory,
3088
0
                                     "Optional Content not valid in this version of PDF. Dropping feature to preserve PDF/A compatibility\n");
3089
0
                            break;
3090
0
                        case 2:
3091
0
                            emprintf(pdev->memory,
3092
0
                                     "Optional Content not valid in this version of PDF,  aborting conversion\n");
3093
0
                            return_error (gs_error_typecheck);
3094
0
                            break;
3095
0
                        default:
3096
0
                            emprintf(pdev->memory,
3097
0
                                     "Optional Content not valid in this version of PDF, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
3098
0
                            pdev->AbortPDFAX = true;
3099
0
                            pdev->PDFA = 0;
3100
0
                            break;
3101
0
                    }
3102
0
                } else {
3103
0
                    emprintf(pdev->memory,
3104
0
                             "Optional Content not valid in this version of PDF. Dropping feature to preserve compatibility\n");
3105
0
                }
3106
0
            } else
3107
81
            {
3108
81
                char *object = data;
3109
81
                if (pdev->PendingOC)
3110
2
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
3111
81
                pdev->PendingOC = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, strlen(object) + 1, "");
3112
81
                if (pdev->PendingOC == NULL)
3113
0
                    return_error(gs_error_VMerror);
3114
81
                memcpy(pdev->PendingOC, object, strlen(object) + 1);
3115
81
            }
3116
81
            return 0;
3117
0
            break;
3118
20
        case gxdso_hilevel_text_clip:
3119
20
            if (data == 0 && !pdev->accumulating_charproc) {
3120
                /* We are exiting a text render mode 'clip' by grestoring back to
3121
                 *  a time when the clip wasn't active.
3122
                 * First, check if we have a clip (this should always be true).
3123
                 */
3124
6
                if (pdev->clipped_text_pending) {
3125
                    /* Get back to the content stream. This will (amongst other things) flush
3126
                     * any pending text.
3127
                     */
3128
6
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
3129
6
                    if (code < 0)
3130
0
                        return code;
3131
                    /* Reset the pending state */
3132
6
                    pdev->clipped_text_pending = 0;
3133
                    /* Restore to our saved state */
3134
3135
                    /* The saved state in this case is the dpeth of the saved gstate stack at the time we
3136
                     * started the text clipping. Note; we cannot restore back past the 'bottom' of the
3137
                     * stack, which is why we alter vgstack_bottom here, rather than just using the saved
3138
                     * level in the loop below.
3139
                     */
3140
6
                    if (pdev->vgstack_bottom)
3141
6
                        pdev->vgstack_bottom = pdev->saved_vgstack_depth_for_textclip;
3142
3143
12
                    while (pdev->vgstack_depth > pdev->vgstack_bottom) {
3144
6
                        code = pdf_restore_viewer_state(pdev, pdev->strm);
3145
6
                        if (code < 0)
3146
0
                            return code;
3147
6
                    }
3148
3149
6
                    pdev->vgstack_bottom = pdev->saved_vgstack_bottom_for_textclip;
3150
6
                    pdf_reset_text(pdev); /* because of Q */
3151
6
                }
3152
14
            } else {
3153
14
                if (!pdev->accumulating_charproc) {
3154
14
                    gs_gstate *pgs = (gs_gstate *)data;
3155
                    /* We are starting text in a clip mode
3156
                     * First make sure we aren't already in a clip mode (this should never be true)
3157
                     */
3158
14
                    if (!pdev->clipped_text_pending) {
3159
                        /* Return to the content stream, this will (amongst other things) flush
3160
                         * any pending text.
3161
                         */
3162
14
                        code = pdf_open_page(pdev, PDF_IN_STREAM);
3163
14
                        if (code < 0)
3164
0
                            return code;
3165
3166
14
                        if (pdf_must_put_clip_path(pdev, pgs->clip_path)) {
3167
0
                           code = pdf_unclip(pdev);
3168
0
                            if (code < 0)
3169
0
                                return code;
3170
0
                            code = pdf_put_clip_path(pdev, pgs->clip_path);
3171
0
                            if (code < 0)
3172
0
                                return code;
3173
0
                        }
3174
3175
14
                        pdev->saved_vgstack_depth_for_textclip = pdev->vgstack_depth;
3176
3177
                        /* Save the current graphics state (or at least that bit which we track) so
3178
                         * that we can put it back later.
3179
                         */
3180
14
                        code = pdf_save_viewer_state(pdev, pdev->strm);
3181
14
                        if (code < 0)
3182
0
                            return code;
3183
14
                        pdev->clipped_text_pending = 1;
3184
3185
                        /* Save the current 'bottom' of the saved gstate stack, we need to
3186
                         * restore back to this state when we exit the graphics state
3187
                         * with a text rendering mode involving a clip.
3188
                         */
3189
14
                        pdev->saved_vgstack_bottom_for_textclip = pdev->vgstack_bottom;
3190
                        /* And push the bottom of the stack up until it is where we are now.
3191
                         * This is because clip paths, images, and possibly other constructs
3192
                         * will emit a clip path if the 'depth - bottom' is not zero, to create
3193
                         * a clip path. We want to make sure that it doesn't try to restore back
3194
                         * to a point before we established the text clip.
3195
                         */
3196
14
                        pdev->vgstack_bottom = pdev->vgstack_depth;
3197
14
                    }
3198
14
                }
3199
14
            }
3200
20
            break;
3201
3.19M
        case gxdso_get_dev_param:
3202
3.19M
            {
3203
3.19M
                int code;
3204
3.19M
                dev_param_req_t *request = (dev_param_req_t *)data;
3205
3.19M
                code = gdev_pdf_get_param(pdev1, request->Param, request->list);
3206
3.19M
                if (code != gs_error_undefined)
3207
3.12M
                    return code;
3208
3.19M
            }
3209
            /* Fall through */
3210
166M
    }
3211
151M
    return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size);
3212
166M
}