Coverage Report

Created: 2025-06-24 07:01

/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
69.3k
{
118
69.3k
    return true;
119
69.3k
}
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
26
{
143
26
    if (pim4->BitsPerComponent == 1 &&
144
26
        pim4->ColorSpace->type->num_components(pim4->ColorSpace) == 1 &&
145
26
        (pim4->MaskColor_is_range ?
146
0
         pim4->MaskColor[0] | pim4->MaskColor[1] :
147
0
         pim4->MaskColor[0]) <= 1
148
26
        ) {
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
26
    return -1;     /* arbitrary <0 */
225
26
}
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
81.2k
{
231
232
81.2k
    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
81.2k
    return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
247
81.2k
}
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.25k
{
254
3.25k
    gs_color_space *cs;
255
3.25k
    gs_memory_t *mem = pdev->v_memory;
256
257
3.25k
    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.25k
        case gs_color_space_index_DeviceRGB:
262
3.25k
            cs = gs_cspace_new_DeviceRGB(mem);
263
3.25k
            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.25k
    }
275
276
3.25k
    if (cs == NULL)
277
0
        return_error(gs_error_VMerror);
278
279
3.25k
    *ppcs = cs;
280
3.25k
    return 0;
281
3.25k
}
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
75.5k
{
318
75.5k
    const gs_image_t *pim1 = (const gs_image_t *)pic;
319
320
75.5k
    if (pim1->Alpha != gs_image_alpha_none)
321
0
        return -1;
322
75.5k
    if (pim1->ImageMask) {
323
        /* If parameters are invalid, use the fallback implementation. */
324
56.2k
        if (!(gx_dc_is_pattern1_color(pdcolor)))
325
55.9k
            if (pim1->BitsPerComponent != 1 ||
326
55.9k
                !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
327
55.9k
                  (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
328
55.9k
                )
329
12
                return -1;
330
56.2k
    }
331
75.4k
    image[0].type1 = *pim1;
332
    /* If we can write in-line then make it so */
333
75.4k
    return (context == PDF_IMAGE_DEFAULT &&
334
75.4k
        can_write_image_in_line(pdev, pim1));
335
75.5k
}
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
109
{
345
109
    const gs_image3_t *pim3 = (const gs_image3_t *)pic;
346
109
    gs_image3_t pim3a;
347
109
    const gs_image_common_t *pic1 = pic;
348
109
    gs_matrix m, mi;
349
109
    const gs_matrix *pmat1 = pmat;
350
109
    int code;
351
352
109
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
353
109
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
354
109
        if (code < 0)
355
0
            return code;
356
109
        if (pdf_must_put_clip_path(pdev, pcpath))
357
25
            code = pdf_unclip(pdev);
358
84
        else
359
84
            code = pdf_open_page(pdev, PDF_IN_STREAM);
360
109
        if (code < 0)
361
0
            return code;
362
109
        code = pdf_put_clip_path(pdev, pcpath);
363
109
        if (code < 0)
364
0
            return code;
365
109
        gs_make_identity(&m);
366
109
        pmat1 = &m;
367
109
        m.tx = floor(pgs->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
368
109
        m.ty = floor(pgs->ctm.ty + 0.5);
369
109
        pim3a = *pim3;
370
109
        code = gs_matrix_invert(&pim3a.ImageMatrix, &mi);
371
109
        if (code < 0)
372
1
            return code;
373
108
        gs_make_identity(&pim3a.ImageMatrix);
374
108
        if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
375
22
            int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
376
377
22
            gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
378
22
            gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
379
22
        }
380
108
        if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
381
16
            int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
382
383
16
            gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
384
16
            gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
385
16
        }
386
108
        gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
387
108
        pim3a.imagematrices_are_untrustworthy = 1;
388
108
        pic1 = (gs_image_common_t *)&pim3a;
389
        /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
390
108
        gs_matrix_multiply(&mi, &ctm_only(pgs), &pdev->converting_image_matrix);
391
108
    }
392
    /*
393
     * We handle ImageType 3 images in a completely different way:
394
     * the default implementation sets up the enumerator.
395
     */
396
108
    return gx_begin_image3_generic((gx_device *)pdev, pgs, pmat1, pic1,
397
108
                                   prect, pdcolor, pcpath, mem,
398
108
                                   pdf_image3_make_mid,
399
108
                                   pdf_image3_make_mcde, pinfo);
400
109
}
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
26
{
411
    /* Try to convert the image to a plain masked image. */
412
26
    gx_drawing_color icolor;
413
26
    int code = 1;
414
415
26
    pdev->image_mask_is_SMask = false;
416
26
    if (pdf_convert_image4_to_image1(pdev, pgs, pdcolor,
417
26
                                     (const gs_image4_t *)pic,
418
26
                                     &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
26
    return code;
445
26
}
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
26
{
454
26
        gs_matrix m, m1, mi;
455
26
        gs_image4_t pi4 = *(const gs_image4_t *)pic;
456
26
        int code;
457
26
        pdf_lcvd_t *cvd = NULL;
458
459
26
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
460
26
        if (code < 0)
461
0
            return code;
462
26
        if (pdf_must_put_clip_path(pdev, pcpath))
463
25
            code = pdf_unclip(pdev);
464
1
        else
465
1
            code = pdf_open_page(pdev, PDF_IN_STREAM);
466
26
        if (code < 0)
467
0
            return code;
468
26
        code = pdf_put_clip_path(pdev, pcpath);
469
26
        if (code < 0)
470
0
            return code;
471
26
        gs_make_identity(&m1);
472
26
        code = gs_matrix_invert(&pic->ImageMatrix, &mi);
473
26
        if (code < 0)
474
0
            return code;
475
26
        gs_matrix_multiply(&mi, &ctm_only(pgs), &m);
476
26
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
477
26
                             true, 0, 0, pi4.Width, pi4.Height, false);
478
26
        if (code < 0)
479
0
            return code;
480
26
        cvd->mdev.is_open = true; /* fixme: same as above. */
481
26
        cvd->mask->is_open = true; /* fixme: same as above. */
482
26
        cvd->mask_is_empty = false;
483
26
        code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
484
26
                    0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
485
26
        if (code < 0)
486
0
            return code;
487
26
        gx_device_retain((gx_device *)cvd, true);
488
26
        gx_device_retain((gx_device *)cvd->mask, true);
489
26
        gs_make_identity(&pi4.ImageMatrix);
490
26
        code = gx_default_begin_typed_image((gx_device *)cvd,
491
26
            pgs, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
492
26
        if (code < 0)
493
0
            return code;
494
26
        (*pinfo)->procs = &pdf_image_cvd_enum_procs;
495
26
        return 0;
496
26
}
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.62k
{
501
1.62k
    int code;
502
1.62k
    gs_color_space *pcs_device = NULL;
503
504
1.62k
    cos_c_string_value(cs_value, sname);
505
1.62k
    *pcs_orig = image->pixel.ColorSpace;
506
1.62k
    code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
507
1.62k
    if (code < 0)
508
0
        return code;
509
1.62k
    image->pixel.ColorSpace = pcs_device;
510
1.62k
    return 0;
511
1.62k
}
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
16.0k
{
547
16.0k
    int code=0;
548
16.0k
    gs_color_space_index csi;
549
16.0k
    gs_color_space_index csi2;
550
16.0k
    const gs_color_space *pcs2 = pcs;
551
552
16.0k
    csi = csi2 = gs_color_space_get_index(pcs);
553
16.0k
    if (csi == gs_color_space_index_ICC) {
554
13.8k
        csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
555
13.8k
    }
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
16.0k
    if (pdev->CompatibilityLevel <= 1.2) {
559
560
        /* If we have an /Indexed space, we need to look at the base space */
561
10.0k
        if (csi2 == gs_color_space_index_Indexed) {
562
1.56k
            pcs2 = pcs->base_space;
563
1.56k
            csi2 = gs_color_space_get_index(pcs2);
564
1.56k
        }
565
566
10.0k
        switch (csi2) {
567
638
            case gs_color_space_index_DeviceGray:
568
638
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
569
638
                    pdev->params.ColorConversionStrategy == ccs_Gray) {
570
638
                    return 0;
571
638
                }
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.28k
            case gs_color_space_index_DeviceRGB:
580
6.28k
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
581
6.28k
                    pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB)
582
6.28k
                    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
146
            case gs_color_space_index_DeviceCMYK:
591
146
                if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
592
146
                    pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
593
146
                    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
12
            case gs_color_space_index_Separation:
606
12
                if (pdev->ForOPDFRead) {
607
12
                    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
12
                        case ccs_LeaveColorUnchanged:
613
12
                            if (csi2 == gs_color_space_index_Separation)
614
12
                                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
12
                    }
636
12
                }
637
0
                else
638
0
                    *pcs_orig = (gs_color_space *)pcs;
639
0
                return 1;
640
0
                break;
641
642
2.92k
            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.92k
                csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
651
652
2.92k
                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.31k
                    case gs_color_space_index_DeviceRGB:
659
1.31k
                        if (pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB ||
660
1.31k
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
661
1.31k
                            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.60k
                    default:
669
1.60k
                        break;
670
2.92k
                }
671
                /* Fall through for non-handled cases */
672
1.62k
            case gs_color_space_index_DeviceN:
673
1.62k
            case gs_color_space_index_DevicePixel:
674
1.62k
            case gs_color_space_index_Indexed:
675
1.62k
                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.62k
                    case gs_color_space_index_DeviceRGB:
680
1.62k
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
681
1.62k
                        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.62k
                }
689
1.62k
                if (code < 0)
690
0
                    return code;
691
1.62k
                return 1;
692
0
                break;
693
0
            default:
694
0
                return (gs_note_error(gs_error_rangecheck));
695
0
                break;
696
10.0k
        }
697
10.0k
    } else {
698
6.00k
        int strategy = pdev->params.ColorConversionStrategy;
699
700
6.00k
        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
6.00k
        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
6.00k
            case ccs_LeaveColorUnchanged:
729
6.00k
                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
6.00k
        }
999
6.00k
    }
1000
0
    return 0;
1001
16.0k
}
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
75.5k
{
1010
75.5k
    int code = 0;
1011
75.5k
    gs_rect sbox, dbox, *Box;
1012
75.5k
    gs_point corners[4];
1013
75.5k
    gs_fixed_rect ibox;
1014
75.5k
    gs_matrix * pmat1 = (gs_matrix *)pmat;
1015
75.5k
    gs_matrix mat;
1016
1017
75.5k
    if (!pdev->Eps2Write)
1018
46.6k
        return 0;
1019
1020
28.9k
    if (!pdev->accumulating_charproc)
1021
27.2k
        Box = &pdev->BBox;
1022
1.68k
    else
1023
1.68k
        Box = &pdev->charproc_BBox;
1024
28.9k
    if (pmat1 == 0)
1025
28.9k
        pmat1 = (gs_matrix *)&ctm_only(pgs);
1026
28.9k
    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
1027
28.9k
        (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
1028
1
        goto exit;
1029
28.8k
    sbox.p.x = prect->p.x;
1030
28.8k
    sbox.p.y = prect->p.y;
1031
28.8k
    sbox.q.x = prect->q.x;
1032
28.8k
    sbox.q.y = prect->q.y;
1033
28.8k
    gs_bbox_transform_only(&sbox, &mat, corners);
1034
28.8k
    gs_points_bbox(corners, &dbox);
1035
28.8k
    ibox.p.x = float2fixed(dbox.p.x);
1036
28.8k
    ibox.p.y = float2fixed(dbox.p.y);
1037
28.8k
    ibox.q.x = float2fixed(dbox.q.x);
1038
28.8k
    ibox.q.y = float2fixed(dbox.q.y);
1039
28.8k
    if (pcpath != NULL &&
1040
28.8k
        !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
1041
27.3k
                                     ibox.q.x, ibox.q.y)
1042
28.8k
        ) {
1043
        /* Let the target do the drawing, but drive two triangles */
1044
        /* through the clipping path to get an accurate bounding box. */
1045
2.85k
        gx_device_clip cdev;
1046
2.85k
        gx_drawing_color devc;
1047
1048
2.85k
        fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
1049
2.85k
        fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
1050
1051
2.85k
        pdev->AccumulatingBBox++;
1052
2.85k
        gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
1053
2.85k
        set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
1054
2.85k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1055
2.85k
                                 float2fixed(corners[1].x) - x0,
1056
2.85k
                                 float2fixed(corners[1].y) - y0,
1057
2.85k
                                 bx2, by2, &devc, lop_default);
1058
2.85k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1059
2.85k
                                 float2fixed(corners[3].x) - x0,
1060
2.85k
                                 float2fixed(corners[3].y) - y0,
1061
2.85k
                                 bx2, by2, &devc, lop_default);
1062
2.85k
        gx_destroy_clip_device_on_stack(&cdev);
1063
2.85k
        pdev->AccumulatingBBox--;
1064
26.0k
    } else {
1065
        /* Just use the bounding box. */
1066
26.0k
        float x0, y0, x1, y1;
1067
26.0k
        x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
1068
26.0k
        y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
1069
26.0k
        x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
1070
26.0k
        y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
1071
26.0k
        if (Box->p.x > x0)
1072
1.98k
            Box->p.x = x0;
1073
26.0k
        if (Box->p.y > y0)
1074
2.23k
            Box->p.y = y0;
1075
26.0k
        if (Box->q.x < x1)
1076
2.77k
            Box->q.x = x1;
1077
26.0k
        if (Box->q.y < y1)
1078
2.99k
            Box->q.y = y1;
1079
26.0k
    }
1080
28.9k
 exit:
1081
28.9k
    return code;
1082
28.8k
}
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
78.7k
{
1093
78.7k
    int code = 0, i;
1094
78.7k
    unsigned int use_fallback  = 0, in_line = 0, is_mask = 0,
1095
78.7k
        force_lossless = 0, convert_to_process_colors = 0;
1096
78.7k
    int width, height;
1097
78.7k
    cos_dict_t *pnamed = 0;
1098
78.7k
    image_union_t *image;
1099
78.7k
    const gs_pixel_image_t *pim;
1100
78.7k
    gs_int_rect rect;
1101
78.7k
    gs_image_format_t format;
1102
78.7k
    gs_color_space *pcs = NULL;
1103
78.7k
    int num_components;
1104
78.7k
    pdf_image_enum *pie = NULL;
1105
78.7k
    const pdf_color_space_names_t *names;
1106
78.7k
    gs_color_space *pcs_orig = NULL;
1107
78.7k
    gs_color_space *pcs_device = NULL;
1108
78.7k
    cos_value_t cs_value;
1109
78.7k
    const gs_range_t *pranges = 0;
1110
1111
78.7k
    image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
1112
78.7k
                       sizeof(image_union_t), "pdf_begin_typed_image(image)");
1113
78.7k
    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
78.7k
    {
1121
78.7k
        cos_value_t ni_value;
1122
1123
78.7k
        if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1124
6
            pnamed = (cos_dict_t *)ni_value.contents.object;
1125
78.7k
    }
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
78.7k
    pdev->image_mask_id = gs_no_id;
1131
1132
78.7k
    pim = (const gs_pixel_image_t *)pic;
1133
1134
    /* Check for the image types we can handle. */
1135
78.7k
    switch (pic->type->index) {
1136
75.5k
    case 1:
1137
75.5k
        is_mask = ((const gs_image_t *)pic)->ImageMask;
1138
75.5k
        code = setup_type1_image(pdev, pic, pdcolor, image, context);
1139
75.5k
        if (code < 0)
1140
12
            use_fallback = 1;
1141
75.4k
        else
1142
75.4k
            in_line = code;
1143
75.5k
        break;
1144
1145
109
    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
109
        pdev->JPEG_PassThrough = 0;
1161
109
        pdev->JPX_PassThrough = 0;
1162
109
        pdev->image_mask_is_SMask = false;
1163
109
        if (pdev->CompatibilityLevel < 1.2 ||
1164
109
            (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
109
        code = setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image);
1171
109
        goto exit;
1172
1173
3.07k
    case IMAGE3X_IMAGETYPE:
1174
3.07k
        {
1175
3.07k
            char *OC = pdev->PendingOC;
1176
1177
3.07k
            pdev->JPEG_PassThrough = 0;
1178
3.07k
            pdev->JPX_PassThrough = 0;
1179
3.07k
            if (pdev->CompatibilityLevel < 1.4 ||
1180
3.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
3.07k
            pdev->image_mask_is_SMask = true;
1187
1188
3.07k
            if (pdev->PendingOC)
1189
0
                gs_free_object(pdev->memory, pdev->PendingOC, "");
1190
3.07k
            OC = pdev->PendingOC = NULL;
1191
3.07k
            code = gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
1192
3.07k
                                            prect, pdcolor, pcpath, mem,
1193
3.07k
                                            pdf_image3x_make_mid,
1194
3.07k
                                            pdf_image3x_make_mcde, pinfo, OC);
1195
3.07k
            goto exit;
1196
3.07k
        }
1197
1198
26
    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
26
        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
26
        pdev->JPEG_PassThrough = 0;
1264
26
        pdev->JPX_PassThrough = 0;
1265
26
        code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
1266
26
                      pcpath, mem, pinfo, context, image, pnamed);
1267
26
        if (code < 0)
1268
0
            use_fallback = 1;
1269
26
        if (code == 0)
1270
0
            goto exit;
1271
        /* No luck.  Masked images require PDF 1.3 or higher. */
1272
26
        if (pdev->CompatibilityLevel < 1.2)
1273
0
            use_fallback = 1;
1274
26
        if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1275
26
            use_fallback = 0;
1276
26
            code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1277
26
                                                 pcpath, mem,pinfo);
1278
26
            goto exit;
1279
26
        }
1280
0
        image[0].type4 = *(const gs_image4_t *)pic;
1281
0
        break;
1282
1283
0
    default:
1284
0
        use_fallback = 1;
1285
0
        break;
1286
78.7k
    }
1287
1288
75.5k
    format = pim->format;
1289
75.5k
    switch (format) {
1290
75.4k
    case gs_image_format_chunky:
1291
75.5k
    case gs_image_format_component_planar:
1292
75.5k
        break;
1293
0
    default:
1294
0
        use_fallback = 1;
1295
75.5k
    }
1296
    /* AR5 on Windows doesn't support 0-size images. Skipping. */
1297
75.5k
    if (pim->Width == 0 || pim->Height == 0)
1298
5
        use_fallback = 1;
1299
    /* PDF doesn't support images with more than 8 bits per component. */
1300
75.5k
    switch (pim->BitsPerComponent) {
1301
56.8k
        case 1:
1302
57.0k
        case 2:
1303
57.0k
        case 4:
1304
75.5k
        case 8:
1305
75.5k
        case 12:
1306
75.5k
        case 16:
1307
75.5k
            break;
1308
0
        default:
1309
0
            code = gs_note_error(gs_error_rangecheck);
1310
0
            goto exit;
1311
75.5k
    }
1312
75.5k
    if (prect)
1313
3.06k
        rect = *prect;
1314
72.4k
    else {
1315
72.4k
        rect.p.x = rect.p.y = 0;
1316
72.4k
        rect.q.x = pim->Width, rect.q.y = pim->Height;
1317
72.4k
    }
1318
75.5k
    if (rect.p.x != 0 || rect.p.y != 0 ||
1319
75.5k
        rect.q.x != pim->Width || rect.q.y != pim->Height ||
1320
75.5k
        (is_mask && pim->CombineWithColor))
1321
0
        use_fallback = 1;
1322
1323
    /* Handle BBox for Eps2Write, if applicable */
1324
75.5k
    code = pdf_image_handle_eps(pdev, pgs, pmat, pic, &rect, pcpath);
1325
75.5k
    if (code < 0) {
1326
1
        use_fallback = 0;
1327
1
        goto exit;
1328
1
    }
1329
1330
75.5k
    if (use_fallback)
1331
16
        goto exit;
1332
1333
75.4k
    pcs = pim->ColorSpace;
1334
75.4k
    rc_increment_cs(pcs);
1335
75.4k
    num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1336
1337
75.4k
    code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
1338
75.4k
    if (code < 0)
1339
0
        goto exit;
1340
75.4k
    if (pdf_must_put_clip_path(pdev, pcpath))
1341
4.54k
        code = pdf_unclip(pdev);
1342
70.9k
    else
1343
70.9k
        code = pdf_open_page(pdev, PDF_IN_STREAM);
1344
75.4k
    if (code < 0)
1345
0
        goto fail_and_fallback;
1346
1347
75.4k
    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
3.06k
        rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1355
3.06k
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
1356
3.06k
        if (pcs == NULL)
1357
0
            code = gs_note_error(gs_error_VMerror);
1358
72.4k
    } else if (is_mask)
1359
56.2k
        code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
1360
16.1k
    else
1361
16.1k
        code = pdf_prepare_image(pdev, pgs);
1362
75.4k
    if (code < 0)
1363
145
        goto fail_and_fallback;
1364
1365
75.3k
    pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1366
75.3k
                        "pdf_begin_image");
1367
75.3k
    if (pie == 0) {
1368
0
        code = gs_note_error(gs_error_VMerror);
1369
0
        goto exit;
1370
0
    }
1371
75.3k
    memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1372
75.3k
    *pinfo = (gx_image_enum_common_t *) pie;
1373
75.3k
    gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1374
75.3k
                    ((pdev->CompatibilityLevel >= 1.3) ?
1375
16.7k
                            (context == PDF_IMAGE_TYPE3_MASK ?
1376
3.06k
                            &pdf_image_object_enum_procs :
1377
16.7k
                            &pdf_image_enum_procs) :
1378
75.3k
                            context == PDF_IMAGE_TYPE3_MASK ?
1379
0
                            &pdf_image_object_enum_procs :
1380
58.6k
                            context == PDF_IMAGE_TYPE3_DATA ?
1381
0
                            &pdf_image_object_enum_procs2 :
1382
58.6k
                            &pdf_image_enum_procs),
1383
75.3k
                        (gx_device *)pdev, num_components, format);
1384
75.3k
    pie->memory = mem;
1385
75.3k
    pie->pgs = pgs;
1386
75.3k
    if (pgs != NULL)
1387
75.3k
        pie->pgs_level = pgs->level;
1388
75.3k
    width = rect.q.x - rect.p.x;
1389
75.3k
    pie->width = width;
1390
75.3k
    height = rect.q.y - rect.p.y;
1391
75.3k
    pie->bits_per_pixel =
1392
75.3k
        pim->BitsPerComponent * num_components / pie->num_planes;
1393
75.3k
    pie->rows_left = height;
1394
75.3k
    if (pnamed != 0 || pdev->PendingOC) /* Don't in-line the image if it is named. Or has Optional Content */
1395
6
        in_line = false;
1396
75.3k
    else {
1397
75.3k
        int64_t nbytes = (int64_t)(((int64_t) pie->width * pie->bits_per_pixel + 7) >> 3) *
1398
75.3k
            pie->num_planes * pie->rows_left;
1399
1400
75.3k
        in_line &= (nbytes < pdev->MaxInlineImageSize);
1401
75.3k
    }
1402
75.3k
    pie->initial_colorspace = pdev->pcm_color_info_index;
1403
1404
75.3k
    if (pmat == 0)
1405
69.2k
        pmat = &ctm_only(pgs);
1406
75.3k
    {
1407
75.3k
        gs_matrix mat;
1408
75.3k
        gs_matrix bmat;
1409
75.3k
        int code;
1410
1411
75.3k
        pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1412
75.3k
                               pim->Width, pim->Height, height);
1413
75.3k
        if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1414
75.3k
            (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1415
75.3k
            (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1416
75.3k
            )
1417
1
            goto exit;
1418
        /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1419
75.3k
        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
1420
384
            use_fallback = 1;
1421
384
            goto fail_and_fallback;
1422
384
        }
1423
75.3k
    }
1424
1425
74.9k
    code = pdf_put_clip_path(pdev, pcpath);
1426
74.9k
    if (code < 0)
1427
0
        goto exit;
1428
74.9k
    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
74.9k
    pie->writer.alt_writer_count = (in_line ||
1438
74.9k
                                    (pim->Width <= 64 && pim->Height <= 64)
1439
74.9k
                                    ? 1 : 2);
1440
74.9k
    if ((image[0].pixel.ColorSpace != NULL &&
1441
74.9k
        image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1442
74.9k
        && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1443
74.9k
        pdev->transfer_not_identity)
1444
588
        force_lossless = true;
1445
1446
74.9k
    if ((image[0].pixel.ColorSpace != NULL && image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed)
1447
74.9k
        || force_lossless)
1448
2.15k
        pie->writer.alt_writer_count = 1;
1449
1450
74.9k
    if (image[0].pixel.ColorSpace != NULL && (image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceGray &&
1451
19.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceRGB &&
1452
19.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceCMYK &&
1453
19.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_Indexed))
1454
16.9k
        names = &pdf_color_space_names;
1455
57.9k
    else
1456
57.9k
        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
74.9k
    if (!is_mask) {
1460
19.1k
#if 1
1461
19.1k
        if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1462
16.0k
           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
19.1k
        if (pim->BitsPerComponent > 8 && convert_to_process_colors) {
1483
0
            use_fallback = 1;
1484
0
            goto fail_and_fallback;
1485
0
        }
1486
19.1k
        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
19.1k
        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
19.1k
        if (convert_to_process_colors == 1) {
1502
1.62k
            code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1503
1.62k
            if (code < 0)
1504
0
                goto fail_and_fallback;
1505
1.62k
            image[0].pixel.ColorSpace = pcs_device;
1506
1.62k
            image[0].pixel.BitsPerComponent = 8;
1507
1.62k
            code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1508
1.62k
                                     in_line, NULL, 0, false);
1509
1.62k
            if (code < 0)
1510
0
                goto fail_and_fallback;
1511
17.4k
        } else {
1512
17.4k
            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
17.4k
            } else {
1519
17.4k
                convert_to_process_colors = 0;
1520
17.4k
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1521
17.4k
                                     in_line, NULL, 0, false);
1522
17.4k
                if (code < 0)
1523
0
                    goto fail_and_fallback;
1524
17.4k
            }
1525
17.4k
        }
1526
19.1k
    }
1527
1528
74.9k
    image[1] = image[0];
1529
1530
74.9k
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1531
1532
74.9k
    code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1533
74.9k
                    height, pnamed, in_line);
1534
74.9k
    if (code < 0)
1535
0
        goto fail_and_fallback;
1536
1537
74.9k
    if (pdev->CompatibilityLevel < 1.5)
1538
58.3k
        pdev->JPX_PassThrough = 0;
1539
1540
74.9k
    if (!convert_to_process_colors)
1541
73.3k
    {
1542
73.3k
        gs_color_space_index csi;
1543
1544
73.3k
        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
73.3k
    }
1595
    /* If we are not preserving the colour space unchanged, then we can't pass through JPEG */
1596
1.62k
    else
1597
1.62k
        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
74.9k
    if (in_line) {
1611
66.8k
        pdev->JPEG_PassThrough = 0;
1612
66.8k
        pdev->JPX_PassThrough = 0;
1613
66.8k
        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1614
66.8k
                                             &pie->writer.binary[0],
1615
66.8k
                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
1616
66.8k
    } else {
1617
8.08k
        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
512
            int saved_downsample = pdev->params.ColorImage.DownsampleType;
1628
1629
512
            pdev->params.ColorImage.DownsampleType = ds_Subsample;
1630
512
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1631
512
                                          &pie->writer.binary[0], &image[0].pixel,
1632
512
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1633
512
            pdev->params.ColorImage.DownsampleType = saved_downsample;
1634
7.57k
        } else {
1635
7.57k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1636
7.57k
                                          &pie->writer.binary[0], &image[0].pixel,
1637
7.57k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1638
7.57k
        }
1639
8.08k
    }
1640
1641
74.9k
    if (code < 0)
1642
0
        goto fail_and_fallback;
1643
1644
74.9k
    if (convert_to_process_colors) {
1645
1.62k
        image[0].pixel.ColorSpace = pcs_orig;
1646
1.62k
        image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
1647
1.62k
        code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1648
1.62k
                                              (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
1649
1.62k
        if (code < 0)
1650
0
            goto fail_and_fallback;
1651
1.62k
        image[0].pixel.ColorSpace = pcs_device;
1652
1.62k
    }
1653
1654
74.9k
    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
1.13k
        pdev->PassThroughWriter = pie->writer.binary[0].strm;
1661
1.13k
        pie->writer.alt_writer_count = 1;
1662
1.13k
    }
1663
74.9k
    pie->JPEG_PassThrough = pdev->JPEG_PassThrough;
1664
74.9k
    pie->JPX_PassThrough = pdev->JPX_PassThrough;
1665
1666
74.9k
    if (pie->writer.alt_writer_count > 1) {
1667
6.25k
        code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1668
6.25k
        if (code < 0)
1669
0
            goto fail_and_fallback;
1670
6.25k
        code = new_setup_image_filters((gx_device_psdf *) pdev,
1671
6.25k
                                  &pie->writer.binary[1], &image[1].pixel,
1672
6.25k
                                  pmat, pgs, force_lossless, in_line, convert_to_process_colors);
1673
6.25k
        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
6.25k
        } else if (code) {
1693
0
            goto fail_and_fallback;
1694
6.25k
        } 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
6.25k
    }
1704
1705
156k
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1706
81.2k
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1707
81.2k
                             &image[i].pixel, &cs_value, pie);
1708
81.2k
        if (code < 0)
1709
0
            goto fail_and_fallback;
1710
81.2k
    }
1711
74.9k
    if (pie->writer.alt_writer_count == 2) {
1712
6.25k
        psdf_setup_compression_chooser(&pie->writer.binary[2],
1713
6.25k
             (gx_device_psdf *)pdev, pim->Width, pim->Height,
1714
6.25k
             num_components, pim->BitsPerComponent);
1715
6.25k
        pie->writer.alt_writer_count = 3;
1716
6.25k
    }
1717
74.9k
    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
74.9k
    code = 0;
1751
1752
    /* This label is used when code < 0 and we want to do the fallback code */
1753
75.4k
 fail_and_fallback:
1754
75.4k
    if (code != 0)
1755
145
        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
78.7k
 exit:
1762
    /* Free everything */
1763
78.7k
    rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1764
78.7k
    rc_decrement(pcs_device, "pdf_begin_typed_image(pcs_device)");
1765
78.7k
    gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1766
78.7k
                                      "pdf_begin_typed_image(image)");
1767
1768
    /* Free pie only if there was an error or we are falling back */
1769
78.7k
    if (code < 0 || use_fallback) {
1770
559
        if (pie)
1771
384
            gs_free_object(mem, pie, "pdf_begin_typed_image(pie)");
1772
559
        *pinfo = NULL;
1773
559
    }
1774
    /* Do the fallback */
1775
78.7k
    if (use_fallback) {
1776
545
        pdev->JPEG_PassThrough = 0;
1777
545
        pdev->JPX_PassThrough = 0;
1778
545
        code = gx_default_begin_typed_image
1779
545
            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo);
1780
545
    }
1781
78.7k
    return code;
1782
75.4k
}
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
72.5k
{
1792
72.5k
    return pdf_begin_typed_image((gx_device_pdf *)dev, pgs, pmat, pic, prect,
1793
72.5k
                                 pdcolor, pcpath, mem, pinfo,
1794
72.5k
                                 PDF_IMAGE_DEFAULT);
1795
72.5k
}
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
9.82M
{
1805
9.82M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1806
9.82M
    int h = height;
1807
9.82M
    int y;
1808
    /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
1809
9.82M
    uint width_bits = pie->width * pie->plane_depths[0];
1810
    /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
1811
9.82M
    uint ignore;
1812
9.82M
    int nplanes = pie->num_planes;
1813
9.82M
    int status = 0;
1814
9.82M
    uint bcount = (width_bits + 7) >> 3;
1815
1816
9.82M
    if (h > pie->rows_left)
1817
51.1k
        h = pie->rows_left;
1818
21.2M
    for (y = 0; y < h; ++y) {
1819
11.4M
        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
11.4M
        } else {
1866
11.4M
            status = sputs(pie->writer.binary[alt_writer_index].strm,
1867
11.4M
                           planes[0].data + planes[0].raster * y, bcount,
1868
11.4M
                           &ignore);
1869
11.4M
        }
1870
11.4M
        if (status < 0)
1871
0
            break;
1872
11.4M
    }
1873
9.82M
    *rows_used = h;
1874
9.82M
    if (status < 0)
1875
0
        return_error(gs_error_ioerror);
1876
9.82M
    return !pie->rows_left;
1877
9.82M
#undef ROW_BYTES
1878
9.82M
}
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
8.87M
{
1885
8.87M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1886
8.87M
    int i;
1887
1888
8.87M
    if (info->pgs != NULL && info->pgs->level < info->pgs_level)
1889
0
        return_error(gs_error_undefinedresult);
1890
1891
8.87M
    if (pie->JPEG_PassThrough || pie->JPX_PassThrough) {
1892
69.1k
        pie->rows_left -= height;
1893
69.1k
        *rows_used = height;
1894
69.1k
        return !pie->rows_left;
1895
69.1k
    }
1896
1897
18.6M
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1898
9.82M
        int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
1899
9.82M
        if (code)
1900
0
            return code;
1901
9.82M
    }
1902
8.80M
    pie->rows_left -= *rows_used;
1903
8.80M
    if (pie->writer.alt_writer_count > 2)
1904
507k
        pdf_choose_compression(&pie->writer, false);
1905
1906
8.80M
    return !pie->rows_left;
1907
8.80M
}
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
72.3k
{
2001
72.3k
    int code = 0;
2002
72.3k
    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
72.3k
    if (do_image == USE_AS_IMAGE) {
2010
69.4k
        if (pdev->image_mask_id != gs_no_id && piw->pres && piw->pres->object) {
2011
2.92k
            char buf[20];
2012
2013
2.92k
            gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->image_mask_id);
2014
2.92k
            code = cos_dict_put_string_copy((cos_dict_t *)piw->pres->object,
2015
2.92k
                    pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
2016
2.92k
            (*(piw->pres->object)).md5_valid = 0;
2017
2.92k
            if (code < 0)
2018
0
                return code;
2019
2.92k
        }
2020
69.4k
    }
2021
2022
72.3k
    code = pdf_end_write_image(pdev, piw);
2023
72.3k
    pres = piw->pres;
2024
2025
72.3k
    switch (code) {
2026
0
    default:
2027
0
        return code; /* error */
2028
65.1k
    case 1:
2029
65.1k
        code = 0;
2030
65.1k
        break;
2031
7.19k
    case 0:
2032
7.19k
        if (do_image == USE_AS_IMAGE) {
2033
4.27k
            if (pdev->image_mask_skip)
2034
0
                code = 0;
2035
4.27k
            else
2036
4.27k
                code = pdf_do_image(pdev, pres, mat, true);
2037
4.27k
        } 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
2.92k
            const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
2042
2043
2.92k
            pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
2044
2.92k
            pdev->image_mask_id = pdf_resource_id(pres);
2045
2.92k
            pdev->converting_image_matrix = *mat;
2046
2.92k
        } else if (do_image == USE_AS_PATTERN)
2047
0
            code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
2048
72.3k
    }
2049
72.3k
    return code;
2050
72.3k
}
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
74.9k
{
2057
74.9k
    gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
2058
74.9k
    pdf_image_enum *pie = (pdf_image_enum *)info;
2059
74.9k
    int height = pie->writer.height;
2060
74.9k
    int data_height = height - pie->rows_left;
2061
74.9k
    int code = 0, ecode;
2062
2063
74.9k
    if (pie->writer.pres)
2064
8.08k
        ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
2065
66.8k
    else if (data_height > 0)
2066
65.1k
        pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
2067
74.9k
    if (data_height > 0) {
2068
72.3k
        if (pie->writer.pres) {
2069
7.19k
            code = pdf_complete_image_data(pdev, &pie->writer, data_height,
2070
7.19k
                        pie->width, pie->bits_per_pixel);
2071
7.19k
            if (code < 0)
2072
0
                return code;
2073
7.19k
        }
2074
72.3k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2075
        /* The call above possibly decreases pie->writer.alt_writer_count in 2. */
2076
72.3k
        if (code < 0)
2077
0
            return code;
2078
72.3k
        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
72.3k
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
2098
72.3k
        pie->writer.alt_writer_count--; /* For GC. */
2099
72.3k
    } else {
2100
2.60k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2101
2.60k
        code = pdf_end_abort_image(pdev, &pie->writer);
2102
2.60k
        pie->writer.alt_writer_count--; /* For GC. */
2103
2.60k
    }
2104
74.9k
    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
74.9k
    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
74.9k
    gx_image_free_enum(&info);
2121
74.9k
    return code;
2122
74.9k
}
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
71.8k
{
2128
71.8k
    return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
2129
71.8k
}
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
26
{   pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
2135
26
    int code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
2136
26
    int code1 = gx_image1_end_image(info, draw_last);
2137
26
    int code2 = gs_closedevice((gx_device *)cvd->mask);
2138
26
    int code3 = gs_closedevice((gx_device *)cvd);
2139
2140
26
    gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
2141
26
    gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
2142
26
    return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
2143
26
}
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
6.13k
{
2153
6.13k
    gx_device *fdev;
2154
6.13k
    int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
2155
2156
6.13k
    if (code < 0)
2157
0
        return code;
2158
6.13k
    gx_device_set_target((gx_device_forward *)fdev, tdev);
2159
6.13k
    *pmxdev = fdev;
2160
6.13k
    return 0;
2161
6.13k
}
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
3.06k
{
2167
3.06k
    return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
2168
3.06k
}
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
105
{
2184
105
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2185
2186
105
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2187
105
        gs_matrix m;
2188
105
        pdf_lcvd_t *cvd = NULL;
2189
105
        int code;
2190
2191
105
        gs_make_identity(&m);
2192
105
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
2193
105
                                        true, 0, 0, width, height, true);
2194
105
        if (code < 0)
2195
0
            return code;
2196
105
        cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
2197
                                         pdf_image3_make_mcde. The latter will reset it. */
2198
105
        cvd->mask_is_empty = false;
2199
105
        *pmidev = (gx_device *)cvd->mask;
2200
105
        return 0;
2201
105
    } else {
2202
0
        int code = pdf_make_mxd(pmidev, dev, mem);
2203
2204
0
        if (code < 0)
2205
0
            return code;
2206
0
        set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2207
0
        return 0;
2208
0
    }
2209
105
}
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
3.06k
{
2218
    /* The target of the null device is the pdfwrite device. */
2219
3.06k
    gx_device_pdf *const pdev = (gx_device_pdf *)
2220
3.06k
        ((gx_device_null *)dev)->target;
2221
3.06k
    return pdf_begin_typed_image
2222
3.06k
        (pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
2223
3.06k
         PDF_IMAGE_TYPE3_MASK);
2224
3.06k
}
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
105
{
2237
105
    int code;
2238
105
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2239
2240
105
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2241
        /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
2242
105
        pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
2243
2244
105
        ((gx_device_memory *)midev)->target = NULL;
2245
105
        cvd->m = pdev->converting_image_matrix;
2246
105
        cvd->mdev.mapped_x = origin->x;
2247
105
        cvd->mdev.mapped_y = origin->y;
2248
105
        cvd->mdev.width += origin->x;
2249
105
        cvd->mdev.height += origin->y;
2250
105
        *pmcdev = (gx_device *)&cvd->mdev;
2251
105
        code = gx_default_begin_typed_image
2252
105
            ((gx_device *)&cvd->mdev, pgs, pmat, pic, prect, pdcolor, NULL, mem,
2253
105
            pinfo);
2254
105
        if (code < 0)
2255
0
            return code;
2256
105
    } else {
2257
0
        code = pdf_make_mxd(pmcdev, midev, mem);
2258
0
        if (code < 0)
2259
0
            return code;
2260
0
        code = pdf_begin_typed_image
2261
0
            ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2262
0
            pinfo, PDF_IMAGE_TYPE3_DATA);
2263
0
        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
0
    }
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
105
    return 0;
2275
105
}
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
3.06k
{
2284
3.06k
    int code = pdf_make_mxd(pmidev, dev, mem);
2285
2286
3.06k
    if (code < 0)
2287
0
        return code;
2288
3.06k
    set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2289
3.06k
    return 0;
2290
3.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
3.06k
{
2305
3.06k
    int code;
2306
3.06k
    pdf_image_enum *pmie;
2307
3.06k
    int i;
2308
3.06k
    const gs_image3x_mask_t *pixm;
2309
3.06k
    gx_device_pdf *pdf_dev = (gx_device_pdf *)dev;
2310
2311
3.06k
    if (midev[0]) {
2312
3.06k
        if (midev[1])
2313
0
            return_error(gs_error_rangecheck);
2314
3.06k
        i = 0, pixm = &pim->Opacity;
2315
3.06k
    } else if (midev[1])
2316
0
        i = 1, pixm = &pim->Shape;
2317
0
    else
2318
0
        return_error(gs_error_rangecheck);
2319
3.06k
    code = pdf_make_mxd(pmcdev, midev[i], mem);
2320
3.06k
    if (code < 0)
2321
0
        return code;
2322
2323
3.06k
    if (pminfo[0] != NULL)
2324
3.06k
        pdf_dev->PendingOC = pminfo[0]->OC;
2325
0
    else
2326
0
        pdf_dev->PendingOC = 0;
2327
2328
3.06k
    code = pdf_begin_typed_image
2329
3.06k
        ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2330
3.06k
         pinfo, PDF_IMAGE_TYPE3_DATA);
2331
3.06k
    pdf_dev->PendingOC = 0;
2332
3.06k
    if (code < 0) {
2333
0
        rc_decrement(*pmcdev, "pdf_image3x_make_mcde");
2334
0
        return code;
2335
0
    }
2336
3.06k
    if ((*pinfo)->procs != &pdf_image_enum_procs) {
2337
        /* We couldn't handle the image.  Bail out. */
2338
0
        gx_image_end(*pinfo, false);
2339
0
        gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
2340
0
        return_error(gs_error_rangecheck);
2341
0
    }
2342
3.06k
    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
3.06k
    if (pixm->has_Matte) {
2348
1
        gx_device_pdf *pdev = (gx_device_pdf *)dev;
2349
1
        int DoMatte = 0, num_components =
2350
1
            gs_color_space_num_components(pim->ColorSpace);
2351
2352
1
        switch (pdev->params.ColorConversionStrategy) {
2353
1
            case ccs_LeaveColorUnchanged:
2354
1
                DoMatte = 1;
2355
1
                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
1
        }
2382
2383
1
        if (DoMatte) {
2384
1
            code = cos_dict_put_c_key_floats((gx_device_pdf *)dev,
2385
1
                                    (cos_dict_t *)pmie->writer.pres->object,
2386
1
                                    "/Matte", pixm->Matte,
2387
1
                                    num_components);
2388
1
            if (code < 0)
2389
0
                return code;
2390
1
        }
2391
1
    }
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
3.06k
    return 0;
2397
3.06k
}
2398
2399
pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
2400
10.7k
{
2401
10.7k
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
2402
2403
10.7k
    return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
2404
10.7k
}
2405
2406
static int
2407
check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
2408
964
{
2409
964
    pdf_pattern_t *ppat0 = (pdf_pattern_t *)pres0;
2410
964
    pdf_pattern_t *ppat1 = (pdf_pattern_t *)pres1;
2411
2412
964
    return (ppat0->substitute == NULL && ppat1->substitute == NULL);
2413
964
}
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
7.38k
{
2425
7.38k
    if (pdev->vg_initial_set) {
2426
7.38k
        destination->strokeconstantalpha = source->strokeconstantalpha;
2427
7.38k
        source->strokeconstantalpha = pdev->vg_initial.strokeconstantalpha;
2428
7.38k
        destination->fillconstantalpha = source->fillconstantalpha;
2429
7.38k
        source->fillconstantalpha = pdev->vg_initial.fillconstantalpha;
2430
7.38k
        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
7.38k
        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
7.38k
        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
7.38k
        if (destination->set_transfer.gray != NULL)
2437
3.69k
            destination->set_transfer.gray->id = (source->set_transfer.gray != NULL ? source->set_transfer.gray->id : 0);
2438
7.38k
        if (source->set_transfer.red != NULL)
2439
0
            source->set_transfer.red->id = pdev->vg_initial.transfer_ids[0];
2440
7.38k
        if (source->set_transfer.green != NULL)
2441
0
            source->set_transfer.green->id = pdev->vg_initial.transfer_ids[1];
2442
7.38k
        if (source->set_transfer.blue != NULL)
2443
0
            source->set_transfer.blue->id = pdev->vg_initial.transfer_ids[2];
2444
7.38k
        if (source->set_transfer.gray != NULL)
2445
3.69k
            source->set_transfer.gray->id = pdev->vg_initial.transfer_ids[3];
2446
7.38k
        destination->alphaisshape = source->alphaisshape;
2447
7.38k
        source->alphaisshape = pdev->vg_initial.alphaisshape;
2448
7.38k
        destination->blend_mode = source->blend_mode;
2449
7.38k
        source->blend_mode = pdev->vg_initial.blend_mode;
2450
7.38k
        if (destination->black_generation != NULL)
2451
3.69k
            destination->black_generation->id = (source->black_generation != NULL ? source->black_generation->id : 0);
2452
7.38k
        if (source->black_generation != NULL)
2453
3.69k
            source->black_generation->id = pdev->vg_initial.black_generation_id;
2454
7.38k
        if (destination->undercolor_removal != NULL)
2455
3.69k
            destination->undercolor_removal->id = (source->undercolor_removal != NULL ? source->undercolor_removal->id : 0);
2456
7.38k
        if (source->undercolor_removal != NULL)
2457
3.69k
            source->undercolor_removal->id = pdev->vg_initial.undercolor_removal_id;
2458
7.38k
        destination->overprint_mode = source->overprint_mode;
2459
7.38k
        source->overprint_mode = pdev->vg_initial.overprint_mode;
2460
7.38k
        destination->flatness = source->flatness;
2461
7.38k
        source->flatness = pdev->vg_initial.flatness;
2462
7.38k
        destination->smoothness = source->smoothness;
2463
7.38k
        source->smoothness = pdev->vg_initial.smoothness;
2464
7.38k
        destination->flatness = source->flatness;
2465
7.38k
        source->flatness = pdev->vg_initial.flatness;
2466
7.38k
        destination->text_knockout = source->text_knockout;
2467
7.38k
        source->text_knockout = pdev->vg_initial.text_knockout;
2468
7.38k
        destination->stroke_adjust = source->stroke_adjust;
2469
7.38k
        source->stroke_adjust = pdev->vg_initial.stroke_adjust;
2470
7.38k
        destination->line_params.half_width = source->line_params.half_width;
2471
7.38k
        source->line_params.half_width = pdev->vg_initial.line_params.half_width;
2472
7.38k
        destination->line_params.start_cap = source->line_params.start_cap;
2473
7.38k
        source->line_params.start_cap = pdev->vg_initial.line_params.start_cap;
2474
7.38k
        destination->line_params.end_cap = source->line_params.end_cap;
2475
7.38k
        source->line_params.end_cap = pdev->vg_initial.line_params.end_cap;
2476
7.38k
        destination->line_params.dash_cap = source->line_params.dash_cap;
2477
7.38k
        source->line_params.dash_cap = pdev->vg_initial.line_params.dash_cap;
2478
7.38k
        destination->line_params.join = source->line_params.join;
2479
7.38k
        source->line_params.join = pdev->vg_initial.line_params.join;
2480
7.38k
        destination->line_params.curve_join = source->line_params.curve_join;
2481
7.38k
        source->line_params.curve_join = pdev->vg_initial.line_params.curve_join;
2482
7.38k
        destination->line_params.miter_limit = source->line_params.miter_limit;
2483
7.38k
        source->line_params.miter_limit = pdev->vg_initial.line_params.miter_limit;
2484
7.38k
        destination->line_params.miter_check = source->line_params.miter_check;
2485
7.38k
        source->line_params.miter_check = pdev->vg_initial.line_params.miter_check;
2486
7.38k
        destination->line_params.dot_length = source->line_params.dot_length;
2487
7.38k
        source->line_params.dot_length = pdev->vg_initial.line_params.dot_length;
2488
7.38k
        destination->line_params.dot_length_absolute = source->line_params.dot_length_absolute;
2489
7.38k
        source->line_params.dot_length_absolute = pdev->vg_initial.line_params.dot_length_absolute;
2490
7.38k
        destination->line_params.dot_orientation = source->line_params.dot_orientation;
2491
7.38k
        source->line_params.dot_orientation = pdev->vg_initial.line_params.dot_orientation;
2492
7.38k
        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
7.38k
        memcpy(&destination->line_params.dash, &source->line_params.dash, sizeof(source->line_params.dash));
2495
7.38k
        memcpy(&source->line_params.dash, &pdev->vg_initial.line_params.dash, sizeof(source->line_params.dash));
2496
7.38k
    }
2497
7.38k
    return 0;
2498
7.38k
}
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
167M
{
2507
167M
    gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
2508
167M
    int code=0, force_CTM_change=0;
2509
167M
    pdf_resource_t *pres, *pres1;
2510
167M
    gx_bitmap_id id = (gx_bitmap_id)size;
2511
2512
167M
    switch (dev_spec_op) {
2513
55.6k
        case gxdso_skip_icc_component_validation:
2514
55.6k
            return 1;
2515
12.5k
        case gxdso_supports_pattern_transparency:
2516
12.5k
            return 1;
2517
3.97k
        case gxdso_pattern_can_accum:
2518
3.97k
            return 1;
2519
140
        case gxdso_pdf_form_name:
2520
140
            if (pdev->PDFFormName) {
2521
0
                gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2522
0
            }
2523
140
            pdev->PDFFormName = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, size + 1, "Name of Form for pdfmark");
2524
140
            if (pdev->PDFFormName == NULL)
2525
0
                return_error(gs_error_VMerror);
2526
140
            memset(pdev->PDFFormName, 0x00, size + 1);
2527
140
            memcpy(pdev->PDFFormName, data, size);
2528
140
            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
140
        case gxdso_form_begin:
2536
140
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 0) && pdev->PatternDepth == 0) {
2537
140
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2538
140
                float arry[6];
2539
140
                cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
2540
2541
                /* Make sure the document and page stream are open */
2542
140
                code = pdfwrite_pdf_open_document(pdev);
2543
140
                if (code < 0)
2544
0
                    return code;
2545
140
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2546
140
                if (code < 0)
2547
0
                    return code;
2548
140
                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
140
                code = pdf_enter_substream(pdev, resourceXObject, id, &pres, false,
2563
140
                        pdev->CompressStreams);
2564
140
                if (code < 0)
2565
0
                    return code;
2566
140
                pcd = cos_stream_dict((cos_stream_t *)pres->object);
2567
140
                pcd_Resources = cos_dict_alloc(pdev, "pdf_form(Resources)");
2568
140
                if (pcd == NULL || pcd_Resources == NULL)
2569
0
                    return_error(gs_error_VMerror);
2570
140
                code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
2571
140
                if (code >= 0)
2572
140
                    code = cos_dict_put_c_strings(pcd, "/Subtype", "/Form");
2573
140
                if (code >= 0)
2574
140
                    code = cos_dict_put_c_strings(pcd, "/FormType", "1");
2575
140
                if (code >= 0)
2576
140
                    code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
2577
2578
140
                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
140
                    gs_rect bbox_out;
2588
140
                    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
140
                    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
140
                    code = gs_matrix_multiply(&tmplate->form_matrix, &tmplate->CTM, &cmat);
2599
140
                    if (code < 0)
2600
0
                        return code;
2601
140
                    code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2602
140
                    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
140
                    cmat.xx = cmat.yy = 1.0f;
2609
140
                    cmat.xy = cmat.yx = cmat.tx = cmat.ty = 0.0f;
2610
140
                    if(bbox_out.q.x - bbox_out.p.x > pdev->width) {
2611
0
                        cmat.xx = pdev->width / (bbox_out.q.x - bbox_out.p.x);
2612
0
                        bbox_out.q.x = bbox_out.p.x + ((bbox_out.q.x - bbox_out.p.x) * cmat.xx);
2613
0
                        force_CTM_change = 1;
2614
0
                    }
2615
140
                    if(bbox_out.q.y - bbox_out.p.y > pdev->height) {
2616
0
                        cmat.yy = pdev->height / (bbox_out.q.y - bbox_out.p.y);
2617
0
                        bbox_out.q.y = bbox_out.p.y + ((bbox_out.q.y - bbox_out.p.y) * cmat.yy);
2618
0
                        force_CTM_change = 1;
2619
0
                    }
2620
2621
140
                    if (bbox_out.p.x < 0) {
2622
0
                        cmat.tx = bbox_out.p.x * -1;
2623
0
                        bbox_out.q.x += cmat.tx;
2624
0
                        force_CTM_change = 1;
2625
0
                    }
2626
140
                    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
140
                    if (bbox_out.p.y < 0) {
2633
0
                        cmat.ty = bbox_out.p.y * -1;
2634
0
                        bbox_out.q.y += cmat.ty;
2635
0
                        force_CTM_change = 1;
2636
0
                    }
2637
140
                    if (floor(bbox_out.q.y) > pdev->height) {
2638
0
                        cmat.ty += pdev->height - bbox_out.q.y;
2639
0
                        force_CTM_change = 1;
2640
0
                    }
2641
2642
140
                    if (force_CTM_change) {
2643
0
                        code = gs_matrix_multiply(&tmplate->CTM, &cmat, &new_mat);
2644
0
                        if (code < 0)
2645
0
                            return code;
2646
0
                        code = gs_matrix_multiply(&tmplate->form_matrix, &new_mat, &cmat);
2647
0
                        if (code < 0)
2648
0
                            return code;
2649
0
                        code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2650
0
                        if (code < 0)
2651
0
                            return code;
2652
0
                        tmplate->CTM = cmat;
2653
0
                    }
2654
140
                    arry[0] = bbox_out.p.x;
2655
140
                    arry[1] = bbox_out.p.y;
2656
140
                    arry[2] = bbox_out.q.x;
2657
140
                    arry[3] = bbox_out.q.y;
2658
140
                    if (code >= 0)
2659
140
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2660
140
                    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
140
                    arry[0] = arry[3] = 1.0f;
2668
140
                    arry[1] = arry[2] = arry[4] = arry[5] = 0.0f;
2669
140
                } 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
140
                code = cos_dict_put_c_key_floats(pdev, pcd, "/Matrix", arry, 6);
2691
140
                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
140
                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
140
                } 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
140
                    pdev->substream_Resources = pcd_Resources;
2719
140
                    pres->rid = id;
2720
140
                    if (code >= 0)
2721
140
                        pdev->HighLevelForm++;
2722
140
                    return force_CTM_change;
2723
140
                }
2724
140
            }
2725
0
            return code;
2726
140
        case gxdso_form_end:
2727
            /* This test must be the same as the one in gxdso_form_begin, above */
2728
140
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 1) && pdev->PatternDepth == 0) {
2729
140
                if (pdev->CompatibilityLevel <= 1.7) {
2730
140
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2731
140
                    if (code < 0)
2732
0
                        return code;
2733
140
                }
2734
140
                pres = pres1 = pdev->accumulating_substream_resource;
2735
140
                if (pres == NULL)
2736
0
                    return_error(gs_error_unregistered);
2737
140
                code = pdf_exit_substream(pdev);
2738
140
                if (code < 0)
2739
0
                    return code;
2740
140
                code = pdf_find_same_resource(pdev, resourceXObject, &pres, check_unsubstituted2);
2741
140
                if (code < 0)
2742
0
                    return code;
2743
140
                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
140
                } else if (pres->object->id < 0)
2749
140
                    pdf_reserve_object_id(pdev, pres, 0);
2750
140
                pdev->LastFormID = pdf_resource_id(pres);
2751
140
                pdev->HighLevelForm--;
2752
140
                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
140
                if (pdev->PDFFormName) {
2758
140
                    cos_value_t value;
2759
2760
140
                    code = cos_dict_put(pdev->local_named_objects, (const byte *)pdev->PDFFormName,
2761
140
                        strlen(pdev->PDFFormName), cos_object_value(&value, pres->object));
2762
2763
140
                    if (code < 0)
2764
0
                        return code;
2765
140
                    pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
2766
140
                    pres->object = NULL;
2767
140
                    gs_free_object(pdev->pdf_memory, pres, "free redundant resource");
2768
2769
140
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2770
140
                    pdev->PDFFormName = 0x00;
2771
140
                } else {
2772
0
                    pprinti64d1(pdev->strm, "/R%"PRId64" Do Q\n", pdf_resource_id(pres));
2773
0
                }
2774
140
            }
2775
140
            return 0;
2776
140
        case gxdso_get_form_ID:
2777
140
            {
2778
140
                int *ID = data;
2779
140
                *ID = pdev->LastFormID;
2780
140
            }
2781
140
            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
3.69k
        case gxdso_pattern_start_accum:
2816
3.69k
            {
2817
3.69k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2818
3.69k
                gs_pattern1_instance_t *pinst = param->pinst;
2819
3.69k
                gs_gstate *pgs = param->graphics_state;
2820
2821
3.69k
                code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
2822
3.69k
                if (code < 0)
2823
0
                    return code;
2824
3.69k
                if (pdev->context == PDF_IN_NONE) {
2825
104
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
2826
104
                    if (code < 0)
2827
0
                        return code;
2828
104
                }
2829
3.69k
                code = pdf_prepare_fill_stroke(pdev, (gs_gstate *)pgs, false);
2830
3.69k
                if (code < 0)
2831
0
                    return code;
2832
3.69k
                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
3.69k
                {
2844
3.69k
                    gs_gstate **new_states;
2845
3.69k
                    int pdepth;
2846
2847
3.69k
                    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
3.69k
                    if (new_states == NULL)
2849
0
                        return_error(gs_error_VMerror);
2850
3.69k
                    memset(new_states, 0x00, sizeof(gs_gstate *) * (pdev->PatternDepth + 2));
2851
3.69k
                    for (pdepth = 0; pdepth < pdev->PatternDepth;pdepth++)
2852
6
                        new_states[pdepth] = pdev->initial_pattern_states[pdepth];
2853
3.69k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing old pattern state stack");
2854
3.69k
                    pdev->initial_pattern_states = new_states;
2855
3.69k
                }
2856
3.69k
                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
3.69k
                if (pdev->initial_pattern_states[pdev->PatternDepth] == NULL)
2858
0
                    return code;
2859
3.69k
                memset(pdev->initial_pattern_states[pdev->PatternDepth], 0x00, sizeof(gs_gstate));
2860
3.69k
                pdev->initial_pattern_states[pdev->PatternDepth]->memory = pdev->pdf_memory;
2861
2862
3.69k
                reset_gstate_for_pattern(pdev, pdev->initial_pattern_states[pdev->PatternDepth], pgs);
2863
3.69k
                code = pdf_enter_substream(pdev, resourcePattern, pinst->id, &pres, false,
2864
3.69k
                        pdev->CompressStreams);
2865
3.69k
                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
3.69k
                pdev->state.soft_mask_id = pgs->soft_mask_id;
2879
3.69k
                pres->rid = pinst->id;
2880
3.69k
                code = pdf_store_pattern1_params(pdev, pres, pinst);
2881
3.69k
                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
3.69k
                pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2888
3.69k
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2889
3.69k
                pdev->PatternDepth++;
2890
3.69k
                pdev->PatternsSinceForm++;
2891
3.69k
            }
2892
0
            return 1;
2893
3.69k
        case gxdso_pattern_finish_accum:
2894
3.69k
            {
2895
3.69k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2896
3.69k
                gs_gstate *pgs = param->graphics_state;
2897
2898
3.69k
                if (pdev->CompatibilityLevel <= 1.7) {
2899
3.69k
                    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
3.69k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2905
3.69k
                    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
3.69k
                }
2911
3.69k
                pres = pres1 = pdev->accumulating_substream_resource;
2912
3.69k
                if (pres == NULL)
2913
0
                    code = gs_note_error(gs_error_unregistered);
2914
3.69k
                else
2915
3.69k
                    code = pdf_exit_substream(pdev);
2916
3.69k
                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
3.69k
                if (pdev->substituted_pattern_count > 300 &&
2922
3.69k
                        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
3.69k
                code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
2928
3.69k
                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
3.69k
                if (code > 0) {
2934
964
                    pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
2935
2936
964
                    code = pdf_cancel_resource(pdev, pres1, resourcePattern);
2937
964
                    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
964
                    ppat->substitute = (pdf_pattern_t *)pres;
2944
964
                    pres->where_used |= pdev->used_mask;
2945
964
                    pdev->substituted_pattern_count++;
2946
2.72k
                } else if (pres->object->id < 0)
2947
2.72k
                    pdf_reserve_object_id(pdev, pres, 0);
2948
3.69k
                reset_gstate_for_pattern(pdev, pgs, pdev->initial_pattern_states[pdev->PatternDepth - 1]);
2949
3.69k
                gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth - 1], "Freeing dangling pattern state");
2950
3.69k
                pdev->initial_pattern_states[pdev->PatternDepth - 1] = NULL;
2951
3.69k
                if (pdev->PatternDepth == 1) {
2952
3.68k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state");
2953
3.68k
                    pdev->initial_pattern_states = NULL;
2954
3.68k
                }
2955
2956
3.69k
                pdev->PatternDepth--;
2957
3.69k
                pdev->PatternsSinceForm--;
2958
3.69k
            }
2959
0
            return 1;
2960
8.44k
        case gxdso_pattern_load:
2961
8.44k
            pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, *((gx_bitmap_id *)data));
2962
8.44k
            if (pres == 0)
2963
3.69k
                return 0;
2964
4.75k
            pres = pdf_substitute_pattern(pres);
2965
4.75k
            pres->where_used |= pdev->used_mask;
2966
4.75k
            code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
2967
4.75k
            if (code < 0)
2968
0
                return code;
2969
4.75k
            return 1;
2970
201k
        case gxdso_pattern_shading_area:
2971
201k
            return 0;
2972
270k
        case gxdso_pattern_is_cpath_accum:
2973
270k
            return 0;
2974
12.7k
        case gxdso_pattern_shfill_doesnt_need_path:
2975
12.7k
            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
9.32k
        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
9.32k
            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
3.01k
        case gxdso_JPEG_passthrough_query:
2996
3.01k
            pdev->JPEG_PassThrough = pdev->params.PassThroughJPEGImages;
2997
3.01k
            return 1;
2998
0
            break;
2999
3.01k
        case gxdso_JPEG_passthrough_begin:
3000
3.01k
            return 0;
3001
0
            break;
3002
256k
        case gxdso_JPEG_passthrough_data:
3003
256k
            if (pdev->JPEG_PassThrough && pdev->PassThroughWriter)
3004
68.6k
            {
3005
68.6k
                uint ignore;
3006
68.6k
                if (sputs(pdev->PassThroughWriter,
3007
68.6k
                           data, size,
3008
68.6k
                           &ignore) < 0)
3009
0
                           return_error(gs_error_ioerror);
3010
68.6k
            }
3011
256k
            return 0;
3012
0
            break;
3013
3.01k
        case gxdso_JPEG_passthrough_end:
3014
3.01k
            pdev->JPEG_PassThrough = 0;
3015
3.01k
            pdev->PassThroughWriter = 0;
3016
3.01k
            return 0;
3017
0
            break;
3018
2.03k
        case gxdso_JPX_passthrough_query:
3019
2.03k
            pdev->JPX_PassThrough = pdev->params.PassThroughJPXImages;
3020
2.03k
            return 1;
3021
0
            break;
3022
1.86k
        case gxdso_JPX_passthrough_begin:
3023
1.86k
            return 0;
3024
0
            break;
3025
153k
        case gxdso_JPX_passthrough_data:
3026
153k
            if (pdev->JPX_PassThrough && pdev->PassThroughWriter)
3027
29.7k
            {
3028
29.7k
                uint ignore;
3029
29.7k
                if (sputs(pdev->PassThroughWriter,
3030
29.7k
                           data, size,
3031
29.7k
                           &ignore) < 0)
3032
0
                           return_error(gs_error_ioerror);
3033
29.7k
            }
3034
153k
            return 0;
3035
0
            break;
3036
1.86k
        case gxdso_JPX_passthrough_end:
3037
1.86k
            pdev->JPX_PassThrough = 0;
3038
1.86k
            pdev->PassThroughWriter = 0;
3039
1.86k
            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
7.23M
        case gxdso_in_smask_construction:
3075
7.23M
            return pdev->smask_construction;
3076
1
        case gxdso_pending_optional_content:
3077
1
            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
1
            {
3108
1
                char *object = data;
3109
1
                if (pdev->PendingOC)
3110
0
                    gs_free_object(pdev->memory, pdev->PendingOC, "");
3111
1
                pdev->PendingOC = (char *)gs_alloc_bytes(pdev->memory, strlen(object) + 1, "");
3112
1
                if (pdev->PendingOC == NULL)
3113
0
                    return_error(gs_error_VMerror);
3114
1
                memcpy(pdev->PendingOC, object, strlen(object) + 1);
3115
1
            }
3116
1
            return 0;
3117
0
            break;
3118
1
        case gxdso_hilevel_text_clip:
3119
1
            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
0
                if (pdev->clipped_text_pending) {
3125
                    /* Get back to the content stream. This will (amongst other things) flush
3126
                     * any pending text.
3127
                     */
3128
0
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
3129
0
                    if (code < 0)
3130
0
                        return code;
3131
                    /* Reset the pending state */
3132
0
                    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
0
                    if (pdev->vgstack_bottom)
3141
0
                        pdev->vgstack_bottom = pdev->saved_vgstack_depth_for_textclip;
3142
3143
0
                    while (pdev->vgstack_depth > pdev->vgstack_bottom) {
3144
0
                        code = pdf_restore_viewer_state(pdev, pdev->strm);
3145
0
                        if (code < 0)
3146
0
                            return code;
3147
0
                    }
3148
3149
0
                    pdev->vgstack_bottom = pdev->saved_vgstack_bottom_for_textclip;
3150
0
                    pdf_reset_text(pdev); /* because of Q */
3151
0
                }
3152
1
            } else {
3153
1
                if (!pdev->accumulating_charproc) {
3154
1
                    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
1
                    if (!pdev->clipped_text_pending) {
3159
                        /* Return to the content stream, this will (amongst other things) flush
3160
                         * any pending text.
3161
                         */
3162
1
                        code = pdf_open_page(pdev, PDF_IN_STREAM);
3163
1
                        if (code < 0)
3164
0
                            return code;
3165
3166
1
                        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
1
                        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
1
                        code = pdf_save_viewer_state(pdev, pdev->strm);
3181
1
                        if (code < 0)
3182
0
                            return code;
3183
1
                        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
1
                        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
1
                        pdev->vgstack_bottom = pdev->vgstack_depth;
3197
1
                    }
3198
1
                }
3199
1
            }
3200
1
            break;
3201
2.17M
        case gxdso_get_dev_param:
3202
2.17M
            {
3203
2.17M
                int code;
3204
2.17M
                dev_param_req_t *request = (dev_param_req_t *)data;
3205
2.17M
                code = gdev_pdf_get_param(pdev1, request->Param, request->list);
3206
2.17M
                if (code != gs_error_undefined)
3207
2.12M
                    return code;
3208
2.17M
            }
3209
            /* Fall through */
3210
167M
    }
3211
156M
    return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size);
3212
167M
}