Coverage Report

Created: 2025-11-16 07:40

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/devices/vector/gdevpdfi.c
Line
Count
Source
1
/* Copyright (C) 2001-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
74.8k
{
118
74.8k
    return true;
119
74.8k
}
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
24
{
143
24
    if (pim4->BitsPerComponent == 1 &&
144
0
        pim4->ColorSpace->type->num_components(pim4->ColorSpace) == 1 &&
145
0
        (pim4->MaskColor_is_range ?
146
0
         pim4->MaskColor[0] | pim4->MaskColor[1] :
147
0
         pim4->MaskColor[0]) <= 1
148
24
        ) {
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
24
    return -1;     /* arbitrary <0 */
225
24
}
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
99.8k
{
231
232
99.8k
    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
99.8k
    return pdf_begin_image_data(pdev, &pie->writer, pi, cs_value, i);
247
99.8k
}
248
249
static int
250
make_device_color_space(gx_device_pdf *pdev,
251
                        gs_color_space_index output_cspace_index,
252
                        gs_color_space **ppcs)
253
2.88k
{
254
2.88k
    gs_color_space *cs;
255
2.88k
    gs_memory_t *mem = pdev->v_memory;
256
257
2.88k
    switch (output_cspace_index) {
258
0
        case gs_color_space_index_DeviceGray:
259
0
            cs = gs_cspace_new_DeviceGray(mem);
260
0
            break;
261
2.88k
        case gs_color_space_index_DeviceRGB:
262
2.88k
            cs = gs_cspace_new_DeviceRGB(mem);
263
2.88k
            break;
264
0
        case gs_color_space_index_DeviceCMYK:
265
0
            cs = gs_cspace_new_DeviceCMYK(mem);
266
0
            break;
267
0
        default:
268
            /* Notify the user and terminate.
269
               Don't emit rangecheck becuause it would fall back
270
               to a default implementation (rasterisation).
271
             */
272
0
            emprintf(mem, "Unsupported ProcessColorModel");
273
0
            return_error(gs_error_undefined);
274
2.88k
    }
275
276
2.88k
    if (cs == NULL)
277
0
        return_error(gs_error_VMerror);
278
279
2.88k
    *ppcs = cs;
280
2.88k
    return 0;
281
2.88k
}
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
87.4k
{
318
87.4k
    const gs_image_t *pim1 = (const gs_image_t *)pic;
319
320
87.4k
    if (pim1->Alpha != gs_image_alpha_none)
321
0
        return -1;
322
87.4k
    if (pim1->ImageMask) {
323
        /* If parameters are invalid, use the fallback implementation. */
324
56.1k
        if (!(gx_dc_is_pattern1_color(pdcolor)))
325
55.7k
            if (pim1->BitsPerComponent != 1 ||
326
55.7k
                !((pim1->Decode[0] == 0.0 && pim1->Decode[1] == 1.0) ||
327
54.0k
                  (pim1->Decode[0] == 1.0 && pim1->Decode[1] == 0.0))
328
55.7k
                )
329
5
                return -1;
330
56.1k
    }
331
87.4k
    image[0].type1 = *pim1;
332
    /* If we can write in-line then make it so */
333
87.4k
    return (context == PDF_IMAGE_DEFAULT &&
334
74.8k
        can_write_image_in_line(pdev, pim1));
335
87.4k
}
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
117
{
345
117
    const gs_image3_t *pim3 = (const gs_image3_t *)pic;
346
117
    gs_image3_t pim3a;
347
117
    const gs_image_common_t *pic1 = pic;
348
117
    gs_matrix m, mi;
349
117
    const gs_matrix *pmat1 = pmat;
350
117
    int code;
351
352
117
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
353
61
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
354
61
        if (code < 0)
355
0
            return code;
356
61
        if (pdf_must_put_clip_path(pdev, pcpath))
357
22
            code = pdf_unclip(pdev);
358
39
        else
359
39
            code = pdf_open_page(pdev, PDF_IN_STREAM);
360
61
        if (code < 0)
361
0
            return code;
362
61
        code = pdf_put_clip_path(pdev, pcpath);
363
61
        if (code < 0)
364
0
            return code;
365
61
        gs_make_identity(&m);
366
61
        pmat1 = &m;
367
61
        m.tx = floor(pgs->ctm.tx + 0.5); /* Round the origin against the image size distorsions */
368
61
        m.ty = floor(pgs->ctm.ty + 0.5);
369
61
        pim3a = *pim3;
370
61
        code = gs_matrix_invert(&pim3a.ImageMatrix, &mi);
371
61
        if (code < 0)
372
1
            return code;
373
60
        gs_make_identity(&pim3a.ImageMatrix);
374
60
        if (pim3a.Width < pim3a.MaskDict.Width && pim3a.Width > 0) {
375
12
            int sx = (pim3a.MaskDict.Width + pim3a.Width - 1) / pim3a.Width;
376
377
12
            gs_matrix_scale(&mi, 1.0 / sx, 1, &mi);
378
12
            gs_matrix_scale(&pim3a.ImageMatrix, 1.0 / sx, 1, &pim3a.ImageMatrix);
379
12
        }
380
60
        if (pim3a.Height < pim3a.MaskDict.Height && pim3a.Height > 0) {
381
8
            int sy = (pim3a.MaskDict.Height + pim3a.Height - 1) / pim3a.Height;
382
383
8
            gs_matrix_scale(&mi, 1, 1.0 / sy, &mi);
384
8
            gs_matrix_scale(&pim3a.ImageMatrix, 1, 1.0 / sy, &pim3a.ImageMatrix);
385
8
        }
386
60
        gs_matrix_multiply(&mi, &pim3a.MaskDict.ImageMatrix, &pim3a.MaskDict.ImageMatrix);
387
60
        pim3a.imagematrices_are_untrustworthy = 1;
388
60
        pic1 = (gs_image_common_t *)&pim3a;
389
        /* Setting pdev->converting_image_matrix to communicate with pdf_image3_make_mcde. */
390
60
        gs_matrix_multiply(&mi, &ctm_only(pgs), &pdev->converting_image_matrix);
391
60
    }
392
    /*
393
     * We handle ImageType 3 images in a completely different way:
394
     * the default implementation sets up the enumerator.
395
     */
396
116
    return gx_begin_image3_generic((gx_device *)pdev, pgs, pmat1, pic1,
397
116
                                   prect, pdcolor, pcpath, mem,
398
116
                                   pdf_image3_make_mid,
399
116
                                   pdf_image3_make_mcde, pinfo);
400
117
}
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
24
{
411
    /* Try to convert the image to a plain masked image. */
412
24
    gx_drawing_color icolor;
413
24
    int code = 1;
414
415
24
    pdev->image_mask_is_SMask = false;
416
24
    if (pdf_convert_image4_to_image1(pdev, pgs, pdcolor,
417
24
                                     (const gs_image4_t *)pic,
418
24
                                     &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
24
    return code;
445
24
}
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
21
{
454
21
        gs_matrix m, m1, mi;
455
21
        gs_image4_t pi4 = *(const gs_image4_t *)pic;
456
21
        int code;
457
21
        pdf_lcvd_t *cvd = NULL;
458
459
21
        code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
460
21
        if (code < 0)
461
0
            return code;
462
21
        if (pdf_must_put_clip_path(pdev, pcpath))
463
20
            code = pdf_unclip(pdev);
464
1
        else
465
1
            code = pdf_open_page(pdev, PDF_IN_STREAM);
466
21
        if (code < 0)
467
0
            return code;
468
21
        code = pdf_put_clip_path(pdev, pcpath);
469
21
        if (code < 0)
470
0
            return code;
471
21
        gs_make_identity(&m1);
472
21
        code = gs_matrix_invert(&pic->ImageMatrix, &mi);
473
21
        if (code < 0)
474
0
            return code;
475
21
        gs_matrix_multiply(&mi, &ctm_only(pgs), &m);
476
21
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
477
21
                             true, 0, 0, pi4.Width, pi4.Height, false);
478
21
        if (code < 0)
479
0
            return code;
480
21
        cvd->mdev.is_open = true; /* fixme: same as above. */
481
21
        cvd->mask->is_open = true; /* fixme: same as above. */
482
21
        cvd->mask_is_empty = false;
483
21
        code = (*dev_proc(cvd->mask, fill_rectangle))((gx_device *)cvd->mask,
484
21
                    0, 0, cvd->mask->width, cvd->mask->height, (gx_color_index)0);
485
21
        if (code < 0)
486
0
            return code;
487
21
        gx_device_retain((gx_device *)cvd, true);
488
21
        gx_device_retain((gx_device *)cvd->mask, true);
489
21
        gs_make_identity(&pi4.ImageMatrix);
490
21
        code = gx_default_begin_typed_image((gx_device *)cvd,
491
21
            pgs, &m1, (gs_image_common_t *)&pi4, prect, pdcolor, NULL, mem, pinfo);
492
21
        if (code < 0)
493
0
            return code;
494
21
        (*pinfo)->procs = &pdf_image_cvd_enum_procs;
495
21
        return 0;
496
21
}
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.44k
{
501
1.44k
    int code;
502
1.44k
    gs_color_space *pcs_device = NULL;
503
504
1.44k
    cos_c_string_value(cs_value, sname);
505
1.44k
    *pcs_orig = image->pixel.ColorSpace;
506
1.44k
    code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
507
1.44k
    if (code < 0)
508
0
        return code;
509
1.44k
    image->pixel.ColorSpace = pcs_device;
510
1.44k
    return 0;
511
1.44k
}
512
513
static int check_colorants_for_pdfx4(const gs_color_space *pcs)
514
0
{
515
0
    int comp, all_present = 1;
516
0
    char *ink;
517
0
    gs_device_n_colorant *colorant = NULL;
518
519
0
    if (pcs->params.device_n.colorants == NULL) {
520
0
        return 0;
521
0
    } else {
522
0
        for (comp = 0; comp < pcs->params.device_n.num_components;comp++){
523
0
            colorant = pcs->params.device_n.colorants;
524
0
            ink = pcs->params.device_n.names[comp];
525
0
            do {
526
0
                if (memcmp(colorant->colorant_name, ink, strlen(ink)) == 0)
527
0
                    break;
528
0
                colorant = colorant->next;
529
0
            }while(colorant);
530
0
            if (!colorant) {
531
0
                all_present = 0;
532
0
                break;
533
0
            }
534
0
        }
535
0
    }
536
0
    return all_present;
537
0
}
538
/* 0 = write unchanged
539
   1 = convert to process
540
   2 = write as ICC
541
   3 = convert base space (Separation)
542
   4 = convert base space (DeviceN)
543
 */
544
static int setup_image_colorspace(gx_device_pdf *pdev, image_union_t *image, const gs_color_space *pcs, gs_color_space **pcs_orig,
545
                                  const pdf_color_space_names_t *names, cos_value_t *cs_value)
546
24.9k
{
547
24.9k
    int code=0;
548
24.9k
    gs_color_space_index csi;
549
24.9k
    gs_color_space_index csi2;
550
24.9k
    const gs_color_space *pcs2 = pcs;
551
552
24.9k
    csi = csi2 = gs_color_space_get_index(pcs);
553
24.9k
    if (csi == gs_color_space_index_ICC) {
554
22.0k
        csi2 = gsicc_get_default_type(pcs->cmm_icc_profile_data);
555
22.0k
    }
556
    /* Figure out what to do if we are outputting to really ancient versions of PDF */
557
    /* NB ps2write sets CompatibilityLevel to 1.2 so we cater for it here */
558
24.9k
    if (pdev->CompatibilityLevel <= 1.2) {
559
560
        /* If we have an /Indexed space, we need to look at the base space */
561
8.50k
        if (csi2 == gs_color_space_index_Indexed) {
562
1.51k
            pcs2 = pcs->base_space;
563
1.51k
            csi2 = gs_color_space_get_index(pcs2);
564
1.51k
        }
565
566
8.50k
        switch (csi2) {
567
498
            case gs_color_space_index_DeviceGray:
568
498
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
569
498
                    pdev->params.ColorConversionStrategy == ccs_Gray) {
570
498
                    return 0;
571
498
                }
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
5.18k
            case gs_color_space_index_DeviceRGB:
580
5.18k
                if (pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
581
0
                    pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB)
582
5.18k
                    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
85
            case gs_color_space_index_DeviceCMYK:
591
85
                if ((pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged ||
592
85
                    pdev->params.ColorConversionStrategy == ccs_CMYK) && !pdev->params.ConvertCMYKImagesToRGB)
593
85
                    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
8
            case gs_color_space_index_Separation:
606
8
                if (pdev->ForOPDFRead) {
607
8
                    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
8
                        case ccs_LeaveColorUnchanged:
613
8
                            if (csi2 == gs_color_space_index_Separation)
614
8
                                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
8
                    }
636
8
                }
637
0
                else
638
0
                    *pcs_orig = (gs_color_space *)pcs;
639
0
                return 1;
640
0
                break;
641
642
2.70k
            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.70k
                csi2 = gsicc_get_default_type(pcs2->cmm_icc_profile_data);
651
652
2.70k
                switch (csi2) {
653
2
                    case gs_color_space_index_DeviceGray:
654
2
                        if (pdev->params.ColorConversionStrategy == ccs_Gray ||
655
2
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
656
2
                            return 0;
657
0
                        break;
658
1.28k
                    case gs_color_space_index_DeviceRGB:
659
1.28k
                        if (pdev->params.ColorConversionStrategy == ccs_RGB || pdev->params.ColorConversionStrategy == ccs_sRGB ||
660
1.28k
                            pdev->params.ColorConversionStrategy == ccs_LeaveColorUnchanged)
661
1.28k
                            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.41k
                    default:
669
1.41k
                        break;
670
2.70k
                }
671
                /* Fall through for non-handled cases */
672
1.44k
            case gs_color_space_index_DeviceN:
673
1.44k
            case gs_color_space_index_DevicePixel:
674
1.44k
            case gs_color_space_index_Indexed:
675
1.44k
                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.44k
                    case gs_color_space_index_DeviceRGB:
680
1.44k
                        code = setup_image_process_colorspace(pdev, image, pcs_orig, names->DeviceRGB, cs_value);
681
1.44k
                        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.44k
                }
689
1.44k
                if (code < 0)
690
0
                    return code;
691
1.44k
                return 1;
692
0
                break;
693
0
            default:
694
0
                return (gs_note_error(gs_error_rangecheck));
695
0
                break;
696
8.50k
        }
697
16.4k
    } else {
698
16.4k
        int strategy = pdev->params.ColorConversionStrategy;
699
700
16.4k
        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
16.4k
        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
16.4k
            case ccs_LeaveColorUnchanged:
729
16.4k
                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
16.4k
        }
999
16.4k
    }
1000
0
    return 0;
1001
24.9k
}
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
87.4k
{
1010
87.4k
    int code = 0;
1011
87.4k
    gs_rect sbox, dbox, *Box;
1012
87.4k
    gs_point corners[4];
1013
87.4k
    gs_fixed_rect ibox;
1014
87.4k
    gs_matrix * pmat1 = (gs_matrix *)pmat;
1015
87.4k
    gs_matrix mat;
1016
1017
87.4k
    if (!pdev->Eps2Write)
1018
59.1k
        return 0;
1019
1020
28.2k
    if (!pdev->accumulating_charproc)
1021
27.0k
        Box = &pdev->BBox;
1022
1.18k
    else
1023
1.18k
        Box = &pdev->charproc_BBox;
1024
28.2k
    if (pmat1 == 0)
1025
28.2k
        pmat1 = (gs_matrix *)&ctm_only(pgs);
1026
28.2k
    if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 ||
1027
28.2k
        (code = gs_matrix_multiply(&mat, pmat1, &mat)) < 0)
1028
1
        goto exit;
1029
28.2k
    sbox.p.x = prect->p.x;
1030
28.2k
    sbox.p.y = prect->p.y;
1031
28.2k
    sbox.q.x = prect->q.x;
1032
28.2k
    sbox.q.y = prect->q.y;
1033
28.2k
    gs_bbox_transform_only(&sbox, &mat, corners);
1034
28.2k
    gs_points_bbox(corners, &dbox);
1035
28.2k
    ibox.p.x = float2fixed(dbox.p.x);
1036
28.2k
    ibox.p.y = float2fixed(dbox.p.y);
1037
28.2k
    ibox.q.x = float2fixed(dbox.q.x);
1038
28.2k
    ibox.q.y = float2fixed(dbox.q.y);
1039
28.2k
    if (pcpath != NULL &&
1040
26.7k
        !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y,
1041
26.7k
                                     ibox.q.x, ibox.q.y)
1042
28.2k
        ) {
1043
        /* Let the target do the drawing, but drive two triangles */
1044
        /* through the clipping path to get an accurate bounding box. */
1045
2.70k
        gx_device_clip cdev;
1046
2.70k
        gx_drawing_color devc;
1047
1048
2.70k
        fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y);
1049
2.70k
        fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0;
1050
1051
2.70k
        pdev->AccumulatingBBox++;
1052
2.70k
        gx_make_clip_device_on_stack(&cdev, pcpath, (gx_device *)pdev);
1053
2.70k
        set_nonclient_dev_color(&devc, gx_device_black((gx_device *)pdev));  /* any non-white color will do */
1054
2.70k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1055
2.70k
                                 float2fixed(corners[1].x) - x0,
1056
2.70k
                                 float2fixed(corners[1].y) - y0,
1057
2.70k
                                 bx2, by2, &devc, lop_default);
1058
2.70k
        gx_default_fill_triangle((gx_device *) & cdev, x0, y0,
1059
2.70k
                                 float2fixed(corners[3].x) - x0,
1060
2.70k
                                 float2fixed(corners[3].y) - y0,
1061
2.70k
                                 bx2, by2, &devc, lop_default);
1062
2.70k
        gx_destroy_clip_device_on_stack(&cdev);
1063
2.70k
        pdev->AccumulatingBBox--;
1064
25.5k
    } else {
1065
        /* Just use the bounding box. */
1066
25.5k
        float x0, y0, x1, y1;
1067
25.5k
        x0 = fixed2float(ibox.p.x) / (pdev->HWResolution[0] / 72.0);
1068
25.5k
        y0 = fixed2float(ibox.p.y) / (pdev->HWResolution[1] / 72.0);
1069
25.5k
        x1 = fixed2float(ibox.q.x) / (pdev->HWResolution[0] / 72.0);
1070
25.5k
        y1 = fixed2float(ibox.q.y) / (pdev->HWResolution[1] / 72.0);
1071
25.5k
        if (Box->p.x > x0)
1072
1.90k
            Box->p.x = x0;
1073
25.5k
        if (Box->p.y > y0)
1074
2.18k
            Box->p.y = y0;
1075
25.5k
        if (Box->q.x < x1)
1076
2.64k
            Box->q.x = x1;
1077
25.5k
        if (Box->q.y < y1)
1078
2.82k
            Box->q.y = y1;
1079
25.5k
    }
1080
28.2k
 exit:
1081
28.2k
    return code;
1082
28.2k
}
1083
1084
static int
1085
pdf_begin_typed_image(gx_device_pdf *pdev, const gs_gstate * pgs,
1086
                      const gs_matrix *pmat, const gs_image_common_t *pic,
1087
                      const gs_int_rect * prect,
1088
                      const gx_drawing_color * pdcolor,
1089
                      const gx_clip_path * pcpath, gs_memory_t * mem,
1090
                      gx_image_enum_common_t ** pinfo,
1091
                      pdf_typed_image_context_t context)
1092
93.8k
{
1093
93.8k
    int code = 0, i;
1094
93.8k
    unsigned int use_fallback  = 0, in_line = 0, is_mask = 0,
1095
93.8k
        force_lossless = 0, convert_to_process_colors = 0;
1096
93.8k
    int width, height;
1097
93.8k
    cos_dict_t *pnamed = 0;
1098
93.8k
    image_union_t *image;
1099
93.8k
    const gs_pixel_image_t *pim;
1100
93.8k
    gs_int_rect rect;
1101
93.8k
    gs_image_format_t format;
1102
93.8k
    gs_color_space *pcs = NULL;
1103
93.8k
    int num_components;
1104
93.8k
    pdf_image_enum *pie = NULL;
1105
93.8k
    const pdf_color_space_names_t *names;
1106
93.8k
    gs_color_space *pcs_orig = NULL;
1107
93.8k
    gs_color_space *pcs_device = NULL;
1108
93.8k
    cos_value_t cs_value;
1109
93.8k
    const gs_range_t *pranges = 0;
1110
1111
93.8k
    image = (image_union_t *)gs_malloc(mem->non_gc_memory, 4,
1112
93.8k
                       sizeof(image_union_t), "pdf_begin_typed_image(image)");
1113
93.8k
    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
93.8k
    {
1121
93.8k
        cos_value_t ni_value;
1122
1123
93.8k
        if (cos_array_unadd(pdev->NI_stack, &ni_value) >= 0)
1124
6
            pnamed = (cos_dict_t *)ni_value.contents.object;
1125
93.8k
    }
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
93.8k
    pdev->image_mask_id = gs_no_id;
1131
1132
93.8k
    pim = (const gs_pixel_image_t *)pic;
1133
1134
    /* Check for the image types we can handle. */
1135
93.8k
    switch (pic->type->index) {
1136
87.4k
    case 1:
1137
87.4k
        is_mask = ((const gs_image_t *)pic)->ImageMask;
1138
87.4k
        code = setup_type1_image(pdev, pic, pdcolor, image, context);
1139
87.4k
        if (code < 0)
1140
5
            use_fallback = 1;
1141
87.4k
        else
1142
87.4k
            in_line = code;
1143
87.4k
        break;
1144
1145
117
    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
117
        pdev->JPEG_PassThrough = 0;
1161
117
        pdev->JPX_PassThrough = 0;
1162
117
        pdev->image_mask_is_SMask = false;
1163
117
        if (pdev->CompatibilityLevel < 1.2 ||
1164
117
            (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
117
        code = setup_type3_image(pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo, image);
1171
117
        goto exit;
1172
1173
6.27k
    case IMAGE3X_IMAGETYPE:
1174
6.27k
        {
1175
6.27k
            char *OC = pdev->PendingOC;
1176
1177
6.27k
            pdev->JPEG_PassThrough = 0;
1178
6.27k
            pdev->JPX_PassThrough = 0;
1179
6.27k
            if (pdev->CompatibilityLevel < 1.4 ||
1180
6.27k
                (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
6.27k
            pdev->image_mask_is_SMask = true;
1187
1188
6.27k
            if (pdev->PendingOC)
1189
3
                gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
1190
6.27k
            OC = pdev->PendingOC = NULL;
1191
6.27k
            code = gx_begin_image3x_generic((gx_device *)pdev, pgs, pmat, pic,
1192
6.27k
                                            prect, pdcolor, pcpath, mem,
1193
6.27k
                                            pdf_image3x_make_mid,
1194
6.27k
                                            pdf_image3x_make_mcde, pinfo, OC);
1195
6.27k
            goto exit;
1196
6.27k
        }
1197
1198
24
    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
24
        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
24
        pdev->JPEG_PassThrough = 0;
1264
24
        pdev->JPX_PassThrough = 0;
1265
24
        code = convert_type4_image(pdev, pgs, pmat, pic, prect, pdcolor,
1266
24
                      pcpath, mem, pinfo, context, image, pnamed);
1267
24
        if (code < 0)
1268
0
            use_fallback = 1;
1269
24
        if (code == 0)
1270
0
            goto exit;
1271
        /* No luck.  Masked images require PDF 1.3 or higher. */
1272
24
        if (pdev->CompatibilityLevel < 1.2)
1273
0
            use_fallback = 1;
1274
24
        if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
1275
21
            use_fallback = 0;
1276
21
            code = convert_type4_to_masked_image(pdev, pgs, pic, prect, pdcolor,
1277
21
                                                 pcpath, mem,pinfo);
1278
21
            goto exit;
1279
21
        }
1280
3
        image[0].type4 = *(const gs_image4_t *)pic;
1281
3
        break;
1282
1283
0
    default:
1284
0
        use_fallback = 1;
1285
0
        break;
1286
93.8k
    }
1287
1288
87.4k
    format = pim->format;
1289
87.4k
    switch (format) {
1290
87.4k
    case gs_image_format_chunky:
1291
87.4k
    case gs_image_format_component_planar:
1292
87.4k
        break;
1293
0
    default:
1294
0
        use_fallback = 1;
1295
87.4k
    }
1296
    /* AR5 on Windows doesn't support 0-size images. Skipping. */
1297
87.4k
    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
87.4k
    switch (pim->BitsPerComponent) {
1301
57.0k
        case 1:
1302
57.3k
        case 2:
1303
57.4k
        case 4:
1304
87.4k
        case 8:
1305
87.4k
        case 12:
1306
87.4k
        case 16:
1307
87.4k
            break;
1308
0
        default:
1309
0
            code = gs_note_error(gs_error_rangecheck);
1310
0
            goto exit;
1311
87.4k
    }
1312
87.4k
    if (prect)
1313
6.31k
        rect = *prect;
1314
81.1k
    else {
1315
81.1k
        rect.p.x = rect.p.y = 0;
1316
81.1k
        rect.q.x = pim->Width, rect.q.y = pim->Height;
1317
81.1k
    }
1318
87.4k
    if (rect.p.x != 0 || rect.p.y != 0 ||
1319
87.4k
        rect.q.x != pim->Width || rect.q.y != pim->Height ||
1320
87.4k
        (is_mask && pim->CombineWithColor))
1321
0
        use_fallback = 1;
1322
1323
    /* Handle BBox for Eps2Write, if applicable */
1324
87.4k
    code = pdf_image_handle_eps(pdev, pgs, pmat, pic, &rect, pcpath);
1325
87.4k
    if (code < 0) {
1326
1
        use_fallback = 0;
1327
1
        goto exit;
1328
1
    }
1329
1330
87.4k
    if (use_fallback)
1331
9
        goto exit;
1332
1333
87.4k
    pcs = pim->ColorSpace;
1334
87.4k
    rc_increment_cs(pcs);
1335
87.4k
    num_components = (is_mask ? 1 : gs_color_space_num_components(pcs));
1336
1337
87.4k
    code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
1338
87.4k
    if (code < 0)
1339
0
        goto exit;
1340
87.4k
    if (pdf_must_put_clip_path(pdev, pcpath))
1341
11.5k
        code = pdf_unclip(pdev);
1342
75.9k
    else
1343
75.9k
        code = pdf_open_page(pdev, PDF_IN_STREAM);
1344
87.4k
    if (code < 0)
1345
0
        goto fail_and_fallback;
1346
1347
87.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
6.31k
        rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1355
6.31k
        pcs = gs_cspace_new_DeviceGray(pdev->memory);
1356
6.31k
        if (pcs == NULL)
1357
0
            code = gs_note_error(gs_error_VMerror);
1358
81.1k
    } else if (is_mask)
1359
56.0k
        code = pdf_prepare_imagemask(pdev, pgs, pdcolor);
1360
25.0k
    else
1361
25.0k
        code = pdf_prepare_image(pdev, pgs);
1362
87.4k
    if (code < 0)
1363
192
        goto fail_and_fallback;
1364
1365
87.2k
    pie = gs_alloc_struct(mem, pdf_image_enum, &st_pdf_image_enum,
1366
87.2k
                        "pdf_begin_image");
1367
87.2k
    if (pie == 0) {
1368
0
        code = gs_note_error(gs_error_VMerror);
1369
0
        goto exit;
1370
0
    }
1371
87.2k
    memset(pie, 0, sizeof(*pie)); /* cleanup entirely for GC to work in all cases. */
1372
87.2k
    *pinfo = (gx_image_enum_common_t *) pie;
1373
87.2k
    gx_image_enum_common_init(*pinfo, (const gs_data_image_t *) pim,
1374
87.2k
                    ((pdev->CompatibilityLevel >= 1.3) ?
1375
54.9k
                            (context == PDF_IMAGE_TYPE3_MASK ?
1376
6.31k
                            &pdf_image_object_enum_procs :
1377
54.9k
                            &pdf_image_enum_procs) :
1378
87.2k
                            context == PDF_IMAGE_TYPE3_MASK ?
1379
0
                            &pdf_image_object_enum_procs :
1380
32.2k
                            context == PDF_IMAGE_TYPE3_DATA ?
1381
0
                            &pdf_image_object_enum_procs2 :
1382
32.2k
                            &pdf_image_enum_procs),
1383
87.2k
                        (gx_device *)pdev, num_components, format);
1384
87.2k
    pie->memory = mem;
1385
87.2k
    pie->pgs = pgs;
1386
87.2k
    if (pgs != NULL)
1387
87.1k
        pie->pgs_level = pgs->level;
1388
87.2k
    width = rect.q.x - rect.p.x;
1389
87.2k
    pie->width = width;
1390
87.2k
    height = rect.q.y - rect.p.y;
1391
87.2k
    pie->bits_per_pixel =
1392
87.2k
        pim->BitsPerComponent * num_components / pie->num_planes;
1393
87.2k
    pie->rows_left = height;
1394
87.2k
    if (pnamed != 0 || pdev->PendingOC) /* Don't in-line the image if it is named. Or has Optional Content */
1395
25
        in_line = false;
1396
87.2k
    else {
1397
87.2k
        int64_t nbytes = (int64_t)(((int64_t) pie->width * pie->bits_per_pixel + 7) >> 3) *
1398
87.2k
            pie->num_planes * pie->rows_left;
1399
1400
87.2k
        in_line &= (nbytes < pdev->MaxInlineImageSize);
1401
87.2k
    }
1402
87.2k
    pie->initial_colorspace = pdev->pcm_color_info_index;
1403
1404
87.2k
    if (pmat == 0)
1405
74.6k
        pmat = &ctm_only(pgs);
1406
87.2k
    {
1407
87.2k
        gs_matrix mat;
1408
87.2k
        gs_matrix bmat;
1409
87.2k
        int code;
1410
1411
87.2k
        pdf_make_bitmap_matrix(&bmat, -rect.p.x, -rect.p.y,
1412
87.2k
                               pim->Width, pim->Height, height);
1413
87.2k
        if ((code = gs_matrix_invert(&pim->ImageMatrix, &mat)) < 0 ||
1414
87.2k
            (code = gs_matrix_multiply(&bmat, &mat, &mat)) < 0 ||
1415
87.2k
            (code = gs_matrix_multiply(&mat, pmat, &pie->mat)) < 0
1416
87.2k
            )
1417
1
            goto exit;
1418
        /* AR3,AR4 show no image when CTM is singular; AR5 reports an error */
1419
87.2k
        if (pie->mat.xx * pie->mat.yy == pie->mat.xy * pie->mat.yx) {
1420
458
            use_fallback = 1;
1421
458
            goto fail_and_fallback;
1422
458
        }
1423
87.2k
    }
1424
1425
86.7k
    code = pdf_put_clip_path(pdev, pcpath);
1426
86.7k
    if (code < 0)
1427
0
        goto exit;
1428
86.7k
    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
86.7k
    pie->writer.alt_writer_count = (in_line ||
1438
20.4k
                                    (pim->Width <= 64 && pim->Height <= 64)
1439
86.7k
                                    ? 1 : 2);
1440
86.7k
    if ((image[0].pixel.ColorSpace != NULL &&
1441
31.1k
        image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed
1442
2.85k
        && pdev->params.ColorImage.DownsampleType != ds_Subsample) ||
1443
85.4k
        pdev->transfer_not_identity)
1444
1.36k
        force_lossless = true;
1445
1446
86.7k
    if ((image[0].pixel.ColorSpace != NULL && image[0].pixel.ColorSpace->type->index == gs_color_space_index_Indexed)
1447
83.9k
        || force_lossless)
1448
2.87k
        pie->writer.alt_writer_count = 1;
1449
1450
86.7k
    if (image[0].pixel.ColorSpace != NULL && (image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceGray &&
1451
31.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceRGB &&
1452
31.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_DeviceCMYK &&
1453
31.1k
        image[0].pixel.ColorSpace->type->index != gs_color_space_index_Indexed))
1454
28.3k
        names = &pdf_color_space_names;
1455
58.4k
    else
1456
58.4k
        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
86.7k
    if (!is_mask) {
1460
31.1k
#if 1
1461
31.1k
        if (image[0].pixel.ColorSpace != NULL && !(context == PDF_IMAGE_TYPE3_MASK))
1462
24.9k
           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
31.1k
        if (pim->BitsPerComponent > 8 && convert_to_process_colors) {
1483
0
            use_fallback = 1;
1484
0
            goto fail_and_fallback;
1485
0
        }
1486
31.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
31.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
31.1k
        if (convert_to_process_colors == 1) {
1502
1.44k
            code = make_device_color_space(pdev, pdev->pcm_color_info_index, &pcs_device);
1503
1.44k
            if (code < 0)
1504
0
                goto fail_and_fallback;
1505
1.44k
            image[0].pixel.ColorSpace = pcs_device;
1506
1.44k
            image[0].pixel.BitsPerComponent = 8;
1507
1.44k
            code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs_device, names,
1508
1.44k
                                     in_line, NULL, 0, false);
1509
1.44k
            if (code < 0)
1510
0
                goto fail_and_fallback;
1511
29.7k
        } else {
1512
29.7k
            if (convert_to_process_colors == 2) {
1513
0
                convert_to_process_colors = 0;
1514
0
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1515
0
                                     in_line, NULL, 0, true);
1516
0
                if (code < 0)
1517
0
                    goto fail_and_fallback;
1518
29.7k
            } else {
1519
29.7k
                convert_to_process_colors = 0;
1520
29.7k
                code = pdf_color_space_named(pdev, pgs, &cs_value, &pranges, pcs, names,
1521
29.7k
                                     in_line, NULL, 0, false);
1522
29.7k
                if (code < 0)
1523
0
                    goto fail_and_fallback;
1524
29.7k
            }
1525
29.7k
        }
1526
31.1k
    }
1527
1528
86.7k
    image[1] = image[0];
1529
1530
86.7k
    pdev->ParamCompatibilityLevel = pdev->CompatibilityLevel;
1531
1532
86.7k
    code = pdf_begin_write_image(pdev, &pie->writer, gs_no_id, width,
1533
86.7k
                    height, pnamed, in_line);
1534
86.7k
    if (code < 0)
1535
0
        goto fail_and_fallback;
1536
1537
86.7k
    if (pdev->CompatibilityLevel < 1.5)
1538
32.1k
        pdev->JPX_PassThrough = 0;
1539
1540
86.7k
    if (!convert_to_process_colors)
1541
85.3k
    {
1542
85.3k
        gs_color_space_index csi;
1543
1544
85.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
85.3k
    }
1595
    /* If we are not preserving the colour space unchanged, then we can't pass through JPEG */
1596
1.44k
    else
1597
1.44k
        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
86.7k
    if (in_line) {
1611
66.3k
        pdev->JPEG_PassThrough = 0;
1612
66.3k
        pdev->JPX_PassThrough = 0;
1613
66.3k
        code = new_setup_lossless_filters((gx_device_psdf *) pdev,
1614
66.3k
                                             &pie->writer.binary[0],
1615
66.3k
                                             &image[0].pixel, in_line, convert_to_process_colors, (gs_matrix *)pmat, (gs_gstate *)pgs);
1616
66.3k
    } else {
1617
20.4k
        if (force_lossless) {
1618
            /*
1619
             * Some regrettable PostScript code (such as LanguageLevel 1 output
1620
             * from Microsoft's PSCRIPT.DLL driver) misuses the transfer
1621
             * function to accomplish the equivalent of indexed color.
1622
             * Downsampling (well, only averaging) or JPEG compression are not
1623
             * compatible with this.  Play it safe by using only lossless
1624
             * filters if the transfer function(s) is/are other than the
1625
             * identity and by setting the downsample type to Subsample..
1626
             */
1627
1.14k
            int saved_downsample = pdev->params.ColorImage.DownsampleType;
1628
1629
1.14k
            pdev->params.ColorImage.DownsampleType = ds_Subsample;
1630
1.14k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1631
1.14k
                                          &pie->writer.binary[0], &image[0].pixel,
1632
1.14k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1633
1.14k
            pdev->params.ColorImage.DownsampleType = saved_downsample;
1634
19.3k
        } else {
1635
19.3k
            code = new_setup_image_filters((gx_device_psdf *) pdev,
1636
19.3k
                                          &pie->writer.binary[0], &image[0].pixel,
1637
19.3k
                                          pmat, pgs, true, in_line, convert_to_process_colors);
1638
19.3k
        }
1639
20.4k
    }
1640
1641
86.7k
    if (code < 0)
1642
1
        goto fail_and_fallback;
1643
1644
86.7k
    if (convert_to_process_colors) {
1645
1.44k
        image[0].pixel.ColorSpace = pcs_orig;
1646
1.44k
        image[0].pixel.BitsPerComponent = pim->BitsPerComponent;
1647
1.44k
        code = psdf_setup_image_colors_filter(&pie->writer.binary[0],
1648
1.44k
                                              (gx_device_psdf *)pdev, pim, &image[0].pixel, pgs);
1649
1.44k
        if (code < 0)
1650
0
            goto fail_and_fallback;
1651
1.44k
        image[0].pixel.ColorSpace = pcs_device;
1652
1.44k
    }
1653
1654
86.7k
    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
5.43k
        pdev->PassThroughWriter = pie->writer.binary[0].strm;
1661
5.43k
        pie->writer.alt_writer_count = 1;
1662
5.43k
    }
1663
86.7k
    pie->JPEG_PassThrough = pdev->JPEG_PassThrough;
1664
86.7k
    pie->JPX_PassThrough = pdev->JPX_PassThrough;
1665
1666
86.7k
    if (pie->writer.alt_writer_count > 1) {
1667
13.1k
        code = pdf_make_alt_stream(pdev, &pie->writer.binary[1]);
1668
13.1k
        if (code < 0)
1669
0
            goto fail_and_fallback;
1670
13.1k
        code = new_setup_image_filters((gx_device_psdf *) pdev,
1671
13.1k
                                  &pie->writer.binary[1], &image[1].pixel,
1672
13.1k
                                  pmat, pgs, force_lossless, in_line, convert_to_process_colors);
1673
13.1k
        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
13.1k
        } else if (code) {
1693
0
            goto fail_and_fallback;
1694
13.1k
        } 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
13.1k
    }
1704
1705
186k
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1706
99.8k
        code = pdf_begin_image_data_decoded(pdev, num_components, pranges, i,
1707
99.8k
                             &image[i].pixel, &cs_value, pie);
1708
99.8k
        if (code < 0)
1709
0
            goto fail_and_fallback;
1710
99.8k
    }
1711
86.7k
    if (pie->writer.alt_writer_count == 2) {
1712
13.1k
        psdf_setup_compression_chooser(&pie->writer.binary[2],
1713
13.1k
             (gx_device_psdf *)pdev, pim->Width, pim->Height,
1714
13.1k
             num_components, pim->BitsPerComponent);
1715
13.1k
        pie->writer.alt_writer_count = 3;
1716
13.1k
    }
1717
86.7k
    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
86.7k
    code = 0;
1751
1752
    /* This label is used when code < 0 and we want to do the fallback code */
1753
87.4k
 fail_and_fallback:
1754
87.4k
    if (code != 0)
1755
193
        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
93.8k
 exit:
1762
    /* Free everything */
1763
93.8k
    rc_decrement(pcs, "pdf_begin_typed_image(pcs)");
1764
93.8k
    rc_decrement(pcs_device, "pdf_begin_typed_image(pcs_device)");
1765
93.8k
    gs_free(mem->non_gc_memory, image, 4, sizeof(image_union_t),
1766
93.8k
                                      "pdf_begin_typed_image(image)");
1767
1768
    /* Free pie only if there was an error or we are falling back */
1769
93.8k
    if (code < 0 || use_fallback) {
1770
699
        if (pie)
1771
459
            gs_free_object(mem, pie, "pdf_begin_typed_image(pie)");
1772
699
        *pinfo = NULL;
1773
699
    }
1774
    /* Do the fallback */
1775
93.8k
    if (use_fallback) {
1776
660
        pdev->JPEG_PassThrough = 0;
1777
660
        pdev->JPX_PassThrough = 0;
1778
660
        code = gx_default_begin_typed_image
1779
660
            ((gx_device *)pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo);
1780
660
    }
1781
93.8k
    return code;
1782
87.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
81.2k
{
1792
81.2k
    return pdf_begin_typed_image((gx_device_pdf *)dev, pgs, pmat, pic, prect,
1793
81.2k
                                 pdcolor, pcpath, mem, pinfo,
1794
81.2k
                                 PDF_IMAGE_DEFAULT);
1795
81.2k
}
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
8.91M
{
1805
8.91M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1806
8.91M
    int h = height;
1807
8.91M
    int y;
1808
    /****** DOESN'T HANDLE IMAGES WITH VARYING WIDTH PER PLANE ******/
1809
8.91M
    uint width_bits = pie->width * pie->plane_depths[0];
1810
    /****** DOESN'T HANDLE NON-ZERO data_x CORRECTLY ******/
1811
8.91M
    uint ignore;
1812
8.91M
    int nplanes = pie->num_planes;
1813
8.91M
    int status = 0;
1814
8.91M
    uint bcount = (width_bits + 7) >> 3;
1815
1816
8.91M
    if (h > pie->rows_left)
1817
53.9k
        h = pie->rows_left;
1818
19.7M
    for (y = 0; y < h; ++y) {
1819
10.8M
        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
10.8M
        } else {
1866
10.8M
            status = sputs(pie->writer.binary[alt_writer_index].strm,
1867
10.8M
                           planes[0].data + planes[0].raster * y, bcount,
1868
10.8M
                           &ignore);
1869
10.8M
        }
1870
10.8M
        if (status < 0)
1871
0
            break;
1872
10.8M
    }
1873
8.91M
    *rows_used = h;
1874
8.91M
    if (status < 0)
1875
0
        return_error(gs_error_ioerror);
1876
8.91M
    return !pie->rows_left;
1877
8.91M
#undef ROW_BYTES
1878
8.91M
}
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
7.04M
{
1885
7.04M
    pdf_image_enum *pie = (pdf_image_enum *) info;
1886
7.04M
    int i;
1887
1888
7.04M
    if (info->pgs != NULL && info->pgs->level < info->pgs_level)
1889
0
        return_error(gs_error_undefinedresult);
1890
1891
7.04M
    if (pie->JPEG_PassThrough || pie->JPX_PassThrough) {
1892
309k
        pie->rows_left -= height;
1893
309k
        *rows_used = height;
1894
309k
        return !pie->rows_left;
1895
309k
    }
1896
1897
15.6M
    for (i = 0; i < pie->writer.alt_writer_count; i++) {
1898
8.91M
        int code = pdf_image_plane_data_alt(info, planes, height, rows_used, i);
1899
8.91M
        if (code)
1900
0
            return code;
1901
8.91M
    }
1902
6.73M
    pie->rows_left -= *rows_used;
1903
6.73M
    if (pie->writer.alt_writer_count > 2)
1904
1.09M
        pdf_choose_compression(&pie->writer, false);
1905
1906
6.73M
    return !pie->rows_left;
1907
6.73M
}
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
82.3k
{
2001
82.3k
    int code = 0;
2002
82.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
82.3k
    if (do_image == USE_AS_IMAGE) {
2010
76.3k
        if (pdev->image_mask_id != gs_no_id && piw->pres && piw->pres->object) {
2011
5.93k
            char buf[20];
2012
2013
5.93k
            gs_snprintf(buf, sizeof(buf), "%ld 0 R", pdev->image_mask_id);
2014
5.93k
            code = cos_dict_put_string_copy((cos_dict_t *)piw->pres->object,
2015
5.93k
                    pdev->image_mask_is_SMask ? "/SMask" : "/Mask", buf);
2016
5.93k
            (*(piw->pres->object)).md5_valid = 0;
2017
5.93k
            if (code < 0)
2018
0
                return code;
2019
5.93k
        }
2020
76.3k
    }
2021
2022
82.3k
    code = pdf_end_write_image(pdev, piw);
2023
82.3k
    pres = piw->pres;
2024
2025
82.3k
    switch (code) {
2026
0
    default:
2027
0
        return code; /* error */
2028
64.5k
    case 1:
2029
64.5k
        code = 0;
2030
64.5k
        break;
2031
17.8k
    case 0:
2032
17.8k
        if (do_image == USE_AS_IMAGE) {
2033
11.8k
            if (pdev->image_mask_skip)
2034
0
                code = 0;
2035
11.8k
            else
2036
11.8k
                code = pdf_do_image(pdev, pres, mat, true);
2037
11.8k
        } 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
5.93k
            const pdf_x_object_t *const pxo = (const pdf_x_object_t *)pres;
2042
2043
5.93k
            pdev->image_mask_scale = (double)pxo->data_height / pxo->height;
2044
5.93k
            pdev->image_mask_id = pdf_resource_id(pres);
2045
5.93k
            pdev->converting_image_matrix = *mat;
2046
5.93k
        } else if (do_image == USE_AS_PATTERN)
2047
0
            code = use_image_as_pattern(pdev, pres, mat, ps_bitmap_id);
2048
82.3k
    }
2049
82.3k
    return code;
2050
82.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
86.7k
{
2057
86.7k
    gx_device_pdf *pdev = (gx_device_pdf *)info->dev;
2058
86.7k
    pdf_image_enum *pie = (pdf_image_enum *)info;
2059
86.7k
    int height = pie->writer.height;
2060
86.7k
    int data_height = height - pie->rows_left;
2061
86.7k
    int code = 0, ecode;
2062
2063
86.7k
    if (pie->writer.pres)
2064
20.4k
        ((pdf_x_object_t *)pie->writer.pres)->data_height = data_height;
2065
66.3k
    else if (data_height > 0)
2066
64.5k
        pdf_put_image_matrix(pdev, &pie->mat, (double)data_height / height);
2067
86.7k
    if (data_height > 0) {
2068
82.3k
        if (pie->writer.pres) {
2069
17.8k
            code = pdf_complete_image_data(pdev, &pie->writer, data_height,
2070
17.8k
                        pie->width, pie->bits_per_pixel);
2071
17.8k
            if (code < 0)
2072
0
                return code;
2073
17.8k
        }
2074
82.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
82.3k
        if (code < 0)
2077
0
            return code;
2078
82.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
82.3k
            code = pdf_end_and_do_image(pdev, &pie->writer, &pie->mat, info->id, do_image);
2098
82.3k
        pie->writer.alt_writer_count--; /* For GC. */
2099
82.3k
    } else {
2100
        /* This closes the stream pointed to by PassThroughWriter
2101
           so we need to NULL that pointer
2102
         */
2103
4.45k
        code = pdf_end_image_binary(pdev, &pie->writer, data_height);
2104
4.45k
        pdev->PassThroughWriter = NULL;
2105
4.45k
        pdev->JPX_PassThrough = false;
2106
4.45k
        pdev->JPEG_PassThrough = false;
2107
4.45k
        code = pdf_end_abort_image(pdev, &pie->writer);
2108
4.45k
        pie->writer.alt_writer_count--; /* For GC. */
2109
4.45k
    }
2110
86.7k
    if (pie->initial_colorspace != pdev->pcm_color_info_index)
2111
0
        pdf_set_process_color_model(pdev, pie->initial_colorspace);
2112
2113
    /* Clean up any outstanding streams before freeing the enumerator */
2114
86.7k
    while (pie->writer.alt_writer_count-- > 0) {
2115
0
        ecode = psdf_end_binary(&(pie->writer.binary[pie->writer.alt_writer_count]));
2116
        /* If we are skipping an image (because its clipped out or similar) then we
2117
         * won't have written any data to it. Some filters (notably the DCTEncode filter)
2118
         * throw an error (premature EOD) if we close the filter without writing any data to it.
2119
         * So if we are skipping the image, ignore errors when closing the stream.
2120
         * Unfortunately we don't set pie->skipping until after begin_typed_image()
2121
         * or we could avoid a lot of setup....
2122
         */
2123
0
        if (ecode < 0 && code >= 0 && !pie->skipping) code  = ecode;
2124
0
    }
2125
2126
86.7k
    gx_image_free_enum(&info);
2127
86.7k
    return code;
2128
86.7k
}
2129
2130
/* End a normal image, drawing it. */
2131
static int
2132
pdf_image_end_image(gx_image_enum_common_t * info, bool draw_last)
2133
80.4k
{
2134
80.4k
    return pdf_image_end_image_data(info, draw_last, USE_AS_IMAGE);
2135
80.4k
}
2136
2137
/* End an image converted with pdf_lcvd_t. */
2138
static int
2139
pdf_image_end_image_cvd(gx_image_enum_common_t * info, bool draw_last)
2140
21
{   pdf_lcvd_t *cvd = (pdf_lcvd_t *)info->dev;
2141
21
    int code = pdf_dump_converted_image(cvd->pdev, cvd, 0);
2142
21
    int code1 = gx_image1_end_image(info, draw_last);
2143
21
    int code2 = gs_closedevice((gx_device *)cvd->mask);
2144
21
    int code3 = gs_closedevice((gx_device *)cvd);
2145
2146
21
    gs_free_object(cvd->mask->memory, (gx_device *)cvd->mask, "pdf_image_end_image_cvd");
2147
21
    gs_free_object(cvd->mdev.memory, (gx_device *)cvd, "pdf_image_end_image_cvd");
2148
21
    return code < 0 ? code : code1 < 0 ? code1 : code2 < 0 ? code2 : code3;
2149
21
}
2150
/* ---------------- Type 3/3x images ---------------- */
2151
2152
/*
2153
 * For both types of masked images, we create temporary dummy (null) devices
2154
 * that forward the begin_typed_image call to the implementation above.
2155
 */
2156
static int
2157
pdf_make_mxd(gx_device **pmxdev, gx_device *tdev, gs_memory_t *mem)
2158
12.6k
{
2159
12.6k
    gx_device *fdev;
2160
12.6k
    int code = gs_copydevice(&fdev, (const gx_device *)&gs_null_device, mem);
2161
2162
12.6k
    if (code < 0)
2163
0
        return code;
2164
12.6k
    gx_device_set_target((gx_device_forward *)fdev, tdev);
2165
12.6k
    *pmxdev = fdev;
2166
12.6k
    return 0;
2167
12.6k
}
2168
2169
/* End the mask of an ImageType 3 image, not drawing it. */
2170
static int
2171
pdf_image_end_image_object(gx_image_enum_common_t * info, bool draw_last)
2172
6.29k
{
2173
6.29k
    return pdf_image_end_image_data(info, draw_last, USE_AS_MASK);
2174
6.29k
}
2175
/* End the data of an ImageType 3 image, converting it into pattern. */
2176
static int
2177
pdf_image_end_image_object2(gx_image_enum_common_t * info, bool draw_last)
2178
0
{
2179
0
    return pdf_image_end_image_data(info, draw_last, USE_AS_PATTERN);
2180
0
}
2181
2182
/* ---------------- Type 3 images ---------------- */
2183
2184
/* Implement the mask image device. */
2185
static dev_proc_begin_typed_image(pdf_mid_begin_typed_image);
2186
static int
2187
pdf_image3_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2188
                    gs_memory_t *mem)
2189
113
{
2190
113
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2191
2192
113
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2193
57
        gs_matrix m;
2194
57
        pdf_lcvd_t *cvd = NULL;
2195
57
        int code;
2196
2197
57
        gs_make_identity(&m);
2198
57
        code = pdf_setup_masked_image_converter(pdev, mem, &m, &cvd,
2199
57
                                        true, 0, 0, width, height, true);
2200
57
        if (code < 0)
2201
0
            return code;
2202
57
        cvd->mask->target = (gx_device *)cvd; /* Temporary, just to communicate with
2203
                                         pdf_image3_make_mcde. The latter will reset it. */
2204
57
        cvd->mask_is_empty = false;
2205
57
        *pmidev = (gx_device *)cvd->mask;
2206
57
        return 0;
2207
57
    } else {
2208
56
        int code = pdf_make_mxd(pmidev, dev, mem);
2209
2210
56
        if (code < 0)
2211
0
            return code;
2212
56
        set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2213
56
        return 0;
2214
56
    }
2215
113
}
2216
static int
2217
pdf_mid_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
2218
                          const gs_matrix *pmat, const gs_image_common_t *pic,
2219
                          const gs_int_rect * prect,
2220
                          const gx_drawing_color * pdcolor,
2221
                          const gx_clip_path * pcpath, gs_memory_t * mem,
2222
                          gx_image_enum_common_t ** pinfo)
2223
6.31k
{
2224
    /* The target of the null device is the pdfwrite device. */
2225
6.31k
    gx_device_pdf *const pdev = (gx_device_pdf *)
2226
6.31k
        ((gx_device_null *)dev)->target;
2227
6.31k
    return pdf_begin_typed_image
2228
6.31k
        (pdev, pgs, pmat, pic, prect, pdcolor, pcpath, mem, pinfo,
2229
6.31k
         PDF_IMAGE_TYPE3_MASK);
2230
6.31k
}
2231
2232
/* Implement the mask clip device. */
2233
static int
2234
pdf_image3_make_mcde(gx_device *dev, const gs_gstate *pgs,
2235
                     const gs_matrix *pmat, const gs_image_common_t *pic,
2236
                     const gs_int_rect *prect, const gx_drawing_color *pdcolor,
2237
                     const gx_clip_path *pcpath, gs_memory_t *mem,
2238
                     gx_image_enum_common_t **pinfo,
2239
                     gx_device **pmcdev, gx_device *midev,
2240
                     gx_image_enum_common_t *pminfo,
2241
                     const gs_int_point *origin)
2242
113
{
2243
113
    int code;
2244
113
    gx_device_pdf *pdev = (gx_device_pdf *)dev;
2245
2246
113
    if (pdev->CompatibilityLevel < 1.3 && !pdev->PatternImagemask) {
2247
        /* pdf_image3_make_mid must set midev with a pdf_lcvd_t instance.*/
2248
57
        pdf_lcvd_t *cvd = (pdf_lcvd_t *)((gx_device_memory *)midev)->target;
2249
2250
57
        ((gx_device_memory *)midev)->target = NULL;
2251
57
        cvd->m = pdev->converting_image_matrix;
2252
57
        cvd->mdev.mapped_x = origin->x;
2253
57
        cvd->mdev.mapped_y = origin->y;
2254
57
        cvd->mdev.width += origin->x;
2255
57
        cvd->mdev.height += origin->y;
2256
57
        *pmcdev = (gx_device *)&cvd->mdev;
2257
57
        code = gx_default_begin_typed_image
2258
57
            ((gx_device *)&cvd->mdev, pgs, pmat, pic, prect, pdcolor, NULL, mem,
2259
57
            pinfo);
2260
57
        if (code < 0)
2261
0
            return code;
2262
57
    } else {
2263
56
        code = pdf_make_mxd(pmcdev, midev, mem);
2264
56
        if (code < 0)
2265
0
            return code;
2266
56
        code = pdf_begin_typed_image
2267
56
            ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2268
56
            pinfo, PDF_IMAGE_TYPE3_DATA);
2269
56
        if (code < 0) {
2270
0
            gx_device_set_target((gx_device_forward *)(*pmcdev), NULL);
2271
0
            gs_closedevice((*pmcdev));
2272
0
            gs_free_object(mem, (*pmcdev), "pdf_image3_make_mcde(*pmcdev)");
2273
0
            *pmcdev = NULL;
2274
0
            return code;
2275
0
        }
2276
56
    }
2277
    /* Due to equal image merging, we delay the adding of the "Mask" entry into
2278
       a type 3 image dictionary until the mask is completed.
2279
       Will do in pdf_end_and_do_image.*/
2280
113
    return 0;
2281
113
}
2282
2283
/* ---------------- Type 3x images ---------------- */
2284
2285
/* Implement the mask image device. */
2286
static int
2287
pdf_image3x_make_mid(gx_device **pmidev, gx_device *dev, int width, int height,
2288
                     int depth, gs_memory_t *mem)
2289
6.25k
{
2290
6.25k
    int code = pdf_make_mxd(pmidev, dev, mem);
2291
2292
6.25k
    if (code < 0)
2293
0
        return code;
2294
6.25k
    set_dev_proc(*pmidev, begin_typed_image, pdf_mid_begin_typed_image);
2295
6.25k
    return 0;
2296
6.25k
}
2297
2298
/* Implement the mask clip device. */
2299
static int
2300
pdf_image3x_make_mcde(gx_device *dev, const gs_gstate *pgs,
2301
                      const gs_matrix *pmat, const gs_image_common_t *pic,
2302
                      const gs_int_rect *prect,
2303
                      const gx_drawing_color *pdcolor,
2304
                      const gx_clip_path *pcpath, gs_memory_t *mem,
2305
                      gx_image_enum_common_t **pinfo,
2306
                      gx_device **pmcdev, gx_device *midev[2],
2307
                      gx_image_enum_common_t *pminfo[2],
2308
                      const gs_int_point origin[2],
2309
                      const gs_image3x_t *pim)
2310
6.25k
{
2311
6.25k
    int code;
2312
6.25k
    pdf_image_enum *pmie;
2313
6.25k
    int i;
2314
6.25k
    const gs_image3x_mask_t *pixm;
2315
6.25k
    gx_device_pdf *pdf_dev = (gx_device_pdf *)dev;
2316
2317
6.25k
    if (midev[0]) {
2318
6.24k
        if (midev[1])
2319
0
            return_error(gs_error_rangecheck);
2320
6.24k
        i = 0, pixm = &pim->Opacity;
2321
6.24k
    } else if (midev[1])
2322
8
        i = 1, pixm = &pim->Shape;
2323
0
    else
2324
0
        return_error(gs_error_rangecheck);
2325
6.25k
    code = pdf_make_mxd(pmcdev, midev[i], mem);
2326
6.25k
    if (code < 0)
2327
0
        return code;
2328
2329
6.25k
    if (pminfo[0] != NULL)
2330
6.24k
        pdf_dev->PendingOC = pminfo[0]->OC;
2331
8
    else
2332
8
        pdf_dev->PendingOC = 0;
2333
2334
6.25k
    code = pdf_begin_typed_image
2335
6.25k
        ((gx_device_pdf *)dev, pgs, pmat, pic, prect, pdcolor, pcpath, mem,
2336
6.25k
         pinfo, PDF_IMAGE_TYPE3_DATA);
2337
6.25k
    pdf_dev->PendingOC = 0;
2338
6.25k
    if (code < 0) {
2339
0
        rc_decrement(*pmcdev, "pdf_image3x_make_mcde");
2340
0
        return code;
2341
0
    }
2342
6.25k
    if ((*pinfo)->procs != &pdf_image_enum_procs) {
2343
        /* We couldn't handle the image.  Bail out. */
2344
12
        gx_image_end(*pinfo, false);
2345
12
        gs_free_object(mem, *pmcdev, "pdf_image3x_make_mcde");
2346
12
        return_error(gs_error_rangecheck);
2347
12
    }
2348
6.24k
    pmie = (pdf_image_enum *)pminfo[i];
2349
    /*
2350
     * Add the SMask entry to the image dictionary, and, if needed,
2351
     * the Matte entry to the mask dictionary.
2352
     */
2353
6.24k
    if (pixm->has_Matte) {
2354
4
        gx_device_pdf *pdev = (gx_device_pdf *)dev;
2355
4
        int DoMatte = 0, num_components =
2356
4
            gs_color_space_num_components(pim->ColorSpace);
2357
2358
4
        switch (pdev->params.ColorConversionStrategy) {
2359
4
            case ccs_LeaveColorUnchanged:
2360
4
                DoMatte = 1;
2361
4
                break;
2362
0
            case ccs_RGB:
2363
0
            case ccs_sRGB:
2364
0
                if (num_components == 3)
2365
0
                    DoMatte = 1;
2366
0
                else
2367
0
                    DoMatte = 0;
2368
0
                break;
2369
0
            case ccs_CMYK:
2370
0
                if (num_components == 4)
2371
0
                    DoMatte = 1;
2372
0
                else
2373
0
                    DoMatte = 0;
2374
0
                break;
2375
0
            case ccs_Gray:
2376
0
                if (num_components == 1)
2377
0
                    DoMatte = 1;
2378
0
                else
2379
0
                    DoMatte = 0;
2380
0
                break;
2381
0
            case ccs_UseDeviceIndependentColor:
2382
0
            case ccs_UseDeviceIndependentColorForImages:
2383
0
            case ccs_ByObjectType:
2384
0
            default:
2385
0
                DoMatte = 0;
2386
0
                break;
2387
4
        }
2388
2389
4
        if (DoMatte) {
2390
4
            code = cos_dict_put_c_key_floats((gx_device_pdf *)dev,
2391
4
                                    (cos_dict_t *)pmie->writer.pres->object,
2392
4
                                    "/Matte", pixm->Matte,
2393
4
                                    num_components);
2394
4
            if (code < 0)
2395
0
                return code;
2396
4
        }
2397
4
    }
2398
/* Don't put SMask here because pmie->writer.pres->object may be substituted
2399
 * after the image stream is accummulated. pdf_end_and_do_image will set
2400
 * SMask with the right value. Bug 690345.
2401
 */
2402
6.24k
    return 0;
2403
6.24k
}
2404
2405
pdf_resource_t *pdf_substitute_pattern(pdf_resource_t *pres)
2406
14.8k
{
2407
14.8k
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres;
2408
2409
14.8k
    return (pdf_resource_t *)(ppat->substitute != 0 ? ppat->substitute : ppat);
2410
14.8k
}
2411
2412
static int
2413
check_unsubstituted2(gx_device_pdf * pdev, pdf_resource_t *pres0, pdf_resource_t *pres1)
2414
1.35k
{
2415
1.35k
    pdf_pattern_t *ppat0 = (pdf_pattern_t *)pres0;
2416
1.35k
    pdf_pattern_t *ppat1 = (pdf_pattern_t *)pres1;
2417
2418
1.35k
    return (ppat0->substitute == NULL && ppat1->substitute == NULL);
2419
1.35k
}
2420
2421
static int
2422
check_unsubstituted1(gx_device_pdf * pdev, pdf_resource_t *pres0)
2423
0
{
2424
0
    pdf_pattern_t *ppat = (pdf_pattern_t *)pres0;
2425
2426
0
    return ppat->substitute != NULL;
2427
0
}
2428
2429
static int reset_gstate_for_pattern(gx_device_pdf * pdev, gs_gstate *destination, gs_gstate *source)
2430
12.2k
{
2431
12.2k
    if (pdev->vg_initial_set) {
2432
12.2k
        destination->strokeconstantalpha = source->strokeconstantalpha;
2433
12.2k
        source->strokeconstantalpha = pdev->vg_initial.strokeconstantalpha;
2434
12.2k
        destination->fillconstantalpha = source->fillconstantalpha;
2435
12.2k
        source->fillconstantalpha = pdev->vg_initial.fillconstantalpha;
2436
12.2k
        if (destination->set_transfer.red != NULL)
2437
0
            destination->set_transfer.red->id = (source->set_transfer.red != NULL ? source->set_transfer.red->id : 0);
2438
12.2k
        if (destination->set_transfer.green != NULL)
2439
0
            destination->set_transfer.green->id = (source->set_transfer.green != NULL ? source->set_transfer.green->id : 0);
2440
12.2k
        if (destination->set_transfer.blue != NULL)
2441
0
            destination->set_transfer.blue->id = (source->set_transfer.blue != NULL ? source->set_transfer.blue->id : 0);
2442
12.2k
        if (destination->set_transfer.gray != NULL)
2443
6.10k
            destination->set_transfer.gray->id = (source->set_transfer.gray != NULL ? source->set_transfer.gray->id : 0);
2444
12.2k
        if (source->set_transfer.red != NULL)
2445
0
            source->set_transfer.red->id = pdev->vg_initial.transfer_ids[0];
2446
12.2k
        if (source->set_transfer.green != NULL)
2447
0
            source->set_transfer.green->id = pdev->vg_initial.transfer_ids[1];
2448
12.2k
        if (source->set_transfer.blue != NULL)
2449
0
            source->set_transfer.blue->id = pdev->vg_initial.transfer_ids[2];
2450
12.2k
        if (source->set_transfer.gray != NULL)
2451
6.11k
            source->set_transfer.gray->id = pdev->vg_initial.transfer_ids[3];
2452
12.2k
        destination->alphaisshape = source->alphaisshape;
2453
12.2k
        source->alphaisshape = pdev->vg_initial.alphaisshape;
2454
12.2k
        destination->blend_mode = source->blend_mode;
2455
12.2k
        source->blend_mode = pdev->vg_initial.blend_mode;
2456
12.2k
        if (destination->black_generation != NULL)
2457
6.10k
            destination->black_generation->id = (source->black_generation != NULL ? source->black_generation->id : 0);
2458
12.2k
        if (source->black_generation != NULL)
2459
6.11k
            source->black_generation->id = pdev->vg_initial.black_generation_id;
2460
12.2k
        if (destination->undercolor_removal != NULL)
2461
6.10k
            destination->undercolor_removal->id = (source->undercolor_removal != NULL ? source->undercolor_removal->id : 0);
2462
12.2k
        if (source->undercolor_removal != NULL)
2463
6.11k
            source->undercolor_removal->id = pdev->vg_initial.undercolor_removal_id;
2464
12.2k
        destination->overprint_mode = source->overprint_mode;
2465
12.2k
        source->overprint_mode = pdev->vg_initial.overprint_mode;
2466
12.2k
        destination->flatness = source->flatness;
2467
12.2k
        source->flatness = pdev->vg_initial.flatness;
2468
12.2k
        destination->smoothness = source->smoothness;
2469
12.2k
        source->smoothness = pdev->vg_initial.smoothness;
2470
12.2k
        destination->flatness = source->flatness;
2471
12.2k
        source->flatness = pdev->vg_initial.flatness;
2472
12.2k
        destination->text_knockout = source->text_knockout;
2473
12.2k
        source->text_knockout = pdev->vg_initial.text_knockout;
2474
12.2k
        destination->stroke_adjust = source->stroke_adjust;
2475
12.2k
        source->stroke_adjust = pdev->vg_initial.stroke_adjust;
2476
12.2k
        destination->line_params.half_width = source->line_params.half_width;
2477
12.2k
        source->line_params.half_width = pdev->vg_initial.line_params.half_width;
2478
12.2k
        destination->line_params.start_cap = source->line_params.start_cap;
2479
12.2k
        source->line_params.start_cap = pdev->vg_initial.line_params.start_cap;
2480
12.2k
        destination->line_params.end_cap = source->line_params.end_cap;
2481
12.2k
        source->line_params.end_cap = pdev->vg_initial.line_params.end_cap;
2482
12.2k
        destination->line_params.dash_cap = source->line_params.dash_cap;
2483
12.2k
        source->line_params.dash_cap = pdev->vg_initial.line_params.dash_cap;
2484
12.2k
        destination->line_params.join = source->line_params.join;
2485
12.2k
        source->line_params.join = pdev->vg_initial.line_params.join;
2486
12.2k
        destination->line_params.curve_join = source->line_params.curve_join;
2487
12.2k
        source->line_params.curve_join = pdev->vg_initial.line_params.curve_join;
2488
12.2k
        destination->line_params.miter_limit = source->line_params.miter_limit;
2489
12.2k
        source->line_params.miter_limit = pdev->vg_initial.line_params.miter_limit;
2490
12.2k
        destination->line_params.miter_check = source->line_params.miter_check;
2491
12.2k
        source->line_params.miter_check = pdev->vg_initial.line_params.miter_check;
2492
12.2k
        destination->line_params.dot_length = source->line_params.dot_length;
2493
12.2k
        source->line_params.dot_length = pdev->vg_initial.line_params.dot_length;
2494
12.2k
        destination->line_params.dot_length_absolute = source->line_params.dot_length_absolute;
2495
12.2k
        source->line_params.dot_length_absolute = pdev->vg_initial.line_params.dot_length_absolute;
2496
12.2k
        destination->line_params.dot_orientation = source->line_params.dot_orientation;
2497
12.2k
        source->line_params.dot_orientation = pdev->vg_initial.line_params.dot_orientation;
2498
12.2k
        if (destination->line_params.dash.pattern != NULL && destination->line_params.dash.pattern != source->line_params.dash.pattern)
2499
0
            gs_free_object(destination->memory, destination->line_params.dash.pattern, "free dash assigned during pattern accumulation");
2500
12.2k
        memcpy(&destination->line_params.dash, &source->line_params.dash, sizeof(source->line_params.dash));
2501
12.2k
        memcpy(&source->line_params.dash, &pdev->vg_initial.line_params.dash, sizeof(source->line_params.dash));
2502
12.2k
    }
2503
12.2k
    return 0;
2504
12.2k
}
2505
2506
/*
2507
   The device specific operations - just pattern management.
2508
   See gxdevcli.h about return codes.
2509
 */
2510
int
2511
gdev_pdf_dev_spec_op(gx_device *pdev1, int dev_spec_op, void *data, int size)
2512
147M
{
2513
147M
    gx_device_pdf *pdev = (gx_device_pdf *)pdev1;
2514
147M
    int code=0, force_CTM_change=0;
2515
147M
    pdf_resource_t *pres, *pres1;
2516
147M
    gx_bitmap_id id = (gx_bitmap_id)size;
2517
2518
147M
    switch (dev_spec_op) {
2519
65.9k
        case gxdso_skip_icc_component_validation:
2520
65.9k
            return 1;
2521
14.2k
        case gxdso_supports_pattern_transparency:
2522
14.2k
            return 1;
2523
6.55k
        case gxdso_pattern_can_accum:
2524
6.55k
            return 1;
2525
16.2k
        case gxdso_pdf_form_name:
2526
16.2k
            if (pdev->PDFFormName) {
2527
3
                gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2528
3
            }
2529
16.2k
            pdev->PDFFormName = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, size + 1, "Name of Form for pdfmark");
2530
16.2k
            if (pdev->PDFFormName == NULL)
2531
0
                return_error(gs_error_VMerror);
2532
16.2k
            memset(pdev->PDFFormName, 0x00, size + 1);
2533
16.2k
            memcpy(pdev->PDFFormName, data, size);
2534
16.2k
            return 0;
2535
0
        case gxdso_pdf_last_form_ID:
2536
0
            {
2537
0
            int *i = (int *)data;
2538
0
            *i = pdev->LastFormID;
2539
0
            }
2540
0
            return 0;
2541
16.2k
        case gxdso_form_begin:
2542
16.2k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 0) && pdev->PatternDepth == 0) {
2543
16.2k
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2544
16.2k
                float arry[6];
2545
16.2k
                cos_dict_t *pcd = NULL, *pcd_Resources = NULL;
2546
2547
                /* Make sure the document and page stream are open */
2548
16.2k
                code = pdfwrite_pdf_open_document(pdev);
2549
16.2k
                if (code < 0)
2550
0
                    return code;
2551
16.2k
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2552
16.2k
                if (code < 0)
2553
0
                    return code;
2554
16.2k
                if (!pdev->PDFFormName) {
2555
                    /* Put any extant clip out before we start the form */
2556
0
                    code = pdf_put_clip_path(pdev, tmplate->pcpath);
2557
0
                    if (code < 0)
2558
0
                        return code;
2559
                    /* Set the CTM to be the one passed in from the interpreter,
2560
                     * this allows us to spot forms even when translation/rotation takes place
2561
                     * as we remove the CTN from the form stream before capture
2562
                     */
2563
0
                    pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2564
0
                             tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2565
0
                }
2566
2567
                /* start capturing the form stream */
2568
16.2k
                code = pdf_enter_substream(pdev, resourceXObject, id, &pres, false,
2569
16.2k
                        pdev->CompressStreams);
2570
16.2k
                if (code < 0)
2571
0
                    return code;
2572
16.2k
                pcd = cos_stream_dict((cos_stream_t *)pres->object);
2573
16.2k
                pcd_Resources = cos_dict_alloc(pdev, "pdf_form(Resources)");
2574
16.2k
                if (pcd == NULL || pcd_Resources == NULL)
2575
0
                    return_error(gs_error_VMerror);
2576
16.2k
                code = cos_dict_put_c_strings(pcd, "/Type", "/XObject");
2577
16.2k
                if (code >= 0)
2578
16.2k
                    code = cos_dict_put_c_strings(pcd, "/Subtype", "/Form");
2579
16.2k
                if (code >= 0)
2580
16.2k
                    code = cos_dict_put_c_strings(pcd, "/FormType", "1");
2581
16.2k
                if (code >= 0)
2582
16.2k
                    code = cos_dict_put_c_key_object(pcd, "/Resources", COS_OBJECT(pcd_Resources));
2583
2584
16.2k
                if (pdev->PDFFormName) {
2585
                    /* This is not (I think) required when executing PS forms, because the
2586
                     * CTM is written out before we execute the Form. It *is* required for
2587
                     * PDF Appearance Forms, because the Form is written directly from the
2588
                     * outer context, not from the page, so we don't emit the CTM first.
2589
                     * We want to alter the Form BBox to take any required rotation and scaling
2590
                     * (from FitPage and /Rotate) into account so that the form appearance is
2591
                     * properly scaled and rotated.
2592
                     */
2593
16.2k
                    gs_rect bbox_out;
2594
16.2k
                    gs_matrix cmat, new_mat = tmplate->CTM;
2595
2596
                    /* We don't want anything left over from the page content stream, or other
2597
                     * annotation appearances, to affect whether or not we emit any graphics
2598
                     * state, so reset the state here to the defaults.
2599
                     */
2600
16.2k
                    pdf_viewer_state_from_gs_gstate(pdev, tmplate->pgs, NULL);
2601
                    /* For PDF Appearance streams at least, the Form BBox is modified by the
2602
                     * Form Matrix.
2603
                     */
2604
16.2k
                    code = gs_matrix_multiply(&tmplate->form_matrix, &tmplate->CTM, &cmat);
2605
16.2k
                    if (code < 0)
2606
0
                        return code;
2607
16.2k
                    code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2608
16.2k
                    if (code < 0)
2609
0
                        return code;
2610
2611
                    /* Check the BBox is on the page. Modify it if it is not (this can happen
2612
                     * if the MediaBox does not have bottom left at 0,0)
2613
                     */
2614
16.2k
                    cmat.xx = cmat.yy = 1.0f;
2615
16.2k
                    cmat.xy = cmat.yx = cmat.tx = cmat.ty = 0.0f;
2616
16.2k
                    if(bbox_out.q.x - bbox_out.p.x > pdev->width) {
2617
1
                        cmat.xx = pdev->width / (bbox_out.q.x - bbox_out.p.x);
2618
1
                        bbox_out.q.x = bbox_out.p.x + ((bbox_out.q.x - bbox_out.p.x) * cmat.xx);
2619
1
                        force_CTM_change = 1;
2620
1
                    }
2621
16.2k
                    if(bbox_out.q.y - bbox_out.p.y > pdev->height) {
2622
1
                        cmat.yy = pdev->height / (bbox_out.q.y - bbox_out.p.y);
2623
1
                        bbox_out.q.y = bbox_out.p.y + ((bbox_out.q.y - bbox_out.p.y) * cmat.yy);
2624
1
                        force_CTM_change = 1;
2625
1
                    }
2626
2627
16.2k
                    if (bbox_out.p.x < 0) {
2628
2
                        cmat.tx = bbox_out.p.x * -1;
2629
2
                        bbox_out.q.x += cmat.tx;
2630
2
                        force_CTM_change = 1;
2631
2
                    }
2632
16.2k
                    if (floor(bbox_out.q.x) > pdev->width) {
2633
0
                        cmat.tx -= bbox_out.p.x;
2634
0
                        bbox_out.q.x -= bbox_out.p.x;
2635
0
                        bbox_out.p.x = 0;
2636
0
                        force_CTM_change = 1;
2637
0
                    }
2638
16.2k
                    if (bbox_out.p.y < 0) {
2639
5
                        cmat.ty = bbox_out.p.y * -1;
2640
5
                        bbox_out.q.y += cmat.ty;
2641
5
                        force_CTM_change = 1;
2642
5
                    }
2643
16.2k
                    if (floor(bbox_out.q.y) > pdev->height) {
2644
1
                        cmat.ty += pdev->height - bbox_out.q.y;
2645
1
                        force_CTM_change = 1;
2646
1
                    }
2647
2648
16.2k
                    if (force_CTM_change) {
2649
7
                        code = gs_matrix_multiply(&tmplate->CTM, &cmat, &new_mat);
2650
7
                        if (code < 0)
2651
0
                            return code;
2652
7
                        code = gs_matrix_multiply(&tmplate->form_matrix, &new_mat, &cmat);
2653
7
                        if (code < 0)
2654
0
                            return code;
2655
7
                        code = gs_bbox_transform(&tmplate->BBox, &cmat, &bbox_out);
2656
7
                        if (code < 0)
2657
0
                            return code;
2658
7
                        tmplate->CTM = cmat;
2659
7
                    }
2660
16.2k
                    arry[0] = bbox_out.p.x;
2661
16.2k
                    arry[1] = bbox_out.p.y;
2662
16.2k
                    arry[2] = bbox_out.q.x;
2663
16.2k
                    arry[3] = bbox_out.q.y;
2664
16.2k
                    if (code >= 0)
2665
16.2k
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2666
16.2k
                    if (code < 0)
2667
0
                        return code;
2668
2669
                    /* Note that we will apply the CTM to the form, and the Form Matrix. To prevcent
2670
                     * us applying the Matrix twice, we need to set it to the identity in the Form
2671
                     * dictionary. I'm not sure why we don't need to do that for PostScript Forms.
2672
                     */
2673
16.2k
                    arry[0] = arry[3] = 1.0f;
2674
16.2k
                    arry[1] = arry[2] = arry[4] = arry[5] = 0.0f;
2675
16.2k
                } else {
2676
0
                    arry[0] = tmplate->BBox.p.x;
2677
0
                    arry[1] = tmplate->BBox.p.y;
2678
0
                    arry[2] = tmplate->BBox.q.x;
2679
0
                    arry[3] = tmplate->BBox.q.y;
2680
0
                    if (code >= 0)
2681
0
                        code = cos_dict_put_c_key_floats(pdev, pcd, "/BBox", arry, 4);
2682
0
                    if (code < 0)
2683
0
                        return code;
2684
2685
0
                    arry[0] = tmplate->form_matrix.xx;
2686
0
                    arry[1] = tmplate->form_matrix.xy;
2687
0
                    arry[2] = tmplate->form_matrix.yx;
2688
0
                    arry[3] = tmplate->form_matrix.yy;
2689
0
                    arry[4] = tmplate->form_matrix.tx;
2690
0
                    arry[5] = tmplate->form_matrix.ty;
2691
2692
0
                    pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2693
0
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2694
0
                }
2695
2696
16.2k
                code = cos_dict_put_c_key_floats(pdev, pcd, "/Matrix", arry, 6);
2697
16.2k
                if (code < 0)
2698
0
                    return code;
2699
2700
                /* We'll return this to the interpreter and have it set
2701
                 * as the CTM, so that we remove the prior CTM before capturing the form.
2702
                 * This is safe because forms are always run inside a gsave/grestore, so
2703
                 * CTM will be put back for us.
2704
                 */
2705
16.2k
                if (!pdev->PDFFormName) {
2706
0
                    tmplate->CTM.xx = pdev->HWResolution[0] / 72;
2707
0
                    tmplate->CTM.xy = 0.0;
2708
0
                    tmplate->CTM.yx = 0.0;
2709
0
                    tmplate->CTM.yy = pdev->HWResolution[0] / 72;
2710
0
                    tmplate->CTM.tx = 0.0;
2711
0
                    tmplate->CTM.ty = 0.0;
2712
2713
0
                    pdev->substream_Resources = pcd_Resources;
2714
0
                    pres->rid = id;
2715
0
                    if (code >= 0)
2716
0
                        pdev->HighLevelForm++;
2717
0
                    return 1;
2718
16.2k
                } else {
2719
                    /* For PDF Appearance streams (Forms) we *must* apply the
2720
                     * CTM. This is because if the PDF has a non-zero Rotate key
2721
                     * we bake that rotation into the CTM. If we didn't apply that
2722
                     * then the annotation wouldn't get rotated :-(
2723
                     */
2724
16.2k
                    pdev->substream_Resources = pcd_Resources;
2725
16.2k
                    pres->rid = id;
2726
16.2k
                    if (code >= 0)
2727
16.2k
                        pdev->HighLevelForm++;
2728
16.2k
                    return force_CTM_change;
2729
16.2k
                }
2730
16.2k
            }
2731
0
            return code;
2732
16.2k
        case gxdso_form_end:
2733
            /* This test must be the same as the one in gxdso_form_begin, above */
2734
16.2k
            if ((!pdev->ForOPDFRead || pdev->HighLevelForm == 1) && pdev->PatternDepth == 0) {
2735
16.2k
                if (pdev->CompatibilityLevel <= 1.7) {
2736
16.2k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2737
16.2k
                    if (code < 0)
2738
0
                        return code;
2739
16.2k
                }
2740
16.2k
                pres = pres1 = pdev->accumulating_substream_resource;
2741
16.2k
                if (pres == NULL)
2742
0
                    return_error(gs_error_unregistered);
2743
16.2k
                code = pdf_exit_substream(pdev);
2744
16.2k
                if (code < 0)
2745
0
                    return code;
2746
16.2k
                code = pdf_find_same_resource(pdev, resourceXObject, &pres, check_unsubstituted2);
2747
16.2k
                if (code < 0)
2748
0
                    return code;
2749
16.2k
                if (code > 0) {
2750
0
                    code = pdf_cancel_resource(pdev, pres1, resourceXObject);
2751
0
                    if (code < 0)
2752
0
                        return code;
2753
0
                    pres->where_used |= pdev->used_mask;
2754
16.2k
                } else if (pres->object->id < 0)
2755
16.2k
                    pdf_reserve_object_id(pdev, pres, 0);
2756
16.2k
                pdev->LastFormID = pdf_resource_id(pres);
2757
16.2k
                pdev->HighLevelForm--;
2758
16.2k
                if (pdev->accumulating_substream_resource) {
2759
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2760
0
                    if (code < 0)
2761
0
                        return code;
2762
0
                }
2763
16.2k
                if (pdev->PDFFormName) {
2764
16.2k
                    cos_value_t value;
2765
2766
16.2k
                    code = cos_dict_put(pdev->local_named_objects, (const byte *)pdev->PDFFormName,
2767
16.2k
                        strlen(pdev->PDFFormName), cos_object_value(&value, pres->object));
2768
2769
16.2k
                    if (code < 0)
2770
0
                        return code;
2771
16.2k
                    pdf_drop_resource_from_chain(pdev, pres, resourceXObject);
2772
16.2k
                    pres->object = NULL;
2773
16.2k
                    gs_free_object(pdev->pdf_memory, pres, "free redundant resource");
2774
2775
16.2k
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PDFFormName, "free Name of Form for pdfmark");
2776
16.2k
                    pdev->PDFFormName = 0x00;
2777
16.2k
                } else {
2778
0
                    pprinti64d1(pdev->strm, "/R%"PRId64" Do Q\n", pdf_resource_id(pres));
2779
0
                }
2780
16.2k
            }
2781
16.2k
            return 0;
2782
16.2k
        case gxdso_get_form_ID:
2783
16.2k
            {
2784
16.2k
                int *ID = data;
2785
16.2k
                *ID = pdev->LastFormID;
2786
16.2k
            }
2787
16.2k
            return 0;
2788
0
        case gxdso_repeat_form:
2789
0
            {
2790
0
                gs_form_template_t *tmplate = (gs_form_template_t *)data;
2791
2792
                /* Make sure the document and page stream are open */
2793
0
                code = pdfwrite_pdf_open_document(pdev);
2794
0
                if (code < 0)
2795
0
                    return code;
2796
0
                code = pdf_open_contents(pdev, PDF_IN_STREAM);
2797
0
                if (code < 0)
2798
0
                    return code;
2799
                /* Put any extant clip out before we start the form */
2800
0
                code = pdf_put_clip_path(pdev, tmplate->pcpath);
2801
0
                if (code < 0)
2802
0
                    return code;
2803
                /* Set the CTM to be the one passed in from the interpreter,
2804
                 * this allows us to spot forms even when translation/rotation takes place
2805
                 * as we remove the CTN from the form stream before capture
2806
                 */
2807
0
                pprintg6(pdev->strm, "q %g %g %g %g %g %g cm\n", tmplate->CTM.xx, tmplate->CTM.xy,
2808
0
                         tmplate->CTM.yx, tmplate->CTM.yy, tmplate->CTM.tx, tmplate->CTM.ty);
2809
0
                pprintld1(pdev->strm, "/R%ld Do Q\n", tmplate->FormID);
2810
0
                pres = pdf_find_resource_by_resource_id(pdev, resourceXObject, tmplate->FormID);
2811
0
                if (pres == NULL)
2812
0
                    return_error(gs_error_undefined);
2813
0
                pres->where_used |= pdev->used_mask;
2814
0
                if (pdev->accumulating_substream_resource) {
2815
0
                    code = pdf_add_resource(pdev, pdev->substream_Resources, "/XObject", pres);
2816
0
                    if (code < 0)
2817
0
                        return code;
2818
0
                }
2819
0
            }
2820
0
            return 0;
2821
6.11k
        case gxdso_pattern_start_accum:
2822
6.11k
            {
2823
6.11k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2824
6.11k
                gs_pattern1_instance_t *pinst = param->pinst;
2825
6.11k
                gs_gstate *pgs = param->graphics_state;
2826
2827
6.11k
                code = pdf_check_soft_mask(pdev, (gs_gstate *)pgs);
2828
6.11k
                if (code < 0)
2829
0
                    return code;
2830
6.11k
                if (pdev->context == PDF_IN_NONE) {
2831
119
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
2832
119
                    if (code < 0)
2833
0
                        return code;
2834
119
                }
2835
6.11k
                code = pdf_prepare_fill_stroke(pdev, (gs_gstate *)pgs, false);
2836
6.11k
                if (code < 0)
2837
0
                    return code;
2838
6.11k
                if (pdev->PatternDepth == 0 && pdev->initial_pattern_states != NULL) {
2839
0
                    int pdepth = 0;
2840
2841
0
                    while (pdev->initial_pattern_states[pdepth] != 0x00) {
2842
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdepth], "Freeing dangling pattern state");
2843
0
                        pdev->initial_pattern_states[pdepth] = NULL;
2844
0
                        pdepth++;
2845
0
                    }
2846
0
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state stack");
2847
0
                }
2848
2849
6.11k
                {
2850
6.11k
                    gs_gstate **new_states;
2851
6.11k
                    int pdepth;
2852
2853
6.11k
                    new_states = (gs_gstate **)gs_alloc_bytes(pdev->pdf_memory->non_gc_memory, sizeof(gs_gstate *) * (pdev->PatternDepth + 2), "pattern initial graphics state stack");
2854
6.11k
                    if (new_states == NULL)
2855
0
                        return_error(gs_error_VMerror);
2856
6.11k
                    memset(new_states, 0x00, sizeof(gs_gstate *) * (pdev->PatternDepth + 2));
2857
6.12k
                    for (pdepth = 0; pdepth < pdev->PatternDepth;pdepth++)
2858
9
                        new_states[pdepth] = pdev->initial_pattern_states[pdepth];
2859
6.11k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing old pattern state stack");
2860
6.11k
                    pdev->initial_pattern_states = new_states;
2861
6.11k
                }
2862
6.11k
                pdev->initial_pattern_states[pdev->PatternDepth] = (gs_gstate *)gs_alloc_struct(pdev->pdf_memory, gs_gstate, &st_gs_gstate, "gdev_pdf_dev_spec_op");
2863
6.11k
                if (pdev->initial_pattern_states[pdev->PatternDepth] == NULL)
2864
0
                    return code;
2865
6.11k
                memset(pdev->initial_pattern_states[pdev->PatternDepth], 0x00, sizeof(gs_gstate));
2866
6.11k
                pdev->initial_pattern_states[pdev->PatternDepth]->memory = pdev->pdf_memory;
2867
2868
6.11k
                reset_gstate_for_pattern(pdev, pdev->initial_pattern_states[pdev->PatternDepth], pgs);
2869
6.11k
                code = pdf_enter_substream(pdev, resourcePattern, pinst->id, &pres, false,
2870
6.11k
                        pdev->CompressStreams);
2871
6.11k
                if (code < 0) {
2872
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2873
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2874
0
                    return code;
2875
0
                }
2876
2877
                /* We have started a new substream, to avoid confusing the 'saved viewer state'
2878
                 * (the stack of pdfwrite's saved copies of graophics states) we need to reset the
2879
                 * soft_mask_id, which is the ID of the SMask we have already created in the pdfwrite
2880
                 * output. The gsave/grestore round the spec_op to start and finish the pattern
2881
                 * accumulator (see pattern_paint_prepare and pattern_paint_finish) will ensure that
2882
                 * the ID is restored when we finish capturing the pattern.
2883
                 */
2884
6.11k
                pdev->state.soft_mask_id = pgs->soft_mask_id;
2885
6.11k
                pres->rid = pinst->id;
2886
6.11k
                code = pdf_store_pattern1_params(pdev, pres, pinst);
2887
6.11k
                if (code < 0) {
2888
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2889
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2890
0
                    return code;
2891
0
                }
2892
                /* Scale the coordinate system, because object handlers assume so. See none_to_stream. */
2893
6.11k
                pprintg2(pdev->strm, "%g 0 0 %g 0 0 cm\n",
2894
6.11k
                         72.0 / pdev->HWResolution[0], 72.0 / pdev->HWResolution[1]);
2895
6.11k
                pdev->PatternDepth++;
2896
6.11k
                pdev->PatternsSinceForm++;
2897
6.11k
            }
2898
0
            return 1;
2899
6.10k
        case gxdso_pattern_finish_accum:
2900
6.10k
            {
2901
6.10k
                pattern_accum_param_s *param = (pattern_accum_param_s *)data;
2902
6.10k
                gs_gstate *pgs = param->graphics_state;
2903
2904
6.10k
                if (pdev->CompatibilityLevel <= 1.7) {
2905
6.10k
                    if (pdev->substream_Resources == NULL) {
2906
0
                        pdev->substream_Resources = cos_dict_alloc(pdev, "pdf_pattern(Resources)");
2907
0
                        if (pdev->substream_Resources == NULL)
2908
0
                            return_error(gs_error_VMerror);
2909
0
                    }
2910
6.10k
                    code = pdf_add_procsets(pdev->substream_Resources, pdev->procsets);
2911
6.10k
                    if (code < 0) {
2912
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2913
0
                        pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2914
0
                        return code;
2915
0
                    }
2916
6.10k
                }
2917
6.10k
                pres = pres1 = pdev->accumulating_substream_resource;
2918
6.10k
                if (pres == NULL)
2919
0
                    code = gs_note_error(gs_error_unregistered);
2920
6.10k
                else
2921
6.10k
                    code = pdf_exit_substream(pdev);
2922
6.10k
                if (code < 0) {
2923
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2924
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2925
0
                    return code;
2926
0
                }
2927
6.10k
                if (pdev->substituted_pattern_count > 300 &&
2928
0
                        pdev->substituted_pattern_drop_page != pdev->next_page) { /* arbitrary */
2929
0
                    pdf_drop_resources(pdev, resourcePattern, check_unsubstituted1);
2930
0
                    pdev->substituted_pattern_count = 0;
2931
0
                    pdev->substituted_pattern_drop_page = pdev->next_page;
2932
0
                }
2933
6.10k
                code = pdf_find_same_resource(pdev, resourcePattern, &pres, check_unsubstituted2);
2934
6.10k
                if (code < 0) {
2935
0
                    gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2936
0
                    pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2937
0
                    return code;
2938
0
                }
2939
6.10k
                if (code > 0) {
2940
1.35k
                    pdf_pattern_t *ppat = (pdf_pattern_t *)pres1;
2941
2942
1.35k
                    code = pdf_cancel_resource(pdev, pres1, resourcePattern);
2943
1.35k
                    if (code < 0) {
2944
0
                        gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth], "Freeing dangling pattern state");
2945
0
                        pdev->initial_pattern_states[pdev->PatternDepth] = NULL;
2946
0
                        return code;
2947
0
                    }
2948
                    /* Do not remove pres1, because it keeps the substitution. */
2949
1.35k
                    ppat->substitute = (pdf_pattern_t *)pres;
2950
1.35k
                    pres->where_used |= pdev->used_mask;
2951
1.35k
                    pdev->substituted_pattern_count++;
2952
4.75k
                } else if (pres->object->id < 0)
2953
4.75k
                    pdf_reserve_object_id(pdev, pres, 0);
2954
6.10k
                reset_gstate_for_pattern(pdev, pgs, pdev->initial_pattern_states[pdev->PatternDepth - 1]);
2955
6.10k
                gs_free_object(pdev->pdf_memory, pdev->initial_pattern_states[pdev->PatternDepth - 1], "Freeing dangling pattern state");
2956
6.10k
                pdev->initial_pattern_states[pdev->PatternDepth - 1] = NULL;
2957
6.10k
                if (pdev->PatternDepth == 1) {
2958
6.10k
                    gs_free_object(pdev->pdf_memory->non_gc_memory, pdev->initial_pattern_states, "Freeing dangling pattern state");
2959
6.10k
                    pdev->initial_pattern_states = NULL;
2960
6.10k
                }
2961
2962
6.10k
                pdev->PatternDepth--;
2963
6.10k
                pdev->PatternsSinceForm--;
2964
6.10k
            }
2965
0
            return 1;
2966
13.3k
        case gxdso_pattern_load:
2967
13.3k
            pres = pdf_find_resource_by_gs_id(pdev, resourcePattern, *((gx_bitmap_id *)data));
2968
13.3k
            if (pres == 0)
2969
6.10k
                return 0;
2970
7.26k
            pres = pdf_substitute_pattern(pres);
2971
7.26k
            pres->where_used |= pdev->used_mask;
2972
7.26k
            code = pdf_add_resource(pdev, pdev->substream_Resources, "/Pattern", pres);
2973
7.26k
            if (code < 0)
2974
0
                return code;
2975
7.26k
            return 1;
2976
106k
        case gxdso_pattern_shading_area:
2977
106k
            return 0;
2978
185k
        case gxdso_pattern_is_cpath_accum:
2979
185k
            return 0;
2980
17.3k
        case gxdso_pattern_shfill_doesnt_need_path:
2981
17.3k
            return 0; /* gdev_pdf_fill_path still does need a path. */
2982
5
        case gxdso_pattern_handles_clip_path:
2983
            /* This is important when the default implementation of
2984
               of fill_path is called due to a failure in setcolor
2985
               or so, for example when a shading is incorrect.
2986
               The test case is the unfixed (buggy) Genoa test 446-01.ps .
2987
               In this case pdfwrite converts the object into rectangles,
2988
               and the clipping device has to be set up. */
2989
5
            return 0;
2990
5.79k
        case gxdso_supports_hlcolor:
2991
            /* This is used due to some aliasing between the rect_hl color
2992
               filling used by pdfwrite vs. that used by the planar device
2993
               which is actually a devn vs. the pattern type for pdfwrite.
2994
               We use this to distingush between the two */
2995
5.79k
            return 1;
2996
0
        case gxdso_needs_invariant_palette:
2997
            /* Indicates that it is not permissible to change /Indexed colour space
2998
             * palette entries after the colour space has been set.
2999
             */
3000
0
            return 1;
3001
6.98k
        case gxdso_JPEG_passthrough_query:
3002
6.98k
            pdev->JPEG_PassThrough = pdev->params.PassThroughJPEGImages;
3003
6.98k
            return 1;
3004
0
            break;
3005
0
        case gxdso_set_JPEG_PassThrough:
3006
0
            pdev->params.PassThroughJPEGImages = *((bool *)data);
3007
0
            if (*((bool *)data) == 0 && pdev->JPEG_PassThrough)
3008
0
                pdev->JPEG_PassThrough = 0;
3009
0
            return 0;
3010
0
            break;
3011
6.96k
        case gxdso_JPEG_passthrough_begin:
3012
6.96k
            return 0;
3013
0
            break;
3014
532k
        case gxdso_JPEG_passthrough_data:
3015
532k
            if (pdev->JPEG_PassThrough && pdev->PassThroughWriter)
3016
317k
            {
3017
317k
                uint ignore;
3018
317k
                if (sputs(pdev->PassThroughWriter,
3019
317k
                           data, size,
3020
317k
                           &ignore) < 0)
3021
0
                           return_error(gs_error_ioerror);
3022
317k
            }
3023
532k
            return 0;
3024
0
            break;
3025
6.98k
        case gxdso_JPEG_passthrough_end:
3026
6.98k
            pdev->JPEG_PassThrough = 0;
3027
6.98k
            pdev->PassThroughWriter = 0;
3028
6.98k
            return 0;
3029
0
            break;
3030
3.61k
        case gxdso_JPX_passthrough_query:
3031
3.61k
            pdev->JPX_PassThrough = pdev->params.PassThroughJPXImages;
3032
3.61k
            return 1;
3033
0
            break;
3034
0
        case gxdso_set_JPX_PassThrough:
3035
0
            pdev->params.PassThroughJPXImages = *((bool *)data);
3036
0
            if (*((bool *)data) == 0 && pdev->JPX_PassThrough)
3037
0
                pdev->JPX_PassThrough = 0;
3038
0
            return 0;
3039
0
            break;
3040
3.39k
        case gxdso_JPX_passthrough_begin:
3041
3.39k
            return 0;
3042
0
            break;
3043
167k
        case gxdso_JPX_passthrough_data:
3044
167k
            if (pdev->JPX_PassThrough && pdev->PassThroughWriter)
3045
55.4k
            {
3046
55.4k
                uint ignore;
3047
55.4k
                if (sputs(pdev->PassThroughWriter,
3048
55.4k
                           data, size,
3049
55.4k
                           &ignore) < 0)
3050
0
                           return_error(gs_error_ioerror);
3051
55.4k
            }
3052
167k
            return 0;
3053
0
            break;
3054
3.39k
        case gxdso_JPX_passthrough_end:
3055
3.39k
            pdev->JPX_PassThrough = 0;
3056
3.39k
            pdev->PassThroughWriter = 0;
3057
3.39k
            return 0;
3058
0
            break;
3059
3060
0
        case gxdso_event_info:
3061
0
            {
3062
0
                dev_param_req_t *request = (dev_param_req_t *)data;
3063
0
                if (memcmp(request->Param, "SubstitutedFont", 15) == 0 && (pdev->PDFA || pdev->PDFX)) {
3064
0
                    switch (pdev->PDFACompatibilityPolicy) {
3065
0
                        case 0:
3066
0
                        case 1:
3067
0
                            emprintf(pdev->memory,
3068
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");
3069
0
                            pdev->AbortPDFAX = true;
3070
0
                            pdev->PDFX = 0;
3071
0
                            pdev->PDFA = 0;
3072
0
                            break;
3073
0
                        case 2:
3074
0
                            emprintf(pdev->memory,
3075
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, aborting conversion!\n");
3076
0
                            pdev->AbortPDFAX = true;
3077
0
                            pdev->PDFX = 0;
3078
0
                            pdev->PDFA = 0;
3079
0
                            return gs_note_error(gs_error_unknownerror);
3080
0
                            break;
3081
0
                        default:
3082
0
                            emprintf(pdev->memory,
3083
0
                             "\n **** A font missing from the input PDF has been substituted with a different font.\n\tWidths may differ, unknown PDFACompatibilityPolicy, reverting to normal PDF output!\n");
3084
0
                            pdev->AbortPDFAX = true;
3085
0
                            pdev->PDFX = 0;
3086
0
                            pdev->PDFA = 0;
3087
0
                            break;
3088
0
                    }
3089
0
                }
3090
0
                return 0;
3091
0
            }
3092
0
            break;
3093
9.26M
        case gxdso_in_smask_construction:
3094
9.26M
            return pdev->smask_construction;
3095
77
        case gxdso_pending_optional_content:
3096
77
            if (pdev->CompatibilityLevel < 1.4999) {
3097
0
                if (pdev->PDFA) {
3098
0
                    switch (pdev->PDFACompatibilityPolicy) {
3099
0
                        case 0:
3100
0
                            emprintf(pdev->memory,
3101
0
                                     "Optional Content not valid in this version of PDF, reverting to normal PDF output\n");
3102
0
                            pdev->AbortPDFAX = true;
3103
0
                            pdev->PDFA = 0;
3104
0
                            break;
3105
0
                        case 1:
3106
0
                            emprintf(pdev->memory,
3107
0
                                     "Optional Content not valid in this version of PDF. Dropping feature to preserve PDF/A compatibility\n");
3108
0
                            break;
3109
0
                        case 2:
3110
0
                            emprintf(pdev->memory,
3111
0
                                     "Optional Content not valid in this version of PDF,  aborting conversion\n");
3112
0
                            return_error (gs_error_typecheck);
3113
0
                            break;
3114
0
                        default:
3115
0
                            emprintf(pdev->memory,
3116
0
                                     "Optional Content not valid in this version of PDF, unrecognised PDFACompatibilityLevel,\nreverting to normal PDF output\n");
3117
0
                            pdev->AbortPDFAX = true;
3118
0
                            pdev->PDFA = 0;
3119
0
                            break;
3120
0
                    }
3121
0
                } else {
3122
0
                    emprintf(pdev->memory,
3123
0
                             "Optional Content not valid in this version of PDF. Dropping feature to preserve compatibility\n");
3124
0
                }
3125
0
            } else
3126
77
            {
3127
77
                char *object = data;
3128
77
                if (pdev->PendingOC)
3129
3
                    gs_free_object(pdev->memory->non_gc_memory, pdev->PendingOC, "");
3130
77
                pdev->PendingOC = (char *)gs_alloc_bytes(pdev->memory->non_gc_memory, strlen(object) + 1, "");
3131
77
                if (pdev->PendingOC == NULL)
3132
0
                    return_error(gs_error_VMerror);
3133
77
                memcpy(pdev->PendingOC, object, strlen(object) + 1);
3134
77
            }
3135
77
            return 0;
3136
0
            break;
3137
24
        case gxdso_hilevel_text_clip:
3138
24
            if (data == 0 && !pdev->accumulating_charproc) {
3139
                /* We are exiting a text render mode 'clip' by grestoring back to
3140
                 *  a time when the clip wasn't active.
3141
                 * First, check if we have a clip (this should always be true).
3142
                 */
3143
6
                if (pdev->clipped_text_pending) {
3144
                    /* Get back to the content stream. This will (amongst other things) flush
3145
                     * any pending text.
3146
                     */
3147
6
                    code = pdf_open_page(pdev, PDF_IN_STREAM);
3148
6
                    if (code < 0)
3149
0
                        return code;
3150
                    /* Reset the pending state */
3151
6
                    pdev->clipped_text_pending = 0;
3152
                    /* Restore to our saved state */
3153
3154
                    /* The saved state in this case is the dpeth of the saved gstate stack at the time we
3155
                     * started the text clipping. Note; we cannot restore back past the 'bottom' of the
3156
                     * stack, which is why we alter vgstack_bottom here, rather than just using the saved
3157
                     * level in the loop below.
3158
                     */
3159
6
                    if (pdev->vgstack_bottom)
3160
6
                        pdev->vgstack_bottom = pdev->saved_vgstack_depth_for_textclip;
3161
3162
12
                    while (pdev->vgstack_depth > pdev->vgstack_bottom) {
3163
6
                        code = pdf_restore_viewer_state(pdev, pdev->strm);
3164
6
                        if (code < 0)
3165
0
                            return code;
3166
6
                    }
3167
3168
6
                    pdev->vgstack_bottom = pdev->saved_vgstack_bottom_for_textclip;
3169
6
                    pdf_reset_text(pdev); /* because of Q */
3170
6
                }
3171
18
            } else {
3172
18
                if (!pdev->accumulating_charproc) {
3173
18
                    gs_gstate *pgs = (gs_gstate *)data;
3174
                    /* We are starting text in a clip mode
3175
                     * First make sure we aren't already in a clip mode (this should never be true)
3176
                     */
3177
18
                    if (!pdev->clipped_text_pending) {
3178
                        /* Return to the content stream, this will (amongst other things) flush
3179
                         * any pending text.
3180
                         */
3181
18
                        code = pdf_open_page(pdev, PDF_IN_STREAM);
3182
18
                        if (code < 0)
3183
0
                            return code;
3184
3185
18
                        if (pdf_must_put_clip_path(pdev, pgs->clip_path)) {
3186
0
                           code = pdf_unclip(pdev);
3187
0
                            if (code < 0)
3188
0
                                return code;
3189
0
                            code = pdf_put_clip_path(pdev, pgs->clip_path);
3190
0
                            if (code < 0)
3191
0
                                return code;
3192
0
                        }
3193
3194
18
                        pdev->saved_vgstack_depth_for_textclip = pdev->vgstack_depth;
3195
3196
                        /* Save the current graphics state (or at least that bit which we track) so
3197
                         * that we can put it back later.
3198
                         */
3199
18
                        code = pdf_save_viewer_state(pdev, pdev->strm);
3200
18
                        if (code < 0)
3201
0
                            return code;
3202
18
                        pdev->clipped_text_pending = 1;
3203
3204
                        /* Save the current 'bottom' of the saved gstate stack, we need to
3205
                         * restore back to this state when we exit the graphics state
3206
                         * with a text rendering mode involving a clip.
3207
                         */
3208
18
                        pdev->saved_vgstack_bottom_for_textclip = pdev->vgstack_bottom;
3209
                        /* And push the bottom of the stack up until it is where we are now.
3210
                         * This is because clip paths, images, and possibly other constructs
3211
                         * will emit a clip path if the 'depth - bottom' is not zero, to create
3212
                         * a clip path. We want to make sure that it doesn't try to restore back
3213
                         * to a point before we established the text clip.
3214
                         */
3215
18
                        pdev->vgstack_bottom = pdev->vgstack_depth;
3216
18
                    }
3217
18
                }
3218
18
            }
3219
24
            break;
3220
2.70M
        case gxdso_get_dev_param:
3221
2.70M
            {
3222
2.70M
                int code;
3223
2.70M
                dev_param_req_t *request = (dev_param_req_t *)data;
3224
2.70M
                code = gdev_pdf_get_param(pdev1, request->Param, request->list);
3225
2.70M
                if (code != gs_error_undefined)
3226
2.65M
                    return code;
3227
2.70M
            }
3228
            /* Fall through */
3229
147M
    }
3230
134M
    return gx_default_dev_spec_op(pdev1, dev_spec_op, data, size);
3231
147M
}