Coverage Report

Created: 2026-02-14 07:09

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