Coverage Report

Created: 2026-02-14 07:09

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.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
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
#include "gdevkrnlsclass.h"
74
75
#if RAW_DUMP
76
unsigned int global_index = 0;
77
unsigned int clist_band_count = 0;
78
#endif
79
80
#define DUMP_MASK_STACK 0
81
82
/* Static prototypes */
83
/* Used for filling rects when we are doing a fill with a pattern that
84
   has transparency */
85
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
86
                                   gx_path * ppath, const gx_fill_params * params,
87
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
88
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
89
static void pdf14_free_smask_color(pdf14_device * pdev);
90
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
91
                                         const gs_rect *pbbox, gs_gstate *pgs);
92
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
93
                                     const gs_gstate * pgs,
94
                                     bool crop_blend_params,
95
                                     gs_pdf14trans_params_t *group_params);
96
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
97
                                               int w, int h, gx_color_index color,
98
                                               const gx_device_color *pdc,
99
                                               bool devn);
100
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
101
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
102
                                  gx_color_index color, const gx_device_color *pdc,
103
                                  int depth, bool devn);
104
105
/* Functions for dealing with soft mask color */
106
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
107
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
108
109
/*
110
 * We chose the blending color space based upon the process color model of the
111
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
112
 * usually simple.  For other devices or if the user is doing custom color
113
 * processing then the user may want to control this choice.
114
 */
115
#define AUTO_USE_CUSTOM_BLENDING 0
116
#define ALWAYS_USE_CUSTOM_BLENDING 1
117
#define DO_NOT_USE_CUSTOM_BLENDING 2
118
119
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
120
121
# define INCR(v) DO_NOTHING
122
123
/* Forward prototypes */
124
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
125
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
126
                                gx_device ** pdev, gx_device * target,
127
                                const gs_pdf14trans_t * pdf14pct);
128
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
129
                                      gx_device ** pdev, gx_device * target,
130
                                      const gs_pdf14trans_t * pdf14pct);
131
static int pdf14_tile_pattern_fill(gx_device * pdev,
132
                const gs_gstate * pgs, gx_path * ppath,
133
                const gx_fill_params * params,
134
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    mask_buf, previous);
169
170
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
171
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
172
                    profiles);
173
174
/* ------ The device descriptors ------ */
175
176
/*
177
 * Default X and Y resolution.
178
 */
179
#define X_DPI 72
180
#define Y_DPI 72
181
182
static int pdf14_initialize_device(gx_device *dev);
183
184
static  int pdf14_open(gx_device * pdev);
185
static  dev_proc_close_device(pdf14_close);
186
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
187
static  dev_proc_put_params(pdf14_put_params);
188
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
189
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
190
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
191
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
192
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
193
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
194
dev_proc_encode_color(pdf14_encode_color);
195
dev_proc_encode_color(pdf14_encode_color_tag);
196
dev_proc_decode_color(pdf14_decode_color);
197
dev_proc_encode_color(pdf14_encode_color16);
198
dev_proc_encode_color(pdf14_encode_color16_tag);
199
dev_proc_decode_color(pdf14_decode_color16);
200
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
201
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
202
static  dev_proc_fill_path(pdf14_fill_path);
203
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
204
static  dev_proc_copy_mono(pdf14_copy_mono);
205
static  dev_proc_fill_mask(pdf14_fill_mask);
206
static  dev_proc_stroke_path(pdf14_stroke_path);
207
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
208
static  dev_proc_text_begin(pdf14_text_begin);
209
static  dev_proc_composite(pdf14_composite);
210
static  dev_proc_composite(pdf14_forward_composite);
211
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
212
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
213
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
214
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
215
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
216
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
217
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
218
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
219
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
220
static  dev_proc_copy_alpha(pdf14_copy_alpha);
221
static  dev_proc_copy_planes(pdf14_copy_planes);
222
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
223
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
224
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
225
static  const gx_color_map_procs *
226
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
227
228
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
229
#define YSIZE (int)(11 * Y_DPI)
230
231
/* 24-bit color. */
232
233
static void
234
pdf14_procs_initialize(gx_device *dev,
235
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
236
                       dev_proc_get_color_comp_index(get_color_comp_index),
237
                       dev_proc_encode_color(encode_color),
238
                       dev_proc_decode_color(decode_color))
239
5.02M
{
240
5.02M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
5.02M
    set_dev_proc(dev, open_device, pdf14_open);
242
5.02M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
5.02M
    set_dev_proc(dev, close_device, pdf14_close);
244
5.02M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
5.02M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
5.02M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
5.02M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
5.02M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
5.02M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
5.02M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
5.02M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
5.02M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
5.02M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
5.02M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
5.02M
    set_dev_proc(dev, composite, pdf14_composite);
256
5.02M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
5.02M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
5.02M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
5.02M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
5.02M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
5.02M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
5.02M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
5.02M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
5.02M
    set_dev_proc(dev, encode_color, encode_color);
265
5.02M
    set_dev_proc(dev, decode_color, decode_color);
266
5.02M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
5.02M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
5.02M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
5.02M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
5.02M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
5.02M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
5.02M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
5.02M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
5.02M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
5.02M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
5.02M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
5.02M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.51M
{
282
1.51M
    pdf14_procs_initialize(dev,
283
1.51M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.51M
                           gx_default_DevGray_get_color_comp_index,
285
1.51M
                           pdf14_encode_color,
286
1.51M
                           pdf14_decode_color);
287
1.51M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
3.19M
{
292
3.19M
    pdf14_procs_initialize(dev,
293
3.19M
                           gx_default_DevRGB_get_color_mapping_procs,
294
3.19M
                           gx_default_DevRGB_get_color_comp_index,
295
3.19M
                           pdf14_encode_color,
296
3.19M
                           pdf14_decode_color);
297
3.19M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
82.1k
{
302
82.1k
    pdf14_procs_initialize(dev,
303
82.1k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
82.1k
                           gx_default_DevCMYK_get_color_comp_index,
305
82.1k
                           pdf14_encode_color,
306
82.1k
                           pdf14_decode_color);
307
82.1k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
154k
{
312
154k
    pdf14_procs_initialize(dev,
313
154k
                           pdf14_cmykspot_get_color_mapping_procs,
314
154k
                           pdf14_cmykspot_get_color_comp_index,
315
154k
                           pdf14_encode_color,
316
154k
                           pdf14_decode_color);
317
154k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
72.3k
{
322
72.3k
    pdf14_procs_initialize(dev,
323
72.3k
                           pdf14_rgbspot_get_color_mapping_procs,
324
72.3k
                           pdf14_rgbspot_get_color_comp_index,
325
72.3k
                           pdf14_encode_color,
326
72.3k
                           pdf14_decode_color);
327
72.3k
}
328
329
static void
330
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           pdf14_grayspot_get_color_mapping_procs,
334
0
                           pdf14_grayspot_get_color_comp_index,
335
0
                           pdf14_encode_color,
336
0
                           pdf14_decode_color);
337
0
}
338
339
static void
340
pdf14_custom_initialize_device_procs(gx_device *dev)
341
0
{
342
0
    pdf14_procs_initialize(dev,
343
0
                           gx_forward_get_color_mapping_procs,
344
0
                           gx_forward_get_color_comp_index,
345
0
                           gx_forward_encode_color,
346
0
                           gx_forward_decode_color);
347
0
}
348
349
static struct_proc_finalize(pdf14_device_finalize);
350
351
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
352
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
353
                          pdf14_device_finalize);
354
355
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
356
                                                        gx_device * target);
357
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
358
                                                        gx_device * target);
359
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
362
/* Alter pdf14 device color model based upon group or softmask. This occurs
363
   post clist or in immediate rendering case. Data stored with buffer */
364
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
365
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
366
                              cmm_profile_t *iccprofile, bool is_mask);
367
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
368
369
/* Alter clist writer device color model based upon group or softmask. Data
370
   stored in the device color model stack */
371
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
372
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
373
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
374
375
/* Used for cleaning up the stack if things go wrong */
376
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
377
378
static const pdf14_procs_t gray_pdf14_procs = {
379
    pdf14_unpack_additive,
380
    pdf14_put_image,
381
    pdf14_unpack16_additive
382
};
383
384
static const pdf14_procs_t rgb_pdf14_procs = {
385
    pdf14_unpack_additive,
386
    pdf14_put_image,
387
    pdf14_unpack16_additive
388
};
389
390
static const pdf14_procs_t cmyk_pdf14_procs = {
391
    pdf14_unpack_subtractive,
392
    pdf14_put_image,
393
    pdf14_unpack16_subtractive
394
};
395
396
static const pdf14_procs_t cmykspot_pdf14_procs = {
397
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
398
    pdf14_cmykspot_put_image,
399
    pdf14_unpack16_custom /* should never be used since we will use devn values */
400
};
401
402
static const pdf14_procs_t rgbspot_pdf14_procs = {
403
    pdf14_unpack_rgb_mix,
404
    pdf14_cmykspot_put_image,
405
    pdf14_unpack16_rgb_mix
406
};
407
408
static const pdf14_procs_t grayspot_pdf14_procs = {
409
    pdf14_unpack_gray_mix,
410
    pdf14_cmykspot_put_image,
411
    pdf14_unpack16_gray_mix
412
};
413
414
static const pdf14_procs_t custom_pdf14_procs = {
415
    pdf14_unpack_custom,
416
    pdf14_custom_put_image,
417
    pdf14_unpack16_custom
418
};
419
420
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
421
    art_blend_luminosity_custom_8,
422
    art_blend_saturation_custom_8,
423
    art_blend_luminosity_custom_16,
424
    art_blend_saturation_custom_16
425
};
426
427
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
428
    art_blend_luminosity_rgb_8,
429
    art_blend_saturation_rgb_8,
430
    art_blend_luminosity_rgb_16,
431
    art_blend_saturation_rgb_16
432
};
433
434
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
435
    art_blend_luminosity_cmyk_8,
436
    art_blend_saturation_cmyk_8,
437
    art_blend_luminosity_cmyk_16,
438
    art_blend_saturation_cmyk_16
439
};
440
441
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
442
    art_blend_luminosity_rgb_8,
443
    art_blend_saturation_rgb_8,
444
    art_blend_luminosity_rgb_16,
445
    art_blend_saturation_rgb_16
446
};
447
448
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
449
    art_blend_luminosity_custom_8,
450
    art_blend_saturation_custom_8,
451
    art_blend_luminosity_custom_16,
452
    art_blend_saturation_custom_16
453
};
454
455
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
456
    art_blend_luminosity_custom_8,
457
    art_blend_saturation_custom_8,
458
    art_blend_luminosity_custom_16,
459
    art_blend_saturation_custom_16
460
};
461
462
const pdf14_device gs_pdf14_Gray_device = {
463
    std_device_std_color_full_body_type(pdf14_device,
464
                                        pdf14_Gray_initialize_device_procs,
465
                                        "pdf14gray",
466
                                        &st_pdf14_device,
467
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
468
                                        0, 0, 0, 0, 0, 0),
469
    { 0 },      /* Procs */
470
    NULL,     /* target */
471
    { 0 },      /* devn_params - not used */
472
    &gray_pdf14_procs,
473
    &gray_blending_procs,
474
    1
475
};
476
477
const pdf14_device gs_pdf14_RGB_device = {
478
    std_device_color_stype_body(pdf14_device,
479
                                pdf14_RGB_initialize_device_procs,
480
                                "pdf14RGB",
481
                                &st_pdf14_device,
482
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
483
    { 0 },      /* Procs */
484
    NULL,     /* target */
485
    { 0 },      /* devn_params - not used */
486
    &rgb_pdf14_procs,
487
    &rgb_blending_procs,
488
    3
489
};
490
491
const pdf14_device gs_pdf14_CMYK_device = {
492
    std_device_std_color_full_body_type(pdf14_device,
493
                                        pdf14_CMYK_initialize_device_procs,
494
                                        "pdf14cmyk",
495
                                        &st_pdf14_device,
496
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
497
                                        0, 0, 0, 0, 0, 0),
498
    { 0 },      /* Procs */
499
    NULL,     /* target */
500
    { 0 },      /* devn_params - not used */
501
    &cmyk_pdf14_procs,
502
    &cmyk_blending_procs,
503
    4
504
};
505
506
const pdf14_device gs_pdf14_CMYKspot_device = {
507
    std_device_part1_(pdf14_device,
508
                      pdf14_CMYKspot_initialize_device_procs,
509
                      "pdf14cmykspot",
510
                      &st_pdf14_device,
511
                      open_init_closed),
512
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
513
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
514
    offset_margin_values(0, 0, 0, 0, 0, 0),
515
    std_device_part3_(),
516
    { 0 },      /* Procs */
517
    NULL,     /* target */
518
    /* DeviceN parameters */
519
    { 8,      /* Not used - Bits per color */
520
      DeviceCMYKComponents, /* Names of color model colorants */
521
      4,      /* Number colorants for CMYK */
522
      0,      /* MaxSeparations has not been specified */
523
      -1,     /* PageSpotColors has not been specified */
524
      {0},      /* SeparationNames */
525
      0,      /* SeparationOrder names */
526
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
527
    },
528
    &cmykspot_pdf14_procs,
529
    &cmyk_blending_procs,
530
    4
531
};
532
533
const pdf14_device gs_pdf14_RGBspot_device = {
534
    std_device_part1_(pdf14_device,
535
                      pdf14_RGBspot_initialize_device_procs,
536
                      "pdf14rgbspot",
537
                      &st_pdf14_device,
538
                      open_init_closed),
539
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
540
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
541
    offset_margin_values(0, 0, 0, 0, 0, 0),
542
    std_device_part3_(),
543
    { 0 },      /* Procs */
544
    NULL,     /* target */
545
                    /* DeviceN parameters */
546
    { 8,      /* Not used - Bits per color */
547
    0,              /* Names of color model colorants */
548
    3,          /* Number colorants for RGB */
549
    0,          /* MaxSeparations has not been specified */
550
    -1,         /* PageSpotColors has not been specified */
551
    { 0 },      /* SeparationNames */
552
    0,          /* SeparationOrder names */
553
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
554
    },
555
    &rgbspot_pdf14_procs,
556
    &rgbspot_blending_procs,
557
    3
558
};
559
560
const pdf14_device gs_pdf14_Grayspot_device = {
561
    std_device_part1_(pdf14_device,
562
                      pdf14_Grayspot_initialize_device_procs,
563
                      "pdf14grayspot",
564
                      &st_pdf14_device,
565
                      open_init_closed),
566
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
567
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
568
    offset_margin_values(0, 0, 0, 0, 0, 0),
569
    std_device_part3_(),
570
    { 0 },      /* Procs */
571
    NULL,     /* target */
572
                    /* DeviceN parameters */
573
    { 8,      /* Not used - Bits per color */
574
    0,              /* Names of color model colorants */
575
    3,          /* Number colorants for RGB */
576
    0,          /* MaxSeparations has not been specified */
577
    -1,         /* PageSpotColors has not been specified */
578
    { 0 },      /* SeparationNames */
579
    0,          /* SeparationOrder names */
580
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
581
    },
582
    &grayspot_pdf14_procs,
583
    &grayspot_blending_procs,
584
    1
585
};
586
587
/*
588
 * The 'custom' PDF 1.4 compositor device is for working with those devices
589
 * which support spot colors but do not have a CMYK process color model.
590
 *
591
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
592
 * blending modes.  These blending modes are 'non separable' and depend upon
593
 * knowing the details of the blending color space.  However we use the
594
 * process color model of the output device for our blending color space.
595
 * With an unknown process color model, we have to fall back to some 'guesses'
596
 * about how to treat these blending modes.
597
 */
598
const pdf14_device gs_pdf14_custom_device = {
599
    std_device_part1_(pdf14_device,
600
                      pdf14_custom_initialize_device_procs,
601
                      "pdf14custom",
602
                      &st_pdf14_device,
603
                      open_init_closed),
604
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
605
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
606
    offset_margin_values(0, 0, 0, 0, 0, 0),
607
    std_device_part3_(),
608
    { 0 },      /* Procs */
609
    NULL,     /* target */
610
    /* DeviceN parameters */
611
    { 8,      /* Not used - Bits per color */
612
      DeviceCMYKComponents, /* Names of color model colorants */
613
      4,      /* Number colorants for CMYK */
614
      0,      /* MaxSeparations has not been specified */
615
      -1,     /* PageSpotColors has not been specified */
616
      {0},      /* SeparationNames */
617
      0,      /* SeparationOrder names */
618
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
619
    },
620
    &custom_pdf14_procs,
621
    &custom_blending_procs,
622
    4
623
};
624
625
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
626
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
627
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
628
629
static dev_proc_print_page(no_print_page);
630
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
631
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
632
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
633
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
634
635
static int
636
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
637
0
{
638
0
    return_error(gs_error_unknownerror);
639
0
}
640
641
struct gx_device_pdf14_accum_s {
642
    gx_devn_prn_device_common;
643
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
644
};
645
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
646
647
int
648
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
649
4.36M
{
650
4.36M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
4.36M
    if (dev_spec_op == gxdso_device_child) {
653
2.46k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
2.46k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
2.46k
        req->target = adev->save_p14dev;
657
2.46k
        req->n = 0;
658
2.46k
        return 0;
659
2.46k
    }
660
661
4.36M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
4.36M
}
663
664
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
665
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
666
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
667
668
static void
669
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
670
960
{
671
960
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
960
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
960
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
960
}
676
677
const gx_device_pdf14_accum pdf14_accum_Gray = {
678
    prn_device_stype_body(gx_device_pdf14_accum,
679
                          pdf14_accum_Gray_initialize_device_procs,
680
                          "pdf14-accum-Gray",
681
                          &st_gx_devn_accum_device,
682
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
683
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
684
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
685
                          256/*dither_grays*/, 0/*dither_colors*/,
686
                          no_print_page),
687
    { 0 },      /* devn_params - not used */
688
    { 0 },      /* equivalent_cmyk_color_params - not used */
689
    0/*save_p14dev*/
690
};
691
692
static void
693
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
694
3.00k
{
695
3.00k
    gdev_prn_initialize_device_procs_rgb(dev);
696
3.00k
}
697
698
const gx_device_pdf14_accum pdf14_accum_RGB = {
699
    prn_device_stype_body(gx_device_pdf14_accum,
700
                          pdf14_accum_RGB_initialize_device_procs,
701
                          "pdf14-accum-RGB",
702
                          &st_gx_devn_accum_device,
703
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
704
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
705
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
706
                          1/*dither_grays*/, 256/*dither_colors*/,
707
                          no_print_page),
708
    { 0 },      /* devn_params - not used */
709
    { 0 },      /* equivalent_cmyk_color_params - not used */
710
    0/*save_p14dev*/
711
};
712
713
static void
714
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
715
0
{
716
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
717
718
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
719
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
720
0
}
721
722
const gx_device_pdf14_accum pdf14_accum_CMYK = {
723
    prn_device_stype_body(gx_device_pdf14_accum,
724
                          pdf14_accum_CMYK_initialize_device_procs,
725
                          "pdf14-accum-CMYK",
726
                          &st_gx_devn_accum_device,
727
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
728
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
729
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
730
                          256/*dither_grays*/, 256/*dither_colors*/,
731
                          no_print_page),
732
    { 0 },      /* devn_params - not used */
733
    { 0 },      /* equivalent_cmyk_color_params - not used */
734
    0/*save_p14dev*/
735
};
736
737
static void
738
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
739
0
{
740
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
741
742
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
743
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
744
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
745
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
746
0
}
747
748
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
749
    prn_device_stype_body(gx_device_pdf14_accum,
750
                          pdf14_accum_initialize_device_procs_cmykspot,
751
                          "pdf14-accum-CMYKspot",
752
                          &st_gx_devn_accum_device,
753
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
754
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
755
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
756
                          256/*dither_grays*/, 256/*dither_colors*/,
757
                          no_print_page),
758
    /* DeviceN parameters */
759
    { 8,      /* Not used - Bits per color */
760
      DeviceCMYKComponents, /* Names of color model colorants */
761
      4,      /* Number colorants for CMYK */
762
      0,      /* MaxSeparations has not been specified */
763
      -1,     /* PageSpotColors has not been specified */
764
      { 0 },      /* SeparationNames */
765
      0,      /* SeparationOrder names */
766
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
767
    },
768
    { true },     /* equivalent_cmyk_color_params */
769
    0/*save_p14dev*/
770
};
771
772
/* GC procedures */
773
static
774
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
775
0
{
776
0
    index -= 5;
777
0
    if (index < pdev->devn_params.separations.num_separations)
778
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
779
0
    index -= pdev->devn_params.separations.num_separations;
780
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
781
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
782
0
    return 0;
783
0
}
784
0
case 0: return ENUM_OBJ(pdev->ctx);
785
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
786
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
787
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
788
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
789
0
ENUM_PTRS_END
790
791
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
792
0
{
793
0
    {
794
0
        int i;
795
796
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
797
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
798
0
        }
799
0
    }
800
0
    RELOC_VAR(pdev->ctx);
801
0
    RELOC_VAR(pdev->smaskcolor);
802
0
    RELOC_VAR(pdev->color_model_stack);
803
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
804
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
805
0
}
806
0
RELOC_PTRS_END
807
808
/* ------ Private definitions ------ */
809
810
static void
811
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
812
              int width, int height, cmm_profile_t *src_profile, int deep)
813
1.11k
{
814
1.11k
    if (deep) {
815
0
        int x, y, i;
816
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
817
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
818
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
819
820
0
        src_planestride >>= 1;
821
0
        src_rowstride >>= 1;
822
823
0
        for (y = 0; y < height; y++) {
824
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
825
0
            uint16_t *src_curr_ptr = src_row_ptr;
826
0
            for (x = 0; x < width; x++) {
827
0
                uint16_t idx = *mask_curr_ptr;
828
0
                byte     top = idx>>8;
829
0
                uint16_t a   = mask_tr_fn[top];
830
0
                int      b   = mask_tr_fn[top+1]-a;
831
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
832
833
                /* matte's happen rarely enough that we allow ourselves to
834
                 * resort to 64bit here. */
835
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
836
0
                    for (i = 0; i < src_profile->num_comps; i++) {
837
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
838
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
839
840
                        /* clip */
841
0
                        if (temp > 0xffff)
842
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
843
0
                        else if (temp < 0)
844
0
                            src_curr_ptr[i * src_planestride] = 0;
845
0
                        else
846
0
                            src_curr_ptr[i * src_planestride] = temp;
847
0
                    }
848
0
                }
849
0
                mask_curr_ptr++;
850
0
                src_curr_ptr++;
851
0
            }
852
0
            src_row_ptr += src_rowstride;
853
0
            mask_row_ptr += (maskbuf->rowstride>>1);
854
0
        }
855
1.11k
    } else {
856
1.11k
        int x, y, i;
857
1.11k
        byte *mask_row_ptr  = maskbuf->data;
858
1.11k
        byte *src_row_ptr   = src_data;
859
1.11k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
860
861
14.2k
        for (y = 0; y < height; y++) {
862
13.1k
            byte *mask_curr_ptr = mask_row_ptr;
863
13.1k
            byte *src_curr_ptr = src_row_ptr;
864
16.6M
            for (x = 0; x < width; x++) {
865
16.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
866
16.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
867
9.15M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
6.86M
                        byte matte = maskbuf->matte[i]>>8;
869
6.86M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
6.86M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
6.86M
                        if (temp > 0xff)
874
4.91M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
1.95M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
1.95M
                        else
878
1.95M
                            src_curr_ptr[i * src_planestride] = temp;
879
6.86M
                    }
880
2.28M
                }
881
16.6M
                mask_curr_ptr++;
882
16.6M
                src_curr_ptr++;
883
16.6M
            }
884
13.1k
            src_row_ptr += src_rowstride;
885
13.1k
            mask_row_ptr += maskbuf->rowstride;
886
13.1k
        }
887
1.11k
    }
888
1.11k
}
889
890
/* Transform of color data and copy noncolor data.  Used in
891
   group pop and during the pdf14 put image calls when the blend color space
892
   is different than the target device color space.  The function will try do
893
   in-place conversion if possible.  If not, it will do an allocation.  The
894
   put_image call needs to know if an allocation was made so that it can adjust
895
   for the fact that we likely don't have a full page any longer and we don't
896
   need to do the offset to our data in the buffer. Bug 700686: If we are in
897
   a softmask that includes a matte entry, then we need to undo the matte
898
   entry here at this time in the image's native color space not the parent
899
   color space.   The endian_swap term here is only set to true if the data
900
   has been baked as BE during the put_image blending operation and we are
901
   on a LE machine.  */
902
static forceinline pdf14_buf*
903
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
904
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
905
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
906
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
907
11.7k
{
908
11.7k
    gsicc_rendering_param_t rendering_params;
909
11.7k
    gsicc_link_t *icc_link;
910
11.7k
    gsicc_bufferdesc_t src_buff_desc;
911
11.7k
    gsicc_bufferdesc_t des_buff_desc;
912
11.7k
    intptr_t src_planestride = src_buf->planestride;
913
11.7k
    intptr_t src_rowstride = src_buf->rowstride;
914
11.7k
    int src_n_planes = src_buf->n_planes;
915
11.7k
    int src_n_chan = src_buf->n_chan;
916
11.7k
    intptr_t des_planestride = src_planestride;
917
11.7k
    intptr_t des_rowstride = src_rowstride;
918
11.7k
    int des_n_planes = src_n_planes;
919
11.7k
    int des_n_chan = src_n_chan;
920
11.7k
    int diff;
921
11.7k
    int k, j;
922
11.7k
    byte *des_data = NULL;
923
11.7k
    pdf14_buf *output = src_buf;
924
11.7k
    pdf14_mask_t *mask_stack;
925
11.7k
    pdf14_buf *maskbuf;
926
11.7k
    int code;
927
928
11.7k
    *did_alloc = false;
929
930
    /* Same profile */
931
11.7k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
932
0
        return src_buf;
933
934
    /* Define the rendering intent get the link */
935
11.7k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
936
11.7k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
937
11.7k
    rendering_params.override_icc = false;
938
11.7k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
939
11.7k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
940
11.7k
    rendering_params.cmm = gsCMM_DEFAULT;
941
11.7k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
942
11.7k
        &rendering_params, pgs->memory, false);
943
11.7k
    if (icc_link == NULL)
944
0
        return NULL;
945
946
    /* If different data sizes, we have to do an allocation */
947
11.7k
    diff = des_profile->num_comps - src_profile->num_comps;
948
11.7k
    if (diff != 0) {
949
11.2k
        byte *src_ptr;
950
11.2k
        byte *des_ptr;
951
952
11.2k
        *did_alloc = true;
953
11.2k
        des_rowstride = ((width + 3) & -4)<<deep;
954
11.2k
        des_planestride = height * des_rowstride;
955
11.2k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
11.2k
        des_n_chan = src_n_chan + diff;
957
11.2k
        des_data = gs_alloc_bytes(ctx->memory,
958
11.2k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
11.2k
                                  "pdf14_transform_color_buffer");
960
11.2k
        if (des_data == NULL)
961
0
            return NULL;
962
963
        /* Copy over the noncolor planes. May only be a dirty part, so have
964
           to copy row by row */
965
11.2k
        src_ptr = src_data;
966
11.2k
        des_ptr = des_data;
967
125k
        for (j = 0; j < height; j++) {
968
229k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
114k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
114k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
114k
                       width<<deep);
972
114k
            }
973
114k
            src_ptr += src_rowstride;
974
114k
            des_ptr += des_rowstride;
975
114k
        }
976
11.2k
    } else
977
460
        des_data = src_data;
978
979
    /* Set up the buffer descriptors. */
980
11.7k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
981
11.7k
                      false, true, src_planestride, src_rowstride, height, width);
982
11.7k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
983
11.7k
                      false, true, des_planestride, des_rowstride, height, width);
984
985
11.7k
    src_buff_desc.endian_swap = endian_swap;
986
11.7k
    des_buff_desc.endian_swap = endian_swap;
987
988
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
989
       context to ensure that this is not done again during the group
990
       composition */
991
11.7k
    if (has_matte &&
992
        /* Should always happen, but check for safety */
993
1.66k
        ((mask_stack = ctx->mask_stack) != NULL) &&
994
1.66k
        ((maskbuf = mask_stack->mask_buf) != NULL) &&
995
1.66k
         (maskbuf->data != NULL))
996
1.11k
    {
997
1.11k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
998
1.11k
    }
999
1000
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1001
       Gray buffers, this transform does not need to worry about the cmap procs
1002
       of the target device. */
1003
11.7k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1004
11.7k
        src_data, des_data);
1005
11.7k
    gsicc_release_link(icc_link);
1006
11.7k
    if (code < 0)
1007
0
        return NULL;
1008
1009
11.7k
    output->planestride = des_planestride;
1010
11.7k
    output->rowstride = des_rowstride;
1011
11.7k
    output->n_planes = des_n_planes;
1012
11.7k
    output->n_chan = des_n_chan;
1013
    /* If not in-place conversion, then release. */
1014
11.7k
    if (des_data != src_data) {
1015
11.2k
        gs_free_object(ctx->memory, output->data,
1016
11.2k
            "pdf14_transform_color_buffer");
1017
11.2k
        output->data = des_data;
1018
        /* Note, this is needed for case where we did a put image, as the
1019
           resulting transformed buffer may not be a full page. */
1020
11.2k
        output->rect.p.x = x0;
1021
11.2k
        output->rect.p.y = y0;
1022
11.2k
        output->rect.q.x = x0 + width;
1023
11.2k
        output->rect.q.y = y0 + height;
1024
11.2k
    }
1025
11.7k
    return output;
1026
11.7k
}
1027
1028
/* This is a routine to do memset's but with 16 bit values.
1029
 * Note, that we still take bytes, NOT "num values to set".
1030
 * We assume dest is 16 bit aligned. We assume that bytes is
1031
 * a multiple of 2. */
1032
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1033
0
{
1034
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1035
0
    uint32_t v;
1036
0
    if (bytes < 0)
1037
0
        return;
1038
0
    if (((intptr_t)dest) & 2) {
1039
0
        *dest++ = value;
1040
0
        bytes--;
1041
0
        if (bytes == 0)
1042
0
            return;
1043
0
    }
1044
0
    v = value | (value<<16);
1045
0
    bytes -= 2;
1046
0
    while (bytes > 0) {
1047
0
        *(uint32_t *)dest = v;
1048
0
        dest += 2;
1049
0
        bytes -= 4;
1050
0
    }
1051
0
    bytes += 2;
1052
0
    if (bytes & 2) {
1053
0
        *dest = value;
1054
0
    }
1055
0
}
1056
1057
static pdf14_buf*
1058
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1059
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1060
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1061
    bool deep, bool endian_swap, int num_channels_to_lose)
1062
10.0k
{
1063
10.0k
    if (deep)
1064
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1065
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1066
10.0k
    else
1067
10.0k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
10.0k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
10.0k
}
1070
1071
static pdf14_buf*
1072
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1073
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1074
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1075
    bool deep, bool endian_swap)
1076
1.66k
{
1077
1.66k
    if (deep)
1078
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1079
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1080
1.66k
    else
1081
1.66k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1082
1.66k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1083
1.66k
}
1084
1085
/**
1086
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1087
 * @n_chan: Number of pixel channels including alpha, but not including
1088
 * shape, group alpha, or tags.
1089
 *
1090
 * Return value: Newly allocated buffer, or NULL on failure.
1091
 **/
1092
static  pdf14_buf *
1093
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1094
              bool has_shape, bool idle, int n_chan, int num_spots,
1095
              gs_memory_t *memory, bool deep)
1096
3.27M
{
1097
1098
    /* Note that alpha_g is the alpha for the GROUP */
1099
    /* This is distinct from the alpha that may also exist */
1100
    /* for the objects within the group.  Hence it can introduce */
1101
    /* yet another plane */
1102
1103
3.27M
    pdf14_buf *result;
1104
3.27M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
3.27M
    int64_t height = (rect->q.y - rect->p.y);
1106
3.27M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
3.27M
                   (has_tags ? 1 : 0);
1108
3.27M
    size_t planestride;
1109
#if ARCH_SIZEOF_SIZE_T <= 4
1110
    int64_t dsize = rowstride * height * n_planes;
1111
1112
    if (dsize > max_size_t)
1113
        return NULL;
1114
#endif
1115
1116
3.27M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
3.27M
                             "pdf14_buf_new");
1118
3.27M
    if (result == NULL)
1119
0
        return result;
1120
1121
3.27M
    result->memory = memory;
1122
3.27M
    result->backdrop = NULL;
1123
3.27M
    result->saved = NULL;
1124
3.27M
    result->isolated = false;
1125
3.27M
    result->knockout = false;
1126
3.27M
    result->has_alpha_g = has_alpha_g;
1127
3.27M
    result->has_shape = has_shape;
1128
3.27M
    result->has_tags = has_tags;
1129
3.27M
    result->rect = *rect;
1130
3.27M
    result->n_chan = n_chan;
1131
3.27M
    result->n_planes = n_planes;
1132
3.27M
    result->rowstride = rowstride;
1133
3.27M
    result->transfer_fn = NULL;
1134
3.27M
    result->is_ident = true;
1135
3.27M
    result->matte_num_comps = 0;
1136
3.27M
    result->matte = NULL;
1137
3.27M
    result->mask_stack = NULL;
1138
3.27M
    result->idle = idle;
1139
3.27M
    result->mask_id = 0;
1140
3.27M
    result->num_spots = num_spots;
1141
3.27M
    result->deep = deep;
1142
3.27M
    result->page_group = false;
1143
3.27M
    result->group_color_info = NULL;
1144
3.27M
    result->group_popped = false;
1145
1146
3.27M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.45M
        result->planestride = 0;
1149
1.45M
        result->data = 0;
1150
1.82M
    } else {
1151
1.82M
        planestride = rowstride * height;
1152
1.82M
        result->planestride = planestride;
1153
1.82M
        result->data = gs_alloc_bytes(memory,
1154
1.82M
                                      planestride * n_planes + CAL_SLOP,
1155
1.82M
                                      "pdf14_buf_new");
1156
1.82M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.82M
        if (has_alpha_g) {
1161
436k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
436k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
436k
        }
1165
1.82M
        if (has_tags) {
1166
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
0
            memset (result->data + tags_plane * planestride,
1169
0
                    GS_UNTOUCHED_TAG, planestride);
1170
0
        }
1171
1.82M
    }
1172
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1173
     * Any future drawing will make it valid again, so we won't blend back
1174
     * more than we need. */
1175
3.27M
    result->dirty.p.x = rect->q.x;
1176
3.27M
    result->dirty.p.y = rect->q.y;
1177
3.27M
    result->dirty.q.x = rect->p.x;
1178
3.27M
    result->dirty.q.y = rect->p.y;
1179
3.27M
    return result;
1180
3.27M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
3.27M
{
1185
3.27M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
3.27M
    gs_memory_t *memory = buf->memory;
1187
1188
3.27M
    if (buf->mask_stack)
1189
3.27M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
3.27M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
3.27M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
3.27M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
6.55M
    while (group_color_info) {
1196
3.27M
       if (group_color_info->icc_profile != NULL) {
1197
3.27M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
3.27M
       }
1199
3.27M
       buf->group_color_info = group_color_info->previous;
1200
3.27M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
3.27M
       group_color_info = buf->group_color_info;
1202
3.27M
    }
1203
1204
3.27M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
3.27M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
3.27M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
1.14M
{
1211
1.14M
    pdf14_ctx *result;
1212
1.14M
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
1.14M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
1.14M
    if (result == NULL)
1216
0
        return result;
1217
1.14M
    result->stack = NULL;
1218
1.14M
    result->mask_stack = pdf14_mask_element_new(memory);
1219
1.14M
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
1.14M
    result->memory = memory;
1224
1.14M
    result->smask_depth = 0;
1225
1.14M
    result->smask_blend = false;
1226
1.14M
    result->deep = deep;
1227
1.14M
    result->base_color = NULL;
1228
1.14M
    return result;
1229
1.14M
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
1.14M
{
1234
1.14M
    pdf14_buf *buf, *next;
1235
1236
1.14M
    if (ctx->base_color) {
1237
612k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
612k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
612k
    }
1240
1.14M
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
552k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
552k
    }
1244
2.11M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
978k
        next = buf->saved;
1246
978k
        pdf14_buf_free(buf);
1247
978k
    }
1248
1.14M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
1.14M
}
1250
1251
/**
1252
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1253
 *
1254
 * Return value: Backdrop buffer for current group operation, or NULL
1255
 * if backdrop is fully transparent.
1256
 **/
1257
static  pdf14_buf *
1258
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1259
1.00M
{
1260
    /* Our new buffer is buf */
1261
1.00M
    pdf14_buf *buf = ctx->stack;
1262
1263
1.00M
    *is_backdrop = false;
1264
1265
1.00M
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
1.00M
        if (buf->isolated) return NULL;
1268
1269
        /* If the previous buffer is a knockout group
1270
           then we need to use its backdrop as the backdrop. If
1271
           it was isolated then that back drop was NULL */
1272
436k
        if (buf->saved != NULL && buf->saved->knockout) {
1273
            /* Per the spec, if we have a non-isolated group
1274
               in a knockout group the non-isolated group
1275
               uses the backdrop of its parent group (the knockout group)
1276
               as its own backdrop.  The non-isolated group must
1277
               go through the standard re-composition operation
1278
               to avoid the double application of the backdrop */
1279
27
            *is_backdrop = true;
1280
27
            return buf->saved;
1281
27
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
436k
        if (buf->saved != NULL) {
1285
436k
            return buf->saved;
1286
436k
        }
1287
436k
    }
1288
0
    return NULL;
1289
1.00M
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
612k
{
1294
612k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
612k
    pdf14_group_color_t* group_color;
1296
612k
    bool deep = pdev->ctx->deep;
1297
612k
    bool has_tags = device_encodes_tags(dev);
1298
1299
612k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
612k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
612k
        pdf14_group_color_t, &st_pdf14_clr,
1303
612k
        "pdf14_make_base_group_color");
1304
1305
612k
    if (group_color == NULL)
1306
0
        return NULL;
1307
612k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
612k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
612k
    group_color->blend_procs = pdev->blend_procs;
1311
612k
    group_color->polarity = pdev->color_info.polarity;
1312
612k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
612k
    group_color->isadditive = pdev->ctx->additive;
1314
612k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
612k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
612k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
612k
    group_color->depth = pdev->color_info.depth;
1318
612k
    group_color->decode = dev_proc(pdev, decode_color);
1319
612k
    group_color->encode = dev_proc(pdev, encode_color);
1320
612k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
612k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
612k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
612k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
612k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
612k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
612k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
612k
    group_color->icc_profile =
1328
612k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
612k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
612k
    return group_color;
1332
612k
}
1333
1334
/* This wil create the first buffer when we have
1335
   either the first drawing operation or transparency
1336
   group push.  At that time, the color space in which
1337
   we are going to be doing the alpha blend will be known. */
1338
static int
1339
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1340
409M
{
1341
409M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
409M
    bool has_tags = device_encodes_tags(dev);
1343
409M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
409M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
409M
    int num_spots = pdev->ctx->num_spots;
1346
409M
    pdf14_buf* buf;
1347
409M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
409M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1351
0
        pdev->ctx->stack->idle) {
1352
0
        pdf14_buf_free(pdev->ctx->stack);
1353
0
        pdev->ctx->stack = NULL;
1354
0
    }
1355
1356
409M
    if (pdev->ctx->stack != NULL)
1357
409M
        return 0;
1358
1359
409M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
541k
        dev->width, dev->height);
1361
1362
541k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
541k
        num_spots, memory, pdev->ctx->deep);
1364
541k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
541k
    if_debug5m('v', memory,
1368
541k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
541k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
541k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
541k
    buf->saved = NULL;
1373
541k
    pdev->ctx->stack = buf;
1374
541k
    pdev->ctx->additive = additive;
1375
1376
    /* Every buffer needs group color information including the base
1377
       one that is created for when we have no group */
1378
541k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
541k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
541k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
541k
    if (pgs != NULL)
1384
277k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
263k
    else
1386
263k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
541k
    buf->group_color_info->group_color_mapping_procs =
1389
541k
        dev_proc(pdev, get_color_mapping_procs);
1390
541k
    buf->group_color_info->group_color_comp_index =
1391
541k
        dev_proc(pdev, get_color_comp_index);
1392
541k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
541k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
541k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
541k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
541k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
541k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
541k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
541k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
541k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
541k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
541k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
541k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
541k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
541k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
541k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
541k
    buf->group_color_info->icc_profile =
1408
541k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
541k
    if (buf->group_color_info->icc_profile != NULL)
1410
541k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
541k
    return 0;
1413
541k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
19.9k
{
1418
19.9k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
19.9k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
19.9k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
19.9k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
19.9k
    if (des->icc_profile != NULL)
1425
19.9k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
19.9k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
19.9k
    return des;
1429
19.9k
}
1430
1431
static  int
1432
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1433
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1434
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1435
                              int numcomps, bool cm_back_drop, bool shade_group,
1436
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1437
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1438
                              gx_device *dev)
1439
2.30M
{
1440
2.30M
    pdf14_buf *tos = ctx->stack;
1441
2.30M
    pdf14_buf *buf, * pdf14_backdrop;
1442
2.30M
    bool has_shape = false;
1443
2.30M
    bool is_backdrop;
1444
2.30M
    int num_spots;
1445
1446
2.30M
    if_debug1m('v', ctx->memory,
1447
2.30M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
2.30M
    if (tos != NULL)
1450
1.86M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
2.30M
    if (ctx->smask_depth > 0)
1453
962
        num_spots = 0;
1454
2.30M
    else
1455
2.30M
        num_spots = ctx->num_spots;
1456
1457
1458
2.30M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
2.30M
                        num_spots, ctx->memory, ctx->deep);
1460
2.30M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
2.30M
    if_debug4m('v', ctx->memory,
1464
2.30M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
2.30M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
2.30M
    buf->isolated = isolated;
1467
2.30M
    buf->knockout = knockout;
1468
2.30M
    buf->alpha = alpha;
1469
2.30M
    buf->shape = shape;
1470
2.30M
    buf->opacity = opacity;
1471
2.30M
    buf->blend_mode = blend_mode;
1472
2.30M
    buf->mask_id = mask_id;
1473
2.30M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
2.30M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
2.30M
    buf->saved = tos;
1478
2.30M
    buf->group_color_info = group_color;
1479
1480
2.30M
    if (tos == NULL)
1481
436k
        buf->page_group = true;
1482
1483
2.30M
    ctx->stack = buf;
1484
2.30M
    if (buf->data == NULL)
1485
1.30M
        return 0;
1486
1.00M
    if (idle)
1487
0
        return 0;
1488
1.00M
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
1.00M
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1492
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1493
        /* Memsetting by 0, so this copes with the deep case too */
1494
565k
        memset(buf->data, 0, buf->planestride *
1495
565k
                                          (buf->n_chan +
1496
565k
                                           (buf->has_shape ? 1 : 0) +
1497
565k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
565k
    } else {
1499
436k
        if (!cm_back_drop) {
1500
436k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
436k
                                    );
1505
436k
        } else {
1506
            /* We must have an non-isolated group with a mismatch in color spaces.
1507
                In this case, we can't just copy the buffer but must CM it */
1508
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1509
0
                                        ctx->memory, pgs, dev, is_backdrop);
1510
0
        }
1511
436k
    }
1512
1513
    /* If our new group is a non-isolated knockout group, we have to maintain
1514
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1515
       knockout group. They have to always blend with the groups backdrop
1516
       not what is currently drawn in the group. Selection of the backdrop
1517
       depends upon the properties of the parent group. For example, if
1518
       the parent itself is a knockout group we actually
1519
       need to blend with its backdrop. This could be NULL if the parent was
1520
       an isolated knockout group. */
1521
1.00M
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
39.3k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
39.3k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
39.3k
                                       "pdf14_push_transparency_group");
1525
39.3k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
39.3k
        memcpy(buf->backdrop, buf->data,
1530
39.3k
               buf->planestride * buf->n_planes);
1531
1532
#if RAW_DUMP
1533
        /* Dump the current buffer to see what we have. */
1534
        dump_raw_buffer(ctx->memory,
1535
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1536
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1537
            ctx->stack->planestride, ctx->stack->rowstride,
1538
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1539
        global_index++;
1540
#endif
1541
39.3k
    }
1542
#if RAW_DUMP
1543
    /* Dump the current buffer to see what we have. */
1544
    dump_raw_buffer(ctx->memory,
1545
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1546
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1547
                    ctx->stack->planestride, ctx->stack->rowstride,
1548
                    "TransGroupPush", ctx->stack->data, buf->deep);
1549
    global_index++;
1550
#endif
1551
1.00M
    return 0;
1552
1.00M
}
1553
1554
static  int
1555
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1556
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1557
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1558
2.30M
{
1559
2.30M
    pdf14_buf *tos = ctx->stack;
1560
2.30M
    pdf14_buf *nos = tos->saved;
1561
2.30M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
2.30M
    pdf14_buf *maskbuf;
1563
2.30M
    int x0, x1, y0, y1;
1564
2.30M
    int nos_num_color_comp;
1565
2.30M
    bool no_icc_match;
1566
2.30M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
2.30M
    bool overprint = pdev->overprint;
1568
2.30M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
2.30M
    bool has_matte = false;
1570
2.30M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
2.30M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
2.30M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
3.84k
        has_matte = true;
1578
1579
    /* Check if this is our last buffer, if yes, there is nothing to
1580
       compose to.  Keep this buffer until we have the put image.
1581
       If we have another group push, this group must be destroyed.
1582
       This only occurs sometimes when at clist creation time
1583
       push_shfill_group occured and nothing was drawn in this group.
1584
       There is also the complication if we have a softmask.  There
1585
       are two approaches to this problem.  Apply the softmask during
1586
       the put image or handle it now.  I choose the later as the
1587
       put_image code is already way to complicated. */
1588
2.30M
    if (nos == NULL && maskbuf == NULL) {
1589
435k
        tos->group_popped = true;
1590
435k
        return 0;
1591
435k
    }
1592
1593
    /* Here is the case with the soft mask.  Go ahead and create a new
1594
       target buffer (nos) with the same color information etc, but blank
1595
       and go ahead and do the blend with the softmask so that it gets applied. */
1596
1.86M
    if (nos == NULL && maskbuf != NULL) {
1597
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1598
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1599
0
        if (nos == NULL) {
1600
0
            code = gs_error_VMerror;
1601
0
            goto exit;
1602
0
        }
1603
1604
0
        if_debug4m('v', ctx->memory,
1605
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1606
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1607
1608
0
        nos->dirty = tos->dirty;
1609
0
        nos->isolated = tos->isolated;
1610
0
        nos->knockout = tos->knockout;
1611
0
        nos->alpha = 65535;
1612
0
        nos->shape = 65535;
1613
0
        nos->opacity = 65535;
1614
0
        nos->blend_mode = tos->blend_mode;
1615
0
        nos->mask_id = tos->mask_id;
1616
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1617
1618
0
        if (nos->data != NULL)
1619
0
            memset(nos->data, 0,
1620
0
                   nos->planestride * (nos->n_chan +
1621
0
                                       (nos->has_shape ? 1 : 0) +
1622
0
                                       (nos->has_alpha_g ? 1 : 0)));
1623
0
    }
1624
1625
    /* Before we get started, lets see if we have somehow gotten into
1626
       what should be an impossible situation where the group color
1627
       information does not match the buffer color information. This
1628
       can occur is there were memory issues that have perhaps blown
1629
       away information, or in the example of Bug 705197 the PDF interpreter
1630
       reuses a pattern during a circular reference causing an aliasing
1631
       of two nested patterns, one of which has a softmask. The change in
1632
       the buffer size of the inner one blows away the buffer of the
1633
       outer one leading to a mismatch of color spaces. Here
1634
       we can at least catch the case when the color space sizes have
1635
       changed and avoid buffer over-runs that would occur when we try
1636
       to do the group composition */
1637
1.86M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
1.86M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
1.86M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
1.86M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1643
1644
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1645
     * have made them overly large. */
1646
1.86M
    rect_intersect(tos->dirty, tos->rect);
1647
1.86M
    rect_intersect(nos->dirty, nos->rect);
1648
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1649
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1650
1.86M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
1.86M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
1.86M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
1.86M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
1.86M
    if (ctx->mask_stack) {
1655
        /* This can occur when we have a situation where we are ending out of
1656
           a group that has internal to it a soft mask and another group.
1657
           The soft mask left over from the previous trans group pop is put
1658
           into ctx->masbuf, since it is still active if another trans group
1659
           push occurs to use it.  If one does not occur, but instead we find
1660
           ourselves popping from a parent group, then this softmask is no
1661
           longer needed.  We will rc_decrement and set it to NULL. */
1662
99
        rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_group");
1663
99
        ctx->mask_stack = NULL;
1664
99
    }
1665
1.86M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
1.86M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
1.86M
    if (tos->idle)
1668
1.27M
        goto exit;
1669
596k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1670
0
        goto exit;
1671
1672
#if RAW_DUMP
1673
    /* Dump the current buffer to see what we have. */
1674
    dump_raw_buffer(ctx->memory,
1675
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1676
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1677
                    ctx->stack->planestride, ctx->stack->rowstride,
1678
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1679
    global_index++;
1680
#endif
1681
/* Note currently if a pattern space has transparency, the ICC profile is not used
1682
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1683
   This is partially due to the fact that pdf14_pop_transparency_group and
1684
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1685
   operations called in the tile transparency code.  Instead we may want to
1686
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1687
   is where all the ICC information is handled.  We will return to look at that later */
1688
596k
    if (nos->group_color_info->icc_profile != NULL) {
1689
596k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
596k
    } else {
1691
        /* Let the other tests make the decision if we need to transform */
1692
0
        no_icc_match = false;
1693
0
    }
1694
    /* If the color spaces are different and we actually did do a swap of
1695
       the procs for color */
1696
596k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
596k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
4.00k
        if (x0 < x1 && y0 < y1) {
1699
3.58k
            pdf14_buf *result;
1700
3.58k
            bool did_alloc; /* We don't care here */
1701
1702
3.58k
            if (has_matte) {
1703
1.66k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1704
1.66k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1705
1.66k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1706
1.66k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1707
1.66k
                has_matte = false;
1708
1.92k
            } else {
1709
1.92k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
1.92k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
1.92k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
1.92k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
1.92k
            }
1714
3.58k
            if (result == NULL) {
1715
                /* Clean up and return error code */
1716
0
                code = gs_error_unknownerror;
1717
0
                goto exit;
1718
0
            }
1719
1720
#if RAW_DUMP
1721
            /* Dump the current buffer to see what we have. */
1722
            dump_raw_buffer(ctx->memory,
1723
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1724
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1725
                            ctx->stack->planestride, ctx->stack->rowstride,
1726
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1727
                            ctx->stack->deep);
1728
#endif
1729
             /* compose. never do overprint in this case */
1730
3.58k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
3.58k
                 nos->group_color_info->isadditive,
1732
3.58k
                 nos->group_color_info->blend_procs,
1733
3.58k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
3.58k
        }
1735
592k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
592k
        if (x0 < x1 && y0 < y1)
1738
371k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
371k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
371k
                                drawn_comps, ctx->memory, dev);
1741
592k
    }
1742
1.86M
exit:
1743
1.86M
    ctx->stack = nos;
1744
    /* We want to detect the cases where we have luminosity soft masks embedded
1745
       within one another.  The "alpha" channel really needs to be merged into
1746
       the luminosity channel in this case.  This will occur during the mask pop */
1747
1.86M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1748
        /* Set the trigger so that we will blend if not alpha. Since
1749
           we have softmasks embedded in softmasks */
1750
701
        ctx->smask_blend = true;
1751
701
    }
1752
1.86M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
1.86M
    pdf14_buf_free(tos);
1754
1.86M
    if (code < 0)
1755
0
        return_error(code);
1756
1.86M
    return 0;
1757
1.86M
}
1758
1759
/*
1760
 * Create a transparency mask that will be used as the mask for
1761
 * the next transparency group that is created afterwards.
1762
 * The sequence of calls is:
1763
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1764
 */
1765
static  int
1766
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1767
                             byte *transfer_fn, bool is_ident, bool idle,
1768
                             bool replacing, uint mask_id,
1769
                             gs_transparency_mask_subtype_t subtype,
1770
                             int numcomps, int Background_components,
1771
                             const float Background[], int Matte_components,
1772
                             const float Matte[], const float GrayBackground,
1773
                             pdf14_group_color_t* group_color)
1774
433k
{
1775
433k
    pdf14_buf *buf;
1776
433k
    int i;
1777
1778
433k
    if_debug2m('v', ctx->memory,
1779
433k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
433k
               idle, replacing);
1781
433k
    ctx->smask_depth += 1;
1782
1783
433k
    if (ctx->stack == NULL) {
1784
0
        return_error(gs_error_VMerror);
1785
0
    }
1786
1787
    /* An optimization to consider is that if the SubType is Alpha
1788
       then we really should only be allocating the alpha band and
1789
       only draw with that channel.  Current architecture makes that
1790
       a bit tricky.  We need to create this based upon the size of
1791
       the color space + an alpha channel. NOT the device size
1792
       or the previous ctx size */
1793
    /* A mask doesn't worry about tags */
1794
433k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
433k
                        ctx->memory, ctx->deep);
1796
433k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
433k
    buf->alpha = bg_alpha;
1799
433k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
433k
    buf->isolated = true;
1802
433k
    buf->knockout = false;
1803
433k
    buf->shape = 0xffff;
1804
433k
    buf->blend_mode = BLEND_MODE_Normal;
1805
433k
    buf->transfer_fn = transfer_fn;
1806
433k
    buf->matte_num_comps = Matte_components;
1807
433k
    buf->group_color_info = group_color;
1808
1809
433k
    if (Matte_components) {
1810
3.84k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
3.84k
                                                "pdf14_push_transparency_mask");
1812
3.84k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
15.3k
        for (i = 0; i < Matte_components; i++) {
1815
11.5k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
11.5k
        }
1817
3.84k
    }
1818
433k
    buf->mask_id = mask_id;
1819
    /* If replacing=false, we start the mask for an image with SMask.
1820
       In this case the image's SMask temporary replaces the
1821
       mask of the containing group. Save the containing droup's mask
1822
       in buf->mask_stack */
1823
433k
    buf->mask_stack = ctx->mask_stack;
1824
433k
    if (buf->mask_stack)
1825
433k
        rc_increment(buf->mask_stack);
1826
#if RAW_DUMP
1827
    /* Dump the current buffer to see what we have. */
1828
    if (ctx->stack->planestride > 0 ){
1829
        dump_raw_buffer(ctx->memory,
1830
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1831
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1832
                        ctx->stack->planestride, ctx->stack->rowstride,
1833
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1834
        global_index++;
1835
    }
1836
#endif
1837
433k
    buf->saved = ctx->stack;
1838
433k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
433k
    buf->SMask_SubType = subtype;
1842
433k
    if (buf->data != NULL) {
1843
        /* We need to initialize it to the BC if it existed */
1844
        /* According to the spec, the CS has to be the same */
1845
        /* If the back ground component is black, then don't bother
1846
           with this.  Since we are forcing the rendering to gray
1847
           earlier now, go ahead and just use the GrayBackGround color
1848
           directly. */
1849
277k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
266
            if (buf->deep) {
1851
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1852
0
                gs_memset16(buf->data, gray, buf->planestride);
1853
                /* If we have a background component that was not black, then we
1854
                   need to set the alpha for this mask as if we had drawn in the
1855
                   entire soft mask buffer */
1856
0
                gs_memset16(buf->data + buf->planestride, 65535,
1857
0
                            buf->planestride *(buf->n_chan - 1));
1858
266
            } else {
1859
266
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
266
                memset(buf->data, gray, buf->planestride);
1861
                /* If we have a background component that was not black, then we
1862
                   need to set the alpha for this mask as if we had drawn in the
1863
                   entire soft mask buffer */
1864
266
                memset(buf->data + buf->planestride, 255,
1865
266
                       buf->planestride * (buf->n_chan - 1));
1866
266
            }
1867
277k
        } else {
1868
            /* Compose mask with opaque background */
1869
277k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
277k
        }
1871
277k
    }
1872
433k
    return 0;
1873
433k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
433k
{
1878
433k
    pdf14_buf* tos = ctx->stack;
1879
433k
    pdf14_buf* nos = tos->saved;
1880
433k
    byte *new_data_buf;
1881
433k
    int icc_match;
1882
433k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
433k
    cmm_profile_t *src_profile;
1884
433k
    gsicc_rendering_param_t rendering_params;
1885
433k
    gsicc_link_t *icc_link;
1886
433k
    gsicc_rendering_param_t render_cond;
1887
433k
    cmm_dev_profile_t *dev_profile;
1888
433k
    int code = 0;
1889
1890
433k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
433k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
433k
                          &render_cond);
1893
433k
    ctx->smask_depth -= 1;
1894
    /* icc_match == -1 means old non-icc code.
1895
       icc_match == 0 means use icc code
1896
       icc_match == 1 mean no conversion needed */
1897
433k
    if (des_profile != NULL && src_profile != NULL ) {
1898
433k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
433k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
433k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
433k
               tos->idle);
1904
433k
    ctx->stack = tos->saved;
1905
433k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
433k
    if (tos->mask_stack) {
1907
        /* During the soft mask push, the mask_stack was copied (not moved) from
1908
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1909
           just set to NULL.  However, before we do that we must perform
1910
           rc decrement to match the increment that occured was made.  Also,
1911
           if this is the last ref count of the rc_mask, we should free the
1912
           buffer now since no other groups need it. */
1913
114k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
114k
        tos->mask_stack = NULL;
1915
114k
    }
1916
1917
433k
    if (tos->data == NULL ) {
1918
        /* This can occur in clist rendering if the soft mask does
1919
           not intersect the current band.  It would be nice to
1920
           catch this earlier and just avoid creating the structure
1921
           to begin with.  For now we need to delete the structure
1922
           that was created.  Only delete if the alpha value is 65535 */
1923
156k
        if (ctx->mask_stack != NULL) {
1924
47.7k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
47.7k
            ctx->mask_stack = NULL;
1926
47.7k
        }
1927
156k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
156k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
4.83k
            pdf14_buf_free(tos);
1930
151k
        } else {
1931
            /* Assign as mask buffer */
1932
151k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
151k
            if (ctx->mask_stack == NULL)
1934
0
                return gs_note_error(gs_error_VMerror);
1935
151k
            ctx->mask_stack->mask_buf = tos;
1936
151k
        }
1937
156k
        ctx->smask_blend = false;  /* just in case */
1938
277k
    } else {
1939
        /* If we are already in the source space then there is no reason
1940
           to do the transformation */
1941
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1942
        /* This will reduce our memory.  We won't reuse the existing one, due */
1943
        /* Due to the fact that on certain systems we may have issues recovering */
1944
        /* the data after a resize */
1945
277k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1946
277k
                                        "pdf14_pop_transparency_mask");
1947
277k
        if (new_data_buf == NULL)
1948
0
            return_error(gs_error_VMerror);
1949
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
1950
           we won't be filling everything during the remap if it had not been
1951
           written into by the PDF14 fill rect */
1952
277k
        memset(new_data_buf, 0, tos->planestride);
1953
        /* If the subtype was alpha, then just grab the alpha channel now
1954
           and we are all done */
1955
277k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1956
40.5k
            ctx->smask_blend = false;  /* not used in this case */
1957
40.5k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1958
40.5k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1959
40.5k
                       tos->rowstride,
1960
40.5k
                       (tos->data)+tos->planestride, new_data_buf);
1961
#if RAW_DUMP
1962
            /* Dump the current buffer to see what we have. */
1963
            dump_raw_buffer(ctx->memory,
1964
                            tos->rect.q.y-tos->rect.p.y,
1965
                            tos->rowstride>>tos->deep, 1,
1966
                            tos->planestride, tos->rowstride,
1967
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
1968
                            tos->deep);
1969
            global_index++;
1970
#endif
1971
236k
        } else {
1972
236k
            if (icc_match == 1 || tos->n_chan == 2) {
1973
#if RAW_DUMP
1974
                /* Dump the current buffer to see what we have. */
1975
                dump_raw_buffer(ctx->memory,
1976
                                tos->rect.q.y-tos->rect.p.y,
1977
                                tos->rowstride>>tos->deep, tos->n_planes,
1978
                                tos->planestride, tos->rowstride,
1979
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
1980
                                tos->deep);
1981
                global_index++;
1982
#endif
1983
                /* There is no need to color convert.  Data is already gray scale.
1984
                   We just need to copy the gray plane.  However it is
1985
                   possible that the soft mask could have a soft mask which
1986
                   would end us up with some alpha blending information
1987
                   (Bug691803). In fact, according to the spec, the alpha
1988
                   blending has to occur.  See FTS test fts_26_2601.pdf
1989
                   for an example of this.  Softmask buffer is intialized
1990
                   with BG values.  It would be nice to keep track if buffer
1991
                   ever has a alpha value not 1 so that we could detect and
1992
                   avoid this blend if not needed. */
1993
236k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1994
236k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1995
236k
                            tos->planestride, tos->deep);
1996
#if RAW_DUMP
1997
                /* Dump the current buffer to see what we have. */
1998
                dump_raw_buffer(ctx->memory,
1999
                                tos->rect.q.y-tos->rect.p.y,
2000
                                tos->rowstride>>tos->deep, 1,
2001
                                tos->planestride, tos->rowstride,
2002
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2003
                                tos->deep);
2004
                global_index++;
2005
#endif
2006
236k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2007
236k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2008
236k
                           tos->rowstride, tos->data, new_data_buf);
2009
236k
            } else {
2010
0
                if ( icc_match == -1 ) {
2011
                    /* The slow old fashioned way */
2012
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2013
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2014
0
                        tos->rowstride, tos->planestride,
2015
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2016
0
                        tos->deep
2017
#if RAW_DUMP
2018
                        , ctx->memory
2019
#endif
2020
0
                        );
2021
0
                } else {
2022
                    /* ICC case where we use the CMM */
2023
                    /* Request the ICC link for the transform that we will need to use */
2024
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2025
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2026
0
                    rendering_params.override_icc = false;
2027
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2028
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2029
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2030
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2031
0
                        src_profile, &rendering_params, pgs->memory, false);
2032
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2033
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2034
0
                              tos->rowstride, tos->planestride,
2035
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2036
                    /* Release the link */
2037
0
                    gsicc_release_link(icc_link);
2038
0
                }
2039
0
            }
2040
236k
        }
2041
        /* Free the old object, NULL test was above */
2042
277k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2043
277k
        tos->data = new_data_buf;
2044
        /* Data is single channel now */
2045
277k
        tos->n_chan = 1;
2046
277k
        tos->n_planes = 1;
2047
        /* Assign as reference counted mask buffer */
2048
277k
        if (ctx->mask_stack != NULL) {
2049
            /* In this case, the source file is wacky as it already had a
2050
               softmask and now is getting a replacement. We need to clean
2051
               up the softmask stack before doing this free and creating
2052
               a new stack. Bug 693312 */
2053
66.8k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2054
66.8k
        }
2055
277k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2056
277k
        if (ctx->mask_stack == NULL)
2057
0
            return gs_note_error(gs_error_VMerror);
2058
277k
        ctx->mask_stack->mask_buf = tos;
2059
277k
    }
2060
433k
    return code;
2061
433k
}
2062
2063
static void
2064
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2065
1.56M
{
2066
    /* Ending the mask buffer. */
2067
1.56M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2068
    /* free the pdf14 buffer. */
2069
1.56M
    if (mask->mask_buf != NULL) {
2070
90.7k
        pdf14_buf_free(mask->mask_buf);
2071
90.7k
    }
2072
1.56M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2073
1.56M
}
2074
2075
static pdf14_mask_t *
2076
pdf14_mask_element_new(gs_memory_t *memory)
2077
1.57M
{
2078
1.57M
    pdf14_mask_t *result;
2079
2080
1.57M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2081
1.57M
                             "pdf14_mask_element_new");
2082
1.57M
    if (result == NULL)
2083
0
        return NULL;
2084
2085
1.57M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2086
2087
1.57M
    result->mask_buf = NULL;
2088
1.57M
    result->memory = memory;
2089
1.57M
    result->previous = NULL;
2090
2091
1.57M
    return result;
2092
1.57M
}
2093
2094
static int
2095
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2096
0
{
2097
    /* We need to push the current soft mask.  We need to
2098
       be able to recover it if we draw a new one and
2099
       then obtain a Q operation ( a pop ) */
2100
2101
0
    pdf14_device *pdev = (pdf14_device *)dev;
2102
0
    pdf14_ctx *ctx = pdev->ctx;
2103
0
    pdf14_mask_t *new_mask;
2104
2105
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2106
    /* We need to push the current mask buffer   */
2107
    /* Allocate a new element for the stack.
2108
       Don't do anything if there is no mask present.*/
2109
0
    if (ctx->mask_stack != NULL) {
2110
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2111
0
        if (new_mask == NULL)
2112
0
            return gs_note_error(gs_error_VMerror);
2113
0
        new_mask->previous = ctx->mask_stack;
2114
0
        ctx->mask_stack = new_mask;
2115
0
    }
2116
#ifdef DEBUG
2117
    pdf14_debug_mask_stack_state(pdev->ctx);
2118
#endif
2119
0
    return 0;
2120
0
}
2121
2122
static int
2123
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2124
3.03M
{
2125
    /* Pop the soft mask.  It is no longer needed. Likely due to
2126
       a Q that has occurred. */
2127
3.03M
    pdf14_device *pdev = (pdf14_device *)dev;
2128
3.03M
    pdf14_ctx *ctx = pdev->ctx;
2129
3.03M
    pdf14_mask_t *old_mask;
2130
2131
3.03M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2132
    /* rc decrement the current link after we break it from
2133
       the list, then free the stack element.  Don't do
2134
       anything if there is no mask present. */
2135
3.03M
    if (ctx->mask_stack != NULL) {
2136
466k
        old_mask = ctx->mask_stack;
2137
466k
        ctx->mask_stack = ctx->mask_stack->previous;
2138
466k
        rc_decrement(old_mask, "pdf14_pop_transparency_state");
2139
        /* We need to have some special handling here for when we have nested
2140
           soft masks.  There may be a copy in the stack that we may need to
2141
           adjust. */
2142
466k
        if (ctx->smask_depth > 0) {
2143
756
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2144
756
                ctx->stack->mask_stack = ctx->mask_stack;
2145
756
            }
2146
756
        }
2147
466k
    }
2148
#ifdef DEBUG
2149
    pdf14_debug_mask_stack_state(pdev->ctx);
2150
#endif
2151
3.03M
    return 0;
2152
3.03M
}
2153
2154
static  int
2155
pdf14_open(gx_device *dev)
2156
1.14M
{
2157
1.14M
    pdf14_device *pdev = (pdf14_device *)dev;
2158
2159
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2160
1.14M
    if (pdev->ctx == NULL) {
2161
1.14M
        bool has_tags = device_encodes_tags(dev);
2162
1.14M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2163
1.14M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2164
1.14M
        if (pdev->ctx == NULL)
2165
0
            return_error(gs_error_VMerror);
2166
2167
1.14M
        pdev->ctx->rect.p.x = 0;
2168
1.14M
        pdev->ctx->rect.p.y = 0;
2169
1.14M
        pdev->ctx->rect.q.x = dev->width;
2170
1.14M
        pdev->ctx->rect.q.y = dev->height;
2171
1.14M
        pdev->ctx->has_tags = has_tags;
2172
1.14M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2173
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2174
         * is. I am not sure how to fix that. */
2175
1.14M
        if (pdev->ctx->num_spots < 0)
2176
0
            pdev->ctx->num_spots = 0;
2177
1.14M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2178
1.14M
    }
2179
1.14M
    pdev->free_devicen = true;
2180
1.14M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2181
1.14M
    return 0;
2182
1.14M
}
2183
2184
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2185
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2186
};
2187
2188
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2189
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2190
};
2191
2192
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2193
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2194
};
2195
2196
static const gx_cm_color_map_procs *
2197
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2198
3.01M
{
2199
3.01M
    *tdev = dev;
2200
3.01M
    return &pdf14_DeviceCMYKspot_procs;
2201
3.01M
}
2202
2203
static const gx_cm_color_map_procs *
2204
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2205
3.01M
{
2206
3.01M
    *tdev = dev;
2207
3.01M
    return &pdf14_DeviceRGBspot_procs;
2208
3.01M
}
2209
2210
static const gx_cm_color_map_procs *
2211
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2212
0
{
2213
0
    *tdev = dev;
2214
0
    return &pdf14_DeviceGrayspot_procs;
2215
0
}
2216
2217
static void
2218
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2219
0
{
2220
0
    for (; n != 0; n--) {
2221
0
        uint16_t in = *src++;
2222
0
        ((byte *)dst)[0] = in>>8;
2223
0
        ((byte *)dst)[1] = in;
2224
0
        dst++;
2225
0
    }
2226
0
}
2227
2228
/* Used to pass along information about the buffer created by the
2229
   pdf14 device.  This is used by the pattern accumulator when the
2230
   pattern contains transparency.  Note that if free_device is true then
2231
   we need to go ahead and get the buffer data copied and free up the
2232
   device.  This only occurs at the end of a pattern accumulation operation */
2233
int
2234
pdf14_get_buffer_information(const gx_device * dev,
2235
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2236
                             bool free_device)
2237
24.8k
{
2238
24.8k
    const pdf14_device * pdev = (pdf14_device *)dev;
2239
24.8k
    pdf14_buf *buf;
2240
24.8k
    gs_int_rect rect;
2241
24.8k
    int x1,y1,width,height;
2242
2243
24.8k
    if ( pdev->ctx == NULL){
2244
0
        return 0;  /* this can occur if the pattern is a clist */
2245
0
    }
2246
#ifdef DEBUG
2247
    pdf14_debug_mask_stack_state(pdev->ctx);
2248
#endif
2249
24.8k
    buf = pdev->ctx->stack;
2250
24.8k
    rect = buf->rect;
2251
24.8k
    transbuff->buf = (free_device ? NULL : buf);
2252
24.8k
    x1 = min(pdev->width, rect.q.x);
2253
24.8k
    y1 = min(pdev->height, rect.q.y);
2254
24.8k
    width = x1 - rect.p.x;
2255
24.8k
    height = y1 - rect.p.y;
2256
2257
24.8k
    transbuff->n_chan    = buf->n_chan;
2258
24.8k
    transbuff->has_tags  = buf->has_tags;
2259
24.8k
    transbuff->has_shape = buf->has_shape;
2260
24.8k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2261
24.8k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2262
24.8k
    transbuff->deep      = buf->deep;
2263
2264
24.8k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2265
8.81k
        transbuff->planestride = 0;
2266
8.81k
        transbuff->rowstride = 0;
2267
8.81k
        return 0;
2268
8.81k
    }
2269
2270
16.0k
    if (free_device) {
2271
4.84k
        transbuff->pdev14 = NULL;
2272
4.84k
        transbuff->rect = rect;
2273
4.84k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2274
            /* If the bbox is smaller than the whole buffer than go ahead and
2275
               create a new one to use.  This can occur if we drew in a smaller
2276
               area than was specified by the transparency group rect. */
2277
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2278
0
            intptr_t planestride = rowstride * height;
2279
0
            int k, j;
2280
0
            byte *buff_ptr_src, *buff_ptr_des;
2281
2282
0
            transbuff->planestride = planestride;
2283
0
            transbuff->rowstride = rowstride;
2284
0
            transbuff->transbytes =
2285
0
                         gs_alloc_bytes(mem,
2286
0
                                        planestride *
2287
0
                                                (buf->n_chan +
2288
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2289
0
                                        "pdf14_get_buffer_information");
2290
0
            if (transbuff->transbytes == NULL)
2291
0
                return gs_error_VMerror;
2292
2293
0
            transbuff->mem = mem;
2294
0
            if (transbuff->deep) {
2295
0
                for (j = 0; j < transbuff->n_chan; j++) {
2296
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2297
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2298
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2299
0
                    for (k = 0; k < height; k++) {
2300
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2301
0
                        buff_ptr_des += rowstride;
2302
0
                        buff_ptr_src += buf->rowstride;
2303
0
                    }
2304
0
                }
2305
0
            } else {
2306
0
                for (j = 0; j < transbuff->n_chan; j++) {
2307
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2308
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2309
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2310
0
                    for (k = 0; k < height; k++) {
2311
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2312
0
                        buff_ptr_des += rowstride;
2313
0
                        buff_ptr_src += buf->rowstride;
2314
0
                    }
2315
0
                }
2316
0
            }
2317
2318
4.84k
        } else {
2319
            /* The entire buffer is used.  Go ahead and grab the pointer and
2320
               clear the pointer in the pdf14 device data buffer so it is not
2321
               freed when we close the device */
2322
4.84k
            transbuff->planestride = buf->planestride;
2323
4.84k
            transbuff->rowstride = buf->rowstride;
2324
4.84k
            transbuff->transbytes = buf->data;
2325
4.84k
            transbuff->mem = buf->memory;
2326
4.84k
            buf->data = NULL;  /* So that the buffer is not freed */
2327
4.84k
            if (transbuff->deep) {
2328
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2329
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2330
0
                uint16_t *buff_ptr;
2331
0
                int j, k, z;
2332
0
                intptr_t rowstride = transbuff->rowstride>>1;
2333
0
                intptr_t planestride = transbuff->planestride;
2334
0
                for (j = 0; j < transbuff->n_chan; j++) {
2335
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2336
0
                    for (k = 0; k < height; k++) {
2337
0
                        for (z = 0; z < width; z++) {
2338
0
                            uint16_t in = buff_ptr[z];
2339
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2340
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2341
0
                        }
2342
0
                        buff_ptr += rowstride;
2343
0
                    }
2344
0
                }
2345
0
            }
2346
4.84k
        }
2347
#if RAW_DUMP
2348
        /* Dump the buffer that should be going into the pattern */;
2349
        dump_raw_buffer_be(buf->memory,
2350
                           height, width, transbuff->n_chan,
2351
                           transbuff->planestride, transbuff->rowstride,
2352
                           "pdf14_pattern_buff", transbuff->transbytes,
2353
                           transbuff->deep);
2354
        global_index++;
2355
#endif
2356
        /* Go ahead and free up the pdf14 device */
2357
4.84k
        dev_proc(dev, close_device)((gx_device *)dev);
2358
11.1k
    } else {
2359
        /* Here we are coming from one of the fill image / pattern / mask
2360
           operations */
2361
11.1k
        transbuff->pdev14 = dev;
2362
11.1k
        transbuff->planestride = buf->planestride;
2363
11.1k
        transbuff->rowstride = buf->rowstride;
2364
11.1k
        transbuff->transbytes = buf->data;
2365
11.1k
        transbuff->mem = buf->memory;
2366
11.1k
        transbuff->rect = rect;
2367
#if RAW_DUMP
2368
    /* Dump the buffer that should be going into the pattern */;
2369
        dump_raw_buffer(buf->memory,
2370
                        height, width, buf->n_chan,
2371
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2372
                        "pdf14_pattern_buff",
2373
                        buf->data,
2374
                        transbuff->deep);
2375
        global_index++;
2376
#endif
2377
11.1k
    }
2378
16.0k
    return 0;
2379
16.0k
}
2380
2381
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2382
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2383
2384
2385
static int
2386
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2387
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2388
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2389
8.15k
{
2390
8.15k
    pdf14_buf* cm_result = NULL;
2391
8.15k
    cmm_profile_t* des_profile;
2392
8.15k
    gsicc_rendering_param_t render_cond;
2393
8.15k
    bool did_alloc;
2394
8.15k
    bool endian_swap;
2395
2396
8.15k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2397
8.15k
        &render_cond);
2398
2399
#if RAW_DUMP
2400
#if !ARCH_IS_BIG_ENDIAN
2401
    if (was_blended && (*buf)->deep)
2402
      dump_raw_buffer_be(dev->ctx->memory,
2403
          height, width, (*buf)->n_planes, (*buf)->planestride,
2404
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2405
    else
2406
#endif
2407
      dump_raw_buffer(dev->ctx->memory,
2408
          height, width, (*buf)->n_planes, (*buf)->planestride,
2409
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2410
    global_index++;
2411
#endif
2412
2413
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2414
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2415
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2416
       will need to know if it is dealing with native or BE data. */
2417
8.15k
    if (was_blended && (*buf)->deep) {
2418
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2419
           color conversion */
2420
#if ARCH_IS_BIG_ENDIAN
2421
        endian_swap = false;
2422
#else
2423
0
        endian_swap = true;
2424
0
#endif
2425
8.15k
    } else {
2426
        /* Data is in native format. No swap needed for CMM */
2427
8.15k
        endian_swap = false;
2428
8.15k
    }
2429
2430
8.15k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2431
8.15k
        *buf_ptr, src_profile, des_profile, x, y, width,
2432
8.15k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2433
2434
8.15k
    if (cm_result == NULL)
2435
0
        return_error(gs_error_VMerror);
2436
2437
    /* Update */
2438
8.15k
    *buf = cm_result;
2439
2440
    /* Make sure our buf_ptr is pointing to the proper location */
2441
8.15k
    if (did_alloc)
2442
8.15k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2443
2444
#if RAW_DUMP
2445
    dump_raw_buffer(dev->ctx->memory,
2446
        height, width, (*buf)->n_planes, (*buf)->planestride,
2447
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2448
    global_index++;
2449
#endif
2450
8.15k
    return 0;
2451
8.15k
}
2452
2453
/**
2454
 * pdf14_put_image: Put rendered image to target device.
2455
 * @pdev: The PDF 1.4 rendering device.
2456
 * @pgs: State for image draw operation.
2457
 * @target: The target device.
2458
 *
2459
 * Puts the rendered image in @pdev's buffer to @target. This is called
2460
 * as part of the sequence of popping the PDF 1.4 device filter.
2461
 *
2462
 * Return code: negative on error.
2463
 **/
2464
static  int
2465
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2466
1.06M
{
2467
1.06M
    const pdf14_device * pdev = (pdf14_device *)dev;
2468
1.06M
    int code;
2469
1.06M
    gs_image1_t image;
2470
1.06M
    gx_image_enum_common_t *info;
2471
1.06M
    pdf14_buf *buf = pdev->ctx->stack;
2472
1.06M
    gs_int_rect rect;
2473
1.06M
    int y;
2474
1.06M
    int num_comp;
2475
1.06M
    byte *linebuf, *linebuf_unaligned;
2476
1.06M
    gs_color_space *pcs;
2477
1.06M
    int x1, y1, width, height;
2478
1.06M
    byte *buf_ptr;
2479
1.06M
    int num_rows_left;
2480
1.06M
    cmm_profile_t* src_profile = NULL;
2481
1.06M
    cmm_profile_t* des_profile = NULL;
2482
1.06M
    cmm_dev_profile_t *pdf14dev_profile;
2483
1.06M
    cmm_dev_profile_t *dev_target_profile;
2484
1.06M
    uint16_t bg;
2485
1.06M
    bool has_tags = device_encodes_tags(dev);
2486
1.06M
    bool deep = pdev->ctx->deep;
2487
1.06M
    intptr_t planestride;
2488
1.06M
    intptr_t rowstride;
2489
1.06M
    blend_image_row_proc_t *blend_row;
2490
1.06M
    bool color_mismatch = false;
2491
1.06M
    bool supports_alpha = false;
2492
1.06M
    int i;
2493
1.06M
    int alpha_offset, tag_offset;
2494
1.06M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2495
1.06M
    int rendering_intent_saved;
2496
1.06M
    int additive;
2497
2498
    /* Nothing was ever drawn. */
2499
1.06M
    if (buf == NULL)
2500
132k
        return 0;
2501
2502
928k
    additive = buf->group_color_info->isadditive;
2503
2504
928k
    src_profile = buf->group_color_info->icc_profile;
2505
2506
928k
    num_comp = buf->n_chan - 1;
2507
928k
    rect = buf->rect;
2508
928k
    planestride = buf->planestride;
2509
928k
    rowstride = buf->rowstride;
2510
2511
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2512
       potential problem. Bug 694190 */
2513
928k
    if (buf->saved != NULL) {
2514
226
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2515
226
    }
2516
928k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2517
928k
    rect_intersect(rect, buf->dirty);
2518
928k
    x1 = min(pdev->width, rect.q.x);
2519
928k
    y1 = min(pdev->height, rect.q.y);
2520
928k
    width = x1 - rect.p.x;
2521
928k
    height = y1 - rect.p.y;
2522
#ifdef DUMP_TO_PNG
2523
    dump_planar_rgba(pdev->memory, buf);
2524
#endif
2525
928k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2526
234k
        return 0;
2527
693k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2528
2529
    /* Check that target is OK.  From fuzzing results the target could have been
2530
       destroyed, for e.g if it were a pattern accumulator that was closed
2531
       prematurely (Bug 694154).  We should always be able to to get an ICC
2532
       profile from the target. */
2533
693k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2534
693k
    if (code < 0)
2535
0
        return code;
2536
693k
    if (dev_target_profile == NULL)
2537
0
        return gs_throw_code(gs_error_Fatal);
2538
2539
693k
    if (src_profile == NULL) {
2540
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2541
0
        if (code < 0) {
2542
0
            return code;
2543
0
        }
2544
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2545
0
    }
2546
2547
    /* Check if we have a color conversion issue */
2548
693k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2549
693k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2550
116k
        color_mismatch = true;
2551
2552
    /* Check if target supports alpha */
2553
693k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2554
693k
    code = 0;
2555
2556
#if RAW_DUMP
2557
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2558
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2559
        "pre_final_blend", buf_ptr, deep);
2560
#endif
2561
2562
    /* Note. The logic below will need a little rework if we ever
2563
       have a device that has tags and alpha support */
2564
693k
    if (supports_alpha) {
2565
0
        if (!color_mismatch) {
2566
0
            alpha_offset = num_comp;
2567
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2568
2569
0
            for (i = 0; i < buf->n_planes; i++)
2570
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2571
0
            for (; i < target->color_info.num_components; i++)
2572
0
                buf_ptrs[i] = 0;
2573
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2574
0
                rect.p.x, rect.p.y, width, height,
2575
0
                rowstride, alpha_offset,
2576
0
                tag_offset);
2577
            /* Right now code has number of rows written */
2578
0
        } else {
2579
            /* In this case, just color convert and maintain alpha.  This is a case
2580
               where we either either blend in the right color space and have no
2581
               alpha for the output device or hand back the wrong color space with
2582
               alpha data.  We choose the later. */
2583
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2584
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2585
0
                width, height, false);
2586
0
            if (code < 0)
2587
0
                return code;
2588
2589
            /* reset */
2590
0
            rowstride = buf->rowstride;
2591
0
            planestride = buf->planestride;
2592
0
            num_comp = buf->n_chan - 1;
2593
0
            alpha_offset = num_comp;
2594
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2595
2596
            /* And then out */
2597
0
            for (i = 0; i < buf->n_planes; i++)
2598
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2599
0
            for (; i < target->color_info.num_components; i++)
2600
0
                buf_ptrs[i] = 0;
2601
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2602
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2603
0
                tag_offset);
2604
            /* Right now code has number of rows written */
2605
0
        }
2606
693k
    } else if (has_tags) {
2607
        /* We are going out to a device that supports tags */
2608
0
        if (deep) {
2609
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2610
0
                buf->planestride, num_comp, additive, false);
2611
0
        } else {
2612
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2613
0
                buf->planestride, num_comp, additive);
2614
0
        }
2615
2616
#if RAW_DUMP
2617
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2618
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2619
            "post_final_blend", buf_ptr, deep);
2620
#endif
2621
2622
        /* Take care of color issues */
2623
0
        if (color_mismatch) {
2624
            /* In this case, just color convert and maintain alpha.  This is a case
2625
               where we either either blend in the right color space and have no
2626
               alpha for the output device or hand back the wrong color space with
2627
               alpha data.  We choose the later. */
2628
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2629
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2630
0
            if (code < 0)
2631
0
                return code;
2632
2633
#if RAW_DUMP
2634
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2635
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2636
                "final_color_manage", buf_ptr, deep);
2637
            global_index++;
2638
#endif
2639
0
        }
2640
2641
        /* reset */
2642
0
        rowstride = buf->rowstride;
2643
0
        planestride = buf->planestride;
2644
0
        num_comp = buf->n_chan - 1;
2645
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2646
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2647
2648
        /* And then out */
2649
0
        for (i = 0; i < buf->n_planes; i++)
2650
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2651
0
        for (; i < target->color_info.num_components; i++)
2652
0
            buf_ptrs[i] = 0;
2653
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2654
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2655
0
            tag_offset);
2656
        /* Right now code has number of rows written */
2657
2658
0
    }
2659
2660
    /* If code > 0 then put image worked.  Let it finish and then exit */
2661
693k
    if (code > 0) {
2662
        /* We processed some or all of the rows.  Continue until we are done */
2663
0
        num_rows_left = height - code;
2664
0
        while (num_rows_left > 0) {
2665
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2666
0
                                                rect.p.x, rect.p.y + code, width,
2667
0
                                                num_rows_left, rowstride,
2668
0
                                                alpha_offset, tag_offset);
2669
0
            num_rows_left = num_rows_left - code;
2670
0
        }
2671
0
        return 0;
2672
0
    }
2673
2674
    /* Target device did not support alpha or tags.
2675
     * Set color space in preparation for sending an image.
2676
     * color conversion will occur after blending with through
2677
     * the begin typed image work flow.
2678
     */
2679
2680
693k
    planestride = buf->planestride;
2681
693k
    rowstride = buf->rowstride;
2682
693k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2683
693k
    if (code < 0)
2684
0
        return code;
2685
    /* Need to set this to avoid color management during the image color render
2686
       operation.  Exception is for the special case when the destination was
2687
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2688
       image operation.  That will happen here as we should have set the profile
2689
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2690
       the case when we have a blend color space that is different than the
2691
       target device color space */
2692
693k
    pcs->cmm_icc_profile_data = src_profile;
2693
2694
    /* pcs takes a reference to the profile data it just retrieved. */
2695
693k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2696
693k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2697
693k
    gs_image_t_init_adjust(&image, pcs, false);
2698
693k
    image.ImageMatrix.xx = (float)width;
2699
693k
    image.ImageMatrix.yy = (float)height;
2700
693k
    image.Width = width;
2701
693k
    image.Height = height;
2702
693k
    image.BitsPerComponent = deep ? 16 : 8;
2703
693k
    image.ColorSpace = pcs;
2704
693k
    ctm_only_writable(pgs).xx = (float)width;
2705
693k
    ctm_only_writable(pgs).xy = 0;
2706
693k
    ctm_only_writable(pgs).yx = 0;
2707
693k
    ctm_only_writable(pgs).yy = (float)height;
2708
693k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2709
693k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2710
    /* Make sure that the relative colorimetric rendering intent is
2711
       used for this image. */
2712
693k
    rendering_intent_saved = pgs->renderingintent;
2713
693k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2714
693k
    code = dev_proc(target, begin_typed_image) (target,
2715
693k
                                                pgs, NULL,
2716
693k
                                                (gs_image_common_t *)&image,
2717
693k
                                                NULL, NULL, NULL,
2718
693k
                                                pgs->memory, &info);
2719
693k
    pgs->renderingintent = rendering_intent_saved;
2720
693k
    if (code < 0) {
2721
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2722
0
        return code;
2723
0
    }
2724
#if RAW_DUMP
2725
    /* Dump the current buffer to see what we have. */
2726
    dump_raw_buffer(pdev->ctx->memory,
2727
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2728
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2729
                    pdev->ctx->stack->n_planes,
2730
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2731
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2732
    dump_raw_buffer(pdev->ctx->memory,
2733
                    height, width, buf->n_planes,
2734
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2735
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2736
    global_index++;
2737
    clist_band_count++;
2738
#endif
2739
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2740
    /* 28 byte overflow for AVX CMYK case. */
2741
693k
#define SSE_ALIGN 32
2742
693k
#define SSE_OVERFLOW 28
2743
693k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2744
693k
    if (linebuf_unaligned == NULL)
2745
0
        return gs_error_VMerror;
2746
693k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2747
2748
693k
    blend_row = deep ? gx_build_blended_image_row16 :
2749
693k
                       gx_build_blended_image_row;
2750
#ifdef WITH_CAL
2751
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2752
                                  blend_row, num_comp, deep);
2753
#endif
2754
2755
693k
    bg = additive ? (deep ? 65535 : 255) : 0;
2756
7.71M
    for (y = 0; y < height; y++) {
2757
7.02M
        gx_image_plane_t planes;
2758
7.02M
        int rows_used;
2759
2760
7.02M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2761
7.02M
        planes.data = linebuf;
2762
7.02M
        planes.data_x = 0;
2763
7.02M
        planes.raster = width * num_comp;
2764
7.02M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2765
        /* todo: check return value */
2766
7.02M
        buf_ptr += buf->rowstride;
2767
7.02M
    }
2768
693k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2769
693k
    info->procs->end_image(info, true);
2770
    /* This will also decrement the device profile */
2771
693k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2772
693k
    return code;
2773
693k
}
2774
2775
/* Overprint simulation with spots.  Collapse to CMYK */
2776
static void
2777
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2778
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2779
    cmyk_composite_map *map, bool keep_alpha)
2780
0
{
2781
0
    int comp_num;
2782
0
    uint cyan, magenta, yellow, black;
2783
0
    cmyk_composite_map *cmyk_map_entry;
2784
0
    int x, y;
2785
0
    intptr_t position;
2786
0
    byte comp, a;
2787
2788
0
    for (y = 0; y < height; y++) {
2789
0
        position = y * rowstride;
2790
0
        for (x = 0; x < width; x++) {
2791
0
            a = buf_ptr[position + planestride * num_comp];
2792
0
            if (a != 0) {
2793
0
                cyan = buf_ptr[position] * frac_1;
2794
0
                magenta = buf_ptr[position + planestride] * frac_1;
2795
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2796
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2797
0
                cmyk_map_entry = &(map[4]);
2798
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2799
0
                    comp = buf_ptr[position + planestride * comp_num];
2800
0
                    cyan += cmyk_map_entry->c * comp;
2801
0
                    magenta += cmyk_map_entry->m * comp;
2802
0
                    yellow += cmyk_map_entry->y * comp;
2803
0
                    black += cmyk_map_entry->k * comp;
2804
0
                    cmyk_map_entry++;
2805
0
                }
2806
0
                cyan /= frac_1;
2807
0
                magenta /= frac_1;
2808
0
                yellow /= frac_1;
2809
0
                black /= frac_1;
2810
2811
0
                if (cyan > 255)
2812
0
                    cyan = 255;
2813
0
                if (magenta > 255)
2814
0
                    magenta = 255;
2815
0
                if (yellow > 255)
2816
0
                    yellow = 255;
2817
0
                if (black > 255)
2818
0
                    black = 255;
2819
2820
0
                buf_ptr[position] = cyan;
2821
0
                buf_ptr[position + planestride] = magenta;
2822
0
                buf_ptr[position + planestride * 2] = yellow;
2823
0
                buf_ptr[position + planestride * 3] = black;
2824
0
            }
2825
0
            if (keep_alpha) {
2826
                /* Move the alpha and tag data */
2827
0
                buf_ptr[position + planestride * 4] = a;
2828
0
                if (tag_offset > 0) {
2829
0
                    buf_ptr[position + planestride * 5] =
2830
0
                        buf_ptr[position + planestride * tag_offset];
2831
0
                }
2832
0
            } else {
2833
                /* Remove alpha but keep tags */
2834
0
                if (tag_offset > 0) {
2835
0
                    buf_ptr[position + planestride * 4] =
2836
0
                        buf_ptr[position + planestride * tag_offset];
2837
0
                }
2838
2839
0
            }
2840
0
            position += 1;
2841
0
        }
2842
0
    }
2843
0
}
2844
2845
static void
2846
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2847
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2848
    cmyk_composite_map *map, bool keep_alpha)
2849
0
{
2850
0
    int comp_num;
2851
0
    ulong cyan, magenta, yellow, black;
2852
0
    cmyk_composite_map *cmyk_map_entry;
2853
0
    int x, y;
2854
0
    intptr_t position;
2855
0
    ulong comp, a;
2856
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2857
2858
    /* planestride and rowstride are in bytes, and we want them in shorts */
2859
0
    planestride >>= 1;
2860
0
    rowstride >>= 1;
2861
2862
0
    for (y = 0; y < height; y++) {
2863
0
        position = y * rowstride;
2864
0
        for (x = 0; x < width; x++) {
2865
0
            a = buf_ptr[position + planestride * num_comp];
2866
0
            if (a != 0) {
2867
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2868
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2869
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2870
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2871
0
                cmyk_map_entry = &(map[4]);
2872
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2873
0
                    comp = buf_ptr[position + planestride * comp_num];
2874
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2875
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2876
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2877
0
                    black += (ulong)cmyk_map_entry->k * comp;
2878
0
                    cmyk_map_entry++;
2879
0
                }
2880
0
                cyan /= frac_1_long;
2881
0
                magenta /= frac_1_long;
2882
0
                yellow /= frac_1_long;
2883
0
                black /= frac_1_long;
2884
2885
0
                if (cyan > 65535)
2886
0
                    cyan = 65535;
2887
0
                if (magenta > 65535)
2888
0
                    magenta = 65535;
2889
0
                if (yellow > 65535)
2890
0
                    yellow = 65535;
2891
0
                if (black > 65535)
2892
0
                    black = 65535;
2893
2894
#if ARCH_IS_BIG_ENDIAN
2895
                buf_ptr[position] = cyan;
2896
                buf_ptr[position + planestride] = magenta;
2897
                buf_ptr[position + planestride * 2] = yellow;
2898
                buf_ptr[position + planestride * 3] = black;
2899
#else
2900
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2901
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2902
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2903
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2904
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2905
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2906
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2907
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2908
0
#endif
2909
0
            }
2910
            /* Move the alpha and tag data */
2911
#if ARCH_IS_BIG_ENDIAN
2912
            if (keep_alpha) {
2913
                buf_ptr[position + planestride * 4] = a;
2914
                if (tag_offset > 0) {
2915
                    buf_ptr[position + planestride * 5] =
2916
                        buf_ptr[position + planestride * tag_offset];
2917
                }
2918
            } else {
2919
                if (tag_offset > 0) {
2920
                    buf_ptr[position + planestride * 4] =
2921
                        buf_ptr[position + planestride * tag_offset];
2922
                }
2923
            }
2924
#else
2925
0
            if (keep_alpha) {
2926
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2927
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2928
0
                if (tag_offset > 0) {
2929
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2930
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2931
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2932
0
                        buf_ptr[position + planestride * tag_offset];
2933
0
                }
2934
0
            } else {
2935
0
                if (tag_offset > 0) {
2936
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2937
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2938
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2939
0
                        buf_ptr[position + planestride * tag_offset];
2940
0
                }
2941
0
            }
2942
0
#endif
2943
0
            position += 1;
2944
0
        }
2945
0
    }
2946
0
}
2947
2948
static void
2949
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2950
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2951
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2952
0
{
2953
0
    if (deep) {
2954
0
        if (keep_alpha) {
2955
0
            if (tag_offset > 0) {
2956
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2957
0
                    planestride, num_comp, spot_start, tag_offset,
2958
0
                    map, true);
2959
0
            } else {
2960
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2961
0
                    planestride, num_comp, spot_start, 0,
2962
0
                    map, true);
2963
0
            }
2964
0
        } else {
2965
0
            if (tag_offset > 0) {
2966
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2967
0
                    planestride, num_comp, spot_start, tag_offset,
2968
0
                    map, false);
2969
0
            } else {
2970
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2971
0
                    planestride, num_comp, spot_start, 0,
2972
0
                    map, false);
2973
0
            }
2974
0
        }
2975
0
    } else {
2976
0
        if (keep_alpha) {
2977
0
            if (tag_offset > 0) {
2978
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2979
0
                    planestride, num_comp, spot_start, tag_offset,
2980
0
                    map, true);
2981
0
            } else {
2982
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2983
0
                    planestride, num_comp, spot_start, 0,
2984
0
                    map, true);
2985
0
            }
2986
0
        } else {
2987
0
            if (tag_offset > 0) {
2988
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2989
0
                    planestride, num_comp, spot_start, tag_offset,
2990
0
                    map, false);
2991
0
            } else {
2992
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2993
0
                    planestride, num_comp, spot_start, 0,
2994
0
                    map, false);
2995
0
            }
2996
0
        }
2997
0
    }
2998
0
}
2999
3000
/* This is for the case where we have mixture of spots and additive color.
3001
   For example, RGB + spots or Gray + spots */
3002
static void
3003
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3004
    intptr_t planestride, int num_comp, int spot_start)
3005
8.15k
{
3006
8.15k
    int x, y;
3007
8.15k
    intptr_t position;
3008
8.15k
    byte comp, a;
3009
8.15k
    int tmp, comp_num;
3010
3011
85.2k
    for (y = 0; y < height; y++) {
3012
77.1k
        position = y * rowstride;
3013
60.3M
        for (x = 0; x < width; x++) {
3014
60.2M
            a = buf_ptr[position + planestride * num_comp];
3015
60.2M
            if ((a + 1) & 0xfe) {
3016
844k
                a ^= 0xff;
3017
3.37M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3018
2.53M
                    comp = buf_ptr[position + planestride * comp_num];
3019
2.53M
                    tmp = ((0xff - comp) * a) + 0x80;
3020
2.53M
                    comp += (tmp + (tmp >> 8)) >> 8;
3021
2.53M
                    buf_ptr[position + planestride * comp_num] = comp;
3022
2.53M
                }
3023
844k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3024
0
                    comp = buf_ptr[position + planestride * comp_num];
3025
0
                    tmp = ((-comp) * a) + 0x80;
3026
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3027
0
                    buf_ptr[position + planestride * comp_num] = comp;
3028
0
                }
3029
59.4M
            } else if (a == 0) {
3030
66.8M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3031
50.1M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3032
50.1M
                }
3033
16.7M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3034
51.1k
                    buf_ptr[position + planestride * comp_num] = 0;
3035
51.1k
                }
3036
16.7M
            }
3037
60.2M
            position += 1;
3038
60.2M
        }
3039
77.1k
    }
3040
8.15k
}
3041
3042
static void
3043
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3044
    intptr_t planestride, int num_comp, int spot_start)
3045
0
{
3046
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3047
0
    int x, y;
3048
0
    intptr_t position;
3049
0
    int comp, a;
3050
0
    int tmp, comp_num;
3051
3052
    /* planestride and rowstride are in bytes, and we want them in shorts */
3053
0
    planestride >>= 1;
3054
0
    rowstride >>= 1;
3055
3056
    /* Note that the input here is native endian, and the output must be in big endian! */
3057
0
    for (y = 0; y < height; y++) {
3058
0
        position = y * rowstride;
3059
0
        for (x = 0; x < width; x++) {
3060
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3061
0
            a = buf_ptr[position + planestride * num_comp];
3062
0
            if (a == 0) {
3063
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3064
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3065
0
                }
3066
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3067
0
                    buf_ptr[position + planestride * comp_num] = 0;
3068
0
                }
3069
0
            } else if (a == 0xffff) {
3070
#if ARCH_IS_BIG_ENDIAN
3071
#else
3072
                /* Convert from native -> big endian */
3073
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3074
0
                    comp = buf_ptr[position + planestride * comp_num];
3075
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3076
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3077
0
                }
3078
0
#endif
3079
0
            } else {
3080
0
                a ^= 0xffff;
3081
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3082
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3083
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3084
0
                    comp = buf_ptr[position + planestride * comp_num];
3085
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3086
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3087
                    /* Store as big endian */
3088
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3089
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3090
0
                }
3091
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3092
0
                    comp = buf_ptr[position + planestride * comp_num];
3093
0
                    tmp = ((0 - comp) * a) + 0x4000;
3094
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3095
                    /* Store as big endian */
3096
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3097
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3098
0
                }
3099
0
            }
3100
0
            position += 1;
3101
0
        }
3102
0
    }
3103
0
}
3104
3105
static int
3106
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3107
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3108
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3109
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3110
    gs_separations* pseparations, bool deep)
3111
22.2k
{
3112
22.2k
    pdf14_device* pdev = (pdf14_device*)dev;
3113
22.2k
    int code = 0;
3114
22.2k
    int y;
3115
22.2k
    int num_rows_left;
3116
22.2k
    int i;
3117
22.2k
    gs_int_rect rect = rect_in;
3118
22.2k
    intptr_t planestride = planestride_in;
3119
22.2k
    intptr_t rowstride = rowstride_in;
3120
22.2k
    byte* buf_ptr = NULL;
3121
22.2k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3122
22.2k
    cmm_profile_t* des_profile = NULL;
3123
22.2k
    cmm_dev_profile_t* dev_target_profile;
3124
22.2k
    cmm_dev_profile_t* pdf14dev_profile;
3125
22.2k
    bool color_mismatch = false;
3126
22.2k
    bool supports_alpha = false;
3127
22.2k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3128
22.2k
    int alpha_offset = num_comp;
3129
22.2k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3130
22.2k
    gs_color_space *pcs;
3131
22.2k
    gs_image1_t image;
3132
22.2k
    gx_image_enum_common_t *info;
3133
22.2k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3134
22.2k
    pdf14_buf *cm_result = NULL;
3135
22.2k
    bool did_alloc;
3136
22.2k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3137
22.2k
    bool has_spots = pdev->ctx->num_spots > 0;
3138
22.2k
    bool blend_spots = !target_sep_device && has_spots;
3139
22.2k
    bool lose_channels = false;
3140
3141
    /* Check if group color space is CMYK based */
3142
22.2k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3143
22.2k
    if (code < 0)
3144
0
        return code;
3145
22.2k
    if (dev_target_profile == NULL)
3146
0
        return gs_throw_code(gs_error_Fatal);
3147
3148
22.2k
    if (src_profile == NULL) {
3149
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3150
0
        if (code < 0) {
3151
0
            return code;
3152
0
        }
3153
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3154
0
    }
3155
3156
    /* If the target device does not support spot colors and we have spot colors
3157
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3158
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3159
22.2k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3160
3161
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3162
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3163
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3164
0
        if (cm_result == NULL)
3165
0
            return_error(gs_error_VMerror);
3166
3167
        /* Update */
3168
0
        buf = cm_result;
3169
0
        src_profile = pgs->icc_manager->default_cmyk;
3170
0
        num_comp = buf->n_chan - 1;
3171
0
        additive = 0;
3172
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3173
0
        alpha_offset = num_comp;
3174
3175
#if RAW_DUMP
3176
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3177
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3178
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3179
        global_index++;
3180
#endif
3181
0
    }
3182
3183
    /* Fix order map if needed */
3184
103k
    for (i = 0; i < num_comp; i++) {
3185
81.0k
        pdev->devn_params.separation_order_map[i] = i;
3186
81.0k
    }
3187
3188
    /* Check if we have a color conversion issue */
3189
22.2k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3190
22.2k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3191
8.15k
        color_mismatch = true;
3192
22.2k
    if (des_profile->data_cs == gsNCHANNEL)
3193
0
        lose_channels = true;
3194
3195
    /* Check if target supports alpha */
3196
22.2k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3197
22.2k
    code = 0;
3198
3199
22.2k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3200
3201
    /* Note. The logic below will need a little rework if we ever
3202
       have a device that has tags and alpha support */
3203
22.2k
    if (supports_alpha) {
3204
3205
        /* If doing simulated overprint, Bring the spot color channels into
3206
           CMYK. Data is planar and 16 bit data in native format. */
3207
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3208
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3209
3210
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3211
0
            if (pdev->pclist_device != NULL) {
3212
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3213
3214
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3215
0
                if (code < 0)
3216
0
                    return code;
3217
0
            }
3218
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3219
3220
            /* Now we go to big endian */
3221
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3222
0
                planestride, num_comp, src_profile->num_comps,
3223
0
                tag_offset, cmyk_map, true, deep);
3224
3225
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3226
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3227
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3228
0
            buf->num_spots = 0;
3229
0
            num_comp = buf->n_chan - 1;
3230
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3231
0
        }
3232
3233
0
        if (!color_mismatch) {
3234
0
            for (i = 0; i < buf->n_planes; i++)
3235
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3236
0
            for (; i < target->color_info.num_components; i++)
3237
0
                buf_ptrs[i] = 0;
3238
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3239
0
                rect.p.x, rect.p.y, width, height,
3240
0
                rowstride, alpha_offset, tag_offset);
3241
            /* Right now code has number of rows written */
3242
0
        } else {
3243
            /* In this case, just color convert and maintain alpha.
3244
               This is a case where we either either blend in the
3245
               right color space and have no alpha for the output
3246
               device or hand back the wrong color space with
3247
               alpha data.  We choose the later. */
3248
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3249
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3250
0
                        rect.p.y, width, height, false);
3251
0
            if (code < 0)
3252
0
                return code;
3253
3254
            /* reset */
3255
0
            rowstride = buf->rowstride;
3256
0
            planestride = buf->planestride;
3257
0
            num_comp = buf->n_chan - 1;
3258
0
            alpha_offset = num_comp;
3259
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3260
3261
            /* And then out */
3262
0
            for (i = 0; i < buf->n_planes; i++)
3263
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3264
0
            for (; i < target->color_info.num_components; i++)
3265
0
                buf_ptrs[i] = 0;
3266
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3267
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3268
0
                tag_offset);
3269
            /* Right now code has number of rows written.  Writing continues below */
3270
0
        }
3271
22.2k
    } else {
3272
        /* Device could not handle the alpha data (we actually don't have
3273
           a device that does spot colorants and has an alpha channel so
3274
           the above code is untested.  Go ahead and preblend now and then
3275
           color convert if needed */
3276
#if RAW_DUMP
3277
           /* Dump before and after the blend to make sure we are doing that ok */
3278
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3279
            "pre_put_image_blend_image", buf_ptr, deep);
3280
        global_index++;
3281
#endif
3282
3283
22.2k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3284
8.15k
            if (deep) {
3285
            /* In this case, we are NOT going to bring the spots into the CMYK
3286
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3287
               16 bit data will be converted now from native endian to big endian during
3288
               the blending process */
3289
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3290
0
                    planestride, num_comp, src_profile->num_comps);
3291
8.15k
            } else {
3292
8.15k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3293
8.15k
                    planestride, num_comp, src_profile->num_comps);
3294
8.15k
            }
3295
14.1k
        } else {
3296
14.1k
            if (deep) {
3297
            /* In this case, if blend_spots == true, we will shortly be bringing
3298
               the spot colors to CMYK equivalent colors. It is at that time that
3299
               we will convert from native endian to big endian. In all other
3300
               cases this blending will due to conversion from native to BE */
3301
0
                bool keep_native = (blend_spots == true);
3302
3303
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3304
0
                    planestride, num_comp, additive, keep_native);
3305
14.1k
            } else {
3306
14.1k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3307
14.1k
                    planestride, num_comp, additive);
3308
14.1k
            }
3309
14.1k
        }
3310
3311
22.2k
        if (deep && has_tags)
3312
0
        {
3313
            /* We still need to convert the tags from Native to BE */
3314
#if ARCH_IS_BIG_ENDIAN
3315
#else
3316
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3317
0
            int i, j;
3318
0
            for (j = 0; j < height; j++)
3319
0
            {
3320
0
                for (i = 0; i < width; i++)
3321
0
                {
3322
0
                    uint16_t tag = *tags++;
3323
0
                    ((byte *)tags)[-2] = tag >> 8;
3324
0
                    ((byte *)tags)[-1] = tag;
3325
0
                }
3326
0
                tags += (buf->rowstride>>1) - width;
3327
0
            }
3328
0
#endif
3329
0
        }
3330
3331
#if RAW_DUMP
3332
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3333
            "post_put_image_blend_image", buf_ptr, deep);
3334
        global_index++;
3335
#endif
3336
3337
        /* If doing simulated overprint and we are not going to a sep device and
3338
           we have spot colors, then bring the spot color channels into CMYK
3339
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3340
           At this point, data is planar and 16 bit data is still in native format. It is
3341
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3342
           above during the alpha blend operation. */
3343
22.2k
        if (blend_spots) {
3344
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3345
3346
            /* In the clist case, we need to get equiv spots out of the
3347
               pseudo-band. */
3348
0
            if (pdev->pclist_device != NULL) {
3349
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3350
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3351
0
                if (code < 0)
3352
0
                    return code;
3353
0
            }
3354
3355
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3356
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3357
0
                planestride, num_comp, src_profile->num_comps,
3358
0
                tag_offset, cmyk_map, false, deep);
3359
3360
            /* Reset buffer information. We have CMYK and maybe tags */
3361
0
            num_comp = 4;
3362
0
            alpha_offset = 0;
3363
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3364
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3365
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3366
0
            buf->num_spots = 0;
3367
3368
#if RAW_DUMP
3369
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3370
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3371
            global_index++;
3372
#endif
3373
0
        }
3374
3375
        /* Map to the destination color space */
3376
22.2k
        if (color_mismatch) {
3377
            /* We started out with the original process colorants, and spots. If we have an
3378
             * nchannel output profile, this can mean that the first few spots might come from
3379
             * that and the rest from the document itself. e.g:
3380
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3381
             * Then we might have a blend space that changes the process colorants:
3382
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3383
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3384
             * If we're not careful, we'll end up with:
3385
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3386
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3387
             */
3388
8.15k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3389
8.15k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3390
8.15k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3391
8.15k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3392
8.15k
            if (code < 0)
3393
0
                return code;
3394
3395
            /* reset */
3396
8.15k
            rowstride = buf->rowstride;
3397
8.15k
            planestride = buf->planestride;
3398
8.15k
            num_comp = buf->n_chan;
3399
8.15k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3400
8.15k
        }
3401
3402
#if RAW_DUMP
3403
        /* Dump after the CS transform */
3404
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3405
            "post_put_image_color_convert", buf_ptr, deep);
3406
        global_index++;
3407
        /* clist_band_count++; */
3408
#endif
3409
3410
        /* Try put_image again. This can occur if the
3411
           target, like psdcmyk and tiffsep, support put_image */
3412
22.2k
        alpha_offset = 0;
3413
133k
        for (i = 0; i < buf->n_planes; i++)
3414
111k
            buf_ptrs[i] = buf_ptr + i * planestride;
3415
22.2k
        for (; i < target->color_info.num_components; i++)
3416
0
            buf_ptrs[i] = 0;
3417
22.2k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3418
22.2k
            rect.p.x, rect.p.y, width, height,
3419
22.2k
            rowstride, alpha_offset, tag_offset);
3420
22.2k
    }
3421
3422
    /* Put image was succesful.  We processed some or all of the rows.
3423
       Continue until we are done */
3424
22.2k
    if (code > 0) {
3425
114
        num_rows_left = height - code;
3426
114
        while (num_rows_left > 0) {
3427
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3428
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3429
0
                alpha_offset, tag_offset);
3430
0
            if (code < 0) {
3431
0
                return code;
3432
0
            }
3433
0
            num_rows_left = num_rows_left - code;
3434
0
        }
3435
114
        return 0;
3436
114
    }
3437
3438
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3439
       as well as those devices that support alpha (pngalpha,
3440
       png16malpha). If we are here, then we are doing an
3441
       overprint simulation on some other device. Image data
3442
       is aleady blended and in device color space. */
3443
22.1k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3444
22.1k
    if (code < 0)
3445
0
        return code;
3446
3447
    /* Already in destination CS */
3448
22.1k
    pcs->cmm_icc_profile_data = des_profile;
3449
3450
    /* pcs takes a reference to the profile data it just retrieved. */
3451
22.1k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3452
22.1k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3453
3454
    /* If we have more components to write out than are in the des_profile,
3455
     * then just using a PCS based on des_profile, will result in us dropping
3456
     * the spot colors.
3457
     * So, if our target supports devn colors, we instead construct a
3458
     * DevN device space with colors names taken from the devn_params, and
3459
     * use that instead. */
3460
22.1k
    if (des_profile->num_comps != target->color_info.num_components &&
3461
33
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3462
33
    {
3463
33
        int num_std;
3464
33
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3465
33
        gs_color_space *pcs2 = pcs;
3466
33
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3467
33
                                     pcs2, pgs->memory->non_gc_memory);
3468
33
        if (code < 0)
3469
0
            return code;
3470
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3471
33
        pcs->params.device_n.use_alt_cspace = false;
3472
33
        num_std = devn_params->num_std_colorant_names;
3473
165
        for (i = 0; i < num_std; i++) {
3474
132
            const char *name = devn_params->std_colorant_names[i];
3475
132
            size_t len = strlen(name);
3476
132
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3477
132
            if (pcs->params.device_n.names[i] == NULL) {
3478
0
                int j = 0;
3479
0
                for (j = 0;j < i; j++) {
3480
0
                    if (pcs->params.device_n.names[j] != NULL)
3481
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3482
0
                    pcs->params.device_n.names[j] = NULL;
3483
0
                }
3484
0
                return_error(gs_error_VMerror);
3485
0
            }
3486
132
            strcpy(pcs->params.device_n.names[i], name);
3487
132
        }
3488
33
        for (; i < devn_params->separations.num_separations; i++) {
3489
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3490
0
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, name->size + 1, "mem_planar_put_image_very_slow");
3491
0
            if (pcs->params.device_n.names[i] == NULL) {
3492
0
                int j = 0;
3493
0
                for (j = 0;j < i; j++) {
3494
0
                    if (pcs->params.device_n.names[j] != NULL)
3495
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3496
0
                    pcs->params.device_n.names[j] = NULL;
3497
0
                }
3498
0
                return_error(gs_error_VMerror);
3499
0
            }
3500
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3501
0
            pcs->params.device_n.names[i][name->size] = 0;
3502
0
        }
3503
33
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3504
0
            return code;
3505
0
        }
3506
        /* One last thing -- we need to fudge the pgs->color_component_map */
3507
198
        for (i=0; i < dev->color_info.num_components; i++)
3508
165
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3509
33
    }
3510
3511
22.1k
    gs_image_t_init_adjust(&image, pcs, false);
3512
22.1k
    image.ImageMatrix.xx = (float)width;
3513
22.1k
    image.ImageMatrix.yy = (float)height;
3514
22.1k
    image.Width = width;
3515
22.1k
    image.Height = height;
3516
22.1k
    image.BitsPerComponent = deep ? 16 : 8;
3517
22.1k
    image.ColorSpace = pcs;
3518
22.1k
    image.format = gs_image_format_component_planar;
3519
3520
22.1k
    ctm_only_writable(pgs).xx = (float)width;
3521
22.1k
    ctm_only_writable(pgs).xy = 0;
3522
22.1k
    ctm_only_writable(pgs).yx = 0;
3523
22.1k
    ctm_only_writable(pgs).yy = (float)height;
3524
22.1k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3525
22.1k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3526
22.1k
    code = dev_proc(target, begin_typed_image) (target,
3527
22.1k
        pgs, NULL, (gs_image_common_t *)&image,
3528
22.1k
        NULL, NULL, NULL, pgs->memory, &info);
3529
22.1k
    if (code < 0) {
3530
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3531
0
        return code;
3532
0
    }
3533
#if RAW_DUMP
3534
    /* Dump the current buffer to see what we have. */
3535
    dump_raw_buffer(pdev->ctx->memory,
3536
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3537
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3538
        pdev->ctx->stack->n_planes,
3539
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3540
        "put_image_final_big", pdev->ctx->stack->data, deep);
3541
    dump_raw_buffer(pdev->ctx->memory,
3542
        height, width, buf->n_planes,
3543
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3544
        "put_image_final_small", buf_ptr, deep);
3545
    global_index++;
3546
    clist_band_count++;
3547
#endif
3548
3549
119k
    for (i = 0; i < num_comp; i++) {
3550
96.8k
        planes[i].data = buf_ptr + i * planestride;
3551
96.8k
        planes[i].data_x = 0;
3552
96.8k
        planes[i].raster = buf->rowstride;
3553
96.8k
    }
3554
3555
243k
    for (y = 0; y < height; y++) {
3556
221k
        int rows_used;
3557
3558
221k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3559
3560
1.18M
        for (i = 0; i < num_comp; i++) {
3561
962k
            planes[i].data += buf->rowstride;
3562
962k
        }
3563
221k
    }
3564
22.1k
    info->procs->end_image(info, true);
3565
3566
    /* This will also decrement the profile */
3567
22.1k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3568
22.1k
    return code;
3569
22.1k
}
3570
3571
/**
3572
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3573
 * @pdev: The PDF 1.4 rendering device.
3574
 * @pgs: State for image draw operation.
3575
 * @target: The target device.
3576
 *
3577
 * Puts the rendered image in @pdev's buffer to @target. This is called
3578
 * as part of the sequence of popping the PDF 1.4 device filter.
3579
 *
3580
 * Return code: negative on error.
3581
 **/
3582
static  int
3583
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3584
69.5k
{
3585
69.5k
    pdf14_device *pdev = (pdf14_device *)dev;
3586
69.5k
    pdf14_buf *buf = pdev->ctx->stack;
3587
69.5k
    gs_int_rect rect;
3588
69.5k
    int x1, y1, width, height;
3589
69.5k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3590
69.5k
    gs_separations *pseparations = &pdevn_params->separations;
3591
69.5k
    intptr_t planestride;
3592
69.5k
    intptr_t rowstride;
3593
69.5k
    bool deep = pdev->ctx->deep;
3594
69.5k
    int num_comp;
3595
3596
    /* Nothing was ever drawn. */
3597
69.5k
    if (buf == NULL)
3598
26.2k
        return 0;
3599
3600
43.3k
    num_comp = buf->n_chan - 1;
3601
43.3k
    rect = buf->rect;
3602
43.3k
    planestride = buf->planestride;
3603
43.3k
    rowstride = buf->rowstride;
3604
3605
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3606
       potential problem. Bug 694190 */
3607
43.3k
    if (buf->saved != NULL) {
3608
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3609
1
    }
3610
43.3k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3611
43.3k
    rect_intersect(rect, buf->dirty);
3612
43.3k
    x1 = min(pdev->width, rect.q.x);
3613
43.3k
    y1 = min(pdev->height, rect.q.y);
3614
43.3k
    width = x1 - rect.p.x;
3615
43.3k
    height = y1 - rect.p.y;
3616
43.3k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3617
21.0k
        return 0;
3618
3619
#if RAW_DUMP
3620
    /* Dump the current buffer to see what we have. */
3621
    dump_raw_buffer(pdev->ctx->memory,
3622
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3623
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3624
                    pdev->ctx->stack->n_planes,
3625
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3626
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3627
                    pdev->ctx->stack->deep);
3628
3629
    global_index++;
3630
    clist_band_count++;
3631
#endif
3632
3633
22.2k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3634
22.2k
                      buf, planestride, rowstride,
3635
22.2k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3636
22.2k
                      buf->has_tags, rect, pseparations, deep);
3637
43.3k
}
3638
3639
/**
3640
 * pdf14_custom_put_image: Put rendered image to target device.
3641
 * @pdev: The PDF 1.4 rendering device.
3642
 * @pgs: State for image draw operation.
3643
 * @target: The target device.
3644
 *
3645
 * Puts the rendered image in @pdev's buffer to @target. This is called
3646
 * as part of the sequence of popping the PDF 1.4 device filter.
3647
 *
3648
 * Return code: negative on error.
3649
 **/
3650
static  int
3651
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3652
0
{
3653
0
    pdf14_device * pdev = (pdf14_device *)dev;
3654
0
    pdf14_buf *buf = pdev->ctx->stack;
3655
0
    bool deep = pdev->ctx->deep;
3656
0
    gs_int_rect rect;
3657
0
    int x0, y0;
3658
0
    intptr_t planestride;
3659
0
    intptr_t rowstride;
3660
0
    int num_comp;
3661
0
    uint16_t bg;
3662
0
    int x1, y1, width, height;
3663
0
    byte *buf_ptr;
3664
3665
    /* Nothing was ever drawn. */
3666
0
    if (buf == NULL)
3667
0
        return 0;
3668
3669
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3670
0
    num_comp = buf->n_chan - 1;
3671
0
    rect = buf->rect;
3672
0
    x0 = rect.p.x;
3673
0
    y0 = rect.p.y;
3674
0
    planestride = buf->planestride;
3675
0
    rowstride = buf->rowstride;
3676
3677
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3678
       potential problem. Bug 694190 */
3679
0
    if (buf->saved != NULL) {
3680
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3681
0
    }
3682
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3683
0
    rect_intersect(rect, buf->dirty);
3684
0
    x1 = min(pdev->width, rect.q.x);
3685
0
    y1 = min(pdev->height, rect.q.y);
3686
0
    width = x1 - rect.p.x;
3687
0
    height = y1 - rect.p.y;
3688
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3689
0
        return 0;
3690
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3691
3692
0
    return gx_put_blended_image_custom(target, buf_ptr,
3693
0
                      planestride, rowstride,
3694
0
                      x0, y0, width, height, num_comp, bg, deep);
3695
0
}
3696
3697
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3698
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3699
 * putting everything back how it was, and cleaning up the reference counts.
3700
 */
3701
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3702
2.29M
{
3703
2.29M
    if (pdev->ctx && pdev->ctx->stack) {
3704
977k
        pdf14_buf *buf, *next;
3705
3706
978k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3707
322
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3708
322
            next = buf->saved;
3709
644
            while (group_color_info) {
3710
322
               if (group_color_info->icc_profile != NULL) {
3711
322
                   cmm_profile_t *group_profile;
3712
322
                   gsicc_rendering_param_t render_cond;
3713
322
                   cmm_dev_profile_t *dev_profile;
3714
322
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3715
3716
322
                   if (code >= 0) {
3717
322
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3718
322
                                             &render_cond);
3719
3720
322
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3721
322
                                               -1, "pdf14_end_transparency_group");
3722
322
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3723
322
                           group_color_info->icc_profile;
3724
322
                       group_color_info->icc_profile = NULL;
3725
322
                   }
3726
322
               }
3727
3728
322
               group_color_info = group_color_info->previous;
3729
322
            }
3730
322
        }
3731
977k
    }
3732
2.29M
}
3733
3734
static  int
3735
pdf14_close(gx_device *dev)
3736
1.14M
{
3737
1.14M
    pdf14_device *pdev = (pdf14_device *)dev;
3738
3739
1.14M
    pdf14_cleanup_group_color_profiles(pdev);
3740
3741
1.14M
    if (pdev->ctx) {
3742
1.14M
        pdf14_ctx_free(pdev->ctx);
3743
1.14M
        pdev->ctx = NULL;
3744
1.14M
    }
3745
1.14M
    return 0;
3746
1.14M
}
3747
3748
/* This is called when something has gone wrong and the interpreter received a
3749
   stop while in the middle of doing something with the PDF14 device.  We need
3750
   to clean up and end this in a graceful manner */
3751
static int
3752
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3753
0
{
3754
0
    pdf14_device *pdev = (pdf14_device *)dev;
3755
    /* The things that need to be cleaned up */
3756
0
    pdf14_ctx *ctx = pdev->ctx;
3757
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3758
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3759
3760
    /* Free up the smask color */
3761
0
    if (smaskcolor != NULL) {
3762
0
        smaskcolor->ref_count = 1;
3763
0
        pdf14_decrement_smask_color(pgs, dev);
3764
0
        pdev->smaskcolor = NULL;
3765
0
    }
3766
3767
    /* Free up the nested color procs and decrement the profiles */
3768
0
    if (group_color != NULL) {
3769
0
        while (group_color->previous != NULL)
3770
0
            pdf14_pop_group_color(dev, pgs);
3771
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3772
0
        pdev->color_model_stack = NULL;
3773
0
    }
3774
3775
    /* Start the context clean up */
3776
0
    if (ctx != NULL) {
3777
0
        pdf14_buf *buf, *next;
3778
0
        pdf14_group_color_t *procs, *prev_procs;
3779
3780
0
        if (ctx->mask_stack != NULL) {
3781
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3782
0
        }
3783
3784
        /* Now the stack of buffers */
3785
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3786
0
            next = buf->saved;
3787
3788
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3789
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3790
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3791
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3792
            /* During the soft mask push, the mask_stack was copied (not moved) from
3793
               the ctx to the tos mask_stack. We are done with this now so it is safe
3794
               to free this one object */
3795
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3796
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3797
0
                prev_procs = procs->previous;
3798
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3799
0
            }
3800
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3801
0
        }
3802
        /* Finally the context itself */
3803
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3804
0
        pdev->ctx = NULL;
3805
0
    }
3806
0
    return 0;
3807
0
}
3808
3809
static  int
3810
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3811
0
{
3812
0
    pdf14_device * pdev = (pdf14_device *)dev;
3813
3814
0
    if (pdev->target != NULL)
3815
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3816
0
    return 0;
3817
0
}
3818
3819
9.25M
#define COPY_PARAM(p) dev->p = target->p
3820
5.78M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3821
3822
static void
3823
copy_tag_setup(gx_device *dev, const gx_device *target)
3824
1.15M
{
3825
1.15M
    bool deep = device_is_deep(target);
3826
1.15M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3827
1.15M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3828
1.15M
    COPY_PARAM(graphics_type_tag);
3829
1.15M
    if (had_tags && !has_tags)
3830
0
    {
3831
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3832
0
        dev->color_info.num_components--;
3833
0
        dev->color_info.depth -= deep ? 16 : 8;
3834
0
    }
3835
1.15M
    else if (!had_tags && has_tags)
3836
0
    {
3837
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3838
0
        dev->color_info.num_components++;
3839
0
        dev->color_info.depth += deep ? 16 : 8;
3840
0
    }
3841
1.15M
}
3842
3843
/*
3844
 * Copy device parameters back from a target.  This copies all standard
3845
 * parameters related to page size and resolution, but not any of the
3846
 * color-related parameters, as the pdf14 device retains its own color
3847
 * handling. This routine is parallel to gx_device_copy_params().
3848
 * Note that it DOES copy the devn_params since these are required to
3849
 * keep agreement with colorant name->number mapping, and don't change
3850
 * with the pdf14 color handling.
3851
 */
3852
static  int
3853
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3854
1.15M
{
3855
1.15M
    cmm_dev_profile_t *profile_targ;
3856
1.15M
    cmm_dev_profile_t *profile_dev14;
3857
1.15M
    pdf14_device *pdev = (pdf14_device*) dev;
3858
1.15M
    cmm_profile_t *blend_profile = NULL;
3859
1.15M
    int k;
3860
3861
1.15M
    COPY_PARAM(width);
3862
1.15M
    COPY_PARAM(height);
3863
1.15M
    COPY_ARRAY_PARAM(MediaSize);
3864
1.15M
    COPY_ARRAY_PARAM(ImagingBBox);
3865
1.15M
    COPY_PARAM(ImagingBBox_set);
3866
1.15M
    COPY_ARRAY_PARAM(HWResolution);
3867
1.15M
    COPY_ARRAY_PARAM(Margins);
3868
1.15M
    COPY_ARRAY_PARAM(HWMargins);
3869
1.15M
    COPY_PARAM(PageCount);
3870
1.15M
    COPY_PARAM(MaxPatternBitmap);
3871
3872
3873
    /* Supposedly this function isn't supposed to change the color setup of dev.
3874
     * BUT... if we change the tags value, we have to change the color setup to
3875
     * keep it valid. This is because num_components and depth include tags. */
3876
1.15M
    copy_tag_setup(dev, target);
3877
1.15M
    COPY_PARAM(interpolate_control);
3878
1.15M
    COPY_PARAM(non_strict_bounds);
3879
1.15M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3880
3881
1.15M
    if (dev->icc_struct == NULL) {
3882
1.15M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3883
1.15M
        if (dev->icc_struct == NULL)
3884
0
            return_error(gs_error_VMerror);
3885
1.15M
        profile_dev14 = dev->icc_struct;
3886
1.15M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3887
1.15M
                                          &(profile_targ));
3888
3889
5.78M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3890
4.62M
            if (profile_targ->device_profile[k] != NULL) {
3891
1.15M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3892
1.15M
            }
3893
4.62M
            if (profile_dev14->device_profile[k] != NULL) {
3894
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3895
0
            }
3896
4.62M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3897
4.62M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3898
4.62M
        }
3899
3900
1.15M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3901
1.15M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3902
1.15M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3903
1.15M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3904
1.15M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3905
1.15M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3906
1.15M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3907
1.15M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3908
1.15M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3909
3910
1.15M
        switch (pdev->blend_cs_state) {
3911
1.15M
            case PDF14_BLEND_CS_UNSPECIFIED:
3912
1.15M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3913
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3914
                   during the device push, when we have
3915
                   access to the pgs */
3916
1.15M
                break;
3917
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3918
0
                blend_profile = profile_targ->oi_profile;
3919
0
                break;
3920
0
            case PDF14_BLEND_CS_SPECIFIED:
3921
0
                blend_profile = profile_targ->blend_profile;
3922
0
                break;
3923
0
            default:
3924
0
                break;
3925
1.15M
        }
3926
3927
1.15M
        if (blend_profile != NULL) {
3928
            /* Set the device profile to the blend profile. Note only default profile is set */
3929
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3930
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3931
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3932
0
        }
3933
3934
1.15M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3935
1.15M
    }
3936
1.15M
#undef COPY_ARRAY_PARAM
3937
1.15M
#undef COPY_PARAM
3938
1.15M
    return 0;
3939
1.15M
}
3940
3941
/*
3942
 * This is a forwarding version of the put_params device proc.  It is only
3943
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3944
 * check if the target device has closed and, if so, close itself.  The routine
3945
 * also sync the device parameters.
3946
 */
3947
static  int
3948
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3949
0
{
3950
0
    pdf14_device * pdev = (pdf14_device *)dev;
3951
0
    gx_device * tdev = pdev->target;
3952
0
    bool was_open = tdev->is_open;
3953
0
    int code = 0;
3954
3955
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3956
0
        gx_device_decache_colors(dev);
3957
0
        if (!tdev->is_open) {
3958
0
            code = gs_closedevice(dev);
3959
0
            if (code == 0)
3960
0
                code = was_open ? 1 : 0;   /* target device closed */
3961
0
        }
3962
0
        gx_device_copy_params(dev, tdev);
3963
0
    }
3964
0
    return code;
3965
0
}
3966
3967
/* Function prototypes */
3968
int put_param_pdf14_spot_names(gx_device * pdev,
3969
                gs_separations * pseparations, gs_param_list * plist);
3970
107k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3971
3972
/*
3973
 * The put_params method for the PDF 1.4 device will check if the
3974
 * target device has closed and, if so, close itself.  Note:  This routine is
3975
 * currently being used by both the pdf14_clist_device and the pdf_device.
3976
 * Please make sure that any changes are either applicable to both devices
3977
 * or clone the routine for each device.
3978
 */
3979
static  int
3980
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3981
0
{
3982
0
    pdf14_device * pdev = (pdf14_device *)dev;
3983
0
    gx_device * tdev = pdev->target;
3984
0
    bool was_open = tdev->is_open;
3985
0
    int code = 0, code2 = 0;
3986
3987
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3988
0
        gx_device_decache_colors(dev);
3989
0
        if (!tdev->is_open) {
3990
0
            code = gs_closedevice(dev);
3991
0
            if (code == 0)
3992
0
                code = was_open ? 1 : 0;   /* target device closed */
3993
0
        }
3994
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
3995
0
        if (code2 < 0)
3996
0
            code = code2;
3997
0
    }
3998
0
    return code;
3999
0
}
4000
4001
/*
4002
 * Copy marking related parameters into the PDF 1.4 device structure for use
4003
 * by pdf14_fill_rectangle.
4004
 */
4005
static  void
4006
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4007
27.7M
{
4008
27.7M
    pdf14_device * pdev = (pdf14_device *)dev;
4009
4010
27.7M
    if (pgs->alphaisshape) {
4011
327k
        pdev->opacity = 1.0;
4012
327k
        if (pgs->is_fill_color) {
4013
321k
            pdev->shape = pgs->fillconstantalpha;
4014
321k
        } else {
4015
6.44k
            pdev->shape = pgs->strokeconstantalpha;
4016
6.44k
        }
4017
27.3M
    } else {
4018
27.3M
        pdev->shape = 1.0;
4019
27.3M
        if (pgs->is_fill_color) {
4020
11.4M
            pdev->opacity = pgs->fillconstantalpha;
4021
15.9M
        } else {
4022
15.9M
            pdev->opacity = pgs->strokeconstantalpha;
4023
15.9M
        }
4024
27.3M
    }
4025
27.7M
    pdev->alpha = pdev->opacity * pdev->shape;
4026
27.7M
    pdev->blend_mode = pgs->blend_mode;
4027
27.7M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4028
27.7M
        pdev->overprint = pgs->overprint;
4029
27.7M
        pdev->stroke_overprint = pgs->stroke_overprint;
4030
27.7M
    } else {
4031
0
        pdev->overprint = false;
4032
0
        pdev->stroke_overprint = false;
4033
0
    }
4034
4035
27.7M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4036
27.7M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4037
4038
27.7M
    if (pgs->is_fill_color)
4039
11.8M
        pdev->op_state = PDF14_OP_STATE_FILL;
4040
15.9M
    else
4041
15.9M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4042
4043
27.7M
    if_debug6m('v', dev->memory,
4044
27.7M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4045
27.7M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4046
27.7M
               pdev->stroke_effective_op_mode);
4047
27.7M
}
4048
4049
static  void
4050
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4051
19.1M
{
4052
19.1M
    bool hastrans = false;
4053
4054
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4055
     * makes other operations much slower. We have no option however, if the
4056
     * current colour involves transparency, or if it's anything other than
4057
     * a completely solid (or transparent) operation in the normal blend mode.
4058
     */
4059
19.1M
    if (pdcolor != NULL)
4060
19.1M
    {
4061
19.1M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4062
495k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4063
4.86k
            hastrans = true;
4064
19.1M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4065
            /* FIXME: Here we assume that ALL type 2 patterns are
4066
             * transparent - this test could be better. */
4067
4.83k
            hastrans = true;
4068
4.83k
        }
4069
19.1M
    }
4070
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4071
       This appears to be the only place where this test is done so
4072
       not adding a is_idempotent method */
4073
19.1M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4074
161k
        pgs->blend_mode != BLEND_MODE_Darken &&
4075
155k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4076
19.0M
        (pgs->fillconstantalpha != 1.0) ||
4077
18.8M
        (pgs->strokeconstantalpha != 1.0) ||
4078
18.7M
        (hastrans))
4079
401k
    {
4080
        /*
4081
         * The blend operations are not idempotent.  Force non-idempotent
4082
         * filling and stroking operations.
4083
         */
4084
401k
        pgs->log_op |= lop_pdf14;
4085
401k
    }
4086
19.1M
}
4087
4088
static int
4089
push_shfill_group(pdf14_clist_device *pdev,
4090
                  gs_gstate *pgs,
4091
                  gs_fixed_rect *box)
4092
40
{
4093
40
    gs_transparency_group_params_t params = { 0 };
4094
40
    int code;
4095
40
    gs_rect cb;
4096
40
    gs_gstate fudged_pgs = *pgs;
4097
4098
40
    params.shade_group = true;
4099
4100
    /* gs_begin_transparency_group takes a bbox that it then
4101
     * transforms by ctm. Our bbox has already been transformed,
4102
     * so clear out the ctm. */
4103
40
    fudged_pgs.ctm.xx = 1.0;
4104
40
    fudged_pgs.ctm.xy = 0;
4105
40
    fudged_pgs.ctm.yx = 0;
4106
40
    fudged_pgs.ctm.yy = 1.0;
4107
40
    fudged_pgs.ctm.tx = 0;
4108
40
    fudged_pgs.ctm.ty = 0;
4109
40
    cb.p.x = fixed2int_pixround(box->p.x);
4110
40
    cb.p.y = fixed2int_pixround(box->p.y);
4111
40
    cb.q.x = fixed2int_pixround(box->q.x);
4112
40
    cb.q.y = fixed2int_pixround(box->q.y);
4113
4114
40
    params.Isolated = false;
4115
40
    params.Knockout = true;
4116
40
    params.page_group = false;
4117
40
    params.group_opacity = fudged_pgs.fillconstantalpha;
4118
40
    params.group_shape = 1.0;
4119
40
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4120
4121
    /* We have the group handle the blendmode and the opacity,
4122
     * and continue with the existing graphics state reset
4123
     * to normal, opaque operation. We could do it the other
4124
     * way around, but this way means that if we push a knockout
4125
     * group for a stroke, and then the code calls back into
4126
     * the fill operation as part of doing the stroking, we don't
4127
     * push another one. */
4128
40
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4129
40
    gs_setfillconstantalpha(pgs, 1.0);
4130
40
    gs_setstrokeconstantalpha(pgs, 1.0);
4131
40
    if (pdev) {
4132
40
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4133
40
        if (code < 0)
4134
0
            return code;
4135
40
    }
4136
4137
40
    return code;
4138
40
}
4139
4140
static int
4141
pop_shfill_group(gs_gstate *pgs)
4142
38
{
4143
38
     return gs_end_transparency_group(pgs);
4144
38
}
4145
4146
static int
4147
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4148
                           gx_path *ppath, const gx_fill_params *params,
4149
                           const gx_drawing_color *pdcolor,
4150
                           const gx_clip_path *pcpath)
4151
16.5M
{
4152
16.5M
    gs_gstate new_pgs = *pgs;
4153
16.5M
    int code = 0;
4154
16.5M
    gs_pattern2_instance_t *pinst = NULL;
4155
16.5M
    int push_group = 0;
4156
4157
16.5M
    code = pdf14_initialize_ctx(dev, pgs);
4158
16.5M
    if (code < 0)
4159
0
        return code;
4160
4161
16.5M
    if (pdcolor == NULL)
4162
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4163
16.5M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4164
16.5M
    if (gx_dc_is_pattern1_color(pdcolor)){
4165
553k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4166
533k
            gx_pattern1_clist_has_trans(pdcolor) ){
4167
            /* In this case, we need to push a transparency group
4168
               and tile the pattern color, which is stored in
4169
               a pdf14 device buffer in the ctile object memember
4170
               variable ttrans */
4171
#if RAW_DUMP
4172
            /* Since we do not get a put_image to view what
4173
               we have do it now */
4174
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4175
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4176
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4177
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4178
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4179
                        ppatdev14->ctx->stack->rect.p.y *
4180
                        ppatdev14->ctx->stack->rowstride +
4181
                        ppatdev14->ctx->stack->rect.p.x;
4182
                    dump_raw_buffer(ppatdev14->ctx->memory,
4183
                                    (ppatdev14->ctx->stack->rect.q.y -
4184
                                     ppatdev14->ctx->stack->rect.p.y),
4185
                                    (ppatdev14->ctx->stack->rect.q.x -
4186
                                     ppatdev14->ctx->stack->rect.p.x),
4187
                                    ppatdev14->ctx->stack->n_planes,
4188
                                    ppatdev14->ctx->stack->planestride,
4189
                                    ppatdev14->ctx->stack->rowstride,
4190
                                    "Pattern_Fill", buf_ptr,
4191
                                    ppatdev14->ctx->stack->deep);
4192
                    global_index++;
4193
                } else {
4194
                     gx_pattern_trans_t *patt_trans =
4195
                                        pdcolor->colors.pattern.p_tile->ttrans;
4196
                     dump_raw_buffer(patt_trans->mem,
4197
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4198
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4199
                                     patt_trans->n_chan,
4200
                                     patt_trans->planestride, patt_trans->rowstride,
4201
                                     "Pattern_Fill_clist",
4202
                                     patt_trans->transbytes +
4203
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4204
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4205
                                     patt_trans->deep);
4206
                    global_index++;
4207
                }
4208
            }
4209
#endif
4210
66.4k
            pdf14_set_marking_params(dev, &new_pgs);
4211
66.4k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4212
66.4k
                params, pdcolor, pcpath);
4213
66.4k
            new_pgs.trans_device = NULL;
4214
66.4k
            new_pgs.has_transparency = false;
4215
66.4k
            return code;
4216
66.4k
        }
4217
553k
    }
4218
16.4M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4219
16.4M
        pdcolor->type == &gx_dc_devn_masked) {
4220
        /* Non-idempotent blends require a transparency
4221
         * group to be pushed because shadings might
4222
         * paint several pixels twice. */
4223
12
        push_group = pgs->fillconstantalpha != 1.0 ||
4224
12
               !blend_is_idempotent(gs_currentblendmode(pgs));
4225
12
        pinst =
4226
12
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4227
12
        pinst->saved->has_transparency = true;
4228
        /* The transparency color space operations are driven
4229
           by the pdf14 clist writer device.  */
4230
12
        pinst->saved->trans_device = dev;
4231
12
    }
4232
16.4M
    if (push_group) {
4233
0
        gs_fixed_rect box;
4234
0
        if (pcpath)
4235
0
            gx_cpath_outer_box(pcpath, &box);
4236
0
        else
4237
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4238
0
        if (ppath) {
4239
0
            gs_fixed_rect path_box;
4240
4241
0
            gx_path_bbox(ppath, &path_box);
4242
0
            if (box.p.x < path_box.p.x)
4243
0
                box.p.x = path_box.p.x;
4244
0
            if (box.p.y < path_box.p.y)
4245
0
                box.p.y = path_box.p.y;
4246
0
            if (box.q.x > path_box.q.x)
4247
0
                box.q.x = path_box.q.x;
4248
0
            if (box.q.y > path_box.q.y)
4249
0
                box.q.y = path_box.q.y;
4250
0
        }
4251
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4252
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4253
0
    } else
4254
16.4M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4255
16.4M
    pdf14_set_marking_params(dev, &new_pgs);
4256
16.4M
    if (code >= 0) {
4257
16.4M
        new_pgs.trans_device = dev;
4258
16.4M
        new_pgs.has_transparency = true;
4259
        /* ppath can permissibly be NULL here, if we want to have a
4260
         * shading or a pattern fill the clipping path. This upsets
4261
         * coverity, which is not smart enough to realise that the
4262
         * validity of a NULL ppath depends on the type of pdcolor.
4263
         * We'll mark it as a false positive. */
4264
16.4M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4265
16.4M
        new_pgs.trans_device = NULL;
4266
16.4M
        new_pgs.has_transparency = false;
4267
16.4M
    }
4268
16.4M
    if (code >= 0 && push_group) {
4269
0
        code = pop_shfill_group(&new_pgs);
4270
0
        pdf14_set_marking_params(dev, pgs);
4271
0
    }
4272
16.4M
    if (pinst != NULL){
4273
12
        pinst->saved->trans_device = NULL;
4274
12
    }
4275
16.4M
    return code;
4276
16.5M
}
4277
4278
static  int
4279
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4280
                             gx_path *ppath, const gx_stroke_params *params,
4281
                             const gx_drawing_color *pdcolor,
4282
                             const gx_clip_path *pcpath)
4283
1.39M
{
4284
1.39M
    gs_gstate new_pgs = *pgs;
4285
1.39M
    int push_group = 0;
4286
1.39M
    int code = 0;
4287
4288
1.39M
    if (pdcolor == NULL)
4289
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4290
4291
1.39M
    code = pdf14_initialize_ctx(dev, pgs);
4292
1.39M
    if (code < 0)
4293
0
        return code;
4294
4295
1.39M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4296
        /* Non-idempotent blends require a transparency
4297
         * group to be pushed because shadings might
4298
         * paint several pixels twice. */
4299
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4300
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4301
0
    }
4302
1.39M
    if (push_group) {
4303
0
        gs_fixed_rect box;
4304
0
        if (pcpath)
4305
0
            gx_cpath_outer_box(pcpath, &box);
4306
0
        else
4307
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4308
4309
        /* For fill_path, we accept ppath == NULL to mean
4310
         * fill the entire clipping region. That makes no
4311
         * sense for stroke_path, hence ppath is always non
4312
         * NULL here. */
4313
0
        {
4314
0
            gs_fixed_rect path_box;
4315
0
            gs_fixed_point expansion;
4316
4317
0
            gx_path_bbox(ppath, &path_box);
4318
            /* Expand the path bounding box by the scaled line width. */
4319
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4320
                /* The expansion is so large it caused a limitcheck. */
4321
0
                path_box.p.x = path_box.p.y = min_fixed;
4322
0
                path_box.q.x = path_box.q.y = max_fixed;
4323
0
            } else {
4324
0
                expansion.x += pgs->fill_adjust.x;
4325
0
                expansion.y += pgs->fill_adjust.y;
4326
                /*
4327
                 * It's theoretically possible for the following computations to
4328
                 * overflow, so we need to check for this.
4329
                 */
4330
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4331
0
                                path_box.p.x - expansion.x);
4332
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4333
0
                                path_box.p.y - expansion.y);
4334
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4335
0
                                path_box.q.x + expansion.x);
4336
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4337
0
                                path_box.q.y + expansion.y);
4338
0
            }
4339
0
            if (box.p.x < path_box.p.x)
4340
0
                box.p.x = path_box.p.x;
4341
0
            if (box.p.y < path_box.p.y)
4342
0
                box.p.y = path_box.p.y;
4343
0
            if (box.q.x > path_box.q.x)
4344
0
                box.q.x = path_box.q.x;
4345
0
            if (box.q.y > path_box.q.y)
4346
0
                box.q.y = path_box.q.y;
4347
0
        }
4348
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4349
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4350
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4351
0
    } else
4352
1.39M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4353
1.39M
    pdf14_set_marking_params(dev, &new_pgs);
4354
1.39M
    if (code >= 0) {
4355
1.39M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4356
4357
1.39M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4358
1.39M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4359
1.39M
        ((pdf14_device*)dev)->op_state = save_op_state;
4360
1.39M
    }
4361
1.39M
    if (code >= 0 && push_group) {
4362
0
        code = pop_shfill_group(&new_pgs);
4363
0
        pdf14_set_marking_params(dev, pgs);
4364
0
    }
4365
4366
1.39M
    return code;
4367
1.39M
}
4368
4369
/* Pull out steps of transparency updates for fill/stroke
4370
   so that they can be invoked elsewhere (e.g.
4371
   when the abuf device is handling the stroke/fill */
4372
4373
/* Set-up prior to fill operation in fill-stroke */
4374
static int
4375
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4376
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4377
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4378
29.1k
{
4379
29.1k
    int code = 0;
4380
29.1k
    gs_transparency_group_params_t params = { 0 };
4381
29.1k
    gs_fixed_rect clip_bbox;
4382
29.1k
    gs_rect bbox, group_stroke_box;
4383
29.1k
    gs_fixed_rect path_bbox;
4384
29.1k
    int expansion_code;
4385
29.1k
    gs_fixed_point expansion;
4386
29.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4387
4388
29.1k
    *path_empty = false;
4389
4390
29.1k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4391
29.0k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4392
69
    {
4393
69
        *op_ca_eq_CA = true;
4394
69
        *path_empty = true;
4395
69
        return 0;
4396
69
    }
4397
4398
    /* The clip box returned here is scaled up by path_log2scale, so we need
4399
     * to scale down by this later. */
4400
29.0k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4401
29.0k
    if (code < 0 && code != gs_error_unknownerror)
4402
0
        return code;
4403
4404
29.0k
    if (code == gs_error_unknownerror) {
4405
        /* didn't get clip box from gx_curr_fixed_bbox */
4406
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4407
         * scaling down by this in a moment. */
4408
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4409
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4410
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4411
0
    }
4412
    /* pcpath->outer_box is scaled by path_log2scale too. */
4413
29.0k
    if (pcpath)
4414
29.0k
        rect_intersect(clip_bbox, pcpath->outer_box);
4415
4416
    /* expand the ppath using stroke expansion rule, then intersect it */
4417
29.0k
    code = gx_path_bbox(ppath, &path_bbox);
4418
4419
    /* If we are coming from the abuf device, the path has been scaled
4420
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4421
       on the path_bbox so that we get the proper bounding box for our group. */
4422
29.0k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4423
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4424
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4425
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4426
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4427
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4428
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4429
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4430
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4431
0
    }
4432
4433
29.0k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4434
2.36k
        *path_empty = true;
4435
2.36k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4436
                     there are simply too many return cases that I can't account for. */
4437
2.36k
    }
4438
26.6k
    if (code < 0)
4439
0
        return code;
4440
4441
26.6k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4442
26.6k
    if (expansion_code >= 0) {
4443
26.6k
        path_bbox.p.x -= expansion.x;
4444
26.6k
        path_bbox.p.y -= expansion.y;
4445
26.6k
        path_bbox.q.x += expansion.x;
4446
26.6k
        path_bbox.q.y += expansion.y;
4447
26.6k
    }
4448
26.6k
    rect_intersect(path_bbox, clip_bbox);
4449
26.6k
    bbox.p.x = fixed2float(path_bbox.p.x);
4450
26.6k
    bbox.p.y = fixed2float(path_bbox.p.y);
4451
26.6k
    bbox.q.x = fixed2float(path_bbox.q.x);
4452
26.6k
    bbox.q.y = fixed2float(path_bbox.q.y);
4453
4454
26.6k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4455
26.6k
    if (code < 0)
4456
1
        return code;
4457
4458
26.6k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4459
0
        p14dev->overprint = pgs->overprint;
4460
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4461
0
    }
4462
4463
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4464
26.6k
    if (fill_alpha == stroke_alpha &&
4465
5.72k
        p14dev->overprint && p14dev->stroke_overprint &&
4466
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4467
4468
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4469
           compatible overprint mode.  Group will be composited with
4470
           original alpha and blend mode */
4471
0
        *op_ca_eq_CA = true;
4472
0
        params.Isolated = false;
4473
0
        params.group_color_type = UNKNOWN;
4474
0
        params.Knockout = false;
4475
0
        params.page_group = false;
4476
0
        params.group_opacity = 1.0;
4477
0
        params.group_shape = fill_alpha;
4478
4479
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4480
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4481
0
        if (code < 0)
4482
0
            return code;
4483
4484
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4485
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4486
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4487
4488
26.6k
    } else {
4489
        /* Push a non-isolated knockout group. Do not change the alpha or
4490
            blend modes. Note: we need to draw those that have alpha = 0 */
4491
26.6k
        *op_ca_eq_CA = false;
4492
26.6k
        params.Isolated = false;
4493
26.6k
        params.group_color_type = UNKNOWN;
4494
26.6k
        params.Knockout = true;
4495
26.6k
        params.page_group = false;
4496
26.6k
        params.group_shape = 1.0;
4497
26.6k
        params.group_opacity = 1.0;
4498
4499
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4500
26.6k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4501
26.6k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4502
26.6k
        if (code < 0)
4503
0
            return code;
4504
4505
        /* restore blend mode for actual drawing in the group */
4506
26.6k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4507
4508
        /* If we are in an overprint situation, set the blend mode to compatible
4509
            overprint */
4510
26.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4511
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4512
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4513
26.6k
    }
4514
26.6k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4515
26.6k
    return code;
4516
26.6k
}
4517
4518
/* Set-up prior to stroke operation in fill-stroke */
4519
static void
4520
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4521
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4522
26.6k
{
4523
26.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4524
4525
26.6k
    if (op_ca_eq_CA) {
4526
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4527
26.6k
    } else {
4528
26.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4529
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4530
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4531
4532
        /* Note that the stroke can end up doing fill methods */
4533
26.6k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4534
4535
26.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4536
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4537
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4538
26.6k
    }
4539
26.6k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4540
26.6k
}
4541
4542
/* Cleanup after the stroke in fill-stroke  */
4543
static int
4544
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4545
26.6k
{
4546
26.6k
    int code;
4547
4548
26.6k
    if (!op_ca_eq_CA) {
4549
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4550
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4551
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4552
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4553
          * We therefore need to make sure it is set according to the current fill state.
4554
          */
4555
26.6k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4556
26.6k
        code = gs_update_trans_marking_params(pgs);
4557
26.6k
        if (code < 0)
4558
0
            return code;
4559
26.6k
        pdf14_set_marking_params(dev, pgs);
4560
26.6k
    }
4561
4562
26.6k
    return 0;
4563
26.6k
}
4564
4565
/* cleanup in fill-stroke  */
4566
static int
4567
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4568
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4569
26.6k
{
4570
26.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4571
26.6k
    int code2;
4572
26.6k
    int code = 0;
4573
4574
    /* Restore the state */
4575
26.6k
    p14dev->op_state = save_op_state;
4576
26.6k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4577
26.6k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4578
26.6k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4579
4580
26.6k
    code2 = gs_end_transparency_group(pgs);
4581
26.6k
    if (code2 < 0) {
4582
        /* At this point things have gone very wrong. We should just shut down */
4583
0
        code = gs_abort_pdf14trans_device(pgs);
4584
0
        return code2;
4585
0
    }
4586
26.6k
    return code;
4587
26.6k
}
4588
4589
static int
4590
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4591
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4592
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4593
    const gx_clip_path *pcpath)
4594
101k
{
4595
101k
    bool op_ca_eq_CA;
4596
101k
    bool path_empty;
4597
101k
    int code;
4598
101k
    float stroke_alpha = cpgs->strokeconstantalpha;
4599
101k
    float fill_alpha = cpgs->fillconstantalpha;
4600
101k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4601
101k
    pdf14_device* p14dev = (pdf14_device*)dev;
4602
101k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4603
101k
    gs_log2_scale_point path_log2scale;
4604
101k
    bool group_needed = true;
4605
101k
    gx_device* curr_pgs_dev = cpgs->device;
4606
4607
101k
    union {
4608
101k
        const gs_gstate* cpgs;
4609
101k
        gs_gstate* pgs;
4610
101k
    } const_breaker;
4611
101k
    gs_gstate* pgs;
4612
4613
    /* Break const just once, neatly */
4614
101k
    const_breaker.cpgs = cpgs;
4615
101k
    pgs = const_breaker.pgs;
4616
101k
    path_log2scale.x = 0;
4617
101k
    path_log2scale.y = 0;
4618
4619
101k
    code = pdf14_initialize_ctx(dev, pgs);
4620
101k
    if (code < 0)
4621
0
        return code;
4622
4623
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4624
     * blend is normal we don't do a group push. Just do the stroke
4625
     * and the fill, even with overprint */
4626
101k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4627
71.9k
        group_needed = false;
4628
4629
101k
    if (group_needed) {
4630
29.1k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4631
                              can be called on the clist writer side when dealing
4632
                              with the abuf/pdf14 interaction. Those calls have to
4633
                              go through the gs_trans API not the gx_trans or pdf14
4634
                              methods.  Perhaps these methods should have a different
4635
                              suffix, but they are static methods here in the pdf14
4636
                              file. */
4637
29.1k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4638
29.1k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4639
29.1k
        pgs->device = curr_pgs_dev;
4640
29.1k
        if (code < 0)
4641
1
            goto cleanup;
4642
29.1k
        if (path_empty)
4643
2.43k
            return 0;
4644
29.1k
    }
4645
4646
98.5k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4647
98.5k
    if (code < 0)
4648
0
        goto cleanup;
4649
4650
98.5k
    if (group_needed)
4651
26.6k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4652
98.5k
    gs_swapcolors_quick(pgs);
4653
4654
4655
#if RAW_DUMP
4656
    /* Dump the current buffer to see what we have. */
4657
    dump_raw_buffer(p14dev->ctx->memory,
4658
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4659
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4660
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4661
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4662
    global_index++;
4663
#endif
4664
4665
98.5k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4666
98.5k
    gs_swapcolors_quick(pgs);
4667
98.5k
    if (code < 0) {
4668
0
        goto cleanup;
4669
0
    }
4670
4671
#if RAW_DUMP
4672
    /* Dump the current buffer to see what we have. */
4673
    dump_raw_buffer(p14dev->ctx->memory,
4674
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4675
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4676
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4677
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4678
    global_index++;
4679
#endif
4680
98.5k
    if (group_needed)
4681
26.6k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4682
4683
98.5k
cleanup:
4684
98.5k
    if (group_needed) {
4685
26.6k
        int code1;
4686
26.6k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4687
26.6k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4688
26.6k
            save_op_state);
4689
26.6k
        if (code1 < 0)
4690
0
            code = code1;
4691
26.6k
        pgs->device = curr_pgs_dev;
4692
26.6k
    }
4693
98.5k
    return code;
4694
98.5k
}
4695
4696
static int
4697
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4698
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4699
                      gx_color_index color, int depth)
4700
0
{
4701
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4702
0
                                  color, NULL, depth, false);
4703
0
}
4704
4705
static int
4706
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4707
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4708
                      const gx_drawing_color *pdcolor, int depth)
4709
0
{
4710
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4711
0
                                  0, pdcolor, depth, true);
4712
0
}
4713
4714
static int
4715
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4716
                          int aa_raster, gx_bitmap_id id, int x, int y,
4717
                          int w, int h, gx_color_index color,
4718
                          const gx_device_color *pdc, int depth, bool devn)
4719
0
{
4720
0
    const byte *aa_row;
4721
0
    pdf14_device *pdev = (pdf14_device *)dev;
4722
0
    pdf14_buf *buf = pdev->ctx->stack;
4723
0
    int i, j, k;
4724
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4725
0
    byte src[PDF14_MAX_PLANES];
4726
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4727
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4728
0
    bool additive = pdev->ctx->additive;
4729
0
    intptr_t rowstride = buf->rowstride;
4730
0
    intptr_t planestride = buf->planestride;
4731
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4732
0
    bool has_alpha_g = buf->has_alpha_g;
4733
0
    bool has_shape = buf->has_shape;
4734
0
    bool has_tags = buf->has_tags;
4735
0
    bool knockout = buf->knockout;
4736
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4737
0
        blend_mode == BLEND_MODE_Compatible ||
4738
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4739
0
    int num_chan = buf->n_chan;
4740
0
    int num_comp = num_chan - 1;
4741
0
    intptr_t shape_off = num_chan * planestride;
4742
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4743
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4744
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4745
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4746
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4747
0
    gx_color_index comps;
4748
0
    byte shape = 0; /* Quiet compiler. */
4749
0
    byte src_alpha;
4750
0
    int alpha2_aa, alpha_aa, sx;
4751
0
    int alpha_aa_act;
4752
0
    int xoff;
4753
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4754
0
    int shift = 8;
4755
0
    bool has_backdrop = buf->backdrop != NULL;
4756
4757
0
    if (buf->data == NULL)
4758
0
        return 0;
4759
0
    aa_row = data;
4760
0
    if (has_tags) {
4761
0
        if (devn)
4762
0
            curr_tag = pdc->tag;
4763
0
        else
4764
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4765
0
    }
4766
4767
0
    if (devn) {
4768
0
        if (additive) {
4769
0
            for (j = 0; j < num_comp; j++) {
4770
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4771
0
            }
4772
0
        } else {
4773
0
            for (j = 0; j < num_comp; j++) {
4774
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4775
0
            }
4776
0
        }
4777
0
    } else
4778
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4779
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4780
0
    if (has_shape)
4781
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4782
    /* Limit the area we write to the bounding rectangle for this buffer */
4783
0
    if (x < buf->rect.p.x) {
4784
0
        xoff = data_x + buf->rect.p.x - x;
4785
0
        w += x - buf->rect.p.x;
4786
0
        x = buf->rect.p.x;
4787
0
    } else {
4788
0
        xoff = data_x;
4789
0
    }
4790
0
    if (y < buf->rect.p.y) {
4791
0
      h += y - buf->rect.p.y;
4792
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4793
0
      y = buf->rect.p.y;
4794
0
    }
4795
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4796
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4797
    /* Update the dirty rectangle. */
4798
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4799
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4800
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4801
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4802
4803
    /* composite with backdrop only. */
4804
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4805
0
    if (knockout && has_backdrop)
4806
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4807
0
    else
4808
0
        bline = line;
4809
4810
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4811
0
        back_ptr = bline;
4812
0
        dst_ptr = line;
4813
0
        sx = xoff;
4814
0
        for (i = 0; i < w; ++i, ++sx) {
4815
            /* Complement the components for subtractive color spaces */
4816
0
            if (additive) {
4817
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4818
0
                    dst[k] = back_ptr[k * planestride];
4819
0
            } else { /* Complement the components for subtractive color spaces */
4820
0
                for (k = 0; k < num_comp; ++k)
4821
0
                    dst[k] = 255 - back_ptr[k * planestride];
4822
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4823
0
            }
4824
            /* Get the aa alpha from the buffer */
4825
0
            switch(depth)
4826
0
            {
4827
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4828
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4829
0
                break;
4830
0
            case 4:
4831
0
                alpha2_aa = aa_row[sx >> 1];
4832
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4833
0
                break;
4834
0
            case 8:
4835
0
                alpha_aa = aa_row[sx];
4836
0
                break;
4837
0
            default:
4838
0
                return_error(gs_error_rangecheck);
4839
0
            }
4840
0
            if (alpha_aa != 0) {  /* This does happen */
4841
0
                if (alpha_aa != 255) {
4842
                    /* We have an alpha value from aa */
4843
0
                    alpha_aa_act = alpha_aa;
4844
0
                    if (src_alpha != 255) {
4845
                        /* Need to combine it with the existing alpha */
4846
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4847
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4848
0
                    }
4849
                    /* Set our source alpha value appropriately */
4850
0
                    src[num_comp] = alpha_aa_act;
4851
0
                } else {
4852
                    /* We may have to reset this is it was changed as we
4853
                       moved across the row */
4854
0
                    src[num_comp] = src_alpha;
4855
0
                }
4856
0
                if (knockout) {
4857
0
                    if (buf->isolated) {
4858
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4859
0
                    } else {
4860
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4861
0
                            blend_mode, pdev->blend_procs, pdev);
4862
0
                    }
4863
0
                } else {
4864
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4865
0
                                                    pdev->blend_procs, pdev);
4866
0
                }
4867
                /* Complement the results for subtractive color spaces */
4868
0
                if (additive) {
4869
0
                    for (k = 0; k < num_chan; ++k)
4870
0
                        dst_ptr[k * planestride] = dst[k];
4871
0
                } else {
4872
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4873
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4874
0
                                ++k, comps >>= 1) {
4875
0
                            if ((comps & 0x1) != 0) {
4876
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4877
0
                            }
4878
0
                        }
4879
                        /* The alpha channel */
4880
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4881
0
                    } else {
4882
0
                        for (k = 0; k < num_comp; ++k)
4883
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4884
                        /* The alpha channel */
4885
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4886
0
                    }
4887
0
                }
4888
0
                if (has_alpha_g) {
4889
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4890
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4891
0
                }
4892
0
                if (has_shape) {
4893
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4894
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4895
0
                }
4896
0
                if (has_tags) {
4897
                    /* If alpha is 100% then set to curr_tag, else or */
4898
                    /* other than Normal BM, we always OR */
4899
0
                    if (src[num_comp] == 255 && tag_blend) {
4900
0
                        dst_ptr[tag_off] = curr_tag;
4901
0
                    } else {
4902
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4903
0
                    }
4904
0
                }
4905
0
            }
4906
0
            ++dst_ptr;
4907
0
            ++back_ptr;
4908
0
        }
4909
0
        line += rowstride;
4910
0
        bline += rowstride;
4911
0
    }
4912
0
    return 0;
4913
0
}
4914
4915
static int
4916
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4917
                             int aa_raster, gx_bitmap_id id, int x, int y,
4918
                             int w, int h, gx_color_index color,
4919
                             const gx_device_color *pdc, int depth, bool devn)
4920
0
{
4921
0
    const byte *aa_row;
4922
0
    pdf14_device *pdev = (pdf14_device *)dev;
4923
0
    pdf14_buf *buf = pdev->ctx->stack;
4924
0
    int i, j, k;
4925
0
    byte *bline, *line;
4926
0
    uint16_t *dst_ptr, *back_ptr;
4927
0
    uint16_t src[PDF14_MAX_PLANES];
4928
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4929
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4930
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4931
0
        blend_mode == BLEND_MODE_Compatible ||
4932
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4933
0
    bool additive = pdev->ctx->additive;
4934
0
    intptr_t rowstride = buf->rowstride;
4935
0
    int planestride = buf->planestride;
4936
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4937
0
    bool has_alpha_g = buf->has_alpha_g;
4938
0
    bool has_shape = buf->has_shape;
4939
0
    bool has_tags = buf->has_tags;
4940
0
    bool knockout = buf->knockout;
4941
0
    int num_chan = buf->n_chan;
4942
0
    int num_comp = num_chan - 1;
4943
0
    intptr_t shape_off = num_chan * planestride;
4944
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4945
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4946
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4947
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4948
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4949
0
    gx_color_index comps;
4950
0
    uint16_t shape = 0; /* Quiet compiler. */
4951
0
    uint16_t src_alpha;
4952
0
    int alpha2_aa, alpha_aa, sx;
4953
0
    int alpha_aa_act;
4954
0
    int xoff;
4955
0
    bool has_backdrop = buf->backdrop != NULL;
4956
4957
0
    if (buf->data == NULL)
4958
0
        return 0;
4959
0
    aa_row = data;
4960
0
    if (has_tags) {
4961
0
        if (devn)
4962
0
            curr_tag = pdc->tag;
4963
0
        else
4964
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4965
0
    }
4966
4967
0
    if (devn) {
4968
0
        if (additive) {
4969
0
            for (j = 0; j < num_comp; j++) {
4970
0
                src[j] = pdc->colors.devn.values[j];
4971
0
            }
4972
0
        } else {
4973
0
            for (j = 0; j < num_comp; j++) {
4974
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4975
0
            }
4976
0
        }
4977
0
    } else
4978
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4979
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4980
0
    if (has_shape)
4981
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4982
    /* Limit the area we write to the bounding rectangle for this buffer */
4983
0
    if (x < buf->rect.p.x) {
4984
0
        xoff = data_x + buf->rect.p.x - x;
4985
0
        w += x - buf->rect.p.x;
4986
0
        x = buf->rect.p.x;
4987
0
    } else {
4988
0
        xoff = data_x;
4989
0
    }
4990
0
    if (y < buf->rect.p.y) {
4991
0
      h += y - buf->rect.p.y;
4992
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4993
0
      y = buf->rect.p.y;
4994
0
    }
4995
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4996
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4997
    /* Update the dirty rectangle. */
4998
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4999
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5000
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5001
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5002
5003
    /* composite with backdrop only. */
5004
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5005
0
    if (knockout && has_backdrop)
5006
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5007
0
    else
5008
0
        bline = line;
5009
5010
0
    planestride >>= 1;
5011
0
    rowstride   >>= 1;
5012
0
    alpha_g_off >>= 1;
5013
0
    shape_off   >>= 1;
5014
0
    tag_off     >>= 1;
5015
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5016
0
        back_ptr = (uint16_t *)(void *)bline;
5017
0
        dst_ptr = (uint16_t *)(void *)line;
5018
0
        sx = xoff;
5019
0
        for (i = 0; i < w; ++i, ++sx) {
5020
            /* Complement the components for subtractive color spaces */
5021
0
            if (additive) {
5022
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5023
0
                    dst[k] = back_ptr[k * planestride];
5024
0
            } else { /* Complement the components for subtractive color spaces */
5025
0
                for (k = 0; k < num_comp; ++k)
5026
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5027
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5028
0
            }
5029
            /* Get the aa alpha from the buffer */
5030
0
            switch(depth)
5031
0
            {
5032
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5033
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5034
0
                break;
5035
0
            case 4:
5036
0
                alpha2_aa = aa_row[sx >> 1];
5037
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5038
0
                break;
5039
0
            case 8:
5040
0
                alpha_aa = aa_row[sx];
5041
0
                break;
5042
0
            default:
5043
0
                return_error(gs_error_rangecheck);
5044
0
            }
5045
0
            if (alpha_aa != 0) {  /* This does happen */
5046
0
                if (alpha_aa != 255) {
5047
                    /* We have an alpha value from aa */
5048
0
                    alpha_aa_act = alpha_aa * 0x101;
5049
0
                    if (src_alpha != 65535) {
5050
                        /* Need to combine it with the existing alpha */
5051
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5052
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5053
0
                    }
5054
                    /* Set our source alpha value appropriately */
5055
0
                    src[num_comp] = alpha_aa_act;
5056
0
                } else {
5057
                    /* We may have to reset this is it was changed as we
5058
                       moved across the row */
5059
0
                    src[num_comp] = src_alpha;
5060
0
                }
5061
0
                if (knockout) {
5062
0
                    if (buf->isolated) {
5063
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5064
0
                    } else {
5065
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5066
0
                            blend_mode, pdev->blend_procs, pdev);
5067
0
                    }
5068
0
                } else {
5069
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5070
0
                                                     pdev->blend_procs, pdev);
5071
0
                }
5072
                /* Complement the results for subtractive color spaces */
5073
0
                if (additive) {
5074
0
                    for (k = 0; k < num_chan; ++k)
5075
0
                        dst_ptr[k * planestride] = dst[k];
5076
0
                } else {
5077
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5078
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5079
0
                                ++k, comps >>= 1) {
5080
0
                            if ((comps & 0x1) != 0) {
5081
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5082
0
                            }
5083
0
                        }
5084
                        /* The alpha channel */
5085
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5086
0
                    } else {
5087
0
                        for (k = 0; k < num_comp; ++k)
5088
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5089
                        /* The alpha channel */
5090
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5091
0
                    }
5092
0
                }
5093
0
                if (has_alpha_g) {
5094
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5095
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5096
0
                }
5097
0
                if (has_shape) {
5098
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5099
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5100
0
                }
5101
0
                if (has_tags) {
5102
                    /* If alpha is 100% then set to curr_tag, else or */
5103
                    /* other than Normal BM, we always OR */
5104
0
                    if (src[num_comp] == 65535 && tag_blend) {
5105
0
                        dst_ptr[tag_off] = curr_tag;
5106
0
                    } else {
5107
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5108
0
                    }
5109
0
                }
5110
0
            }
5111
0
            ++dst_ptr;
5112
0
            ++back_ptr;
5113
0
        }
5114
0
        line += rowstride;
5115
0
        bline += rowstride;
5116
0
    }
5117
0
    return 0;
5118
0
}
5119
5120
static int
5121
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5122
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5123
                      gx_color_index color, const gx_device_color *pdc,
5124
                      int depth, bool devn)
5125
0
{
5126
0
    bool deep = device_is_deep(dev);
5127
0
    int code;
5128
5129
0
    code = pdf14_initialize_ctx(dev, NULL);
5130
0
    if (code < 0)
5131
0
        return code;
5132
5133
0
    if (deep)
5134
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5135
0
                                            id, x, y, w, h,
5136
0
                                            color, pdc, depth, devn);
5137
0
    else
5138
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5139
0
                                         id, x, y, w, h,
5140
0
                                         color, pdc, depth, devn);
5141
0
}
5142
5143
static  int
5144
pdf14_fill_mask(gx_device * orig_dev,
5145
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5146
                     int x, int y, int w, int h,
5147
                     const gx_drawing_color * pdcolor, int depth,
5148
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5149
12.8M
{
5150
12.8M
    gx_device *dev;
5151
12.8M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5152
12.8M
    gx_device_clip cdev;
5153
12.8M
    gx_color_tile *ptile = NULL;
5154
12.8M
    int code = 0;
5155
12.8M
    gs_int_rect group_rect;
5156
12.8M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5157
12.8M
    bool has_pattern_trans = false;
5158
12.8M
    cmm_dev_profile_t *dev_profile;
5159
5160
12.8M
    if (pdcolor == NULL)
5161
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5162
5163
12.8M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5164
12.8M
    if (code < 0)
5165
0
        return code;
5166
5167
    /* If we are doing a fill with a pattern that has a transparency then
5168
       go ahead and do a push and a pop of the transparency group */
5169
12.8M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5170
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5171
0
            ptile = pdcolor->colors.pattern.p_tile;
5172
            /* Set up things in the ptile so that we get the proper
5173
               blending etc */
5174
            /* Set the blending procs and the is_additive setting based
5175
               upon the number of channels */
5176
0
            if (ptile->ttrans->n_chan-1 < 4) {
5177
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5178
0
                ptile->ttrans->is_additive = true;
5179
0
            } else {
5180
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5181
0
                ptile->ttrans->is_additive = false;
5182
0
            }
5183
            /* Set the procs so that we use the proper filling method. */
5184
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5185
            /* Based upon if the tiles overlap pick the type of rect
5186
               fill that we will want to use */
5187
0
            if (ptile->has_overlap) {
5188
                /* This one does blending since there is tile overlap */
5189
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5190
0
            } else {
5191
                /* This one does no blending since there is no tile overlap */
5192
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5193
0
            }
5194
            /* Push the group */
5195
0
            group_rect.p.x = x;
5196
0
            group_rect.p.y = max(0,y);
5197
0
            group_rect.q.x = x + w;
5198
0
            group_rect.q.y = y + h;
5199
0
            if (!(w <= 0 || h <= 0)) {
5200
5201
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5202
0
                if (group_color_info == NULL)
5203
0
                    return_error(gs_error_VMerror);
5204
5205
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5206
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5207
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5208
0
                     group_color_info, NULL, NULL);
5209
0
                if (code < 0)
5210
0
                    return code;
5211
                /* Set up the output buffer information now that we have
5212
                   pushed the group */
5213
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5214
0
                if (fill_trans_buffer == NULL)
5215
0
                    return_error(gs_error_VMerror);
5216
5217
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5218
0
                                              fill_trans_buffer, NULL, false);
5219
                /* Store this in the appropriate place in pdcolor.  This
5220
                   is released later after the mask fill */
5221
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5222
0
                has_pattern_trans = true;
5223
0
            }
5224
0
        }
5225
0
    }
5226
12.8M
    if (pcpath != 0) {
5227
1.71M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5228
1.71M
        dev = (gx_device *) & cdev;
5229
1.71M
    } else
5230
11.1M
        dev = orig_dev;
5231
12.8M
    if (depth > 1) {
5232
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5233
0
        code = (*dev_proc(dev, copy_alpha))
5234
0
            (dev, data, dx, raster, id, x, y, w, h,
5235
0
             gx_dc_pure_color(pdcolor), depth);
5236
12.8M
    } else {
5237
12.8M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5238
12.8M
                                          x, y, w, h, dev, lop, false);
5239
12.8M
    }
5240
12.8M
    if (has_pattern_trans) {
5241
0
        bool has_tags = device_encodes_tags(dev);
5242
0
        if (code >= 0)
5243
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5244
0
        if (code >= 0)
5245
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5246
0
                                                p14dev->blend_procs,
5247
0
                                                p14dev->color_info.num_components - has_tags,
5248
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5249
0
                                                orig_dev);
5250
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5251
0
                       "pdf14_fill_mask");
5252
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5253
0
    }
5254
12.8M
    if (pcpath != 0)
5255
1.71M
        gx_destroy_clip_device_on_stack(&cdev);
5256
12.8M
    return code;
5257
12.8M
}
5258
5259
5260
5261
/* Used for filling rects when we are doing a fill with a pattern that
5262
   has transparency */
5263
static  int
5264
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5265
                        gx_path * ppath, const gx_fill_params * params,
5266
                        const gx_device_color * pdevc,
5267
                        const gx_clip_path * pcpath)
5268
66.4k
{
5269
66.4k
    int code;
5270
66.4k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5271
66.4k
    gs_fixed_rect clip_box;
5272
66.4k
    gs_fixed_rect outer_box;
5273
66.4k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5274
66.4k
    gs_int_rect rect;
5275
66.4k
    gx_clip_rect *curr_clip_rect;
5276
66.4k
    gx_color_tile *ptile = NULL;
5277
66.4k
    int k;
5278
66.4k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5279
66.4k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5280
66.4k
    int n_chan_tile;
5281
66.4k
    gx_clip_path cpath_intersection;
5282
66.4k
    gx_path path_ttrans;
5283
66.4k
    pdf14_group_color_t *group_color_info;
5284
66.4k
    bool has_tags = device_encodes_tags(pdev);
5285
5286
66.4k
    if (ppath == NULL)
5287
0
        return_error(gs_error_unknownerror);  /* should not happen */
5288
66.4k
    if (pcpath != NULL) {
5289
62.4k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5290
62.4k
    } else {
5291
3.97k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5292
3.97k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5293
3.97k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5294
3.97k
    }
5295
66.4k
    if (code < 0)
5296
0
        return code;
5297
66.4k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5298
66.4k
                                          params->rule, pgs_noconst, params);
5299
66.4k
    if (code < 0)
5300
0
        return code;
5301
    /* One (common) case worth optimising for is where we have a pattern that
5302
     * is positioned such that only one repeat of the tile is actually
5303
     * visible. In this case, we can restrict the size of the blending group
5304
     * we need to produce to be that of the actual area of the tile that is
5305
     * used. */
5306
66.4k
    ptile = pdevc->colors.pattern.p_tile;
5307
66.4k
    if (ptile->ttrans != NULL)
5308
19.9k
    {
5309
19.9k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5310
19.9k
            (cpath_intersection.outer_box.p.y < 0) ||
5311
19.9k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5312
12.4k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5313
7.97k
        {
5314
            /* More than one repeat of the tile would be visible, so we can't
5315
             * use the optimisation here. (Actually, this test isn't quite
5316
             * right - it actually tests whether more than the '0th' repeat
5317
             * of the tile is visible. A better test would test if just one
5318
             * repeat of the tile was visible, irrespective of which one.
5319
             * This is (hopefully) relatively rare, and would make the code
5320
             * below more complex too, so we're ignoring that for now. If it
5321
             * becomes evident that it's a case that matters we can revisit
5322
             * it.) */
5323
11.9k
        } else {
5324
            /* Only the 0th repeat is visible. Restrict the size further to
5325
             * just the used area of that patch. */
5326
11.9k
            gx_path_init_local(&path_ttrans, ppath->memory);
5327
11.9k
            code = gx_path_add_rectangle(&path_ttrans,
5328
11.9k
                                         int2fixed(ptile->ttrans->rect.p.x),
5329
11.9k
                                         int2fixed(ptile->ttrans->rect.p.y),
5330
11.9k
                                         int2fixed(ptile->ttrans->rect.q.x),
5331
11.9k
                                         int2fixed(ptile->ttrans->rect.q.y));
5332
11.9k
            if (code < 0)
5333
0
                return code;
5334
11.9k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5335
11.9k
                                      params->rule, pgs_noconst);
5336
11.9k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5337
11.9k
            if (code < 0)
5338
0
                return code;
5339
11.9k
        }
5340
19.9k
    }
5341
    /* Now let us push a transparency group into which we are
5342
     * going to tile the pattern.  */
5343
66.4k
    if (ppath != NULL) {
5344
66.4k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5345
5346
66.4k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5347
66.4k
        rect.p.x = fixed2int(outer_box.p.x);
5348
66.4k
        rect.p.y = fixed2int(outer_box.p.y);
5349
66.4k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5350
66.4k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5351
5352
        /* The color space of this group must be the same as that of the
5353
           tile.  Then when we pop the group, if there is a mismatch between
5354
           the tile color space and the current context we will do the proper
5355
           conversion.  In this way, we ensure that if the tile has any overlapping
5356
           occuring it will be blended in the proper manner i.e in the tile
5357
           underlying color space. */
5358
66.4k
        if (ptile->cdev == NULL) {
5359
19.9k
            if (ptile->ttrans == NULL)
5360
0
                return_error(gs_error_unknownerror);  /* should not happen */
5361
19.9k
            n_chan_tile = ptile->ttrans->n_chan;
5362
46.4k
        } else {
5363
46.4k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5364
46.4k
        }
5365
66.4k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5366
5367
        /* Transparency handling with patterns confuses me, so some notes...
5368
         *
5369
         * For simple, non-transparent patterns, like you'd get in PS, we've
5370
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5371
         * times. To cope with unmarked pixels, we have a "transparency" plane
5372
         * (simple on/off) that says whether a pixel is marked or not.
5373
         *
5374
         * For patterns with transparency (but not blending), we can create an
5375
         * isolated transparency group, tile all the bitmap tiles into that, and
5376
         * then blend that back with the required alpha at the end. This works
5377
         * because the alpha values of the individual objects within the tile are
5378
         * recorded in that group.
5379
         *
5380
         * We can't do that for groups that use blending though, as each object
5381
         * in the pattern might use a different blend, and we don't (can't) record
5382
         * the blending mode. An isolated group doesn't even allow us to actually
5383
         * do the blending at all. So, for such patterns (any patterns that sets (or
5384
         * just has a resource that mentions) a non-normal blend mode), we use
5385
         * a pattern clist.
5386
         */
5387
66.4k
        if (ptile->cdev == NULL) {
5388
19.9k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5389
19.9k
            if (group_color_info == NULL)
5390
0
                return gs_error_VMerror;
5391
5392
19.9k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5393
19.9k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5394
19.9k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5395
19.9k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5396
19.9k
            if (code < 0)
5397
0
                return code;
5398
19.9k
        }
5399
5400
        /* Set the blending procs and the is_additive setting based
5401
           upon the number of channels */
5402
66.4k
        if (ptile->cdev == NULL) {
5403
19.9k
            if (n_chan_tile-1 < 4) {
5404
19.2k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5405
19.2k
                ptile->ttrans->is_additive = true;
5406
19.2k
            } else {
5407
690
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5408
690
                ptile->ttrans->is_additive = false;
5409
690
            }
5410
19.9k
        }
5411
        /* Now lets go through the rect list and fill with the pattern */
5412
        /* First get the buffer that we will be filling */
5413
66.4k
        if (ptile->cdev == NULL) {
5414
19.9k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5415
19.9k
            if (fill_trans_buffer == NULL) {
5416
0
                p14dev->pclist_device = NULL;
5417
0
                return_error(gs_error_VMerror);
5418
0
            }
5419
19.9k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5420
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5421
               want to use */
5422
19.9k
            if (ptile->has_overlap) {
5423
                /* This one does blending since there is tile overlap */
5424
1.35k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5425
18.6k
            } else {
5426
                /* This one does no blending since there is no tile overlap */
5427
18.6k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5428
18.6k
            }
5429
            /* fill the rectangles */
5430
19.9k
            phase.x = pdevc->phase.x;
5431
19.9k
            phase.y = pdevc->phase.y;
5432
19.9k
            if (cpath_intersection.rect_list->list.head != NULL){
5433
782
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5434
13.0k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5435
12.2k
                    if_debug5m('v', pgs->memory,
5436
12.2k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5437
12.2k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5438
12.2k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5439
12.2k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5440
12.2k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5441
12.2k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5442
12.2k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5443
12.2k
                    curr_clip_rect = curr_clip_rect->next;
5444
12.2k
                }
5445
19.1k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5446
                /* The case when there is just a single rect */
5447
18.9k
                if_debug5m('v', pgs->memory,
5448
18.9k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5449
18.9k
                           cpath_intersection.rect_list->list.single.xmin,
5450
18.9k
                           cpath_intersection.rect_list->list.single.ymin,
5451
18.9k
                           cpath_intersection.rect_list->list.single.xmax-
5452
18.9k
                              cpath_intersection.rect_list->list.single.xmin,
5453
18.9k
                           cpath_intersection.rect_list->list.single.ymax-
5454
18.9k
                              cpath_intersection.rect_list->list.single.ymin,
5455
18.9k
                           (int)ptile->id);
5456
18.9k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5457
18.9k
                                                  cpath_intersection.rect_list->list.single.ymin,
5458
18.9k
                                                  cpath_intersection.rect_list->list.single.xmax,
5459
18.9k
                                                  cpath_intersection.rect_list->list.single.ymax,
5460
18.9k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5461
18.9k
            }
5462
46.4k
        } else {
5463
            /* Clist pattern with transparency.  Create a clip device from our
5464
               cpath_intersection.  The above non-clist case could probably be
5465
               done this way too, which will reduce the amount of code here.
5466
               That is for another day though due to time constraints*/
5467
46.4k
            gx_device *dev;
5468
46.4k
            gx_device_clip clipdev;
5469
5470
46.4k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5471
46.4k
            dev = (gx_device *)&clipdev;
5472
46.4k
            phase.x = pdevc->phase.x;
5473
46.4k
            phase.y = pdevc->phase.y;
5474
46.4k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5475
46.4k
                                              ptile, fill_trans_buffer, phase,
5476
46.4k
                                              dev, pdevc, 1);
5477
46.4k
            gx_destroy_clip_device_on_stack(&clipdev);
5478
46.4k
        }
5479
        /* We're done drawing with the pattern, remove the reference to the
5480
         * pattern device
5481
         */
5482
66.4k
        p14dev->pclist_device = NULL;
5483
66.4k
        if (code < 0)
5484
0
            return code;
5485
5486
        /* free our buffer object */
5487
66.4k
        if (fill_trans_buffer != NULL) {
5488
19.9k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5489
19.9k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5490
19.9k
        }
5491
66.4k
        if (ptile->cdev == NULL) {
5492
            /* pop our transparency group which will force the blending.
5493
               This was all needed for Bug 693498 */
5494
19.9k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5495
19.9k
                                                p14dev->blend_procs,
5496
19.9k
                                                p14dev->color_info.num_components - has_tags,
5497
19.9k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5498
19.9k
                                                pdev);
5499
19.9k
        }
5500
66.4k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5501
66.4k
        p14dev->pclist_device = NULL;
5502
66.4k
    }
5503
66.4k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5504
66.4k
    return code;
5505
66.4k
}
5506
5507
/* Useful function that should probably go elsewhere.
5508
 * Call this function to find the topmost pdf14 device in the device chain,
5509
 * or NULL if there is not one.
5510
 */
5511
static pdf14_device *find_pdf14_device(gx_device *dev)
5512
0
{
5513
0
    pdf14_device *pdev;
5514
5515
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5516
0
        return NULL;
5517
0
    return pdev;
5518
0
}
5519
5520
/* Imager render for pattern transparency filling.  This is just here to catch
5521
   the final flush, at which time we will pop the group and reset a few items */
5522
static  int
5523
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5524
                    uint w, int h, gx_device * dev)
5525
0
{
5526
0
    int code;
5527
0
    pdf14_device * p14dev;
5528
0
    const gs_gstate * pgs = penum->pgs;
5529
0
    gx_device_color * pdcolor = (penum->icolor1);
5530
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5531
0
    bool has_tags = device_encodes_tags(dev);
5532
5533
    /* Pass along to the original renderer */
5534
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5535
0
    if (code < 0)
5536
0
        return code;
5537
    /* On our final time through here, go ahead and pop the transparency
5538
       group and reset the procs in the device color. And free the fill
5539
       trans buffer object */
5540
0
    if (h == 0 && ptile->trans_group_popped == false) {
5541
0
        p14dev = find_pdf14_device(dev);
5542
5543
0
        if (p14dev->pclist_device == NULL) {
5544
            /* Used if we are on clist writing phase.  Would only
5545
               occur if we somehow failed in high level clist
5546
               image writing */
5547
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5548
0
        } else {
5549
            /* Used if we are on clist reading phase.  If we had high level
5550
               image in clist */
5551
0
            cmm_dev_profile_t *dev_profile;
5552
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5553
0
            if (code < 0)
5554
0
                return code;
5555
5556
0
            if_debug2m('v', p14dev->ctx->memory,
5557
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5558
0
                       ptile->uid.id, ptile->id);
5559
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5560
0
                    p14dev->color_info.num_components - has_tags,
5561
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5562
0
                    (gx_device *) p14dev);
5563
0
        }
5564
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5565
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5566
0
                       "pdf14_pattern_trans_render");
5567
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5568
0
    }
5569
0
    return code;
5570
0
}
5571
5572
/* This function is used to get things in place for filling a mask image
5573
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5574
   and pdf14_clist_begin_type_image */
5575
static int
5576
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5577
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5578
                           const gs_int_rect * prect,
5579
                           const gx_drawing_color * pdcolor,
5580
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5581
                           gx_image_enum_common_t ** pinfo)
5582
0
{
5583
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5584
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5585
0
    gx_color_tile *ptile;
5586
0
    int code;
5587
0
    gs_int_rect group_rect;
5588
0
    gx_image_enum *penum;
5589
0
    gs_rect bbox_in, bbox_out;
5590
0
    gx_pattern_trans_t *fill_trans_buffer;
5591
5592
0
    ptile = pdcolor->colors.pattern.p_tile;
5593
    /* Set up things in the ptile so that we get the proper
5594
       blending etc */
5595
    /* Set the blending procs and the is_additive setting based
5596
       upon the number of channels */
5597
0
    if (ptile->ttrans->n_chan-1 < 4) {
5598
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5599
0
        ptile->ttrans->is_additive = true;
5600
0
    } else {
5601
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5602
0
        ptile->ttrans->is_additive = false;
5603
0
    }
5604
    /* Set the blending mode in the ptile based upon the current
5605
       setting in the gs_gstate */
5606
0
    ptile->blending_mode = pgs->blend_mode;
5607
    /* Based upon if the tiles overlap pick the type of rect
5608
       fill that we will want to use */
5609
0
    if (ptile->has_overlap) {
5610
        /* This one does blending since there is tile overlap */
5611
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5612
0
    } else {
5613
        /* This one does no blending since there is no tile overlap */
5614
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5615
0
    }
5616
    /* Set the procs so that we use the proper filling method. */
5617
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5618
    /* Let the imaging stuff get set up */
5619
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5620
0
                            prect, pdcolor,pcpath, mem, pinfo);
5621
0
    if (code < 0)
5622
0
        return code;
5623
    /* Now Push the group */
5624
    /* First apply the inverse of the image matrix to our
5625
       image size to get our bounding box. */
5626
0
    bbox_in.p.x = 0;
5627
0
    bbox_in.p.y = 0;
5628
0
    bbox_in.q.x = pim->Width;
5629
0
    bbox_in.q.y = pim->Height;
5630
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5631
0
                                &bbox_out);
5632
0
    if (code < 0)
5633
0
        return code;
5634
    /* That in turn will get hit by the matrix in the gs_gstate */
5635
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5636
0
                                            &bbox_out, (gs_gstate *)pgs);
5637
0
    if (code < 0)
5638
0
        return code;
5639
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5640
0
        if_debug2m('v', p14dev->ctx->memory,
5641
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5642
0
                   ptile->uid.id, ptile->id);
5643
5644
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5645
0
                                             65535, pgs->blend_mode, 0, 0,
5646
0
                                             ptile->ttrans->n_chan-1, false, false,
5647
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5648
5649
        /* Set up the output buffer information now that we have
5650
           pushed the group */
5651
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5652
0
        if (fill_trans_buffer == NULL)
5653
0
            return_error(gs_error_VMerror);
5654
5655
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5656
5657
        /* Store this in the appropriate place in pdcolor.  This
5658
           is released later in pdf14_pattern_trans_render when
5659
           we are all done with the mask fill */
5660
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5661
5662
        /* Change the renderer to handle this case so we can catch the
5663
           end.  We will then pop the group and reset the pdcolor proc.
5664
           Keep the base renderer also. */
5665
0
        penum = (gx_image_enum *) *pinfo;
5666
0
        ptile->ttrans->image_render = penum->render;
5667
0
        penum->render = &pdf14_pattern_trans_render;
5668
0
        ptile->trans_group_popped = false;
5669
0
    }
5670
0
    return code;
5671
0
}
5672
5673
static  int
5674
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5675
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5676
                           const gs_int_rect * prect,
5677
                           const gx_drawing_color * pdcolor,
5678
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5679
                           gx_image_enum_common_t ** pinfo)
5680
382k
{
5681
382k
    const gs_image_t *pim = (const gs_image_t *)pic;
5682
382k
    int code;
5683
5684
382k
    code = pdf14_initialize_ctx(dev, pgs);
5685
382k
    if (code < 0)
5686
0
        return code;
5687
5688
    /* If we are filling an image mask with a pattern that has a transparency
5689
       then we need to do some special handling */
5690
382k
    if (pim->ImageMask) {
5691
96
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5692
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5693
                /* If we are in a final run through here for this case then
5694
                   go ahead and push the transparency group.   Also, update
5695
                   the proc for the pattern color so that we used the
5696
                   appropriate fill operation.  Note that the group
5697
                   is popped and the proc will be reset when we flush the
5698
                   image data.  This is handled in a special pdf14 image
5699
                   renderer which will end up installed for this case.
5700
                   Detect setting of begin_image to gx_no_begin_image.
5701
                   (final recursive call) */
5702
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5703
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5704
0
                                                prect, pdcolor, pcpath, mem,
5705
0
                                                pinfo);
5706
0
                    return code;
5707
0
                }
5708
0
            }
5709
0
        }
5710
96
    }
5711
382k
    pdf14_set_marking_params(dev, pgs);
5712
382k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5713
382k
                                        pcpath, mem, pinfo);
5714
382k
}
5715
5716
static  void
5717
pdf14_set_params(gs_gstate * pgs,
5718
                 gx_device * dev,
5719
                 const gs_pdf14trans_params_t * pparams)
5720
8.26M
{
5721
8.26M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5722
8.26M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5723
2.32M
        pgs->blend_mode = pparams->blend_mode;
5724
8.26M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5725
1.14M
        pgs->text_knockout = pparams->text_knockout;
5726
8.26M
    if (pparams->changed & PDF14_SET_AIS)
5727
232k
        pgs->alphaisshape = pparams->ais;
5728
8.26M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5729
2.14M
        pgs->overprint = pparams->overprint;
5730
8.26M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5731
2.13M
        pgs->stroke_overprint = pparams->stroke_overprint;
5732
8.26M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5733
2.68M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5734
8.26M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5735
1.78M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5736
8.26M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5737
1.81M
        gs_swapcolors_quick(pgs);
5738
1.81M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5739
633k
            pgs->is_fill_color = false;
5740
1.18M
        else
5741
1.18M
            pgs->is_fill_color = true;
5742
1.81M
    }
5743
8.26M
    pdf14_set_marking_params(dev, pgs);
5744
8.26M
}
5745
5746
/*
5747
 * This open_device method for the PDF 1.4 compositor devices is only used
5748
 * when these devices are disabled.  This routine is about as close to
5749
 * a pure "forwarding" open_device operation as is possible. Its only
5750
 * significant function is to ensure that the is_open field of the
5751
 * PDF 1.4 compositor devices matches that of the target device.
5752
 *
5753
 * We assume this procedure is called only if the device is not already
5754
 * open, and that gs_opendevice will take care of the is_open flag.
5755
 */
5756
static  int
5757
pdf14_forward_open_device(gx_device * dev)
5758
0
{
5759
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5760
0
    gx_device * tdev = pdev->target;
5761
0
    int code;
5762
5763
    /* The PDF 1.4 compositing devices must have a target */
5764
0
    if (tdev == 0)
5765
0
        return_error(gs_error_unknownerror);
5766
0
    if ((code = gs_opendevice(tdev)) >= 0)
5767
0
        gx_device_copy_params(dev, tdev);
5768
0
    return code;
5769
0
}
5770
5771
/*
5772
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5773
 * for setting any device procs that should not be forwarded.
5774
 */
5775
static  void
5776
pdf14_forward_device_procs(gx_device * dev)
5777
1.14M
{
5778
1.14M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5779
1.14M
    pdf14_device *p14dev = (pdf14_device*)dev;
5780
5781
    /* If doing simulated overprint with spot colors
5782
       then makes sure to reset devn setting */
5783
1.14M
    if (p14dev->overprint_sim &&
5784
0
        p14dev->color_info.num_components > 4)
5785
0
        p14dev->icc_struct->supports_devn =
5786
0
            p14dev->target_support_devn;
5787
5788
    /*
5789
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5790
     * This will ensure that any new device procs are also set.  However that
5791
     * routine only changes procs which are NULL.  Thus we start by setting all
5792
     * procs to NULL.
5793
     */
5794
1.14M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5795
1.14M
    gx_device_forward_fill_in_procs(pdev);
5796
    /*
5797
     * gx_device_forward_fill_in_procs does not forward all procs.
5798
     * Set the remainding procs to also forward.
5799
     */
5800
1.14M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5801
1.14M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5802
1.14M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5803
1.14M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5804
1.14M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5805
1.14M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5806
1.14M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5807
1.14M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5808
1.14M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5809
1.14M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5810
    /* These are forwarding devices with minor tweaks. */
5811
1.14M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5812
1.14M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5813
1.14M
}
5814
5815
/*
5816
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5817
 * compositor device is never removed.  (We do not have a remove compositor
5818
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5819
 * routine implements that action.
5820
 */
5821
int
5822
pdf14_disable_device(gx_device * dev)
5823
1.13M
{
5824
1.13M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5825
5826
1.13M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5827
1.13M
    dev->color_info = pdev->target->color_info;
5828
1.13M
    pdf14_forward_device_procs(dev);
5829
1.13M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5830
1.13M
    return 0;
5831
1.13M
}
5832
5833
/*
5834
 * The default color space for PDF 1.4 blend modes is based upon the process
5835
 * color model of the output device.
5836
 */
5837
static  pdf14_default_colorspace_t
5838
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5839
                                 pdf14_blend_cs_t *blend_cs_state)
5840
3.53M
{
5841
    /* If a blend color space was specified, then go ahead and use that to
5842
       define the default color space for the blend modes.  Only Gray, RGB
5843
       or CMYK blend color spaces are allowed.  Note we do not allow this
5844
       setting if we are dealing with a separation device. */
5845
3.53M
    cmm_dev_profile_t *dev_profile;
5846
3.53M
    cmm_profile_t *blend_profile = NULL;
5847
3.53M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5848
3.53M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5849
3.53M
    bool valid_blend_cs = false;
5850
3.53M
    int has_tags = device_encodes_tags(pdev);
5851
5852
3.53M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5853
5854
    /* Are we using a blend color space or the output intent color space? Also
5855
       is there a conflict in the settings. i.e. has someone set a blend color
5856
       space and tried to use the output intent with simulate overprint setting.
5857
    */
5858
3.53M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5859
0
        dev_profile->oi_profile != NULL &&
5860
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5861
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5862
           possible conflicting command line settings and we will err on using the blend profile
5863
           if one was specified. */
5864
0
        if (dev_profile->blend_profile != NULL &&
5865
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5866
0
            blend_profile = dev_profile->blend_profile;
5867
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5868
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5869
0
        } else {
5870
            /* All good, use the output intent profile as we have one
5871
               and are doing simulate overprint with a different device
5872
               profile set. */
5873
0
            blend_profile = dev_profile->oi_profile;
5874
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5875
0
        }
5876
3.53M
    } else if (dev_profile->blend_profile != NULL &&
5877
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5878
        /* Blend profile is different than device profile */
5879
0
        blend_profile = dev_profile->blend_profile;
5880
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5881
0
    }
5882
5883
    /* Make sure any blend color space is valid along with other cond */
5884
3.53M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5885
0
        if (!blend_profile->isdevlink &&
5886
0
            !blend_profile->islab &&
5887
0
            (blend_profile->data_cs == gsGRAY ||
5888
0
             blend_profile->data_cs == gsRGB ||
5889
0
             blend_profile->data_cs == gsCMYK)) {
5890
            /* Also, do not allow the use of the blend space when we are pushing
5891
               a pattern pdf14 device.  Those should inherit from the parent */
5892
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5893
0
                  gx_device_is_pattern_accum(pdev))) {
5894
0
                valid_blend_cs = true;
5895
0
            }
5896
0
        }
5897
0
    }
5898
5899
    /* If num components is one, just go ahead and use gray.  This avoids
5900
       issues with additive/subtractive mono color devices  */
5901
3.53M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5902
3.28M
        pdev->color_info.num_components == 1) {
5903
        /*
5904
        * Note:  We do not allow the SeparationOrder device parameter for
5905
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5906
        * and 3 colorants for DeviceRGB.
5907
        */
5908
3.28M
        if (valid_blend_cs) {
5909
0
            *blend_cs_state = temp_cs_state;
5910
0
            switch (blend_profile->num_comps) {
5911
0
            case 1:
5912
0
                return PDF14_DeviceGray;
5913
0
            case 3:
5914
0
                return PDF14_DeviceRGB;
5915
0
            case 4:
5916
0
                return PDF14_DeviceCMYK;
5917
0
            }
5918
0
        }
5919
3.28M
        if (pdev->color_info.num_components - has_tags == 1)
5920
1.14M
            return PDF14_DeviceGray;
5921
2.14M
        else if (pdev->color_info.num_components - has_tags == 3)
5922
2.14M
            return PDF14_DeviceRGB;
5923
0
        else
5924
0
            return PDF14_DeviceRGBspot;
5925
3.28M
    } else {
5926
        /*
5927
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5928
         * the CMYK plus spot colors will not support the blend color space
5929
         */
5930
243k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5931
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5932
        return PDF14_DeviceCustom;
5933
#endif
5934
        /*
5935
         * Count the number of CMYK process components supported by the output
5936
         * device.
5937
         */
5938
1.21M
        for (i = 0; i < 4; i++) {
5939
975k
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5940
5941
975k
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5942
975k
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5943
975k
            if (output_comp_num >= 0) {
5944
975k
                num_cmyk++;
5945
975k
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5946
975k
                    num_cmyk_used++;
5947
975k
            }
5948
975k
        }
5949
        /*
5950
         * Check if the device supports only CMYK.  Otherewise we assume that
5951
         * the output device supports spot colors.  Note:  This algorithm can
5952
         * be fooled if the SeparationOrder device parameter is being used by
5953
         * the output device device to only select CMYK.
5954
         */
5955
243k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5956
232k
            && pdev->color_info.max_components == 4) {
5957
49.8k
            if (valid_blend_cs) {
5958
0
                *blend_cs_state = temp_cs_state;
5959
0
                switch (blend_profile->num_comps) {
5960
0
                case 1:
5961
0
                    return PDF14_DeviceGray;
5962
0
                case 3:
5963
0
                    return PDF14_DeviceRGB;
5964
0
                case 4:
5965
0
                    return PDF14_DeviceCMYK;
5966
0
                }
5967
0
            }
5968
49.8k
            return PDF14_DeviceCMYK;
5969
49.8k
        }
5970
        /*
5971
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5972
         * This device is only needed for those devices which do not support
5973
         * a basic CMYK process color model.
5974
         */
5975
194k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5976
194k
        if (num_cmyk != 4)
5977
0
            return PDF14_DeviceCustom;
5978
194k
#endif
5979
        /*
5980
         * Otherewise we use a CMYK plus spot colors for blending.
5981
         */
5982
194k
        if (valid_blend_cs)
5983
0
            *blend_cs_state = temp_cs_state;
5984
194k
        return PDF14_DeviceCMYKspot;
5985
194k
    }
5986
3.53M
}
5987
5988
/*
5989
 * the PDF 1.4 transparency spec says that color space for blending
5990
 * operations can be based upon either a color space specified in the
5991
 * group or a default value based upon the output device.  We are
5992
 * currently only using a color space based upon the device.
5993
 */
5994
static  int
5995
get_pdf14_device_proto(gx_device       *dev,
5996
                       pdf14_device    *pdevproto,
5997
                       gs_gstate       *pgs,
5998
                 const gs_pdf14trans_t *pdf14pct,
5999
                       bool             use_pdf14_accum)
6000
1.14M
{
6001
1.14M
    pdf14_blend_cs_t blend_cs_state;
6002
1.14M
    pdf14_default_colorspace_t dev_cs =
6003
1.14M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6004
1.14M
                                                 &blend_cs_state);
6005
1.14M
    bool deep = device_is_deep(dev);
6006
1.14M
    int num_spots = pdf14pct->params.num_spot_colors;
6007
1.14M
    bool has_tags = device_encodes_tags(dev);
6008
6009
    /* overprint overide */
6010
1.14M
    if (pdf14pct->params.overprint_sim_push &&
6011
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6012
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6013
0
            dev_cs = PDF14_DeviceCMYKspot;
6014
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6015
0
        } else
6016
0
            dev_cs = PDF14_DeviceCMYK;
6017
0
    }
6018
6019
1.14M
    switch (dev_cs) {
6020
415k
        case PDF14_DeviceGray:
6021
415k
            *pdevproto = gs_pdf14_Gray_device;
6022
415k
            pdevproto->color_info.max_components = 1 + has_tags;
6023
415k
            pdevproto->color_info.num_components =
6024
415k
                                    pdevproto->color_info.max_components + has_tags;
6025
415k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6026
415k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6027
415k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6028
415k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6029
415k
            pdevproto->sep_device = false;
6030
415k
            break;
6031
652k
        case PDF14_DeviceRGB:
6032
652k
            *pdevproto = gs_pdf14_RGB_device;
6033
652k
            pdevproto->color_info.max_components += has_tags;
6034
652k
            pdevproto->color_info.num_components += has_tags;
6035
652k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6036
652k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6037
652k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6038
652k
            pdevproto->sep_device = false;
6039
652k
            break;
6040
2.59k
        case PDF14_DeviceCMYK:
6041
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6042
2.59k
            pdevproto->color_info.max_components += has_tags;
6043
2.59k
            pdevproto->color_info.num_components += has_tags;
6044
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6045
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6046
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6047
2.59k
            pdevproto->sep_device = false;
6048
2.59k
            break;
6049
70.7k
        case PDF14_DeviceCMYKspot:
6050
70.7k
            *pdevproto = gs_pdf14_CMYKspot_device;
6051
            /* Need to figure out how we want to handle the device profile
6052
               for this case */
6053
            /*
6054
             * The number of components for the PDF14 device is the sum
6055
             * of the process components and the number of spot colors
6056
             * for the page.
6057
             */
6058
70.7k
            if (num_spots >= 0) {
6059
70.7k
                pdevproto->color_info.num_components =
6060
70.7k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6061
70.7k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6062
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6063
70.7k
                pdevproto->color_info.depth =
6064
70.7k
                                    pdevproto->color_info.num_components * (8<<deep);
6065
70.7k
                pdevproto->sep_device = true;
6066
70.7k
            }
6067
0
            else
6068
0
            {
6069
0
                pdevproto->color_info.max_components += has_tags;
6070
0
                pdevproto->color_info.num_components += has_tags;
6071
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6072
0
            }
6073
70.7k
            break;
6074
0
        case PDF14_DeviceRGBspot:
6075
0
            *pdevproto = gs_pdf14_RGBspot_device;
6076
            /* Need to figure out how we want to handle the device profile
6077
               for this case */
6078
            /*
6079
             * The number of components for the PDF14 device is the sum
6080
             * of the process components and the number of spot colors
6081
             * for the page.
6082
             */
6083
0
            if (num_spots >= 0) {
6084
0
                pdevproto->color_info.num_components =
6085
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6086
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6087
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6088
0
                pdevproto->color_info.depth =
6089
0
                    pdevproto->color_info.num_components * (8 << deep);
6090
0
                pdevproto->sep_device = true;
6091
0
            }
6092
0
            else
6093
0
            {
6094
0
                pdevproto->color_info.max_components += has_tags;
6095
0
                pdevproto->color_info.num_components += has_tags;
6096
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6097
0
            }
6098
0
            break;
6099
0
        case PDF14_DeviceCustom:
6100
            /*
6101
             * We are using the output device's process color model.  The
6102
             * color_info for the PDF 1.4 compositing device needs to match
6103
             * the output device.
6104
             */
6105
0
            *pdevproto = gs_pdf14_custom_device;
6106
0
            pdevproto->color_info = dev->color_info;
6107
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6108
0
            pdevproto->color_info.depth =
6109
0
                       pdevproto->color_info.num_components * (8<<deep);
6110
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6111
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6112
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6113
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6114
0
            break;
6115
0
        default:      /* Should not occur */
6116
0
            return_error(gs_error_rangecheck);
6117
1.14M
    }
6118
1.14M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6119
1.14M
    pdevproto->blend_cs_state = blend_cs_state;
6120
1.14M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6121
1.14M
    return 0;
6122
1.14M
}
6123
6124
/* When playing back the clist, we need to know if the buffer device is compatible */
6125
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6126
/* depth are critical since these must match when reading back colors.             */
6127
bool
6128
pdf14_ok_to_optimize(gx_device *dev)
6129
2.38M
{
6130
2.38M
    pdf14_blend_cs_t blend_cs_state;
6131
2.38M
    pdf14_default_colorspace_t pdf14_cs =
6132
2.38M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6133
2.38M
    gsicc_colorbuffer_t dev_icc_cs;
6134
2.38M
    bool ok = false;
6135
2.38M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6136
2.38M
    cmm_dev_profile_t *dev_profile;
6137
2.38M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6138
2.38M
    bool deep = device_is_deep(dev);
6139
6140
2.38M
    if (code < 0)
6141
0
        return false;
6142
6143
2.38M
    check_device_compatible_encoding(dev);
6144
6145
2.38M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6146
971k
        return false;
6147
6148
1.40M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6149
    /* If the outputprofile is not "standard" then colors converted to device color */
6150
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6151
1.40M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6152
0
        return false;                           /* can't handle funky output profiles */
6153
6154
1.40M
    switch (pdf14_cs) {
6155
385k
        case PDF14_DeviceGray:
6156
385k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6157
385k
            break;
6158
901k
        case PDF14_DeviceRGB:
6159
901k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6160
901k
            break;
6161
0
        case PDF14_DeviceCMYK:
6162
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6163
0
            break;
6164
122k
        case PDF14_DeviceCMYKspot:
6165
122k
            ok = false;     /* punt for this case */
6166
122k
            break;
6167
0
        case PDF14_DeviceRGBspot:
6168
0
            ok = false;     /* punt for this case */
6169
0
            break;
6170
0
        case PDF14_DeviceCustom:
6171
            /*
6172
             * We are using the output device's process color model.  The
6173
             * color_info for the PDF 1.4 compositing device needs to match
6174
             * the output device, but it may not have been contone.
6175
             */
6176
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6177
0
            break;
6178
0
        default:      /* Should not occur */
6179
0
            ok = false;
6180
1.40M
    }
6181
1.40M
    return ok;
6182
1.40M
}
6183
6184
/*
6185
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6186
 * compositor device is never removed.  (We do not have a remove compositor
6187
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6188
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6189
 * again.
6190
 */
6191
static  int
6192
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6193
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6194
0
{
6195
0
    pdf14_device * pdev = (pdf14_device *)dev;
6196
0
    gx_device * target = pdev->target;
6197
0
    pdf14_device dev_proto;
6198
0
    bool has_tags = device_encodes_tags(dev);
6199
0
    int code;
6200
0
    bool deep = device_is_deep(dev);
6201
6202
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6203
6204
    /*
6205
     * We will not use the entire prototype device but we will set the
6206
     * color related info and the device procs to match the prototype.
6207
     */
6208
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6209
0
                                  pdf14pct, false);
6210
0
    if (code < 0)
6211
0
        return code;
6212
0
    pdev->color_info = dev_proto.color_info;
6213
0
    pdev->pad = target->pad;
6214
0
    pdev->log2_align_mod = target->log2_align_mod;
6215
6216
    /* The prototype has the color setup without tags. If we are
6217
     * using tags, then we need to extend num_components and depth.
6218
     */
6219
0
    if (has_tags) {
6220
0
        pdev->color_info.num_components++;
6221
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6222
0
    }
6223
6224
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6225
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6226
0
    else
6227
0
        pdev->num_planar_planes = target->num_planar_planes;
6228
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6229
6230
0
    if (dev_proto.initialize_device_procs != NULL)
6231
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6232
0
    pdev->procs = dev_proto.procs;
6233
0
    if (deep) {
6234
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6235
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6236
0
    }
6237
0
    if (has_tags) {
6238
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6239
0
    }
6240
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6241
0
    gx_device_fill_in_procs((gx_device *)pdev);
6242
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6243
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6244
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6245
0
    check_device_separable(dev);
6246
0
    return dev_proc(pdev, open_device)(dev);
6247
0
}
6248
6249
/*
6250
 * Implement the various operations that can be specified via the PDF 1.4
6251
 * create compositor request.
6252
 */
6253
static  int
6254
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6255
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6256
21.6M
{
6257
21.6M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6258
21.6M
    gs_pdf14trans_params_t params = pdf14pct->params;
6259
21.6M
    int code = 0;
6260
6261
21.6M
    params.idle = pdf14pct->idle;
6262
21.6M
    switch (params.pdf14_op) {
6263
0
        default:      /* Should not occur. */
6264
0
            break;
6265
11.8k
        case PDF14_PUSH_DEVICE:
6266
11.8k
            if (!(params.is_pattern)) {
6267
0
                p14dev->blend_mode = 0;
6268
0
                p14dev->opacity = p14dev->shape = 0.0;
6269
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6270
0
            }
6271
11.8k
            break;
6272
0
        case PDF14_ABORT_DEVICE:
6273
            /* Something has gone very wrong.  Let transparency device clean up
6274
               what ever it has allocated and then we are shutting it down */
6275
0
            code = gx_abort_trans_device(pgs, pdev);
6276
0
            if (p14dev->free_devicen) {
6277
0
                devn_free_params(pdev);
6278
0
            }
6279
0
            pdf14_disable_device(pdev);
6280
0
            pdf14_close(pdev);
6281
0
            break;
6282
1.14M
        case PDF14_POP_DEVICE:
6283
1.14M
            if (!(params.is_pattern)) {
6284
1.13M
                if_debug0m('v', pdev->memory,
6285
1.13M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6286
1.13M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6287
1.13M
                gx_set_cmap_procs(pgs, p14dev->target);
6288
                /* Send image out raster data to output device */
6289
1.13M
                {
6290
                    /* Make a copy so we can change the ROP */
6291
1.13M
                    gs_gstate new_pgs = *pgs;
6292
6293
                    /* We don't use the gs_gstate log_op since this is for the */
6294
                    /* clist playback. Putting the image (band in the case of the */
6295
                    /* clist) only needs to use the default ROP to copy the data  */
6296
1.13M
                    new_pgs.log_op = rop3_default;
6297
1.13M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6298
1.13M
                }
6299
                /* Before we disable the device release any deviceN structures.
6300
                    free_devicen is set if the pdf14 device had inherited its
6301
                    deviceN parameters from the target clist device.  In this
6302
                    case they should not be freed */
6303
1.13M
                if (p14dev->free_devicen) {
6304
1.12M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6305
1.12M
                    if (devn_params) {
6306
1.12M
                        gxdso_spot_info si;
6307
1.12M
                        si.params = devn_params;
6308
1.12M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6309
1.12M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6310
1.12M
                    }
6311
1.12M
                    devn_free_params(pdev);
6312
1.12M
                }
6313
1.13M
                pdf14_disable_device(pdev);
6314
1.13M
                pdf14_close(pdev);
6315
1.13M
            }
6316
1.14M
            break;
6317
436k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6318
2.28M
        case PDF14_BEGIN_TRANS_GROUP:
6319
2.28M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6320
337k
                p14dev->depth_within_smask++;
6321
2.28M
            p14dev->smask_constructed = 0;
6322
2.28M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6323
2.28M
            break;
6324
1.78M
        case PDF14_END_TRANS_GROUP:
6325
1.78M
            code = gx_end_transparency_group(pgs, pdev);
6326
1.78M
            if (p14dev->depth_within_smask)
6327
337k
                p14dev->depth_within_smask--;
6328
1.78M
            break;
6329
166
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6330
166
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6331
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6332
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6333
0
            } else
6334
166
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6335
166
            break;
6336
503k
        case PDF14_END_TRANS_TEXT_GROUP:
6337
503k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6338
503k
                code = gx_end_transparency_group(pgs, pdev);
6339
503k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6340
503k
            break;
6341
4.23M
        case PDF14_BEGIN_TRANS_MASK:
6342
4.23M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6343
4.23M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6344
433k
                p14dev->in_smask_construction++;
6345
4.23M
            break;
6346
433k
        case PDF14_END_TRANS_MASK:
6347
433k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6348
433k
            if (code >= 0) {
6349
433k
                p14dev->in_smask_construction--;
6350
433k
                if (p14dev->in_smask_construction < 0)
6351
0
                    p14dev->in_smask_construction = 0;
6352
433k
                if (p14dev->in_smask_construction == 0)
6353
433k
                    p14dev->smask_constructed = 1;
6354
433k
            }
6355
433k
            break;
6356
8.26M
        case PDF14_SET_BLEND_PARAMS:
6357
8.26M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6358
8.26M
            break;
6359
0
        case PDF14_PUSH_TRANS_STATE:
6360
0
            code = gx_push_transparency_state(pgs, pdev);
6361
0
            break;
6362
3.03M
        case PDF14_POP_TRANS_STATE:
6363
3.03M
            code = gx_pop_transparency_state(pgs, pdev);
6364
3.03M
            break;
6365
4.26k
        case PDF14_PUSH_SMASK_COLOR:
6366
4.26k
            code = pdf14_increment_smask_color(pgs, pdev);
6367
4.26k
            break;
6368
4.26k
        case PDF14_POP_SMASK_COLOR:
6369
4.26k
            code = pdf14_decrement_smask_color(pgs, pdev);
6370
4.26k
            break;
6371
21.6M
    }
6372
21.6M
    return code;
6373
21.6M
}
6374
6375
/*
6376
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6377
 * compositor' method.  However the compositor is disabled when we are not
6378
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6379
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6380
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6381
 * to the target.
6382
 */
6383
static  int
6384
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6385
        const gs_composite_t * pct, gs_gstate * pgs,
6386
        gs_memory_t * mem, gx_device *cdev)
6387
1.38k
{
6388
1.38k
    pdf14_device *pdev = (pdf14_device *)dev;
6389
1.38k
    gx_device * tdev = pdev->target;
6390
1.38k
    int code;
6391
6392
1.38k
    *pcdev = dev;
6393
1.38k
    if (gs_is_pdf14trans_compositor(pct)) {
6394
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6395
6396
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6397
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6398
0
        return 0;
6399
0
    }
6400
1.38k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6401
1.38k
    if (code == 1) {
6402
        /* We have created a new compositor that wrapped tdev. This means
6403
         * that our target should be updated to point to that. */
6404
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6405
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6406
0
    }
6407
1.38k
    return code;
6408
1.38k
}
6409
6410
/*
6411
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6412
 * and return. Since the gs_pdf14_device only supports the high-level routines
6413
 * of the interface, don't bother trying to handle any other compositor.
6414
 */
6415
static int
6416
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6417
        const gs_composite_t * pct, gs_gstate * pgs,
6418
        gs_memory_t * mem, gx_device *cdev)
6419
100M
{
6420
100M
    pdf14_device *p14dev = (pdf14_device *)dev;
6421
100M
    if (gs_is_pdf14trans_compositor(pct)) {
6422
21.6M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6423
21.6M
        *pcdev = dev;
6424
        /* cdev, may be the clist reader device which may contain information that
6425
           we will need related to the ICC color spaces that define transparency
6426
           groups.  We want this propogated through all the pdf14 functions.  Store
6427
           a pointer to it in the pdf14 device */
6428
21.6M
        p14dev->pclist_device = cdev;
6429
21.6M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6430
78.7M
    } else if (gs_is_overprint_compositor(pct)) {
6431
                /* If we had an overprint compositer action, then the
6432
                   color components that were drawn should be updated.
6433
                   The overprint compositor logic and its interactions
6434
                   with the clist is a little odd as it passes uninitialized
6435
                   values around a fair amount.  Hence the forced assignement here.
6436
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6437
78.7M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6438
78.7M
                gx_color_index drawn_comps;
6439
78.7M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6440
6441
78.7M
                p14dev->op_state = op_pct->params.op_state;
6442
78.7M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6443
39.3M
                    if (op_pct->params.retain_any_comps) {
6444
30.3k
                        drawn_comps = op_pct->params.drawn_comps;
6445
39.3M
                    } else {
6446
                        /* Draw everything. If this parameter was not set, clist does
6447
                           not fill it in.  */
6448
39.3M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6449
39.3M
                    }
6450
6451
39.3M
                    if (op_pct->params.is_fill_color) {
6452
22.0M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6453
22.0M
                        p14dev->drawn_comps_fill = drawn_comps;
6454
22.0M
                    } else {
6455
17.3M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6456
17.3M
                        p14dev->drawn_comps_stroke = drawn_comps;
6457
17.3M
                    }
6458
                    /* We restore the NONE states as that is used just to force
6459
                       overprint settings in the overprint compositor communication */
6460
39.3M
                    p14dev->op_state = curr_state;
6461
39.3M
                }
6462
78.7M
                *pcdev = dev;
6463
78.7M
                return 0;
6464
78.7M
    } else
6465
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6466
100M
}
6467
6468
static int
6469
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6470
                      gs_blend_mode_t blend_mode, float opacity,
6471
                      float shape, bool is_clist)
6472
2.96k
{
6473
2.96k
    int code;
6474
2.96k
    gs_transparency_group_params_t params = { 0 };
6475
2.96k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6476
2.96k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6477
2.96k
    float alpha = pgs->fillconstantalpha;
6478
6479
    /* Push a non-isolated knock-out group making sure the opacity and blend
6480
       mode are correct */
6481
2.96k
    params.Isolated = false;
6482
2.96k
    params.Knockout = true;
6483
2.96k
    params.page_group = false;
6484
2.96k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6485
2.96k
    params.group_opacity = 1.0;
6486
2.96k
    params.group_shape = 1.0;
6487
6488
2.96k
    gs_setfillconstantalpha(pgs, 1.0);
6489
2.96k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6490
6491
2.96k
    if (is_clist) {
6492
2.96k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6493
2.96k
        if (code < 0)
6494
0
            return code;
6495
2.96k
    }
6496
6497
2.96k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6498
2.96k
    gs_setfillconstantalpha(pgs, alpha);
6499
2.96k
    gs_setblendmode(pgs, blend_mode);
6500
2.96k
    if (code < 0)
6501
0
        return code;
6502
6503
2.96k
    if (is_clist) {
6504
2.96k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6505
2.96k
    }
6506
2.96k
    return code;
6507
2.96k
}
6508
6509
static  int
6510
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6511
                 const gs_text_params_t * text, gs_font * font,
6512
                 const gx_clip_path * pcpath,
6513
                 gs_text_enum_t ** ppenum)
6514
392
{
6515
392
    int code;
6516
392
    gs_text_enum_t *penum;
6517
392
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6518
392
    float opacity = pgs->fillconstantalpha;
6519
392
    float shape = 1.0;
6520
392
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6521
392
    pdf14_device *pdev = (pdf14_device*)dev;
6522
392
    bool draw = !(text->operation & TEXT_DO_NONE);
6523
392
    uint text_mode = gs_currenttextrenderingmode(pgs);
6524
392
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6525
392
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6526
6527
392
    code = pdf14_initialize_ctx(dev, pgs);
6528
392
    if (code < 0)
6529
0
        return code;
6530
6531
392
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6532
392
    pdf14_set_marking_params(dev, pgs);
6533
392
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6534
392
    if (code < 0)
6535
0
        return code;
6536
6537
    /* We may need to push a non-isolated transparency group if the following
6538
       is true.
6539
       1) We are not currently in one that we pushed for text and we are in
6540
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6541
       2) The blend mode is not Normal or the opacity is not 1.0
6542
       3) Text knockout is set to true
6543
       4) We are actually doing a text drawing
6544
6545
       Special note:  If text-knockout is set to false while we are within a
6546
       BT ET pair, we should pop the group.  I need to create a test file for
6547
       this case.  */
6548
6549
       /* Catch case where we already pushed a group and are trying to push another one.
6550
       In that case, we will pop the current one first, as we don't want to be left
6551
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6552
       will not be caught until we do the put_image and notice that the stack is not
6553
       empty. */
6554
392
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6555
0
        code = gs_end_transparency_group(pgs);
6556
0
        if (code < 0)
6557
0
            return code;
6558
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6559
0
    }
6560
6561
392
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6562
391
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6563
391
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6564
1
         text_mode != 3 && /* don't bother with invisible text */
6565
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6566
1
        if (draw) {
6567
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6568
1
                false);
6569
1
        }
6570
392
    *ppenum = (gs_text_enum_t *)penum;
6571
392
    return code;
6572
392
}
6573
6574
static  int
6575
pdf14_initialize_device(gx_device *new_dev)
6576
1.14M
{
6577
1.14M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6578
6579
1.14M
    pdev->ctx = NULL;
6580
1.14M
    pdev->color_model_stack = NULL;
6581
1.14M
    pdev->smaskcolor = NULL;
6582
6583
1.14M
    return 0;
6584
1.14M
}
6585
6586
/*
6587
 * Implement copy_mono by filling lots of small rectangles.
6588
 */
6589
static int
6590
pdf14_copy_mono(gx_device * dev,
6591
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6592
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6593
12.9M
{
6594
12.9M
    const byte *sptr;
6595
12.9M
    const byte *line;
6596
12.9M
    int sbit, first_bit;
6597
12.9M
    int code, sbyte, bit, count;
6598
12.9M
    int run_length, startx, current_bit, bit_value;
6599
12.9M
    gx_color_index current_color;
6600
6601
12.9M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6602
12.9M
    line = base + (sourcex >> 3);
6603
12.9M
    sbit = sourcex & 7;
6604
12.9M
    first_bit = 7 - sbit;
6605
6606
    /* Loop through the height of the specified area. */
6607
98.7M
    while (h-- > 0) {
6608
        /* Set up for the start of each line of the area. */
6609
85.8M
        sptr = line;
6610
85.8M
        sbyte = *sptr++;
6611
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6612
         * the loop below so adding 1 means that we don't fall into the bit == 0
6613
         * case and incorrectly read a new byte from the source. This weirdness is because
6614
         * the original code wouold read off the end of the buffer if the number of bits in
6615
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6616
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6617
         * of the loop to the beginning meant we would not read past the end of the buffer
6618
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6619
         * reading another byte.
6620
         */
6621
85.8M
        bit = first_bit + 1;
6622
85.8M
        count = w;
6623
85.8M
        run_length = 0;
6624
85.8M
        startx = x;
6625
85.8M
        current_bit = 0;
6626
85.8M
        current_color = zero;
6627
6628
        /* Loop across each pixel of a line. */
6629
1.24G
        do {
6630
            /* Move to the next input bit. */
6631
1.24G
            if (bit == 0) {
6632
108M
                bit = 7;
6633
108M
                sbyte = *sptr++;
6634
108M
            }
6635
1.13G
            else
6636
1.13G
                bit--;
6637
1.24G
            bit_value = (sbyte >> bit) & 1;
6638
1.24G
            if (bit_value == current_bit) {
6639
                /* The value did not change, simply increment our run length */
6640
1.02G
                run_length++;
6641
1.02G
            } else {
6642
                /* The value changed, fill the current rectangle. */
6643
214M
                if (run_length != 0) {
6644
204M
                    if (current_color != gx_no_color_index) {
6645
88.4M
                        code = (*dev_proc(dev, fill_rectangle))
6646
88.4M
                                (dev, startx, y, run_length, 1, current_color);
6647
88.4M
                        if (code < 0)
6648
0
                            return code;
6649
88.4M
                    }
6650
204M
                    startx += run_length;
6651
204M
                }
6652
214M
                run_length = 1;
6653
214M
                current_color = bit_value ? one : zero;
6654
214M
                current_bit = bit_value;
6655
214M
            }
6656
1.24G
        } while (--count > 0);
6657
        /* Fill the last rectangle in the line. */
6658
85.8M
        if (run_length != 0 && current_color != gx_no_color_index) {
6659
38.2M
            code = (*dev_proc(dev, fill_rectangle))
6660
38.2M
                        (dev, startx, y, run_length, 1, current_color);
6661
38.2M
            if (code < 0)
6662
0
                return code;
6663
38.2M
        }
6664
        /* Move to the next line */
6665
85.8M
        line += sraster;
6666
85.8M
        y++;
6667
85.8M
    }
6668
12.9M
    return 0;
6669
12.9M
}
6670
6671
/* Added to avoid having to go back and forth between fixed and int
6672
   in some of the internal methods used for dealing with tiling
6673
   and devn colors */
6674
static int
6675
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6676
    const gx_drawing_color *pdcolor)
6677
2.44k
{
6678
2.44k
    pdf14_device *pdev = (pdf14_device *)dev;
6679
2.44k
    pdf14_buf *buf;
6680
2.44k
    int code;
6681
6682
2.44k
    fit_fill_xywh(dev, x, y, w, h);
6683
2.44k
    if (w <= 0 || h <= 0)
6684
0
        return 0;
6685
6686
2.44k
    code = pdf14_initialize_ctx(dev, NULL);
6687
2.44k
    if (code < 0)
6688
0
        return code;
6689
2.44k
    buf = pdev->ctx->stack;
6690
6691
2.44k
    if (buf->knockout)
6692
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6693
0
            true);
6694
2.44k
    else
6695
2.44k
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6696
2.44k
}
6697
6698
/* Step through and do rect fills with the devn colors as
6699
   we hit each transition in the bitmap. It is possible
6700
   that one of the colors is not devn, but is pure and
6701
   is set to gx_no_color_index. This type of mix happens
6702
   for example from tile_clip_fill_rectangle_hl_color */
6703
static int
6704
pdf14_copy_mono_devn(gx_device *dev,
6705
    const byte *base, int sourcex, int sraster,
6706
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6707
    const gx_drawing_color *pdcolor1)
6708
668
{
6709
668
    const byte *sptr;
6710
668
    const byte *line;
6711
668
    int sbit, first_bit;
6712
668
    int code, sbyte, bit, count;
6713
668
    int run_length, startx, current_bit, bit_value;
6714
668
    const gx_drawing_color *current_color;
6715
6716
668
    if ((x | y) < 0) {
6717
0
        if (x < 0) {
6718
0
            w += x;
6719
0
            sourcex -= x;
6720
0
            x = 0;
6721
0
        }
6722
0
        if (y < 0) {
6723
0
            h += y;
6724
0
            base -= (int)(y * sraster);
6725
0
            y = 0;
6726
0
        }
6727
0
    }
6728
668
    if (w > (dev)->width - x)
6729
0
        w = (dev)->width - x;
6730
668
    if (h > (dev)->height - y)
6731
0
        h = (dev)->height - y;
6732
668
    if (w <= 0 || h <= 0)
6733
0
        return 0;
6734
6735
668
    line = base + (sourcex >> 3);
6736
668
    sbit = sourcex & 7;
6737
668
    first_bit = 7 - sbit;
6738
6739
    /* Loop through the height of the specified area. */
6740
2.10k
    while (h-- > 0) {
6741
        /* Set up for the start of each line of the area. */
6742
1.43k
        sptr = line;
6743
1.43k
        sbyte = *sptr++;
6744
1.43k
        bit = first_bit;
6745
1.43k
        count = w;
6746
1.43k
        run_length = 0;
6747
1.43k
        startx = x;
6748
1.43k
        current_bit = 0;
6749
1.43k
        current_color = pdcolor0;
6750
6751
        /* Loop across each pixel of a line. */
6752
15.6k
        do {
6753
15.6k
            bit_value = (sbyte >> bit) & 1;
6754
15.6k
            if (bit_value == current_bit) {
6755
                /* The value did not change, simply increment our run length */
6756
11.3k
                run_length++;
6757
11.3k
            } else {
6758
                /* The value changed, fill the current rectangle. */
6759
4.26k
                if (run_length != 0) {
6760
3.85k
                    if (current_color->type != gx_dc_type_pure &&
6761
1.82k
                        current_color->colors.pure != gx_no_color_index) {
6762
1.82k
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6763
1.82k
                            run_length, 1, current_color);
6764
1.82k
                        if (code < 0)
6765
0
                            return code;
6766
1.82k
                    }
6767
3.85k
                    startx += run_length;
6768
3.85k
                }
6769
4.26k
                run_length = 1;
6770
4.26k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6771
4.26k
                current_bit = bit_value;
6772
4.26k
            }
6773
6774
            /* Move to the next input bit. */
6775
15.6k
            if (bit == 0) {
6776
1.40k
                bit = 7;
6777
1.40k
                sbyte = *sptr++;
6778
1.40k
            } else
6779
14.2k
                bit--;
6780
15.6k
        } while (--count > 0);
6781
6782
        /* Fill the last rectangle in the line. */
6783
1.43k
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6784
619
            current_color->colors.pure != gx_no_color_index) {
6785
619
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6786
619
                run_length, 1, current_color);
6787
619
            if (code < 0)
6788
0
                return code;
6789
619
        }
6790
        /* Move to the next line */
6791
1.43k
        line += sraster;
6792
1.43k
        y++;
6793
1.43k
    }
6794
668
    return 0;
6795
668
}
6796
6797
/* Step through the tiles doing essentially copy_mono but with devn colors */
6798
static int
6799
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6800
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6801
    const gx_drawing_color *pdcolor1, int px, int py)
6802
668
{   /* Fill the rectangle in chunks. */
6803
668
    int width = tiles->size.x;
6804
668
    int height = tiles->size.y;
6805
668
    int raster = tiles->raster;
6806
668
    int rwidth = tiles->rep_width;
6807
668
    int rheight = tiles->rep_height;
6808
668
    int shift = tiles->shift;
6809
6810
668
    if (rwidth == 0 || rheight == 0)
6811
0
        return_error(gs_error_unregistered);
6812
668
    fit_fill_xy(dev, x, y, w, h);
6813
6814
668
     {
6815
668
        int xoff = (shift == 0 ? px :
6816
668
                px + (y + py) / rheight * tiles->rep_shift);
6817
668
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6818
0
            (x + xoff) & (rwidth - 1) :
6819
668
            (x + xoff) % rwidth);
6820
668
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6821
0
            (y + py) & (rheight - 1) :
6822
668
            (y + py) % rheight);
6823
668
        int icw = width - irx;
6824
668
        int ch = height - ry;
6825
668
        byte *row = tiles->data + ry * raster;
6826
668
        int code = 0;
6827
6828
668
        if (ch >= h) {      /* Shallow operation */
6829
668
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6830
668
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6831
668
                    w, h, pdcolor0, pdcolor1);
6832
668
                if (code < 0)
6833
0
                    return_error(code);
6834
668
            } else {
6835
0
                int ex = x + w;
6836
0
                int fex = ex - width;
6837
0
                int cx = x + icw;
6838
6839
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6840
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6841
0
                if (code < 0)
6842
0
                    return_error(code);
6843
6844
0
                while (cx <= fex) {
6845
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6846
0
                        width, h, pdcolor0, pdcolor1);
6847
0
                    if (code < 0)
6848
0
                        return_error(code);
6849
0
                    cx += width;
6850
0
                }
6851
0
                if (cx < ex) {
6852
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6853
0
                        ex - cx, h, pdcolor0, pdcolor1);
6854
0
                    if (code < 0)
6855
0
                        return_error(code);
6856
0
                }
6857
0
            }
6858
668
        } else if (icw >= w && shift == 0) {
6859
            /* Narrow operation, no shift */
6860
0
            int ey = y + h;
6861
0
            int fey = ey - height;
6862
0
            int cy = y + ch;
6863
6864
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6865
0
                x, y, w, ch, pdcolor0, pdcolor1);
6866
0
            if (code < 0)
6867
0
                return_error(code);
6868
0
            row = tiles->data;
6869
0
            do {
6870
0
                ch = (cy > fey ? ey - cy : height);
6871
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6872
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6873
0
                if (code < 0)
6874
0
                    return_error(code);
6875
0
            } while ((cy += ch) < ey);
6876
0
        } else {
6877
            /* Full operation.  If shift != 0, some scan lines */
6878
            /* may be narrow.  We could test shift == 0 in advance */
6879
            /* and use a slightly faster loop, but right now */
6880
            /* we don't bother. */
6881
0
            int ex = x + w, ey = y + h;
6882
0
            int fex = ex - width, fey = ey - height;
6883
0
            int cx, cy;
6884
6885
0
            for (cy = y;;) {
6886
0
                if (icw >= w) {
6887
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6888
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6889
0
                    if (code < 0)
6890
0
                        return_error(code);
6891
0
                } else {
6892
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6893
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6894
0
                    if (code < 0)
6895
0
                        return_error(code);
6896
0
                    cx = x + icw;
6897
0
                    while (cx <= fex) {
6898
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6899
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6900
0
                        if (code < 0)
6901
0
                            return_error(code);
6902
0
                        cx += width;
6903
0
                    }
6904
0
                    if (cx < ex) {
6905
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6906
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6907
0
                        if (code < 0)
6908
0
                            return_error(code);
6909
0
                    }
6910
0
                }
6911
0
                if ((cy += ch) >= ey)
6912
0
                    break;
6913
0
                ch = (cy > fey ? ey - cy : height);
6914
0
                if ((irx += shift) >= rwidth)
6915
0
                    irx -= rwidth;
6916
0
                icw = width - irx;
6917
0
                row = tiles->data;
6918
0
            }
6919
0
        }
6920
668
    }
6921
668
    return 0;
6922
668
}
6923
6924
/* pdf14 device supports devn */
6925
static int
6926
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6927
    int x, int y, int w, int h,
6928
    const gx_drawing_color *pdcolor0,
6929
    const gx_drawing_color *pdcolor1, int px, int py)
6930
668
{
6931
668
    pdf14_device *pdev = (pdf14_device *)dev;
6932
668
    pdf14_buf *buf;
6933
668
    int num_comp;
6934
668
    int k;
6935
668
    bool same = false;
6936
668
    int code;
6937
6938
668
    code = pdf14_initialize_ctx(dev, NULL);
6939
668
    if (code < 0)
6940
0
        return code;
6941
668
    buf = pdev->ctx->stack;
6942
668
    num_comp = buf->n_chan - 1;
6943
6944
    /* if color0 is identical to color1, do rect fill */
6945
668
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6946
0
        same = true;
6947
0
        for (k = 0; k < num_comp; k++) {
6948
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6949
0
                same = false;
6950
0
                break;
6951
0
            }
6952
0
        }
6953
0
    }
6954
6955
668
    if (same) {
6956
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6957
668
    } else {
6958
        /* Go through the tile stepping using code stolen from
6959
           gx_default_strip_tile_rectangle and call the rect fills
6960
           using code stolen from pdf14_copy_mono but using devn
6961
           colors */
6962
668
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6963
668
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6964
668
    }
6965
668
    return code;
6966
668
}
6967
6968
/* Used in a few odd cases where the target device is planar and we have
6969
   a planar tile (pattern) and we are copying it into place here */
6970
static int
6971
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6972
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6973
4.05k
{
6974
4.05k
    pdf14_device *pdev = (pdf14_device *)dev;
6975
4.05k
    pdf14_ctx *ctx;
6976
4.05k
    pdf14_buf *buf;
6977
4.05k
    int xo = x;
6978
4.05k
    int yo = y;
6979
4.05k
    pdf14_buf fake_tos;
6980
4.05k
    int deep;
6981
6982
4.05k
    int code = pdf14_initialize_ctx(dev, NULL);
6983
4.05k
    if (code < 0)
6984
0
        return code;
6985
6986
4.05k
    fit_fill_xywh(dev, x, y, w, h);
6987
4.05k
    if (w <= 0 || h <= 0)
6988
0
        return 0;
6989
6990
4.05k
    ctx = pdev->ctx;
6991
4.05k
    buf = ctx->stack;
6992
4.05k
    deep = ctx->deep;
6993
6994
4.05k
    fake_tos.deep = deep;
6995
4.05k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
6996
4.05k
    fake_tos.backdrop = NULL;
6997
4.05k
    fake_tos.blend_mode = pdev->blend_mode;
6998
4.05k
    fake_tos.color_space = buf->color_space;
6999
4.05k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7000
4.05k
    fake_tos.dirty.p.x = x;
7001
4.05k
    fake_tos.dirty.p.y = y;
7002
4.05k
    fake_tos.dirty.q.x = x + w;
7003
4.05k
    fake_tos.dirty.q.y = y + h;
7004
4.05k
    fake_tos.has_alpha_g = 0;
7005
4.05k
    fake_tos.has_shape = 0;
7006
4.05k
    fake_tos.has_tags = 0;
7007
4.05k
    fake_tos.idle = false;
7008
4.05k
    fake_tos.isolated = false;
7009
4.05k
    fake_tos.knockout = false;
7010
4.05k
    fake_tos.mask_id = 0;
7011
4.05k
    fake_tos.mask_stack = NULL;
7012
4.05k
    fake_tos.matte = NULL;
7013
4.05k
    fake_tos.matte_num_comps = 0;
7014
4.05k
    fake_tos.memory = dev->memory;
7015
4.05k
    fake_tos.n_chan = dev->color_info.num_components;
7016
4.05k
    fake_tos.n_planes = dev->color_info.num_components;
7017
4.05k
    fake_tos.num_spots = 0;
7018
4.05k
    fake_tos.group_color_info = NULL;
7019
4.05k
    fake_tos.planestride = raster * (size_t)plane_height;
7020
4.05k
    fake_tos.rect.p.x = x;
7021
4.05k
    fake_tos.rect.p.y = y;
7022
4.05k
    fake_tos.rect.q.x = x + w;
7023
4.05k
    fake_tos.rect.q.y = y + h;
7024
4.05k
    fake_tos.rowstride = raster;
7025
4.05k
    fake_tos.saved = NULL;
7026
4.05k
    fake_tos.shape = 0xffff;
7027
4.05k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7028
4.05k
    fake_tos.transfer_fn = NULL;
7029
4.05k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7030
4.05k
                                  pdev->ctx->memory, dev);
7031
4.05k
    return 0;
7032
4.05k
}
7033
7034
static int
7035
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7036
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7037
    const gx_clip_path *pcpath)
7038
6.58M
{
7039
6.58M
    pdf14_device *pdev = (pdf14_device *)dev;
7040
6.58M
    pdf14_buf* buf;
7041
6.58M
    int code;
7042
6.58M
    int x = fixed2int(rect->p.x);
7043
6.58M
    int y = fixed2int(rect->p.y);
7044
6.58M
    int w = fixed2int(rect->q.x) - x;
7045
6.58M
    int h = fixed2int(rect->q.y) - y;
7046
7047
6.58M
    fit_fill_xywh(dev, x, y, w, h);
7048
6.58M
    if (w <= 0 || h <= 0)
7049
267k
        return 0;
7050
7051
6.31M
    code = pdf14_initialize_ctx(dev, pgs);
7052
6.31M
    if (code < 0)
7053
0
        return code;
7054
6.31M
    buf = pdev->ctx->stack;
7055
7056
6.31M
    if (buf->knockout)
7057
76.5k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7058
76.5k
                                                   true);
7059
6.23M
    else
7060
6.23M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7061
6.31M
}
7062
7063
static  int
7064
pdf14_fill_rectangle(gx_device * dev,
7065
                    int x, int y, int w, int h, gx_color_index color)
7066
379M
{
7067
379M
    pdf14_device *pdev = (pdf14_device *)dev;
7068
379M
    pdf14_buf *buf;
7069
379M
    int code;
7070
7071
379M
    fit_fill_xywh(dev, x, y, w, h);
7072
379M
    if (w <= 0 || h <= 0)
7073
11.7M
        return 0;
7074
7075
367M
    code = pdf14_initialize_ctx(dev, NULL);
7076
367M
    if (code < 0)
7077
0
        return code;
7078
7079
367M
    buf = pdev->ctx->stack;
7080
7081
367M
    if (buf->knockout)
7082
2.25M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7083
2.25M
                                                   false);
7084
365M
    else
7085
365M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7086
367M
}
7087
7088
static int
7089
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7090
                                    const gs_rect *pbbox, gs_int_rect *rect)
7091
2.29M
{
7092
2.29M
    gs_rect dev_bbox;
7093
2.29M
    int code;
7094
7095
2.29M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7096
2.29M
    if (code < 0)
7097
0
        return code;
7098
2.29M
    rect->p.x = (int)floor(dev_bbox.p.x);
7099
2.29M
    rect->p.y = (int)floor(dev_bbox.p.y);
7100
2.29M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7101
2.29M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7102
    /* Sanity check rect for insane ctms */
7103
2.29M
    if (rect->p.x < 0)
7104
86.6k
        rect->p.x = 0;
7105
2.29M
    if (rect->q.x < rect->p.x)
7106
2.22k
        rect->q.x = rect->p.x;
7107
2.29M
    if (rect->p.y < 0)
7108
2.10M
        rect->p.y = 0;
7109
2.29M
    if (rect->q.y < rect->p.y)
7110
50.0k
        rect->q.y = rect->p.y;
7111
2.29M
    return 0;
7112
2.29M
}
7113
7114
static  int
7115
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7116
                              const gs_rect *pbbox, gs_gstate *pgs)
7117
2.21M
{
7118
2.21M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7119
7120
2.21M
    if (code < 0)
7121
0
        return code;
7122
2.21M
    rect_intersect(*rect, pdev->ctx->rect);
7123
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7124
2.21M
    if (rect->q.x < rect->p.x)
7125
14.4k
        rect->q.x = rect->p.x;
7126
2.21M
    if (rect->q.y < rect->p.y)
7127
27.7k
        rect->q.y = rect->p.y;
7128
2.21M
    return 0;
7129
2.21M
}
7130
7131
static  int
7132
pdf14_begin_transparency_group(gx_device* dev,
7133
    const gs_transparency_group_params_t* ptgp,
7134
    const gs_rect* pbbox,
7135
    gs_gstate* pgs, gs_memory_t* mem)
7136
2.28M
{
7137
2.28M
    pdf14_device* pdev = (pdf14_device*)dev;
7138
2.28M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7139
2.28M
    gs_int_rect rect;
7140
2.28M
    int code;
7141
2.28M
    bool isolated = ptgp->Isolated;
7142
2.28M
    gs_transparency_color_t group_color_type;
7143
2.28M
    cmm_profile_t* group_profile;
7144
2.28M
    cmm_profile_t* tos_profile;
7145
2.28M
    gsicc_rendering_param_t render_cond;
7146
2.28M
    cmm_dev_profile_t* dev_profile;
7147
2.28M
    bool cm_back_drop = false;
7148
2.28M
    bool new_icc = false;
7149
2.28M
    pdf14_group_color_t* group_color_info;
7150
2.28M
    bool has_tags = device_encodes_tags(dev);
7151
7152
2.28M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7153
2.28M
    if (code < 0)
7154
0
        return code;
7155
2.28M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7156
7157
2.28M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7158
503k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7159
503k
    }
7160
7161
2.28M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7162
503k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7163
1.78M
    else
7164
1.78M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7165
7166
2.28M
    if (code < 0)
7167
0
        return code;
7168
2.28M
    if_debug5m('v', pdev->memory,
7169
2.28M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7170
2.28M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7171
7172
    /* If the group color is unknown then use the current device profile. */
7173
2.28M
    if (ptgp->group_color_type == UNKNOWN) {
7174
1.84M
        group_color_type = ICC;
7175
1.84M
        group_profile = tos_profile;
7176
1.84M
    }
7177
442k
    else {
7178
442k
        group_color_type = ptgp->group_color_type;
7179
442k
        group_profile = ptgp->iccprofile;
7180
442k
    }
7181
7182
    /* We have to handle case where the profile is in the clist */
7183
2.28M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7184
        /* Get the serialized data from the clist. */
7185
442k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7186
442k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7187
442k
        if (group_profile == NULL)
7188
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7189
        /* Keep a pointer to the clist device */
7190
442k
        group_profile->dev = (gx_device*)pcrdev;
7191
442k
        new_icc = true;
7192
442k
    }
7193
2.28M
    if (group_profile != NULL) {
7194
        /* If we have a non-isolated group and the color space is different,
7195
            we will need to CM the backdrop. */
7196
2.28M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7197
197k
            cm_back_drop = true;
7198
197k
        }
7199
2.28M
    }
7200
7201
    /* Always create the base color group information as it is only through
7202
       groups that we can have a color space change.  This will survive
7203
       the life of the context. */
7204
2.28M
    if (pdev->ctx->base_color == NULL) {
7205
612k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7206
612k
    }
7207
7208
    /* If this is not the page group and we don't yet have a group, we need
7209
       to create a buffer for the whole page so that we can handle stuff drawn
7210
       outside this current group (e.g. two non inclusive groups drawn independently) */
7211
2.28M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7212
80.0k
        code = pdf14_initialize_ctx(dev, NULL);
7213
80.0k
        if (code < 0)
7214
0
            return code;
7215
80.0k
        pdev->ctx->stack->isolated = true;
7216
80.0k
    }
7217
7218
2.28M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7219
2.28M
        group_profile, false);
7220
2.28M
    if (group_color_info == NULL)
7221
0
        return gs_error_VMerror;
7222
2.28M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7223
7224
2.28M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7225
2.28M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7226
2.28M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7227
2.28M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7228
2.28M
                                        pgs->blend_mode, ptgp->idle,
7229
2.28M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7230
2.28M
                                         cm_back_drop, ptgp->shade_group,
7231
2.28M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7232
2.28M
    if (new_icc)
7233
442k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7234
2.28M
    return code;
7235
2.28M
}
7236
7237
static void
7238
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7239
2.28M
{
7240
2.28M
    pdf14_device* pdev = (pdf14_device*)dev;
7241
7242
2.28M
    if (group_color != NULL &&
7243
2.28M
        !(group_color->group_color_mapping_procs == NULL &&
7244
2.28M
            group_color->group_color_comp_index == NULL)) {
7245
2.28M
        bool has_tags = device_encodes_tags(dev);
7246
2.28M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7247
2.28M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7248
2.28M
        pdev->color_info.polarity = group_color->polarity;
7249
2.28M
        if (pdev->num_planar_planes > 0)
7250
84.9k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7251
2.28M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7252
2.28M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7253
2.28M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7254
2.28M
        pdev->blend_procs = group_color->blend_procs;
7255
2.28M
        pdev->ctx->additive = group_color->isadditive;
7256
2.28M
        pdev->pdf14_procs = group_color->unpack_procs;
7257
2.28M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7258
2.28M
        pdev->color_info.depth = group_color->depth;
7259
2.28M
        pdev->color_info.max_color = group_color->max_color;
7260
2.28M
        pdev->color_info.max_gray = group_color->max_gray;
7261
2.28M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7262
2.28M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7263
2.28M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7264
2.28M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7265
2.28M
        if (group_color->icc_profile != NULL) {
7266
            /* make sure to decrement the device profile.  If it was allocated
7267
               with the push then it will be freed. */
7268
2.28M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7269
2.28M
                                    -1, "pdf14_pop_color_model");
7270
2.28M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7271
2.28M
                                    group_color->icc_profile;
7272
7273
2.28M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7274
2.28M
                                    1, "pdf14_pop_color_model");
7275
2.28M
        }
7276
2.28M
        pdev->num_std_colorants = group_color->num_std_colorants;
7277
2.28M
    }
7278
2.28M
}
7279
7280
static  int
7281
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7282
2.28M
{
7283
2.28M
    pdf14_device* pdev = (pdf14_device*)dev;
7284
2.28M
    int code;
7285
2.28M
    cmm_profile_t* group_profile;
7286
2.28M
    gsicc_rendering_param_t render_cond;
7287
2.28M
    cmm_dev_profile_t* dev_profile;
7288
2.28M
    int has_tags = device_encodes_tags(dev);
7289
7290
2.28M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7291
2.28M
    if (code < 0)
7292
0
        return code;
7293
7294
2.28M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7295
2.28M
        &render_cond);
7296
2.28M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7297
7298
2.28M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7299
2.28M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7300
2.28M
    if (code < 0)
7301
0
        return code;
7302
#ifdef DEBUG
7303
    pdf14_debug_mask_stack_state(pdev->ctx);
7304
#endif
7305
    /* If this group is the base group, then restore the color model
7306
       of the device at this time.  Note that during the actual device pop
7307
       we will need to use the profile of the buffer not the pdf14 device
7308
       as the source color space */
7309
2.28M
    if (pdev->ctx->stack->group_popped) {
7310
435k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7311
1.84M
    } else {
7312
1.84M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7313
1.84M
    }
7314
7315
2.28M
    return code;
7316
2.28M
}
7317
7318
static pdf14_group_color_t*
7319
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7320
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7321
                        bool is_mask)
7322
2.71M
{
7323
2.71M
    pdf14_device *pdevproto = NULL;
7324
2.71M
    pdf14_device *pdev = (pdf14_device *)dev;
7325
2.71M
    const pdf14_procs_t *new_14procs = NULL;
7326
2.71M
    pdf14_group_color_t *group_color;
7327
2.71M
    gx_color_polarity_t new_polarity;
7328
2.71M
    uchar new_num_comps;
7329
2.71M
    bool new_additive;
7330
2.71M
    gx_device_clist_reader *pcrdev;
7331
2.71M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7332
2.71M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7333
2.71M
    int k;
7334
2.71M
    bool has_tags = device_encodes_tags(dev);
7335
2.71M
    bool deep = pdev->ctx->deep;
7336
7337
2.71M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7338
7339
2.71M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7340
7341
2.71M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7342
2.71M
                               pdf14_group_color_t, &st_pdf14_clr,
7343
2.71M
                               "pdf14_push_color_model");
7344
2.71M
    if (group_color == NULL)
7345
0
        return NULL;
7346
7347
2.71M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7348
7349
2.71M
    switch (group_color_type) {
7350
0
        case GRAY_SCALE:
7351
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7352
0
            new_num_comps = 1;
7353
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7354
0
            new_additive = true;
7355
0
            new_14procs = &gray_pdf14_procs;
7356
0
            break;
7357
0
        case DEVICE_RGB:
7358
0
        case CIE_XYZ:
7359
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7360
0
            new_num_comps = 3;
7361
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7362
0
            new_additive = true;
7363
0
            new_14procs = &rgb_pdf14_procs;
7364
0
            break;
7365
0
        case DEVICE_CMYK:
7366
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7367
0
            new_num_comps = 4;
7368
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7369
0
            new_additive = false;
7370
            /* This is needed due to the mismatched compressed encode decode
7371
                between the device procs and the pdf14 procs */
7372
0
            if (dev->color_info.num_components > 4){
7373
0
                new_14procs = &cmykspot_pdf14_procs;
7374
0
            } else {
7375
0
                new_14procs = &cmyk_pdf14_procs;
7376
0
            }
7377
0
            break;
7378
2.71M
        case ICC:
7379
            /* If we are coming from the clist reader, then we need to get
7380
                the ICC data now  */
7381
2.71M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7382
                /* Get the serialized data from the clist.  Not the whole
7383
                    profile. */
7384
429k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7385
429k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7386
429k
                                                    icc_hashcode);
7387
429k
                if (iccprofile == NULL)
7388
0
                    return NULL;
7389
                /* Keep a pointer to the clist device */
7390
429k
                iccprofile->dev = (gx_device *) pcrdev;
7391
2.28M
            } else {
7392
                /* Go ahead and rc increment right now.  This way when
7393
                    we pop, we will make sure to decrement and avoid a
7394
                    leak for the above profile that we just created.  This
7395
                    goes with the assignment to the device's profile.
7396
                    Note that we still do the increment for the group_color
7397
                    assignment below. */
7398
2.28M
                if (iccprofile == NULL)
7399
0
                    return NULL;
7400
2.28M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7401
2.28M
            }
7402
2.71M
            new_num_comps = iccprofile->num_comps;
7403
2.71M
            if (new_num_comps == 4) {
7404
89.8k
                new_additive = false;
7405
89.8k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7406
2.62M
            } else {
7407
2.62M
                new_additive = true;
7408
2.62M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7409
2.62M
            }
7410
2.71M
            switch (new_num_comps) {
7411
666k
                case 1:
7412
666k
                    if (pdev->sep_device && !is_mask) {
7413
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7414
0
                        new_14procs = &grayspot_pdf14_procs;
7415
666k
                    } else {
7416
666k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7417
666k
                        new_14procs = &gray_pdf14_procs;
7418
666k
                    }
7419
666k
                    break;
7420
1.96M
                case 3:
7421
1.96M
                    if (pdev->sep_device) {
7422
71.8k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7423
71.8k
                        new_14procs = &rgbspot_pdf14_procs;
7424
71.8k
                    }
7425
1.89M
                    else {
7426
1.89M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7427
1.89M
                        new_14procs = &rgb_pdf14_procs;
7428
1.89M
                    }
7429
1.96M
                    break;
7430
89.8k
                case 4:
7431
89.8k
                    if (pdev->sep_device) {
7432
13.0k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7433
13.0k
                        new_14procs = &cmykspot_pdf14_procs;
7434
76.7k
                    } else {
7435
76.7k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7436
76.7k
                        new_14procs = &cmyk_pdf14_procs;
7437
76.7k
                    }
7438
89.8k
                    break;
7439
0
                default:
7440
0
                    return NULL;
7441
0
                    break;
7442
2.71M
            }
7443
2.71M
            break;
7444
2.71M
        default:
7445
0
            return NULL;
7446
0
            break;
7447
2.71M
    }
7448
7449
    /* We might just have changed the colorspace of the device, which means
7450
     * the number of colorants have changed. */
7451
2.71M
    group_color->num_std_colorants = new_num_comps;
7452
2.71M
    pdev->num_std_colorants = new_num_comps;
7453
7454
2.71M
    if (has_tags)
7455
0
        new_num_comps++;
7456
7457
2.71M
    if (group_color_type == ICC && iccprofile != NULL) {
7458
2.71M
        group_color->icc_profile = iccprofile;
7459
2.71M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7460
2.71M
    }
7461
7462
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7463
       spot colorants and know how to index into them */
7464
2.71M
    if (pdev->sep_device && !is_mask) {
7465
84.8k
        int num_spots = dev->color_info.num_components - has_tags -
7466
84.8k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7467
7468
84.8k
        if (num_spots > 0)
7469
688
            new_num_comps += num_spots;
7470
84.8k
    }
7471
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7472
9.63M
    for (k = 0; k < new_num_comps; k++) {
7473
6.91M
        comp_bits[k] = 8<<deep;
7474
6.91M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7475
6.91M
    }
7476
7477
    /* Set device values now and store settings in group_color.  Then they
7478
       are available when we pop the previous group */
7479
2.71M
    if_debug2m('v', pdev->memory,
7480
2.71M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7481
2.71M
                pdev->color_info.num_components,new_num_comps);
7482
2.71M
    {
7483
2.71M
        gx_device local_device;
7484
7485
2.71M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7486
2.71M
        local_device.initialize_device_procs((gx_device *)&local_device);
7487
2.71M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7488
2.71M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7489
2.71M
    }
7490
2.71M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7491
2.71M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7492
2.71M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7493
2.71M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7494
2.71M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7495
2.71M
    if (pdev->num_planar_planes > 0)
7496
113k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7497
2.71M
    group_color->num_components = new_num_comps - has_tags;
7498
2.71M
    pdev->color_info.num_components = new_num_comps;
7499
2.71M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7500
2.71M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7501
2.71M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7502
2.71M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7503
2.71M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7504
2.71M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7505
2.71M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7506
2.71M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7507
2.71M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7508
2.71M
    group_color->depth = pdev->color_info.depth;
7509
2.71M
    group_color->decode = dev_proc(pdev, decode_color);
7510
2.71M
    group_color->encode = dev_proc(pdev, encode_color);
7511
2.71M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7512
2.71M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7513
2.71M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7514
2.71M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7515
2.71M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7516
2.71M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7517
2.71M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7518
7519
    /* If the CS was ICC based, we need to update the device ICC profile
7520
        in the ICC manager, since that is the profile that is used for the
7521
        PDF14 device */
7522
2.71M
    if (group_color_type == ICC && iccprofile != NULL) {
7523
        /* iccprofile was incremented above if we had not just created it.
7524
           When we do the pop we will decrement and if we just created it, it
7525
           will be destroyed */
7526
2.71M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7527
2.71M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7528
2.71M
    }
7529
2.71M
    return group_color;
7530
2.71M
}
7531
7532
static int
7533
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7534
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7535
                             bool is_mask)
7536
63.1k
{
7537
63.1k
    pdf14_device* pdev = (pdf14_device*)dev;
7538
63.1k
    pdf14_group_color_t* new_group_color;
7539
63.1k
    gsicc_rendering_param_t render_cond;
7540
63.1k
    cmm_dev_profile_t* dev_profile;
7541
63.1k
    pdf14_device* pdevproto;
7542
63.1k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7543
63.1k
    const pdf14_procs_t* new_14procs;
7544
63.1k
    bool update_color_info;
7545
63.1k
    gx_color_polarity_t new_polarity;
7546
63.1k
    int new_num_comps;
7547
63.1k
    bool new_additive = false;
7548
63.1k
    byte new_depth;
7549
63.1k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7550
63.1k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7551
63.1k
    int k;
7552
63.1k
    bool has_tags = device_encodes_tags(dev);
7553
63.1k
    bool deep = device_is_deep(dev);
7554
63.1k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7555
63.1k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7556
63.1k
    cmm_profile_t *old_profile = NULL;
7557
7558
63.1k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7559
7560
63.1k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7561
63.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7562
63.1k
        &render_cond);
7563
63.1k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7564
7565
    /* Allocate a new one */
7566
63.1k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7567
63.1k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7568
7569
63.1k
    if (new_group_color == NULL)
7570
0
        return_error(gs_error_VMerror);
7571
7572
    /* Link to old one */
7573
63.1k
    new_group_color->previous = pdev->color_model_stack;
7574
7575
    /* Reassign new one to dev */
7576
63.1k
    pdev->color_model_stack = new_group_color;
7577
7578
    /* Initialize with values */
7579
63.1k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7580
63.1k
    new_group_color->group_color_mapping_procs =
7581
63.1k
        dev_proc(pdev, get_color_mapping_procs);
7582
63.1k
    new_group_color->group_color_comp_index =
7583
63.1k
        dev_proc(pdev, get_color_comp_index);
7584
63.1k
    new_group_color->blend_procs = pdev->blend_procs;
7585
63.1k
    new_group_color->polarity = pdev->color_info.polarity;
7586
63.1k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7587
63.1k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7588
63.1k
    new_group_color->depth = pdev->color_info.depth;
7589
63.1k
    new_group_color->max_color = pdev->color_info.max_color;
7590
63.1k
    new_group_color->max_gray = pdev->color_info.max_gray;
7591
63.1k
    new_group_color->decode = dev_proc(pdev, decode_color);
7592
63.1k
    new_group_color->encode = dev_proc(pdev, encode_color);
7593
63.1k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7594
63.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7595
63.1k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7596
63.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7597
7598
63.1k
    if (new_profile == NULL)
7599
38.1k
        new_group_color->icc_profile = NULL;
7600
7601
    /* isadditive is only used in ctx */
7602
63.1k
    if (pdev->ctx) {
7603
0
        new_group_color->isadditive = pdev->ctx->additive;
7604
0
    }
7605
7606
63.1k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7607
63.1k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7608
7609
63.1k
    if (group_color_type == ICC && new_profile == NULL)
7610
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7611
63.1k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7612
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7613
       are based upon the color space of the device.  We want to remain in the
7614
       color space defined by the color space of the soft mask or transparency
7615
       group as opposed to the device color space. Later, when we pop the softmask
7616
       we will collapse it to a single band and then compose with it to the device
7617
       color space (or the parent layer space).  In the case where we pop an
7618
       isolated transparency group, we will do the blending in the proper color
7619
       space and then transform the data when we pop the group.  Remember that only
7620
       isolated groups can have color spaces that are different than their parent. */
7621
63.1k
    update_color_info = false;
7622
63.1k
    switch (group_color_type) {
7623
0
    case GRAY_SCALE:
7624
0
        if (pdev->color_info.num_components != 1) {
7625
0
            update_color_info = true;
7626
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7627
0
            new_num_comps = 1;
7628
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7629
0
            new_additive = true;
7630
0
            new_14procs = &gray_pdf14_procs;
7631
0
            new_depth = 8 << deep;
7632
0
        }
7633
0
        break;
7634
0
    case DEVICE_RGB:
7635
0
    case CIE_XYZ:
7636
0
        if (pdev->color_info.num_components != 3) {
7637
0
            update_color_info = true;
7638
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7639
0
            new_num_comps = 3;
7640
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7641
0
            new_additive = true;
7642
0
            new_14procs = &rgb_pdf14_procs;
7643
0
            new_depth = 24 << deep;
7644
0
        }
7645
0
        break;
7646
0
    case DEVICE_CMYK:
7647
0
        if (pdev->color_info.num_components != 4) {
7648
0
            update_color_info = true;
7649
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7650
0
            new_num_comps = 4;
7651
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7652
0
            new_additive = false;
7653
            /* This is needed due to the mismatched compressed encode decode
7654
               between the device procs and the pdf14 procs */
7655
0
            if (dev->color_info.num_components > 4) {
7656
0
                new_14procs = &cmykspot_pdf14_procs;
7657
0
            }
7658
0
            else {
7659
0
                new_14procs = &cmyk_pdf14_procs;
7660
0
            }
7661
0
            new_depth = 32 << deep;
7662
0
        }
7663
0
        break;
7664
25.0k
    case ICC:
7665
        /* Check if the profile is different. */
7666
25.0k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7667
22.7k
            update_color_info = true;
7668
22.7k
            new_num_comps = new_profile->num_comps;
7669
22.7k
            new_depth = new_profile->num_comps * (8 << deep);
7670
22.7k
            switch (new_num_comps) {
7671
20.4k
            case 1:
7672
20.4k
                if (pdev->sep_device && !is_mask) {
7673
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7674
0
                    new_14procs = &grayspot_pdf14_procs;
7675
0
                }
7676
20.4k
                else {
7677
20.4k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7678
20.4k
                    new_14procs = &gray_pdf14_procs;
7679
20.4k
                }
7680
20.4k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7681
20.4k
                new_additive = true;
7682
20.4k
                break;
7683
2.09k
            case 3:
7684
2.09k
                if (pdev->sep_device) {
7685
536
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7686
536
                    new_14procs = &rgbspot_pdf14_procs;
7687
536
                }
7688
1.55k
                else {
7689
1.55k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7690
1.55k
                    new_14procs = &rgb_pdf14_procs;
7691
1.55k
                }
7692
2.09k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7693
2.09k
                new_additive = true;
7694
2.09k
                break;
7695
207
            case 4:
7696
207
                if (pdev->sep_device) {
7697
3
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7698
3
                    new_14procs = &cmykspot_pdf14_procs;
7699
3
                }
7700
204
                else {
7701
204
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7702
204
                    new_14procs = &cmyk_pdf14_procs;
7703
204
                }
7704
207
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7705
207
                new_additive = false;
7706
207
                break;
7707
0
            default:
7708
0
                return gs_throw(gs_error_undefinedresult,
7709
22.7k
                    "ICC Number of colorants illegal");
7710
22.7k
            }
7711
22.7k
        }
7712
25.0k
        break;
7713
38.1k
    case UNKNOWN:
7714
38.1k
        return 0;
7715
0
        break;
7716
0
    default:
7717
0
        return_error(gs_error_rangecheck);
7718
0
        break;
7719
63.1k
    }
7720
7721
25.0k
    if (!update_color_info) {
7722
        /* Profile not updated */
7723
2.25k
        new_group_color->icc_profile = NULL;
7724
2.25k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7725
2.25k
        return 0;
7726
2.25k
    }
7727
7728
22.7k
    if (has_tags) {
7729
0
        new_num_comps++;
7730
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7731
0
        if (pdev->num_planar_planes > 0)
7732
0
            new_depth += deep ? 16 : 8;
7733
0
        else
7734
0
            new_depth += 8;
7735
0
    }
7736
22.7k
    if (pdev->sep_device && !is_mask) {
7737
539
        int num_spots;
7738
7739
539
        if (old_profile == NULL)
7740
0
            return_error(gs_error_undefined);
7741
7742
539
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7743
7744
539
        if (num_spots > 0) {
7745
45
            new_num_comps += num_spots;
7746
45
            new_depth = (8 << deep) * new_num_comps;
7747
45
        }
7748
539
    }
7749
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7750
50.4k
    for (k = 0; k < new_num_comps; k++) {
7751
27.6k
        comp_bits[k] = 8 << deep;
7752
27.6k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7753
27.6k
    }
7754
22.7k
    if_debug2m('v', pdev->memory,
7755
22.7k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7756
22.7k
        pdev->color_info.num_components, new_num_comps);
7757
    /* Set new information in the device */
7758
22.7k
    {
7759
22.7k
        gx_device local_device;
7760
7761
22.7k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7762
22.7k
        local_device.initialize_device_procs((gx_device *)&local_device);
7763
22.7k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7764
22.7k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7765
22.7k
    }
7766
22.7k
    pdev->blend_procs = pdevproto->blend_procs;
7767
22.7k
    pdev->color_info.polarity = new_polarity;
7768
22.7k
    pdev->color_info.max_color = deep ? 65535 : 255;
7769
22.7k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7770
22.7k
    pdev->pdf14_procs = new_14procs;
7771
22.7k
    if (pdev->num_planar_planes > 0)
7772
2.66k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7773
22.7k
    pdev->color_info.num_components = new_num_comps;
7774
22.7k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7775
22.7k
    pdev->color_info.depth = new_depth;
7776
22.7k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7777
22.7k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7778
22.7k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7779
22.7k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7780
22.7k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7781
7782
    /* If we have a compressed color codec, and we are doing a soft mask
7783
       push operation then go ahead and update the color encode and
7784
       decode for the pdf14 device to not used compressed color
7785
       encoding while in the soft mask.  We will just check for gray
7786
       and compressed.  Note that we probably don't have_tags if we
7787
       are dealing with compressed color.  But is is possible so
7788
       we add it in to catch for future use. */
7789
22.7k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7790
22.7k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7791
22.7k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7792
22.7k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7793
22.7k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7794
22.7k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7795
    /* For the ICC profiles, we want to update the ICC profile for the
7796
       device.  We store the original in group_color.
7797
       That will be stored in the clist and restored during the reading phase. */
7798
22.7k
    if (group_color_type == ICC) {
7799
22.7k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7800
22.7k
        new_group_color->icc_profile =
7801
22.7k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7802
22.7k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7803
22.7k
    }
7804
22.7k
    if (pdev->ctx) {
7805
0
        pdev->ctx->additive = new_additive;
7806
0
    }
7807
22.7k
    return 1;  /* Lets us detect that we did do an update */
7808
22.7k
}
7809
7810
static int
7811
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7812
63.0k
{
7813
7814
63.0k
    pdf14_device *pdev = (pdf14_device *)dev;
7815
63.0k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7816
63.0k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7817
7818
63.0k
    if (group_color == NULL)
7819
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7820
7821
63.0k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7822
    /* The color procs are always pushed.  Simply restore them. */
7823
63.0k
    if (group_color->group_color_mapping_procs == NULL &&
7824
0
        group_color->group_color_comp_index == NULL) {
7825
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7826
63.0k
    } else {
7827
63.0k
        bool has_tags = device_encodes_tags(dev);
7828
63.0k
        if_debug2m('v', pdev->memory,
7829
63.0k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7830
63.0k
                   pdev->color_info.num_components,group_color->num_components);
7831
63.0k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7832
63.0k
        gx_set_cmap_procs(pgs, dev);
7833
63.0k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7834
63.0k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7835
63.0k
        pdev->color_info.polarity = group_color->polarity;
7836
63.0k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7837
63.0k
        pdev->color_info.depth = group_color->depth;
7838
63.0k
        if (pdev->num_planar_planes > 0)
7839
6.27k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7840
63.0k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7841
63.0k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7842
63.0k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7843
63.0k
        pdev->blend_procs = group_color->blend_procs;
7844
63.0k
        pdev->pdf14_procs = group_color->unpack_procs;
7845
63.0k
        pdev->color_info.max_color = group_color->max_color;
7846
63.0k
        pdev->color_info.max_gray = group_color->max_gray;
7847
63.0k
        set_dev_proc(pdev, encode_color, group_color->encode);
7848
63.0k
        set_dev_proc(pdev, decode_color, group_color->decode);
7849
63.0k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7850
63.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7851
63.0k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7852
63.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7853
7854
        /* clist writer fill rect has no access to gs_gstate */
7855
        /* and it forwards the target device.  this information */
7856
        /* is passed along to use in this case */
7857
63.0k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7858
63.0k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7859
63.0k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7860
63.0k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7861
63.0k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7862
63.0k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7863
63.0k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7864
63.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7865
63.0k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7866
63.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7867
63.0k
        if (pdev->ctx){
7868
0
            pdev->ctx->additive = group_color->isadditive;
7869
0
        }
7870
       /* The device profile must be restored. */
7871
63.0k
        if (group_color->icc_profile != NULL) {
7872
22.7k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7873
22.7k
                                    -1, "pdf14_clist_pop_color_model");
7874
22.7k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7875
22.7k
        }
7876
63.0k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7877
63.0k
    }
7878
63.0k
   pdf14_pop_group_color(dev, pgs);
7879
63.0k
    return 0;
7880
63.0k
}
7881
7882
/* When a transparency group is popped, the parent colorprocs must be restored.
7883
   Since the color mapping procs are all based upon the device, we must have a
7884
   nested list based upon the transparency group color space.  This nesting
7885
   must be outside the nested ctx structures to allow the nesting for the
7886
   clist writer */
7887
static void
7888
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7889
63.1k
{
7890
63.1k
    pdf14_device *pdev = (pdf14_device *)dev;
7891
63.1k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7892
7893
63.1k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7894
7895
    /* Update the link */
7896
63.1k
    pdev->color_model_stack = group_color->previous;
7897
7898
    /* Free the old one */
7899
63.1k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7900
63.1k
}
7901
7902
static  int
7903
pdf14_begin_transparency_mask(gx_device *dev,
7904
                              const gx_transparency_mask_params_t *ptmp,
7905
                              const gs_rect *pbbox,
7906
                              gs_gstate *pgs, gs_memory_t *mem)
7907
4.23M
{
7908
4.23M
    pdf14_device *pdev = (pdf14_device *)dev;
7909
4.23M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7910
4.23M
    byte *transfer_fn;
7911
4.23M
    gs_int_rect rect;
7912
4.23M
    int code;
7913
4.23M
    int group_color_numcomps;
7914
4.23M
    gs_transparency_color_t group_color_type;
7915
4.23M
    bool deep = device_is_deep(dev);
7916
4.23M
    pdf14_group_color_t* group_color_info;
7917
7918
4.23M
    code = pdf14_initialize_ctx(dev, pgs);
7919
4.23M
    if (code < 0)
7920
0
        return code;
7921
7922
4.23M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7923
3.80M
        pdf14_ctx *ctx = pdev->ctx;
7924
7925
        /* free up any maskbuf on the current tos */
7926
3.80M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7927
338k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7928
338k
            ctx->mask_stack->mask_buf = NULL;
7929
338k
        }
7930
3.80M
        return 0;
7931
3.80M
    }
7932
433k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7933
433k
                                         "pdf14_begin_transparency_mask");
7934
433k
    if (transfer_fn == NULL)
7935
0
        return_error(gs_error_VMerror);
7936
433k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7937
433k
    if (code < 0)
7938
0
        return code;
7939
    /* If we have background components the background alpha may be nonzero */
7940
433k
    if (ptmp->Background_components)
7941
51.1k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7942
433k
    if_debug1m('v', dev->memory,
7943
433k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7944
433k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7945
   /* If the group color is unknown, then we must use the previous group color
7946
       space or the device process color space */
7947
433k
    if (ptmp->group_color_type == UNKNOWN){
7948
0
        if (pdev->ctx->stack){
7949
            /* Use previous group color space */
7950
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7951
0
        } else {
7952
            /* Use process color space */
7953
0
            group_color_numcomps = pdev->color_info.num_components;
7954
0
        }
7955
0
        switch (group_color_numcomps) {
7956
0
            case 1:
7957
0
                group_color_type = GRAY_SCALE;
7958
0
                break;
7959
0
            case 3:
7960
0
                group_color_type = DEVICE_RGB;
7961
0
                break;
7962
0
            case 4:
7963
0
                group_color_type = DEVICE_CMYK;
7964
0
            break;
7965
0
            default:
7966
                /* We can end up here if we are in a deviceN color space and
7967
                   we have a sep output device */
7968
0
                group_color_type = DEVICEN;
7969
0
            break;
7970
0
         }
7971
433k
    } else {
7972
433k
        group_color_type = ptmp->group_color_type;
7973
433k
        group_color_numcomps = ptmp->group_color_numcomps;
7974
433k
    }
7975
7976
433k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7977
433k
                                               ptmp->iccprofile, true);
7978
433k
    if (group_color_info == NULL)
7979
0
        return gs_error_VMerror;
7980
7981
    /* Note that the soft mask always follows the group color requirements even
7982
       when we have a separable device */
7983
433k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7984
433k
                                        transfer_fn, ptmp->function_is_identity,
7985
433k
                                        ptmp->idle, ptmp->replacing,
7986
433k
                                        ptmp->mask_id, ptmp->subtype,
7987
433k
                                        group_color_numcomps,
7988
433k
                                        ptmp->Background_components,
7989
433k
                                        ptmp->Background,
7990
433k
                                        ptmp->Matte_components,
7991
433k
                                        ptmp->Matte,
7992
433k
                                        ptmp->GrayBackground,
7993
433k
                                        group_color_info);
7994
433k
    if (code < 0)
7995
0
        return code;
7996
7997
433k
    return 0;
7998
433k
}
7999
8000
static  int
8001
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8002
433k
{
8003
433k
    pdf14_device *pdev = (pdf14_device *)dev;
8004
433k
    pdf14_group_color_t *group_color;
8005
433k
    int ok;
8006
433k
    bool has_tags = device_encodes_tags(dev);
8007
8008
433k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8009
433k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8010
#ifdef DEBUG
8011
    pdf14_debug_mask_stack_state(pdev->ctx);
8012
#endif
8013
8014
    /* May need to reset some color stuff related
8015
     * to a mismatch between the Smask color space
8016
     * and the Smask blending space */
8017
433k
    if (pdev->ctx->stack != NULL ) {
8018
433k
        group_color = pdev->ctx->stack->group_color_info;
8019
433k
        if (!(group_color->group_color_mapping_procs == NULL &&
8020
433k
            group_color->group_color_comp_index == NULL)) {
8021
433k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8022
433k
            gx_set_cmap_procs(pgs, dev);
8023
433k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8024
433k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8025
433k
            pdev->color_info.polarity = group_color->polarity;
8026
433k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8027
433k
            if (pdev->num_planar_planes > 0)
8028
28.3k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8029
433k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8030
433k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8031
433k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8032
433k
            pdev->num_std_colorants = group_color->num_std_colorants;
8033
433k
            pdev->color_info.depth = group_color->depth;
8034
433k
            pdev->blend_procs = group_color->blend_procs;
8035
433k
            pdev->ctx->additive = group_color->isadditive;
8036
433k
            pdev->pdf14_procs = group_color->unpack_procs;
8037
433k
            pdev->color_info.max_color = group_color->max_color;
8038
433k
            pdev->color_info.max_gray = group_color->max_gray;
8039
433k
            set_dev_proc(pdev, encode_color, group_color->encode);
8040
433k
            set_dev_proc(pdev, decode_color, group_color->decode);
8041
433k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8042
433k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8043
433k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8044
433k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8045
            /* Take care of the ICC profile */
8046
433k
            if (group_color->icc_profile != NULL) {
8047
433k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8048
433k
                                        -1, "pdf14_end_transparency_mask");
8049
433k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8050
433k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8051
433k
                                         1, "pdf14_end_transparency_mask");
8052
433k
            }
8053
433k
        }
8054
433k
    }
8055
433k
    return ok;
8056
433k
}
8057
8058
static  int
8059
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8060
                                 gx_color_index color,
8061
                                 const gx_device_color *pdc, bool devn)
8062
2.32M
{
8063
2.32M
    pdf14_device *pdev = (pdf14_device *)dev;
8064
2.32M
    pdf14_buf *buf = pdev->ctx->stack;
8065
2.32M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8066
2.32M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8067
203k
        blend_mode == BLEND_MODE_Compatible ||
8068
203k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8069
2.32M
    int i, j, k;
8070
2.32M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8071
2.32M
    byte src[PDF14_MAX_PLANES];
8072
2.32M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8073
2.32M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8074
2.32M
    intptr_t rowstride = buf->rowstride;
8075
2.32M
    intptr_t planestride = buf->planestride;
8076
2.32M
    int num_chan = buf->n_chan;
8077
2.32M
    int num_comp = num_chan - 1;
8078
2.32M
    intptr_t shape_off = num_chan * planestride;
8079
2.32M
    bool has_shape = buf->has_shape;
8080
2.32M
    bool has_alpha_g = buf->has_alpha_g;
8081
2.32M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8082
2.32M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8083
2.32M
                                   (has_shape ? planestride : 0);
8084
2.32M
    bool has_tags = buf->has_tags;
8085
2.32M
    bool additive = pdev->ctx->additive;
8086
2.32M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8087
2.32M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8088
2.32M
    int shift = 8;
8089
2.32M
    byte shape = 0; /* Quiet compiler. */
8090
2.32M
    byte src_alpha;
8091
2.32M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8092
2.32M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8093
1.86M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8094
2.32M
    gx_color_index comps;
8095
2.32M
    bool has_backdrop = buf->backdrop != NULL;
8096
8097
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8098
       subtractive) and we are doing overprint with drawn_comps == 0
8099
       then this is a no-operation */
8100
2.32M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8101
0
        return 0;
8102
8103
2.32M
    if (buf->data == NULL)
8104
1
        return 0;
8105
#if 0
8106
    if (sizeof(color) <= sizeof(ulong))
8107
        if_debug6m('v', dev->memory,
8108
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8109
                   x, y, w, h, (ulong)color, num_chan);
8110
    else
8111
        if_debug7m('v', dev->memory,
8112
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8113
                   x, y, w, h,
8114
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8115
                   num_chan);
8116
#endif
8117
    /*
8118
     * Unpack the gx_color_index values.  Complement the components for subtractive
8119
     * color spaces.
8120
     */
8121
2.32M
    if (devn) {
8122
76.5k
        if (has_tags) {
8123
0
            curr_tag = pdc->tag;
8124
0
        }
8125
76.5k
        if (additive) {
8126
109k
            for (j = 0; j < num_comp; j++) {
8127
82.2k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8128
82.2k
            }
8129
49.0k
        } else {
8130
245k
            for (j = 0; j < num_comp; j++) {
8131
196k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8132
196k
            }
8133
49.0k
        }
8134
2.25M
    } else {
8135
2.25M
        if (has_tags) {
8136
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8137
0
        }
8138
2.25M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8139
2.25M
    }
8140
8141
2.32M
    if (!has_tags)
8142
2.32M
        tag_off = 0;
8143
8144
2.32M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8145
2.32M
    if (has_shape) {
8146
907
        shape = (byte)floor (255 * pdev->shape + 0.5);
8147
2.32M
    } else {
8148
2.32M
        shape_off = 0;
8149
2.32M
    }
8150
8151
2.32M
    if (!has_alpha_g)
8152
0
        alpha_g_off = 0;
8153
2.32M
    src_alpha = 255 - src_alpha;
8154
2.32M
    shape = 255 - shape;
8155
8156
    /* Fit the mark into the bounds of the buffer */
8157
2.32M
    if (x < buf->rect.p.x) {
8158
0
        w += x - buf->rect.p.x;
8159
0
        x = buf->rect.p.x;
8160
0
    }
8161
2.32M
    if (y < buf->rect.p.y) {
8162
10
      h += y - buf->rect.p.y;
8163
10
      y = buf->rect.p.y;
8164
10
    }
8165
2.32M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8166
2.32M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8167
    /* Update the dirty rectangle with the mark. */
8168
2.32M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8169
2.32M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8170
2.32M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8171
2.32M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8172
8173
    /* composite with backdrop only. */
8174
2.32M
    if (has_backdrop)
8175
2.32M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8176
0
    else
8177
0
        bline = NULL;
8178
8179
2.32M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8180
8181
4.92M
    for (j = 0; j < h; ++j) {
8182
2.59M
        bg_ptr = bline;
8183
2.59M
        dst_ptr = line;
8184
113M
        for (i = 0; i < w; ++i) {
8185
            /* Complement the components for subtractive color spaces */
8186
110M
            if (has_backdrop) {
8187
110M
                if (additive) {
8188
390M
                    for (k = 0; k < num_comp; ++k)
8189
282M
                        dst[k] = bg_ptr[k * planestride];
8190
107M
                } else {
8191
14.8M
                    for (k = 0; k < num_comp; ++k)
8192
11.8M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8193
2.96M
                }
8194
110M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8195
110M
            }
8196
110M
            if (buf->isolated || !has_backdrop) {
8197
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8198
110M
            } else {
8199
110M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8200
110M
                                            blend_mode, pdev->blend_procs, pdev);
8201
110M
            }
8202
            /* Complement the results for subtractive color spaces */
8203
110M
            if (additive) {
8204
107M
                if (!overprint) {
8205
498M
                    for (k = 0; k < num_chan; ++k)
8206
390M
                        dst_ptr[k * planestride] = dst[k];
8207
107M
                } else {
8208
                    /* Hybrid additive with subtractive spots */
8209
                    /* We may have to do the compatible overprint blending */
8210
51.1k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8211
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8212
0
                            blend_mode, pdev->blend_procs, pdev);
8213
0
                    }
8214
204k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8215
153k
                        if ((comps & 0x1) != 0) {
8216
153k
                            dst_ptr[k * planestride] = dst[k];
8217
153k
                        } else {
8218
                            /* Compatible overprint blend result. */
8219
0
                            dst_ptr[k * planestride] = dst2[k];
8220
0
                        }
8221
153k
                    }
8222
51.1k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8223
51.1k
                }
8224
107M
            } else {
8225
2.96M
                if (overprint) {
8226
                    /* We may have to do the compatible overprint blending */
8227
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8228
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8229
0
                            blend_mode, pdev->blend_procs, pdev);
8230
0
                    }
8231
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8232
0
                        if ((comps & 0x1) != 0) {
8233
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8234
0
                        } else {
8235
                            /* Compatible overprint blend result. */
8236
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8237
0
                        }
8238
0
                    }
8239
2.96M
                } else {
8240
14.8M
                    for (k = 0; k < num_comp; ++k)
8241
11.8M
                        dst_ptr[k * planestride] = 255 - dst[k];
8242
2.96M
                }
8243
2.96M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8244
2.96M
            }
8245
110M
            if (tag_off) {
8246
                /* If src alpha is 100% then set to curr_tag, else or */
8247
                /* other than Normal BM, we always OR */
8248
0
                if (src[num_comp] == 255 && tag_blend) {
8249
0
                    dst_ptr[tag_off] = curr_tag;
8250
0
                } else {
8251
0
                    dst_ptr[tag_off] |= curr_tag;
8252
0
                }
8253
0
            }
8254
            /* Knockout group alpha and shape too */
8255
110M
            if (alpha_g_off)
8256
110M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8257
110M
            if (shape_off)
8258
1.91k
                dst_ptr[shape_off] = 255 - shape;
8259
110M
            ++dst_ptr;
8260
110M
            if (has_backdrop)
8261
110M
                ++bg_ptr;
8262
110M
        }
8263
2.59M
        bline += rowstride;
8264
2.59M
        line += rowstride;
8265
2.59M
    }
8266
#if 0
8267
/* #if RAW_DUMP */
8268
    /* Dump the current buffer to see what we have. */
8269
    dump_raw_buffer(pdev->ctx->memory,
8270
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8271
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8272
                    pdev->ctx->stack->n_planes,
8273
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8274
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8275
                    pdev->ctx->stack->deep);
8276
    global_index++;
8277
#endif
8278
2.32M
    return 0;
8279
2.32M
}
8280
8281
static  int
8282
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8283
                                   gx_color_index color,
8284
                                   const gx_device_color *pdc, bool devn)
8285
0
{
8286
0
    pdf14_device *pdev = (pdf14_device *)dev;
8287
0
    pdf14_buf *buf = pdev->ctx->stack;
8288
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8289
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8290
0
        blend_mode == BLEND_MODE_Compatible ||
8291
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8292
0
    int i, j, k;
8293
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8294
0
    uint16_t src[PDF14_MAX_PLANES];
8295
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8296
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8297
0
    intptr_t rowstride = buf->rowstride;
8298
0
    intptr_t planestride = buf->planestride;
8299
0
    int num_chan = buf->n_chan;
8300
0
    int num_comp = num_chan - 1;
8301
0
    intptr_t shape_off = num_chan * planestride;
8302
0
    bool has_shape = buf->has_shape;
8303
0
    bool has_alpha_g = buf->has_alpha_g;
8304
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8305
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8306
0
                                   (has_shape ? planestride : 0);
8307
0
    bool has_tags = buf->has_tags;
8308
0
    bool additive = pdev->ctx->additive;
8309
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8310
0
    uint16_t shape = 0; /* Quiet compiler. */
8311
0
    uint16_t src_alpha;
8312
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8313
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8314
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8315
0
    gx_color_index comps;
8316
0
    bool has_backdrop = buf->backdrop != NULL;
8317
8318
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8319
       subtractive) and we are doing overprint with drawn_comps == 0
8320
       then this is a no-operation */
8321
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8322
0
        return 0;
8323
8324
0
    if (buf->data == NULL)
8325
0
        return 0;
8326
#if 0
8327
    if (sizeof(color) <= sizeof(ulong))
8328
        if_debug6m('v', dev->memory,
8329
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8330
                   x, y, w, h, (ulong)color, num_chan);
8331
    else
8332
        if_debug7m('v', dev->memory,
8333
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8334
                   x, y, w, h,
8335
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8336
                   num_chan);
8337
#endif
8338
    /*
8339
     * Unpack the gx_color_index values.  Complement the components for subtractive
8340
     * color spaces.
8341
     */
8342
0
    if (devn) {
8343
0
        if (has_tags) {
8344
0
            curr_tag = pdc->tag;
8345
0
        }
8346
0
        if (additive) {
8347
0
            for (j = 0; j < num_comp; j++) {
8348
0
                src[j] = pdc->colors.devn.values[j];
8349
0
            }
8350
0
        } else {
8351
0
            for (j = 0; j < num_comp; j++) {
8352
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8353
0
            }
8354
0
        }
8355
0
    } else {
8356
0
        if (has_tags) {
8357
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8358
0
        }
8359
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8360
0
    }
8361
8362
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8363
0
    if (has_shape) {
8364
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8365
0
    } else {
8366
0
        shape_off = 0;
8367
0
    }
8368
8369
0
    if (!has_tags) {
8370
0
        tag_off = 0;
8371
0
    }
8372
8373
0
    if (!has_alpha_g)
8374
0
        alpha_g_off = 0;
8375
0
    src_alpha = 65535 - src_alpha;
8376
0
    shape = 65535 - shape;
8377
8378
    /* Fit the mark into the bounds of the buffer */
8379
0
    if (x < buf->rect.p.x) {
8380
0
        w += x - buf->rect.p.x;
8381
0
        x = buf->rect.p.x;
8382
0
    }
8383
0
    if (y < buf->rect.p.y) {
8384
0
      h += y - buf->rect.p.y;
8385
0
      y = buf->rect.p.y;
8386
0
    }
8387
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8388
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8389
    /* Update the dirty rectangle with the mark. */
8390
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8391
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8392
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8393
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8394
8395
8396
    /* composite with backdrop only. */
8397
0
    if (has_backdrop)
8398
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8399
0
    else
8400
0
        bline = NULL;
8401
8402
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8403
0
    planestride >>= 1;
8404
0
    rowstride >>= 1;
8405
0
    alpha_g_off >>= 1;
8406
0
    shape_off >>= 1;
8407
0
    tag_off >>= 1;
8408
8409
0
    for (j = 0; j < h; ++j) {
8410
0
        bg_ptr = bline;
8411
0
        dst_ptr = line;
8412
0
        for (i = 0; i < w; ++i) {
8413
            /* Complement the components for subtractive color spaces */
8414
0
            if (has_backdrop) {
8415
0
                if (additive) {
8416
0
                    for (k = 0; k < num_comp; ++k)
8417
0
                        dst[k] = bg_ptr[k * planestride];
8418
0
                } else {
8419
0
                    for (k = 0; k < num_comp; ++k)
8420
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8421
0
                }
8422
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8423
0
            }
8424
0
            if (buf->isolated || !has_backdrop) {
8425
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8426
0
            } else {
8427
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8428
0
                                              blend_mode, pdev->blend_procs, pdev);
8429
0
            }
8430
            /* Complement the results for subtractive color spaces */
8431
0
            if (additive) {
8432
0
                if (!overprint) {
8433
0
                    for (k = 0; k < num_chan; ++k)
8434
0
                        dst_ptr[k * planestride] = dst[k];
8435
0
                } else {
8436
                    /* Hybrid additive with subtractive spots */
8437
                    /* We may have to do the compatible overprint blending */
8438
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8439
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8440
0
                            blend_mode, pdev->blend_procs, pdev);
8441
0
                    }
8442
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8443
0
                        if ((comps & 0x1) != 0) {
8444
0
                            dst_ptr[k * planestride] = dst[k];
8445
0
                        } else {
8446
                            /* Compatible overprint blend result. */
8447
0
                            dst_ptr[k * planestride] = dst2[k];
8448
0
                        }
8449
0
                    }
8450
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8451
0
                }
8452
0
            } else {
8453
0
                if (overprint) {
8454
                    /* We may have to do the compatible overprint blending */
8455
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8456
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8457
0
                            blend_mode, pdev->blend_procs, pdev);
8458
0
                    }
8459
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8460
0
                        if ((comps & 0x1) != 0) {
8461
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8462
0
                        } else {
8463
                            /* Compatible overprint blend result. */
8464
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8465
0
                        }
8466
0
                    }
8467
0
                } else {
8468
0
                    for (k = 0; k < num_comp; ++k)
8469
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8470
0
                }
8471
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8472
0
            }
8473
0
            if (tag_off) {
8474
                /* FIXME: As we are knocking out, possibly, we should be
8475
                 * always overwriting tag values here? */
8476
                /* If src alpha is 100% then set to curr_tag, else or */
8477
                /* other than Normal BM, we always OR */
8478
0
                if (src[num_comp] == 65535 && tag_blend) {
8479
0
                    dst_ptr[tag_off] = curr_tag;
8480
0
                } else {
8481
0
                    dst_ptr[tag_off] |= curr_tag;
8482
0
                }
8483
0
            }
8484
            /* Knockout group alpha and shape too */
8485
0
            if (alpha_g_off)
8486
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8487
0
            if (shape_off)
8488
0
                dst_ptr[shape_off] = 65535 - shape;
8489
0
            ++dst_ptr;
8490
0
            if (has_backdrop)
8491
0
                ++bg_ptr;
8492
0
        }
8493
0
        bline += rowstride;
8494
0
        line += rowstride;
8495
0
    }
8496
#if 0
8497
/* #if RAW_DUMP */
8498
    /* Dump the current buffer to see what we have. */
8499
    dump_raw_buffer(pdev->ctx->memory,
8500
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8501
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8502
                    pdev->ctx->stack->n_planes,
8503
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8504
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8505
                    pdev->ctx->stack->deep);
8506
    global_index++;
8507
#endif
8508
0
    return 0;
8509
0
}
8510
8511
static  int
8512
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8513
                                    gx_color_index color,
8514
                                    const gx_device_color *pdc, bool devn)
8515
2.32M
{
8516
2.32M
    pdf14_device *pdev = (pdf14_device *)dev;
8517
2.32M
    pdf14_buf *buf = pdev->ctx->stack;
8518
8519
2.32M
    if (buf->deep)
8520
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8521
2.32M
    else
8522
2.32M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8523
2.32M
}
8524
8525
/**
8526
 * Here we have logic to override the cmap_procs with versions that
8527
 * do not apply the transfer function. These copies should track the
8528
 * versions in gxcmap.c.
8529
 **/
8530
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8531
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8532
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8533
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8534
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8535
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8536
8537
static  const gx_color_map_procs pdf14_cmap_many = {
8538
     pdf14_cmap_gray_direct,
8539
     pdf14_cmap_rgb_direct,
8540
     pdf14_cmap_cmyk_direct,
8541
     pdf14_cmap_separation_direct,
8542
     pdf14_cmap_devicen_direct,
8543
     pdf14_cmap_is_halftoned
8544
    };
8545
8546
/**
8547
 * Note: copied from gxcmap.c because it's inlined.
8548
 **/
8549
static  inline void
8550
map_components_to_colorants(const frac * pcc,
8551
                            const gs_devicen_color_map * pcolor_component_map,
8552
                            frac * plist,
8553
                            int num_additives)
8554
3.34M
{
8555
3.34M
    int i = pcolor_component_map->num_colorants - 1;
8556
3.34M
    int pos;
8557
8558
    /* Clear all output colorants first */
8559
16.7M
    for (; i >= num_additives; i--) {
8560
13.3M
        plist[i] = frac_0;
8561
13.3M
    }
8562
3.35M
    for (; i >= 0; i--) {
8563
3.37k
        plist[i] = frac_1;
8564
3.37k
    }
8565
    /* Map color components into output list */
8566
7.01M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8567
3.66M
        pos = pcolor_component_map->color_map[i];
8568
3.66M
        if (pos >= 0) {
8569
3.66M
            if (pos < num_additives)
8570
0
                plist[pos] = frac_1 - pcc[i];
8571
3.66M
            else
8572
3.66M
                plist[pos] = pcc[i];
8573
3.66M
        }
8574
3.66M
    }
8575
3.34M
}
8576
8577
/* See Section 7.6.4 of PDF 1.7 spec */
8578
static inline bool
8579
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8580
202M
{
8581
202M
    if (pgs->fillconstantalpha != 1.0 ||
8582
202M
        pgs->strokeconstantalpha != 1.0 ||
8583
202M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8584
11.3M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8585
12.2M
        return 0;
8586
8587
    /* We can only be opaque if we're not in an SMask. */
8588
190M
    return dev_proc(pdev, dev_spec_op)(pdev,
8589
190M
                                       gxdso_in_smask,
8590
190M
                                       NULL, 0) != 1;
8591
202M
}
8592
8593
static  void
8594
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8595
                       gx_device * dev, gs_color_select_t select)
8596
12.0M
{
8597
12.0M
    int i, nc, ncomps;
8598
12.0M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8599
12.0M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8600
12.0M
    gx_color_index color;
8601
12.0M
    gx_device *trans_device;
8602
12.0M
    const gx_device *map_dev;
8603
12.0M
    const gx_cm_color_map_procs *procs;
8604
8605
    /* If trans device is set, we need to use its procs. */
8606
12.0M
    if (pgs->trans_device != NULL) {
8607
7.11M
        trans_device = pgs->trans_device;
8608
7.11M
    } else {
8609
4.93M
        trans_device = dev;
8610
4.93M
    }
8611
12.0M
    ncomps = trans_device->color_info.num_components;
8612
8613
    /* map to the color model */
8614
12.0M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8615
12.0M
    procs->map_gray(map_dev, gray, cm_comps);
8616
8617
12.0M
    nc = ncomps;
8618
12.0M
    if (device_encodes_tags(trans_device))
8619
0
        nc--;
8620
12.0M
    if (pdf14_state_opaque(trans_device, pgs)) {
8621
9.28M
        for (i = 0; i < nc; i++)
8622
4.64M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8623
7.41M
    } else {
8624
14.8M
        for (i = 0; i < nc; i++)
8625
7.41M
            cv[i] = frac2cv(cm_comps[i]);
8626
7.41M
    }
8627
    /* Copy tags untransformed. */
8628
12.0M
    if (nc < ncomps)
8629
0
        cv[nc] = dev->graphics_type_tag;
8630
8631
    /* If output device supports devn, we need to make sure we send it the
8632
       proper color type.  We now support Gray + spots as devn colors */
8633
12.0M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8634
369k
        for (i = 0; i < ncomps; i++)
8635
184k
            pdc->colors.devn.values[i] = cv[i];
8636
11.8M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8637
11.6M
            pdc->colors.devn.values[i] = 0;
8638
184k
        pdc->type = gx_dc_type_devn;
8639
11.8M
    } else {
8640
        /* encode as a color index */
8641
11.8M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8642
        /* check if the encoding was successful; we presume failure is rare */
8643
11.8M
        if (color != gx_no_color_index)
8644
11.8M
            color_set_pure(pdc, color);
8645
11.8M
    }
8646
12.0M
}
8647
8648
static  void
8649
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8650
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8651
181M
{
8652
181M
    int i, nc, ncomps;
8653
181M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8654
181M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8655
181M
    gx_color_index color;
8656
181M
    gx_device *trans_device;
8657
181M
    const gx_device *map_dev;
8658
181M
    const gx_cm_color_map_procs *procs;
8659
8660
    /* If trans device is set, we need to use its procs. */
8661
181M
    if (pgs->trans_device != NULL){
8662
3.95M
        trans_device = pgs->trans_device;
8663
177M
    } else {
8664
177M
        trans_device = dev;
8665
177M
    }
8666
181M
    ncomps = trans_device->color_info.num_components;
8667
    /* map to the color model */
8668
181M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8669
181M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8670
8671
181M
    nc = ncomps;
8672
181M
    if (device_encodes_tags(trans_device))
8673
0
        nc--;
8674
181M
    if (pdf14_state_opaque(trans_device, pgs)) {
8675
426M
        for (i = 0; i < nc; i++)
8676
320M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8677
106M
    } else {
8678
297M
        for (i = 0; i < nc; i++)
8679
223M
            cv[i] = frac2cv(cm_comps[i]);
8680
74.3M
    }
8681
    /* Copy tags untransformed. */
8682
181M
    if (nc < ncomps)
8683
0
        cv[nc] = dev->graphics_type_tag;
8684
8685
    /* If output device supports devn, we need to make sure we send it the
8686
       proper color type.  We now support RGB + spots as devn colors */
8687
181M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8688
12.0M
        for (i = 0; i < ncomps; i++)
8689
9.05M
            pdc->colors.devn.values[i] = cv[i];
8690
186M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8691
183M
            pdc->colors.devn.values[i] = 0;
8692
3.01M
        pdc->type = gx_dc_type_devn;
8693
178M
    } else {
8694
        /* encode as a color index */
8695
178M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8696
        /* check if the encoding was successful; we presume failure is rare */
8697
178M
        if (color != gx_no_color_index)
8698
178M
            color_set_pure(pdc, color);
8699
178M
    }
8700
181M
}
8701
8702
static  void
8703
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8704
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8705
     const gs_color_space *pcs)
8706
9.81M
{
8707
9.81M
    int i, nc, ncomps;
8708
9.81M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8709
9.81M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8710
9.81M
    gx_color_index color;
8711
9.81M
    gx_device *trans_device;
8712
9.81M
    const gx_device *map_dev;
8713
9.81M
    const gx_cm_color_map_procs *procs;
8714
8715
8716
    /* If trans device is set, we need to use its procs. */
8717
9.81M
    if (pgs->trans_device != NULL){
8718
7.16M
        trans_device = pgs->trans_device;
8719
7.16M
    } else {
8720
2.64M
        trans_device = dev;
8721
2.64M
    }
8722
9.81M
    ncomps = trans_device->color_info.num_components;
8723
8724
    /* Map to the color model. Transfer function is only used
8725
       if we are drawing with an opaque color. */
8726
9.81M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8727
9.81M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8728
8729
9.81M
    nc = ncomps;
8730
9.81M
    if (device_encodes_tags(trans_device))
8731
0
        nc--;
8732
9.81M
    if (pdf14_state_opaque(trans_device, pgs)) {
8733
41.6M
        for (i = 0; i < nc; i++)
8734
33.3M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8735
8.33M
    } else {
8736
7.36M
        for (i = 0; i < nc; i++)
8737
5.88M
            cv[i] = frac2cv(cm_comps[i]);
8738
1.47M
    }
8739
    /* Copy tags untransformed. */
8740
9.81M
    if (nc < ncomps)
8741
0
        cv[nc] = dev->graphics_type_tag;
8742
8743
    /* if output device supports devn, we need to make sure we send it the
8744
       proper color type */
8745
9.81M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8746
15.0M
        for (i = 0; i < ncomps; i++)
8747
12.0M
            pdc->colors.devn.values[i] = cv[i];
8748
184M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8749
181M
            pdc->colors.devn.values[i] = 0;
8750
3.01M
        pdc->type = gx_dc_type_devn;
8751
6.79M
    } else {
8752
        /* encode as a color index */
8753
6.79M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8754
        /* check if the encoding was successful; we presume failure is rare */
8755
6.79M
        if (color != gx_no_color_index)
8756
6.79M
            color_set_pure(pdc, color);
8757
6.79M
    }
8758
9.81M
}
8759
8760
static int
8761
pdf14_get_num_spots(gx_device * dev)
8762
3.34M
{
8763
3.34M
    cmm_dev_profile_t *dev_profile;
8764
3.34M
    cmm_profile_t *icc_profile;
8765
3.34M
    gsicc_rendering_param_t render_cond;
8766
8767
3.34M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8768
3.34M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8769
3.34M
        &render_cond);
8770
3.34M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8771
3.34M
}
8772
8773
static  void
8774
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8775
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8776
1.60k
{
8777
1.60k
    int i, nc, ncomps = dev->color_info.num_components;
8778
1.60k
    int num_spots = pdf14_get_num_spots(dev);
8779
1.60k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8780
1.60k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8781
1.60k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8782
1.60k
    gx_color_index color;
8783
1.60k
    int n = 0;
8784
8785
1.60k
    nc = ncomps;
8786
1.60k
    if (device_encodes_tags(dev))
8787
0
        nc--;
8788
8789
1.60k
    n = additive ? nc - num_spots : 0;
8790
1.60k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8791
0
        frac comp_value = all;
8792
8793
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8794
0
            cm_comps[i] = comp_value;
8795
        /*
8796
         * Invert the photometric interpretation for additive
8797
         * color spaces because separations are always subtractive.
8798
         */
8799
0
        if (additive)
8800
0
            comp_value = frac_1 - comp_value;
8801
        /* Use the "all" value for all components */
8802
0
        for (; i >= 0; i--)
8803
0
            cm_comps[i] = comp_value;
8804
1.60k
    } else {
8805
1.60k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8806
8807
1.60k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8808
0
            color_set_null(pdc);
8809
0
            return;
8810
0
        }
8811
8812
        /* map to the color model */
8813
3.21k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8814
1.60k
            comp_value[i] = all;
8815
1.60k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8816
1.60k
    }
8817
8818
    /* apply the transfer function(s); convert to color values */
8819
4.98k
    for (i = 0; i < n; i++)
8820
3.37k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8821
4.67k
    for (; i < nc; i++)
8822
3.06k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8823
8824
    /* Copy tags untransformed. */
8825
1.60k
    if (nc < ncomps)
8826
0
        cv[nc] = dev->graphics_type_tag;
8827
8828
    /* if output device supports devn, we need to make sure we send it the
8829
       proper color type */
8830
1.60k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8831
8.04k
        for (i = 0; i < ncomps; i++)
8832
6.43k
            pdc->colors.devn.values[i] = cv[i];
8833
98.1k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8834
96.5k
            pdc->colors.devn.values[i] = 0;
8835
1.60k
        pdc->type = gx_dc_type_devn;
8836
1.60k
    } else {
8837
        /* encode as a color index */
8838
0
        color = dev_proc(dev, encode_color)(dev, cv);
8839
        /* check if the encoding was successful; we presume failure is rare */
8840
0
        if (color != gx_no_color_index)
8841
0
            color_set_pure(pdc, color);
8842
0
    }
8843
1.60k
}
8844
8845
static  void
8846
pdf14_cmap_devicen_direct(const frac * pcc,
8847
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8848
    gs_color_select_t select, const gs_color_space *pcs)
8849
3.34M
{
8850
3.34M
    int i, nc, ncomps = dev->color_info.num_components;
8851
3.34M
    int num_spots = pdf14_get_num_spots(dev);
8852
3.34M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8853
3.34M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8854
3.34M
    gx_color_index color;
8855
3.34M
    gx_device *trans_device;
8856
3.34M
    int num_add_colorants = 0;
8857
8858
     /*  We may be coming from the clist writer which often forwards us the
8859
         target device. If this occurs we actually need to get to the color
8860
         space defined by the transparency group and we use the operators
8861
         defined by the transparency device to do the job.
8862
       */
8863
3.34M
    if (pgs->trans_device != NULL){
8864
3.34M
        trans_device = pgs->trans_device;
8865
3.34M
    } else {
8866
0
        trans_device = dev;
8867
0
    }
8868
3.34M
    ncomps = trans_device->color_info.num_components;
8869
3.34M
    nc = ncomps;
8870
3.34M
    if (device_encodes_tags(trans_device))
8871
0
        nc--;
8872
8873
3.34M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8874
0
        num_add_colorants = nc - num_spots;
8875
8876
    /* map to the color model */
8877
3.34M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8878
8879
    /* apply the transfer function(s); convert to color values */
8880
    /* The additive ones (if there are any) need to be inverted. */
8881
3.34M
    for (i = 0; i < num_add_colorants; i++)
8882
3.34M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8883
16.7M
    for (; i < nc; i++)
8884
13.3M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8885
    /* Copy tags untransformed. */
8886
3.34M
    if (nc < ncomps)
8887
0
        cv[nc] = dev->graphics_type_tag;
8888
8889
    /* if output device supports devn, we need to make sure we send it the
8890
       proper color type */
8891
3.34M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8892
1.31M
        for (i = 0; i < ncomps; i++)
8893
1.05M
            pdc->colors.devn.values[i] = cv[i];
8894
16.0M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8895
15.7M
            pdc->colors.devn.values[i] = 0;
8896
262k
        pdc->type = gx_dc_type_devn;
8897
3.08M
    } else {
8898
    /* encode as a color index */
8899
3.08M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8900
        /* check if the encoding was successful; we presume failure is rare */
8901
3.08M
        if (color != gx_no_color_index)
8902
3.08M
            color_set_pure(pdc, color);
8903
3.08M
    }
8904
3.34M
}
8905
8906
static  bool
8907
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8908
45.0k
{
8909
45.0k
    return false;
8910
45.0k
}
8911
8912
static  const gx_color_map_procs *
8913
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8914
1.76M
{
8915
    /* The pdf14 marking device itself is always continuous tone. */
8916
1.76M
    return &pdf14_cmap_many;
8917
1.76M
}
8918
8919
static int
8920
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8921
                  void *data, int size)
8922
450M
{
8923
450M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8924
8925
450M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8926
825k
        return 1;
8927
449M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8928
4.83k
        return 1;
8929
449M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8930
1.11k
        if (data != NULL && size == sizeof(gx_device *))
8931
522
            *(gx_device **)data = pdev;
8932
1.11k
        return 1;
8933
1.11k
    }
8934
449M
    if (dev_spec_op == gxdso_device_child) {
8935
2.63k
        pdf14_device *dev = (pdf14_device *)pdev;
8936
2.63k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8937
2.63k
        if (d->target == pdev) {
8938
2.63k
            d->target = dev->target;
8939
2.63k
            return 1;
8940
2.63k
        }
8941
2.63k
    }
8942
449M
    if (dev_spec_op == gxdso_supports_devn
8943
231M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8944
231M
        cmm_dev_profile_t *dev_profile;
8945
231M
        int code;
8946
231M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8947
231M
        if (code == 0) {
8948
231M
            return dev_profile->supports_devn;
8949
231M
        } else {
8950
0
            return 0;
8951
0
        }
8952
231M
    }
8953
217M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8954
314k
        pdf14_device* dev = (pdf14_device*)pdev;
8955
8956
314k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8957
314k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8958
161k
            return 1;
8959
153k
        return 0;
8960
314k
    }
8961
217M
    if (dev_spec_op == gxdso_is_encoding_direct)
8962
370k
        return 1;
8963
8964
    /* We don't want to pass on these spec_ops either, because the child might respond
8965
     * with an inappropriate response when the PDF14 device is active. For example; the
8966
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8967
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8968
     */
8969
216M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8970
394k
        return 0;
8971
216M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8972
217k
        return 0;
8973
216M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8974
4.83k
        return 0;
8975
216M
    if(dev_spec_op == gxdso_supports_hlcolor)
8976
1.26k
        return 0;
8977
216M
    if(dev_spec_op == gxdso_pattern_can_accum)
8978
96.4k
        return 0;
8979
215M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8980
1.63k
        return 0;
8981
215M
    if (dev_spec_op == gxdso_overprint_active) {
8982
3.62M
        if (p14dev->pclist_device != NULL) {
8983
3.61M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8984
3.61M
        } else {
8985
9.99k
            return p14dev->overprint || p14dev->stroke_overprint;
8986
9.99k
        }
8987
3.62M
    }
8988
8989
    /* These should be coming only from the abuf device
8990
       during fill-stroke operation. Any other use will
8991
       result in bad things. */
8992
212M
    if (dev_spec_op == gxdso_abuf_optrans)
8993
0
    {
8994
0
        int ret = p14dev->op_state;
8995
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
8996
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
8997
0
        const gs_gstate* cpgs = state_data->pgs;
8998
0
        union {
8999
0
            const gs_gstate* cpgs;
9000
0
            gs_gstate* pgs;
9001
0
        } const_breaker;
9002
0
        gs_gstate* pgs;
9003
0
        int code = 0;
9004
0
        int code1 = 0;
9005
9006
        /* A compile time assert to check our storage types are appropriately sized. */
9007
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9008
9009
        /* I don't really like this, but there is no easy way around it. The device
9010
           in the pgs needs to be the pdf14 device to ensure that the compositor
9011
           actions occur with the gs_transparency calls. We have to call at that
9012
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9013
           operations are invoked. We could change the gs_trans calls to take a
9014
           device to avoid this dance but that changes the device procs. */
9015
0
        gx_device *curr_dev;
9016
9017
0
        const_breaker.cpgs = cpgs;
9018
0
        pgs = const_breaker.pgs;
9019
0
        curr_dev = pgs->device;
9020
0
        pgs->device = pdev;
9021
9022
0
        switch (state_data->op_trans) {
9023
9024
0
            case OP_FS_TRANS_PREFILL:
9025
0
                pdf14_abuf->orig_state = p14dev->op_state;
9026
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9027
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9028
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9029
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9030
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9031
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9032
0
                    pdf14_abuf->group_needed = false;
9033
0
                else
9034
0
                    pdf14_abuf->group_needed = true;
9035
9036
0
                if (pdf14_abuf->group_needed) {
9037
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9038
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9039
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9040
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9041
0
                        state_data->alpha_buf_path_scale);
9042
0
                    if (code < 0)
9043
0
                        goto cleanup;
9044
0
                    if (pdf14_abuf->path_empty)
9045
0
                        pdf14_abuf->group_needed = 0;
9046
0
                }
9047
0
                code = gs_update_trans_marking_params(pgs);
9048
0
                break;
9049
9050
0
            case OP_FS_TRANS_PRESTROKE:
9051
0
                if (pdf14_abuf->group_needed) {
9052
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9053
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9054
0
                }
9055
0
                code = gs_update_trans_marking_params(pgs);
9056
0
                break;
9057
9058
0
            case OP_FS_TRANS_POSTSTROKE:
9059
0
                if (pdf14_abuf->group_needed) {
9060
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9061
0
                                                        pdf14_abuf->op_ca_eq_CA);
9062
0
                }
9063
0
                if (code >= 0)
9064
0
                    code = gs_update_trans_marking_params(pgs);
9065
9066
                /* fallthrough */
9067
9068
0
            case OP_FS_TRANS_CLEANUP:
9069
0
cleanup:
9070
0
                if (pdf14_abuf->group_needed) {
9071
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9072
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9073
0
                    if (code1 < 0)
9074
0
                        code = gs_note_error(gs_error_Fatal);
9075
0
                }
9076
0
                break;
9077
0
        }
9078
0
        pgs->device = curr_dev;
9079
9080
0
        return (code < 0) ? code : ret;
9081
0
    }
9082
9083
212M
    if (dev_spec_op == gxdso_in_smask_construction)
9084
3.76M
        return p14dev->in_smask_construction > 0;
9085
208M
    if (dev_spec_op == gxdso_in_smask)
9086
191M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9087
17.4M
    if (dev_spec_op == gxdso_replacecolor) {
9088
17.3M
        gx_device *tdev = p14dev->target;
9089
17.3M
        cmm_dev_profile_t *tdev_profile;
9090
17.3M
        int code;
9091
9092
         /* If in a softmask or softmask construction do not allow
9093
           replacement. */
9094
17.3M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9095
2.72M
            return 0;
9096
9097
        /* If the target CS is different than the pdf14 profile add this information
9098
           for the target device that will be handling the replacement. While not
9099
           perfect this at least lets you do the replacehment and have some information
9100
           about what the situation is. */
9101
14.5M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9102
14.5M
        if (code != 0)
9103
0
            return 0;
9104
9105
14.5M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9106
14.5M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9107
7.33M
            color_replace_t* replace_data = (color_replace_t*)data;
9108
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9109
               color remap operation. */
9110
7.33M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9111
7.33M
        }
9112
9113
        /* Pass on to target device */
9114
14.5M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9115
14.5M
    }
9116
186k
    if (dev_spec_op == gxdso_device_insert_child) {
9117
168
        gx_device *tdev = p14dev->target;
9118
168
        p14dev->target = (gx_device *)data;
9119
168
        rc_increment(p14dev->target);
9120
168
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9121
168
        return 0;
9122
168
    }
9123
186k
    if (dev_spec_op == gxdso_interpolate_threshold)
9124
5.21k
        return p14dev->interpolate_threshold;
9125
9126
181k
    if (dev_spec_op == gxdso_overprintsim_state) {
9127
5.20k
        unsigned char *data_uchar = (unsigned char *) data;
9128
5.20k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9129
5.20k
        if (p14dev->ctx != NULL)
9130
16
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9131
5.19k
        else
9132
5.19k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9133
5.20k
        return 1;
9134
5.20k
    }
9135
9136
176k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9137
181k
}
9138
9139
/* Needed to set color monitoring in the target device's profile */
9140
int
9141
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9142
0
{
9143
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9144
0
    gx_device *targ = p14dev->target;
9145
0
    cmm_dev_profile_t *dev_profile;
9146
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9147
9148
0
    if (code == 0)
9149
0
        dev_profile->pageneutralcolor = monitoring;
9150
0
    return code;
9151
0
}
9152
9153
static int
9154
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9155
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9156
1.14M
{
9157
1.14M
    pdf14_device dev_proto;
9158
1.14M
    pdf14_device * p14dev;
9159
1.14M
    int code;
9160
1.14M
    bool has_tags;
9161
1.14M
    cmm_profile_t *icc_profile;
9162
1.14M
    gsicc_rendering_param_t render_cond;
9163
1.14M
    cmm_dev_profile_t *dev_profile;
9164
1.14M
    uchar k;
9165
1.14M
    int max_bitmap;
9166
1.14M
    bool use_pdf14_accum = false;
9167
1.14M
    bool deep;
9168
9169
    /* Guard against later seg faults, this should not be possible */
9170
1.14M
    if (target == NULL)
9171
0
        return gs_throw_code(gs_error_Fatal);
9172
9173
1.14M
    has_tags = device_encodes_tags(target);
9174
1.14M
    deep = device_is_deep(target);
9175
1.14M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9176
1.14M
                                 target->space_params.MaxBitmap;
9177
    /* If the device is not a printer class device, it won't support saved-pages */
9178
    /* and so we may need to make a clist device in order to prevent very large  */
9179
    /* or high resolution pages from having allocation problems.                 */
9180
    /* We use MaxBitmap to decide when a clist is needed.*/
9181
1.14M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9182
5.69k
        gx_device_is_pattern_clist(target) == 0 &&
9183
5.69k
        gx_device_is_pattern_accum(target) == 0 &&
9184
4.24k
        gs_device_is_memory(target) == 0) {
9185
9186
4.24k
        uint32_t pdf14_trans_buffer_size =
9187
4.24k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9188
4.24k
                                         target->color_info.num_components,
9189
4.24k
                                         deep ? 16 : 8) >> 3);
9190
9191
4.24k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9192
4.24k
                pdf14_trans_buffer_size *= target->height;
9193
0
        else
9194
0
                max_bitmap = 0;     /* Force decision to clist */
9195
4.24k
        if (pdf14_trans_buffer_size > max_bitmap)
9196
3.96k
            use_pdf14_accum = true;
9197
4.24k
    }
9198
1.14M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9199
1.14M
    if (code < 0)
9200
0
        return code;
9201
1.14M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9202
1.14M
                          &render_cond);
9203
1.14M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9204
9205
    /* Get the proto from which to copy the device. This will always
9206
     * ignore tags! */
9207
1.14M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9208
1.14M
                                  pdf14pct, use_pdf14_accum);
9209
1.14M
    if (code < 0)
9210
0
        return code;
9211
1.14M
    code = gs_copydevice((gx_device **) &p14dev,
9212
1.14M
                         (const gx_device *) &dev_proto, mem);
9213
1.14M
    if (code < 0)
9214
0
        return code;
9215
9216
1.14M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9217
9218
    /* Copying the params across will add tags to the colorinfo as required. */
9219
1.14M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9220
1.14M
    if (code < 0)
9221
0
        return code;
9222
9223
1.14M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9224
1.14M
    p14dev->pad = target->pad;
9225
1.14M
    p14dev->log2_align_mod = target->log2_align_mod;
9226
1.14M
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0) {
9227
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9228
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9229
0
    }
9230
1.14M
    else if (pdf14pct->params.overprint_sim_push && target->num_planar_planes != 0) {
9231
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9232
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9233
0
    }
9234
1.14M
    else
9235
1.14M
    {
9236
1.14M
        p14dev->color_info.num_components = target->color_info.num_components;
9237
1.14M
        p14dev->num_planar_planes = target->num_planar_planes;
9238
1.14M
    }
9239
1.14M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9240
9241
1.14M
    p14dev->alpha = 1.0;
9242
1.14M
    p14dev->shape = 1.0;
9243
1.14M
    p14dev->opacity = 1.0;
9244
1.14M
    p14dev->fillconstantalpha = 1.0;
9245
1.14M
    p14dev->strokeconstantalpha = 1.0;
9246
9247
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9248
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9249
       do the mapping to the NCLR profile when the put_image occurs */
9250
1.14M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9251
1.14M
        icc_profile->data_cs == gsNCHANNEL) {
9252
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9253
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9254
0
            -1, "gs_pdf14_device_push");
9255
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9256
1.14M
    } else {
9257
        /* If the target profile was CIELAB (and we are not using a blend CS),
9258
           then overide with default RGB for proper blending.  During put_image
9259
           we will convert from RGB to CIELAB.  Need to check that we have a
9260
           default profile, which will not be the case if we are coming from the clist reader */
9261
1.14M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9262
0
            && pgs->icc_manager->default_rgb != NULL &&
9263
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9264
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9265
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9266
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9267
0
                -1, "gs_pdf14_device_push");
9268
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9269
0
        }
9270
1.14M
    }
9271
9272
1.14M
    if (pdf14pct->params.overprint_sim_push &&
9273
0
        pdf14pct->params.num_spot_colors_int > 0) {
9274
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9275
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9276
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9277
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9278
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9279
0
    }
9280
9281
    /* The number of color planes should not exceed that of the target.
9282
       Unless we are using a blend CS */
9283
1.14M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9284
1.14M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9285
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9286
1.14M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9287
70.7k
            p14dev->color_info.max_components = target->color_info.max_components;
9288
1.14M
    }
9289
1.14M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9290
    /* If we have a tag device then go ahead and do a special encoder
9291
       decoder for the pdf14 device to make sure we maintain this
9292
       information in the encoded color information.  We could use
9293
       the target device's methods but the PDF14 device has to maintain
9294
       8 bit color always and we could run into other issues if the number
9295
       of colorants became large.  If we need to do compressed color with
9296
       tags that will be a special project at that time */
9297
1.14M
    if (deep) {
9298
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9299
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9300
0
    }
9301
1.14M
    if (has_tags) {
9302
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9303
0
    }
9304
    /* if the device has separations already defined (by SeparationOrderNames) */
9305
    /* we need to copy them (allocating new names) so the colorants are in the */
9306
    /* same order as the target device.                                        */
9307
1.14M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9308
70.8k
        code = devn_copy_params(target, (gx_device *)p14dev);
9309
70.8k
        if (code < 0) {
9310
50
            *pdev = NULL;
9311
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9312
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9313
50
            return code;
9314
50
        }
9315
70.8k
    }
9316
    /* by definition pdf14_encode _is_ standard */
9317
1.14M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9318
1.14M
    gx_device_fill_in_procs((gx_device *)p14dev);
9319
1.14M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9320
1.14M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9321
1.14M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9322
9323
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9324
3.80M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9325
2.66M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9326
2.66M
        p14dev->color_info.comp_shift[k] =
9327
2.66M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9328
2.66M
    }
9329
1.14M
    if (use_pdf14_accum) {
9330
        /* we will disable this device later, but we don't want to allocate large buffers */
9331
3.96k
        p14dev->width = 1;
9332
3.96k
        p14dev->height = 1;
9333
3.96k
    }
9334
9335
1.14M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9336
1.14M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9337
1.14M
    *pdev = (gx_device *) p14dev;
9338
1.14M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9339
1.14M
    p14dev->color_model_stack = NULL;
9340
9341
    /* In case we have alphabits set */
9342
1.14M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9343
9344
1.14M
    if (pdf14pct->params.is_pattern) {
9345
6.30k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9346
6.30k
        if (code < 0) {
9347
0
            *pdev = NULL;
9348
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9349
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9350
0
            return code;
9351
0
        }
9352
6.30k
    }
9353
9354
    /* We should never go into this when using a blend color space */
9355
1.14M
    if (use_pdf14_accum) {
9356
3.96k
        const gx_device_pdf14_accum *accum_proto = NULL;
9357
3.96k
        gx_device *new_target = NULL;
9358
3.96k
        gx_device_color pdcolor;
9359
3.96k
        frac pconc_white = frac_1;
9360
3.96k
        bool UsePlanarBuffer = false;
9361
9362
3.96k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9363
9364
        /* get the prototype for the accumulator device based on colorspace */
9365
3.96k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9366
960
            case 1:
9367
960
                accum_proto = &pdf14_accum_Gray;
9368
960
                break;
9369
3.00k
            case 3:
9370
3.00k
                accum_proto = &pdf14_accum_RGB;
9371
3.00k
                break;
9372
0
            case 4:
9373
0
                accum_proto = &pdf14_accum_CMYK;
9374
0
                break;
9375
0
            default:
9376
0
                accum_proto = &pdf14_accum_CMYKspot;
9377
0
                UsePlanarBuffer = true;
9378
3.96k
        }
9379
3.96k
        if (accum_proto == NULL ||
9380
3.96k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9381
0
            goto no_clist_accum;
9382
9383
3.96k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9384
        /* Fill in values from the target device before opening */
9385
3.96k
        new_target->color_info = p14dev->color_info;
9386
3.96k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9387
3.96k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9388
3.96k
        set_linear_color_bits_mask_shift(new_target);
9389
3.96k
        gs_pdf14_device_copy_params(new_target, target);
9390
3.96k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9391
3.96k
        gx_device_fill_in_procs(new_target);
9392
9393
3.96k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9394
3.96k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9395
3.96k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9396
9397
        /* This is used to mark the various internal subclass devices as having already
9398
         * been pushed, so that opening the device won't result in us trying to push
9399
         * them again, which leads to trouble.
9400
         */
9401
3.96k
        code = mark_internal_subclass_devices(new_target);
9402
3.96k
        if (code < 0)
9403
0
            return code;
9404
9405
        /* if the device has separations already defined (by SeparationOrderNames) */
9406
        /* we need to copy them (allocating new names) so the colorants are in the */
9407
        /* same order as the target device.                                        */
9408
3.96k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9409
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9410
0
            if (code < 0)
9411
0
                return code;
9412
0
        }
9413
        /* UsePlanarBuffer is true in case this is CMYKspot */
9414
3.96k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9415
3.96k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9416
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9417
0
            goto no_clist_accum;
9418
0
        }
9419
        /* Do the initial fillpage into the pdf14-accum device we just created */
9420
3.96k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9421
3.96k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9422
3.96k
                                            &pconc_white,
9423
3.96k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9424
3.96k
                                            dev_profile)) < 0)
9425
0
            goto no_clist_accum;
9426
9427
3.96k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9428
3.96k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9429
3.96k
        if (code < 0)
9430
0
            goto no_clist_accum;
9431
9432
3.96k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9433
3.96k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9434
3.96k
    }
9435
1.14M
    return code;
9436
9437
0
no_clist_accum:
9438
        /* FIXME: We allocated a really small p14dev, but that won't work */
9439
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9440
1.14M
}
9441
9442
/*
9443
 * In a modest violation of good coding practice, the gs_composite_common
9444
 * fields are "known" to be simple (contain no pointers to garbage
9445
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9446
 * to be simple, so we just create a trivial structure descriptor for the
9447
 * entire gs_pdf14trans_s structure.
9448
 */
9449
#define private_st_gs_pdf14trans_t()\
9450
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9451
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9452
9453
/* GC descriptor for gs_pdf14trans_t */
9454
private_st_gs_pdf14trans_t();
9455
9456
/*
9457
 * Check for equality of two PDF 1.4 transparency compositor objects.
9458
 *
9459
 * We are currently always indicating that PDF 1.4 transparency compositors are
9460
 * equal.  Two transparency compositors may have teh same data but still
9461
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9462
 * operations in a row mean that we are creating a group inside of a group.
9463
 */
9464
static  bool
9465
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9466
0
{
9467
0
    return false;
9468
0
}
9469
9470
#ifdef DEBUG
9471
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9472
#endif
9473
9474
#define put_value(dp, value)\
9475
7.21M
    BEGIN\
9476
7.21M
        memcpy(dp, &value, sizeof(value));\
9477
7.21M
        dp += sizeof(value);\
9478
7.21M
    END
9479
9480
static inline int
9481
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9482
903k
{
9483
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9484
       because clist writer may skip this command for some bands.
9485
       For a better result we need individual CTM for each band.
9486
     */
9487
903k
    byte *pbuf = *ppbuf;
9488
903k
    int len, code;
9489
9490
903k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9491
903k
    pbuf--; /* For cmd_write_ctm. */
9492
903k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9493
903k
    if (code < 0)
9494
0
        return code;
9495
903k
    pbuf += len + 1;
9496
903k
    *ppbuf = pbuf;
9497
903k
    return 0;
9498
903k
}
9499
9500
/*
9501
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9502
 * list device. This is also where we update the pdf14_needed. When set the clist
9503
 * painting procs will update the trans_bbox state for bands that are affected.
9504
*/
9505
static  int
9506
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9507
                   gx_device_clist_writer *cdev)
9508
2.05M
{
9509
2.05M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9510
2.05M
    int need, avail = *psize;
9511
2.05M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9512
        to fit the data written below. We don't implement a dynamic check for
9513
        the buffer owerflow, assuming that the consistency is verified in the
9514
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9515
2.05M
    byte * pbuf = buf;
9516
2.05M
    int opcode = pparams->pdf14_op;
9517
2.05M
    int mask_size = 0;
9518
2.05M
    uint mask_id = 0;
9519
2.05M
    int code;
9520
2.05M
    bool found_icc;
9521
2.05M
    int64_t hashcode = 0;
9522
2.05M
    cmm_profile_t *icc_profile;
9523
2.05M
    gsicc_rendering_param_t render_cond;
9524
2.05M
    cmm_dev_profile_t *dev_profile;
9525
    /* We maintain and update working copies until we actually write the clist */
9526
2.05M
    int pdf14_needed = cdev->pdf14_needed;
9527
2.05M
    int trans_group_level = cdev->pdf14_trans_group_level;
9528
2.05M
    int smask_level = cdev->pdf14_smask_level;
9529
2.05M
    bool deep = device_is_deep((gx_device *)cdev);
9530
9531
2.05M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9532
2.05M
                                                     &dev_profile);
9533
2.05M
    if (code < 0)
9534
0
        return code;
9535
2.05M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9536
2.05M
                          &render_cond);
9537
2.05M
    *pbuf++ = opcode;     /* 1 byte */
9538
2.05M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9539
5
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9540
9541
2.05M
    switch (opcode) {
9542
0
        default:      /* Should not occur. */
9543
0
            break;
9544
22.4k
        case PDF14_PUSH_DEVICE:
9545
22.4k
            trans_group_level = 0;
9546
22.4k
            cdev->pdf14_smask_level = 0;
9547
22.4k
            cdev->page_pdf14_needed = false;
9548
22.4k
            put_value(pbuf, pparams->num_spot_colors);
9549
22.4k
            put_value(pbuf, pparams->num_spot_colors_int);
9550
22.4k
            put_value(pbuf, pparams->overprint_sim_push);
9551
22.4k
            put_value(pbuf, pparams->is_pattern);
9552
9553
            /* If we happen to be going to a color space like CIELAB then
9554
               we are going to do our blending in default RGB and convert
9555
               to CIELAB at the end.  To do this, we need to store the
9556
               default RGB profile in the clist so that we can grab it
9557
               later on during the clist read back and put image command */
9558
22.4k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9559
                /* Get the default RGB profile.  Set the device hash code
9560
                   so that we can extract it during the put_image operation. */
9561
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9562
0
                found_icc =
9563
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9564
0
                if (!found_icc) {
9565
                    /* Add it to the table */
9566
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9567
0
                                       pparams->iccprofile);
9568
0
                }
9569
0
            }
9570
22.4k
            break;
9571
21.6k
        case PDF14_POP_DEVICE:
9572
21.6k
            pdf14_needed = false;   /* reset pdf14_needed */
9573
21.6k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9574
21.6k
            smask_level = 0;
9575
21.6k
            put_value(pbuf, pparams->is_pattern);
9576
21.6k
            break;
9577
489k
        case PDF14_END_TRANS_GROUP:
9578
495k
        case PDF14_END_TRANS_TEXT_GROUP:
9579
495k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9580
495k
            if (smask_level == 0 && trans_group_level == 0)
9581
29.0k
                pdf14_needed = cdev->page_pdf14_needed;
9582
495k
            break;      /* No data */
9583
8.03k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9584
495k
        case PDF14_BEGIN_TRANS_GROUP:
9585
495k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9586
495k
            trans_group_level++;
9587
495k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9588
495k
            if (code < 0)
9589
0
                return code;
9590
495k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9591
495k
            *pbuf++ = pparams->blend_mode;
9592
495k
            *pbuf++ = pparams->group_color_type;
9593
495k
            *pbuf++ = pparams->page_group;
9594
495k
            put_value(pbuf, pparams->group_color_numcomps);
9595
495k
            put_value(pbuf, pparams->opacity);
9596
495k
            put_value(pbuf, pparams->shape);
9597
495k
            put_value(pbuf, pparams->bbox);
9598
495k
            put_value(pbuf, pparams->shade_group);
9599
495k
            put_value(pbuf, pparams->text_group);
9600
495k
            mask_id = pparams->mask_id;
9601
495k
            put_value(pbuf, mask_id);
9602
            /* Color space information maybe ICC based
9603
               in this case we need to store the ICC
9604
               profile or the ID if it is cached already */
9605
495k
            if (pparams->group_color_type == ICC) {
9606
                /* Check if it is already in the ICC clist table */
9607
12.2k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9608
12.2k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9609
12.2k
                if (!found_icc) {
9610
                    /* Add it to the table */
9611
4.24k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9612
4.24k
                    put_value(pbuf, hashcode);
9613
7.97k
                } else {
9614
                    /* It will be in the clist. Just write out the hashcode */
9615
7.97k
                    put_value(pbuf, hashcode);
9616
7.97k
                }
9617
483k
            } else {
9618
483k
                put_value(pbuf, hashcode);
9619
483k
            }
9620
495k
            break;
9621
407k
        case PDF14_BEGIN_TRANS_MASK:
9622
407k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9623
348k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9624
348k
                smask_level++;
9625
348k
            }
9626
407k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9627
407k
            if (code < 0)
9628
0
                return code;
9629
407k
            put_value(pbuf, pparams->subtype);
9630
407k
            *pbuf++ = pparams->group_color_type;
9631
407k
            put_value(pbuf, pparams->group_color_numcomps);
9632
407k
            *pbuf++ = pparams->replacing;
9633
407k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9634
407k
            *pbuf++ = pparams->Background_components;
9635
407k
            *pbuf++ = pparams->Matte_components;
9636
407k
            put_value(pbuf, pparams->bbox);
9637
407k
            mask_id = pparams->mask_id;
9638
407k
            put_value(pbuf, mask_id);
9639
407k
            if (pparams->Background_components) {
9640
1.18k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9641
9642
1.18k
                memcpy(pbuf, pparams->Background, l);
9643
1.18k
                pbuf += l;
9644
1.18k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9645
1.18k
                pbuf += sizeof(pparams->GrayBackground);
9646
1.18k
            }
9647
407k
            if (pparams->Matte_components) {
9648
105
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9649
9650
105
                memcpy(pbuf, pparams->Matte, m);
9651
105
                pbuf += m;
9652
105
            }
9653
407k
            if (!pparams->function_is_identity)
9654
1.36k
                mask_size = (256+deep)<<deep;
9655
            /* Color space information may be ICC based
9656
               in this case we need to store the ICC
9657
               profile or the ID if it is cached already */
9658
407k
            if (pparams->group_color_type == ICC) {
9659
                /* Check if it is already in the ICC clist table */
9660
348k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9661
348k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9662
348k
                if (!found_icc) {
9663
                    /* Add it to the table */
9664
2.76k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9665
2.76k
                    put_value(pbuf, hashcode);
9666
346k
                } else {
9667
                    /* It will be in the clist. Just write out the hashcode */
9668
346k
                    put_value(pbuf, hashcode);
9669
346k
                }
9670
348k
            } else {
9671
58.7k
                put_value(pbuf, hashcode);
9672
58.7k
            }
9673
407k
            break;
9674
348k
        case PDF14_END_TRANS_MASK:
9675
348k
            smask_level--;
9676
348k
            if (smask_level == 0 && trans_group_level == 0)
9677
8.28k
                pdf14_needed = cdev->page_pdf14_needed;
9678
348k
            break;
9679
215k
        case PDF14_SET_BLEND_PARAMS:
9680
215k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9681
0
                pparams->shape != 1.0)
9682
215k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9683
0
            else if (smask_level == 0 && trans_group_level == 0)
9684
0
                pdf14_needed = false;   /* At page level, set back to false */
9685
215k
            if (smask_level == 0 && trans_group_level == 0)
9686
83.1k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9687
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9688
215k
            put_value(pbuf, pparams->changed);
9689
215k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9690
43.8k
                *pbuf++ = pparams->blend_mode;
9691
215k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9692
20.9k
                *pbuf++ = pparams->text_knockout;
9693
215k
            if (pparams->changed & PDF14_SET_AIS)
9694
215k
                put_value(pbuf, pparams->ais);
9695
215k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9696
215k
                put_value(pbuf, pparams->overprint);
9697
215k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9698
215k
                put_value(pbuf, pparams->stroke_overprint);
9699
215k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9700
215k
                put_value(pbuf, pparams->fillconstantalpha);
9701
215k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9702
215k
                put_value(pbuf, pparams->strokeconstantalpha);
9703
215k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9704
215k
                put_value(pbuf, pparams->op_fs_state);
9705
215k
            break;
9706
0
        case PDF14_PUSH_TRANS_STATE:
9707
0
            break;
9708
51.0k
        case PDF14_POP_TRANS_STATE:
9709
51.0k
            break;
9710
0
        case PDF14_PUSH_SMASK_COLOR:
9711
0
            return 0;   /* We really should never be here */
9712
0
            break;
9713
0
        case PDF14_POP_SMASK_COLOR:
9714
0
            return 0;   /* We really should never be here */
9715
0
            break;
9716
2.05M
    }
9717
9718
    /* check for fit */
9719
2.05M
    need = (pbuf - buf) + mask_size;
9720
2.05M
    *psize = need;
9721
2.05M
    if (need > avail) {
9722
300k
        if (avail)
9723
0
            return_error(gs_error_rangecheck);
9724
300k
        else
9725
300k
            return gs_error_rangecheck;
9726
300k
    }
9727
9728
    /* If we are writing more than the maximum ever expected,
9729
     * return a rangecheck error. Second check is for Coverity
9730
     */
9731
1.75M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9732
1.75M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9733
0
        return_error(gs_error_rangecheck);
9734
9735
    /* Copy our serialized data into the output buffer */
9736
1.75M
    memcpy(data, buf, need - mask_size);
9737
1.75M
    if (mask_size)  /* Include the transfer mask data if present */
9738
1.05k
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9739
1.75M
    if_debug3m('v', cdev->memory,
9740
1.75M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9741
1.75M
               pdf14_opcode_names[opcode], mask_id, need);
9742
1.75M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9743
1.75M
    cdev->pdf14_trans_group_level = trans_group_level;
9744
1.75M
    cdev->pdf14_smask_level = smask_level;
9745
1.75M
    return 0;
9746
1.75M
}
9747
9748
#undef put_value
9749
9750
/* Function prototypes */
9751
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9752
                const gs_pdf14trans_params_t * pparams,
9753
                gs_memory_t * mem );
9754
9755
#define read_value(dp, value)\
9756
123M
    BEGIN\
9757
123M
        memcpy(&value, dp, sizeof(value));\
9758
123M
        dp += sizeof(value);\
9759
123M
    END
9760
9761
/*
9762
 * Convert the string representation of the PDF 1.4 transparency parameter
9763
 * into the full compositor.
9764
 */
9765
static  int
9766
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9767
                                uint size, gs_memory_t * mem )
9768
38.4M
{
9769
38.4M
    gs_pdf14trans_params_t params = {0};
9770
38.4M
    const byte * start = data;
9771
38.4M
    int used, code = 0;
9772
38.4M
    bool deep;
9773
9774
38.4M
    if (size < 1)
9775
0
        return_error(gs_error_rangecheck);
9776
9777
    /* Read PDF 1.4 compositor data from the clist */
9778
38.4M
    params.pdf14_op = *data++;
9779
38.4M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9780
38.4M
               pdf14_opcode_names[params.pdf14_op], size);
9781
38.4M
    memset(&params.ctm, 0, sizeof(params.ctm));
9782
38.4M
    switch (params.pdf14_op) {
9783
0
        default:      /* Should not occur. */
9784
0
            break;
9785
1.82M
        case PDF14_PUSH_DEVICE:
9786
1.82M
            read_value(data, params.num_spot_colors);
9787
1.82M
            read_value(data, params.num_spot_colors_int);
9788
1.82M
            read_value(data, params.overprint_sim_push);
9789
1.82M
            read_value(data, params.is_pattern);
9790
1.82M
            break;
9791
0
        case PDF14_ABORT_DEVICE:
9792
0
            break;
9793
1.82M
        case PDF14_POP_DEVICE:
9794
1.82M
            read_value(data, params.is_pattern);
9795
1.82M
            break;
9796
2.28M
        case PDF14_END_TRANS_GROUP:
9797
2.84M
        case PDF14_END_TRANS_TEXT_GROUP:
9798
#ifdef DEBUG
9799
            code += 0; /* A good place for a breakpoint. */
9800
#endif
9801
2.84M
            break;      /* No data */
9802
0
        case PDF14_PUSH_TRANS_STATE:
9803
0
            break;
9804
3.73M
        case PDF14_POP_TRANS_STATE:
9805
3.73M
            break;
9806
714k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9807
2.84M
        case PDF14_BEGIN_TRANS_GROUP:
9808
            /*
9809
             * We are currently not using the bbox or the colorspace so they were
9810
             * not placed in the clist
9811
             */
9812
2.84M
            data = cmd_read_matrix(&params.ctm, data);
9813
2.84M
            params.Isolated = (*data) & 1;
9814
2.84M
            params.Knockout = (*data++ >> 1) & 1;
9815
2.84M
            params.blend_mode = *data++;
9816
2.84M
            params.group_color_type = *data++;  /* Trans group color */
9817
2.84M
            params.page_group = *data++;
9818
2.84M
            read_value(data,params.group_color_numcomps);  /* color group size */
9819
2.84M
            read_value(data, params.opacity);
9820
2.84M
            read_value(data, params.shape);
9821
2.84M
            read_value(data, params.bbox);
9822
2.84M
            read_value(data, params.shade_group);
9823
2.84M
            read_value(data, params.text_group);
9824
2.84M
            read_value(data, params.mask_id);
9825
2.84M
            read_value(data, params.icc_hash);
9826
2.84M
            break;
9827
5.24M
        case PDF14_BEGIN_TRANS_MASK:
9828
                /* This is the largest transparency parameter at this time (potentially
9829
                 * 1531 bytes in size if Background_components =
9830
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9831
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9832
                 *
9833
                 * NOTE:
9834
                 * The clist reader must be able to handle this sized device.
9835
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9836
                 * may also need to be changed correspondingly (defined in gstparam.h)
9837
                 * Also... if another compositor param should exceed this size, this
9838
                 * same condition applies.
9839
                 */
9840
5.24M
            data = cmd_read_matrix(&params.ctm, data);
9841
5.24M
            read_value(data, params.subtype);
9842
5.24M
            params.group_color_type = *data++;
9843
5.24M
            read_value(data, params.group_color_numcomps);
9844
5.24M
            params.replacing = *data++;
9845
5.24M
            params.function_is_identity = *data & 1;
9846
5.24M
            deep = (*data++)>>1;
9847
5.24M
            params.Background_components = *data++;
9848
5.24M
            params.Matte_components = *data++;
9849
5.24M
            read_value(data, params.bbox);
9850
5.24M
            read_value(data, params.mask_id);
9851
5.24M
            if (params.Background_components) {
9852
81.4k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9853
9854
81.4k
                memcpy(params.Background, data, l);
9855
81.4k
                data += l;
9856
81.4k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9857
81.4k
                data += sizeof(params.GrayBackground);
9858
81.4k
            }
9859
5.24M
            if (params.Matte_components) {
9860
4.21k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9861
9862
4.21k
                memcpy(params.Matte, data, m);
9863
4.21k
                data += m;
9864
4.21k
            }
9865
5.24M
            read_value(data, params.icc_hash);
9866
5.24M
            if (params.function_is_identity) {
9867
5.20M
                int i;
9868
9869
5.20M
                if (deep) {
9870
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9871
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9872
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9873
5.20M
                } else {
9874
1.33G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9875
1.33G
                        params.transfer_fn[i] = (byte)floor(i *
9876
1.33G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9877
1.33G
                    }
9878
5.20M
                }
9879
5.20M
            } else {
9880
34.7k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9881
34.7k
                data += (256+deep)<<deep;
9882
34.7k
            }
9883
5.24M
            break;
9884
503k
        case PDF14_END_TRANS_MASK:
9885
503k
            break;
9886
0
        case PDF14_PUSH_SMASK_COLOR:
9887
0
            return 0;
9888
0
            break;
9889
0
        case PDF14_POP_SMASK_COLOR:
9890
0
            return 0;
9891
0
            break;
9892
19.6M
        case PDF14_SET_BLEND_PARAMS:
9893
19.6M
            read_value(data, params.changed);
9894
19.6M
            if (params.changed & PDF14_SET_BLEND_MODE)
9895
4.05M
                params.blend_mode = *data++;
9896
19.6M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9897
1.77M
                params.text_knockout = *data++;
9898
19.6M
            if (params.changed & PDF14_SET_AIS)
9899
19.6M
                read_value(data, params.ais);
9900
19.6M
            if (params.changed & PDF14_SET_OVERPRINT)
9901
19.6M
                read_value(data, params.overprint);
9902
19.6M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9903
19.6M
                read_value(data, params.stroke_overprint);
9904
19.6M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9905
19.6M
                read_value(data, params.fillconstantalpha);
9906
19.6M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9907
19.6M
                read_value(data, params.strokeconstantalpha);
9908
19.6M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9909
19.6M
                read_value(data, params.op_fs_state);
9910
19.6M
            break;
9911
38.4M
    }
9912
38.4M
    code = gs_create_pdf14trans(ppct, &params, mem);
9913
38.4M
    if (code < 0)
9914
0
        return code;
9915
38.4M
    used = data - start;
9916
38.4M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9917
9918
    /* If we read more than the maximum expected, return a rangecheck error */
9919
38.4M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9920
0
        return_error(gs_error_rangecheck);
9921
38.4M
    else
9922
38.4M
        return used;
9923
38.4M
}
9924
9925
/*
9926
 * Adjust the compositor's CTM.
9927
 */
9928
static int
9929
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9930
23.3M
{
9931
23.3M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9932
23.3M
    gs_matrix mat = pct->params.ctm;
9933
9934
23.3M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9935
23.3M
               mat.xx, mat.xy, mat.yx, mat.yy,
9936
23.3M
               mat.tx, mat.ty);
9937
23.3M
    mat.tx -= x0;
9938
23.3M
    mat.ty -= y0;
9939
23.3M
    gs_gstate_setmatrix(pgs, &mat);
9940
23.3M
    return 0;
9941
23.3M
}
9942
9943
/*
9944
 * Create a PDF 1.4 transparency compositor.
9945
 *
9946
 * Note that this routine will be called only if the device is not already
9947
 * a PDF 1.4 transparency compositor.
9948
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9949
 */
9950
static  int
9951
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9952
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9953
    gs_memory_t * mem)
9954
1.16M
{
9955
1.16M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9956
1.16M
    int code = 0;
9957
9958
    /*
9959
     * We only handle the push operation.  All other operations are ignored.
9960
     * The other operations will be handled by the composite routine
9961
     * for the PDF 1.4 compositing device.
9962
     */
9963
1.16M
    switch (pdf14pct->params.pdf14_op) {
9964
1.14M
        case PDF14_PUSH_DEVICE:
9965
1.14M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9966
            /* Change (non-error) code to 1 to indicate that we created
9967
             * a device. */
9968
1.14M
            if (code >= 0)
9969
1.14M
                code = 1;
9970
1.14M
            break;
9971
26.6k
        default:
9972
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9973
26.6k
            *pp14dev = NULL;
9974
26.6k
            return_error(gs_error_unregistered);
9975
1.16M
    }
9976
1.14M
    return code;
9977
1.16M
}
9978
9979
/*
9980
 * Find an opening compositor op.
9981
 */
9982
static gs_compositor_closing_state
9983
find_opening_op(int opening_op, gs_composite_t **ppcte,
9984
                gs_compositor_closing_state return_code)
9985
2.43M
{
9986
    /* Assuming a right *BEGIN* - *END* operation balance. */
9987
2.43M
    gs_composite_t *pcte = *ppcte;
9988
9989
5.54M
    for (;;) {
9990
5.54M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9991
5.20M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9992
5.20M
            int op = pct->params.pdf14_op;
9993
9994
5.20M
            *ppcte = pcte;
9995
5.20M
            if (op == opening_op)
9996
1.53M
                return return_code;
9997
3.66M
            if (op != PDF14_SET_BLEND_PARAMS) {
9998
2.10M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9999
826
                    return COMP_ENQUEUE;
10000
2.10M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10001
273k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10002
257k
                        return COMP_ENQUEUE;
10003
273k
                }
10004
1.84M
                if (opening_op == PDF14_PUSH_DEVICE) {
10005
1.83M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10006
1.80M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10007
322k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10008
143k
                        return COMP_ENQUEUE;
10009
1.83M
                }
10010
1.84M
            }
10011
3.66M
        } else
10012
337k
            return COMP_ENQUEUE;
10013
3.26M
        pcte = pcte->prev;
10014
3.26M
        if (pcte == NULL)
10015
156k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10016
3.26M
    }
10017
2.43M
}
10018
10019
/*
10020
 * Find an opening compositor op.
10021
 */
10022
static gs_compositor_closing_state
10023
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10024
15.8M
{
10025
15.8M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10026
15.8M
    gs_composite_t *pct = *ppcte;
10027
10028
15.8M
    for (;;) {
10029
15.8M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10030
13.6M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10031
10032
13.6M
            *ppcte = pct;
10033
13.6M
            if (pct_pdf14->params.pdf14_op != my_op)
10034
4.38M
                return COMP_ENQUEUE;
10035
9.22M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10036
                /* If the new parameters completely replace the old ones
10037
                   then remove the old one from the queu */
10038
9.22M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10039
9.22M
                    pct_pdf14->params.changed) {
10040
8.47M
                    return COMP_REPLACE_CURR;
10041
8.47M
                } else {
10042
756k
                    return COMP_ENQUEUE;
10043
756k
                }
10044
9.22M
            }
10045
9.22M
        } else
10046
2.25M
            return COMP_ENQUEUE;
10047
0
        pct = pct->prev;
10048
0
        if (pct == NULL)
10049
0
            return COMP_ENQUEUE; /* Not in queue. */
10050
0
    }
10051
15.8M
}
10052
10053
/*
10054
 * Check for closing compositor.
10055
 */
10056
static gs_compositor_closing_state
10057
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10058
                        gx_device *dev)
10059
31.8M
{
10060
31.8M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10061
31.8M
    int op0 = pct0->params.pdf14_op;
10062
10063
31.8M
    switch (op0) {
10064
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10065
1.24M
        case PDF14_PUSH_DEVICE:
10066
1.24M
            return COMP_ENQUEUE;
10067
0
        case PDF14_ABORT_DEVICE:
10068
0
            return COMP_ENQUEUE;
10069
1.24M
        case PDF14_POP_DEVICE:
10070
1.24M
            if (*ppcte == NULL)
10071
842k
                return COMP_ENQUEUE;
10072
406k
            else {
10073
406k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10074
10075
406k
                if (state == COMP_EXEC_IDLE)
10076
106k
                    return COMP_DROP_QUEUE;
10077
299k
                return state;
10078
406k
            }
10079
500k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10080
2.36M
        case PDF14_BEGIN_TRANS_GROUP:
10081
2.36M
            return COMP_ENQUEUE;
10082
1.86M
        case PDF14_END_TRANS_GROUP:
10083
2.36M
        case PDF14_END_TRANS_TEXT_GROUP:
10084
2.36M
            if (*ppcte == NULL)
10085
483k
                return COMP_EXEC_QUEUE;
10086
1.88M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10087
4.22M
        case PDF14_BEGIN_TRANS_MASK:
10088
4.22M
            return COMP_ENQUEUE;
10089
0
        case PDF14_PUSH_TRANS_STATE:
10090
0
            return COMP_ENQUEUE;
10091
3.02M
        case PDF14_POP_TRANS_STATE:
10092
3.02M
            return COMP_ENQUEUE;
10093
0
        case PDF14_PUSH_SMASK_COLOR:
10094
0
            return COMP_ENQUEUE;
10095
0
            break;
10096
0
        case PDF14_POP_SMASK_COLOR:
10097
0
            return COMP_ENQUEUE;
10098
0
            break;
10099
429k
        case PDF14_END_TRANS_MASK:
10100
429k
            if (*ppcte == NULL)
10101
288k
                return COMP_EXEC_QUEUE;
10102
141k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10103
16.8M
        case PDF14_SET_BLEND_PARAMS:
10104
16.8M
            if (*ppcte == NULL)
10105
1.01M
                return COMP_ENQUEUE;
10106
            /* hack : ignore csel - here it is always zero : */
10107
15.8M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10108
31.8M
    }
10109
31.8M
}
10110
10111
/*
10112
 * Check whether a next operation is friendly to the compositor.
10113
 */
10114
static bool
10115
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10116
3.82M
{
10117
3.82M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10118
3.82M
    int op0 = pct0->params.pdf14_op;
10119
10120
3.82M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10121
2.50M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10122
        /* Halftone commands are always passed to the target printer device,
10123
           because transparency buffers are always contone.
10124
           So we're safe to execute them before queued transparency compositors. */
10125
1.34M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10126
389k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10127
636k
            return true;
10128
704k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10129
700k
            return true;
10130
704k
    }
10131
2.48M
    return false;
10132
3.82M
}
10133
10134
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10135
static composite_equal_proc(c_pdf14trans_equal);
10136
static composite_write_proc(c_pdf14trans_write);
10137
static composite_read_proc(c_pdf14trans_read);
10138
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10139
static composite_is_closing_proc(c_pdf14trans_is_closing);
10140
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10141
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10142
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10143
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10144
10145
/*
10146
 * Methods for the PDF 1.4 transparency compositor
10147
 *
10148
 * Note:  We have two set of methods.  They are the same except for the
10149
 * composite_clist_write_update method.  Once the clist write device is created,
10150
 * we use the second set of procedures.  This prevents the creation of multiple
10151
 * PDF 1.4 clist write compositor devices being chained together.
10152
 */
10153
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10154
    GX_COMPOSITOR_PDF14_TRANS,
10155
    {
10156
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10157
        c_pdf14trans_equal,                      /* procs.equal */
10158
        c_pdf14trans_write,                      /* procs.write */
10159
        c_pdf14trans_read,                       /* procs.read */
10160
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10161
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10162
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10163
                /* Create a PDF 1.4 clist write device */
10164
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10165
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10166
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10167
    }                                            /* procs */
10168
};
10169
10170
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10171
    GX_COMPOSITOR_PDF14_TRANS,
10172
    {
10173
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10174
        c_pdf14trans_equal,                      /* procs.equal */
10175
        c_pdf14trans_write,                      /* procs.write */
10176
        c_pdf14trans_read,                       /* procs.read */
10177
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10178
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10179
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10180
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10181
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10182
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10183
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10184
    }                                            /* procs */
10185
};
10186
10187
/*
10188
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10189
 */
10190
int
10191
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10192
230M
{
10193
230M
    return (pct->type == &gs_composite_pdf14trans_type
10194
169M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10195
230M
}
10196
10197
/*
10198
 * Create a PDF 1.4 transparency compositor data structure.
10199
 */
10200
static int
10201
gs_create_pdf14trans(
10202
    gs_composite_t **               ppct,
10203
    const gs_pdf14trans_params_t *  pparams,
10204
    gs_memory_t *                   mem )
10205
39.8M
{
10206
39.8M
    gs_pdf14trans_t *                pct;
10207
10208
39.8M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10209
39.8M
                             "gs_create_pdf14trans");
10210
39.8M
    if (pct == NULL)
10211
0
        return_error(gs_error_VMerror);
10212
39.8M
    pct->type = &gs_composite_pdf14trans_type;
10213
39.8M
    pct->id = gs_next_ids(mem, 1);
10214
39.8M
    pct->params = *pparams;
10215
39.8M
    pct->idle = false;
10216
39.8M
    *ppct = (gs_composite_t *)pct;
10217
39.8M
    return 0;
10218
39.8M
}
10219
10220
/*
10221
 * Send a PDF 1.4 transparency compositor action to the specified device.
10222
 */
10223
int
10224
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10225
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10226
1.26M
{
10227
1.26M
    gs_composite_t * pct = NULL;
10228
1.26M
    int code;
10229
10230
1.26M
    pparams->ctm = ctm_only(pgs);
10231
1.26M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10232
1.26M
    if (code < 0)
10233
0
        return code;
10234
1.26M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10235
1.26M
    if (code == gs_error_handled)
10236
0
        code = 0;
10237
10238
1.26M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10239
10240
1.26M
    return code;
10241
1.26M
}
10242
10243
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10244
10245
/*
10246
 * The PDF 1.4 transparency compositor device may have a different process
10247
 * color model than the output device.  If we are banding then we need to
10248
 * create two compositor devices.  The output side (clist reader) needs a
10249
 * compositor to actually composite the output.  We also need a compositor
10250
 * device before the clist writer.  This is needed to provide a process color
10251
 * model which matches the PDF 1.4 blending space.
10252
 *
10253
 * This section provides support for this device.
10254
 */
10255
10256
/*
10257
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10258
 * We actually use the same structure for both the clist writer and reader
10259
 * devices.  However we use separate names to identify the routines for each
10260
 * device.
10261
 */
10262
10263
static  dev_proc_composite(pdf14_clist_composite);
10264
static  dev_proc_composite(pdf14_clist_forward_composite);
10265
static  dev_proc_fill_path(pdf14_clist_fill_path);
10266
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10267
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10268
static  dev_proc_text_begin(pdf14_clist_text_begin);
10269
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10270
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10271
10272
static void
10273
pdf14_clist_init_procs(gx_device *dev,
10274
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10275
                       dev_proc_get_color_comp_index(get_color_comp_index))
10276
11.2k
{
10277
11.2k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10278
11.2k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10279
11.2k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10280
11.2k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10281
11.2k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10282
11.2k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10283
11.2k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10284
11.2k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10285
11.2k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10286
11.2k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10287
11.2k
    set_dev_proc(dev, put_params, pdf14_put_params);
10288
11.2k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10289
11.2k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10290
11.2k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10291
11.2k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10292
11.2k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10293
11.2k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10294
11.2k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10295
11.2k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10296
11.2k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10297
11.2k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10298
11.2k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10299
11.2k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10300
11.2k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10301
11.2k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10302
11.2k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10303
11.2k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10304
11.2k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10305
11.2k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10306
11.2k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10307
11.2k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10308
11.2k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10309
11.2k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10310
11.2k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10311
11.2k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10312
11.2k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10313
11.2k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10314
11.2k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10315
11.2k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10316
11.2k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10317
11.2k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10318
11.2k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10319
11.2k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10320
11.2k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10321
11.2k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10322
11.2k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10323
11.2k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10324
11.2k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10325
11.2k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10326
11.2k
}
10327
10328
static void
10329
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10330
3.44k
{
10331
3.44k
    pdf14_clist_init_procs(dev,
10332
3.44k
                           gx_default_DevGray_get_color_mapping_procs,
10333
3.44k
                           gx_default_DevGray_get_color_comp_index);
10334
3.44k
}
10335
10336
static void
10337
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10338
6.51k
{
10339
6.51k
    pdf14_clist_init_procs(dev,
10340
6.51k
                           gx_default_DevRGB_get_color_mapping_procs,
10341
6.51k
                           gx_default_DevRGB_get_color_comp_index);
10342
6.51k
}
10343
10344
static void
10345
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10346
13
{
10347
13
    pdf14_clist_init_procs(dev,
10348
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10349
13
                           gx_default_DevCMYK_get_color_comp_index);
10350
13
}
10351
10352
static void
10353
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10354
1.23k
{
10355
1.23k
    pdf14_clist_init_procs(dev,
10356
1.23k
                           pdf14_cmykspot_get_color_mapping_procs,
10357
1.23k
                           pdf14_cmykspot_get_color_comp_index);
10358
1.23k
}
10359
10360
static void
10361
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10362
0
{
10363
0
    pdf14_clist_init_procs(dev,
10364
0
                           pdf14_rgbspot_get_color_mapping_procs,
10365
0
                           pdf14_rgbspot_get_color_comp_index);
10366
0
}
10367
10368
#if 0 /* NOT USED */
10369
static int
10370
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10371
{
10372
    pdf14_clist_init_procs(dev,
10373
                           pdf14_grayspot_get_color_mapping_procs,
10374
                           pdf14_grayspot_get_color_comp_index);
10375
}
10376
#endif  /* NOT USED */
10377
10378
const pdf14_clist_device pdf14_clist_Gray_device = {
10379
    std_device_color_stype_body(pdf14_clist_device,
10380
                                pdf14_clist_Gray_initialize_device_procs,
10381
                                "pdf14clistgray",
10382
                                &st_pdf14_device,
10383
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10384
    { 0 },      /* Procs */
10385
    NULL,     /* target */
10386
    { 0 },      /* devn_params - not used */
10387
    &gray_pdf14_procs,
10388
    &gray_blending_procs
10389
};
10390
10391
const pdf14_clist_device pdf14_clist_RGB_device = {
10392
    std_device_color_stype_body(pdf14_clist_device,
10393
                                pdf14_clist_RGB_initialize_device_procs,
10394
                                "pdf14clistRGB",
10395
                                &st_pdf14_device,
10396
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10397
    { 0 },      /* Procs */
10398
    NULL,     /* target */
10399
    { 0 },      /* devn_params - not used */
10400
    &rgb_pdf14_procs,
10401
    &rgb_blending_procs
10402
};
10403
10404
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10405
    std_device_part1_(pdf14_device,
10406
                      pdf14_clist_RGBspot_initialize_device_procs,
10407
                      "pdf14clistrgbspot",
10408
                      &st_pdf14_device,
10409
                      open_init_closed),
10410
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10411
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10412
    offset_margin_values(0, 0, 0, 0, 0, 0),
10413
    std_device_part3_(),
10414
    { 0 },      /* Procs */
10415
    NULL,     /* target */
10416
    /* DeviceN parameters */
10417
    { 8,      /* Not used - Bits per color */
10418
      DeviceRGBComponents,  /* Names of color model colorants */
10419
      3,      /* Number colorants for CMYK */
10420
      0,      /* MaxSeparations has not been specified */
10421
      -1,     /* PageSpotColors has not been specified */
10422
      {0},      /* SeparationNames */
10423
      0,      /* SeparationOrder names */
10424
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10425
    },
10426
    &rgbspot_pdf14_procs,
10427
    &rgb_blending_procs
10428
};
10429
10430
const pdf14_clist_device pdf14_clist_CMYK_device = {
10431
    std_device_std_color_full_body_type(pdf14_clist_device,
10432
                                        pdf14_clist_CMYK_initialize_device_procs,
10433
                                        "pdf14clistcmyk",
10434
                                        &st_pdf14_device,
10435
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10436
                                        0, 0, 0, 0, 0, 0),
10437
    { 0 },      /* Procs */
10438
    NULL,     /* target */
10439
    { 0 },      /* devn_params - not used */
10440
    &cmyk_pdf14_procs,
10441
    &cmyk_blending_procs
10442
};
10443
10444
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10445
    std_device_part1_(pdf14_device,
10446
                      pdf14_clist_CMYKspot_initialize_device_procs,
10447
                      "pdf14clistcmykspot",
10448
                      &st_pdf14_device,
10449
                      open_init_closed),
10450
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10451
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10452
    offset_margin_values(0, 0, 0, 0, 0, 0),
10453
    std_device_part3_(),
10454
    { 0 },      /* Procs */
10455
    NULL,     /* target */
10456
    /* DeviceN parameters */
10457
    { 8,      /* Not used - Bits per color */
10458
      DeviceCMYKComponents, /* Names of color model colorants */
10459
      4,      /* Number colorants for CMYK */
10460
      0,      /* MaxSeparations has not been specified */
10461
      -1,     /* PageSpotColors has not been specified */
10462
      {0},      /* SeparationNames */
10463
      0,      /* SeparationOrder names */
10464
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10465
    },
10466
    &cmykspot_pdf14_procs,
10467
    &cmyk_blending_procs
10468
};
10469
10470
const pdf14_clist_device pdf14_clist_custom_device = {
10471
    std_device_part1_(pdf14_device,
10472
                      pdf14_clist_CMYKspot_initialize_device_procs,
10473
                      "pdf14clistcustom",
10474
                      &st_pdf14_device,
10475
                      open_init_closed),
10476
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10477
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10478
    offset_margin_values(0, 0, 0, 0, 0, 0),
10479
    std_device_part3_(),
10480
    { 0 },      /* Procs */
10481
    NULL,     /* target */
10482
    /* DeviceN parameters */
10483
    { 8,      /* Not used - Bits per color */
10484
      DeviceCMYKComponents, /* Names of color model colorants */
10485
      4,      /* Number colorants for CMYK */
10486
      0,      /* MaxSeparations has not been specified */
10487
      -1,     /* PageSpotColors has not been specified */
10488
      {0},      /* SeparationNames */
10489
      0,      /* SeparationOrder names */
10490
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10491
    },
10492
    &custom_pdf14_procs,
10493
    &custom_blending_procs
10494
};
10495
10496
/*
10497
 * the PDF 1.4 transparency spec says that color space for blending
10498
 * operations can be based upon either a color space specified in the
10499
 * group or a default value based upon the output device.  We are
10500
 * currently only using a color space based upon the device.
10501
 */
10502
static  int
10503
get_pdf14_clist_device_proto(gx_device          *dev,
10504
                             pdf14_clist_device *pdevproto,
10505
                             gs_gstate          *pgs,
10506
                       const gs_pdf14trans_t    *pdf14pct,
10507
                             bool                use_pdf14_accum)
10508
11.2k
{
10509
11.2k
    pdf14_blend_cs_t blend_cs_state;
10510
11.2k
    pdf14_default_colorspace_t dev_cs =
10511
11.2k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10512
11.2k
                                                 &blend_cs_state);
10513
11.2k
    bool deep = device_is_deep(dev);
10514
11.2k
    int num_spots = pdf14pct->params.num_spot_colors;
10515
10516
    /* overprint overide */
10517
11.2k
    if (pdf14pct->params.overprint_sim_push &&
10518
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10519
10520
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10521
0
            dev_cs = PDF14_DeviceCMYKspot;
10522
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10523
0
        } else
10524
0
            dev_cs = PDF14_DeviceCMYK;
10525
0
    }
10526
10527
11.2k
    switch (dev_cs) {
10528
3.44k
        case PDF14_DeviceGray:
10529
           /* We want gray to be single channel.  Low level
10530
               initialization of gray device prototype is
10531
               peculiar in that in dci_std_color_num_components
10532
               the comment is
10533
              "A device is monochrome only if it is bi-level"
10534
              Here we want monochrome anytime we have a gray device.
10535
              To avoid breaking things elsewhere, we will overide
10536
              the prototype intialization here */
10537
3.44k
            *pdevproto = pdf14_clist_Gray_device;
10538
3.44k
            pdevproto->color_info.max_components = 1;
10539
3.44k
            pdevproto->color_info.num_components =
10540
3.44k
                                    pdevproto->color_info.max_components;
10541
3.44k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10542
3.44k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10543
3.44k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10544
3.44k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10545
3.44k
            pdevproto->color_info.depth = deep ? 16 : 8;
10546
3.44k
            pdevproto->sep_device = false;
10547
3.44k
            break;
10548
6.51k
        case PDF14_DeviceRGB:
10549
6.51k
            *pdevproto = pdf14_clist_RGB_device;
10550
6.51k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10551
6.51k
            pdevproto->sep_device = false;
10552
6.51k
            if (deep) {
10553
0
                pdevproto->color_info.depth = 3*16;
10554
0
                pdevproto->color_info.max_color = 65535;
10555
0
                pdevproto->color_info.max_gray = 65535;
10556
0
                pdevproto->color_info.dither_colors = 65536;
10557
0
                pdevproto->color_info.dither_grays = 65536;
10558
0
            }
10559
6.51k
            break;
10560
13
        case PDF14_DeviceCMYK:
10561
13
            *pdevproto = pdf14_clist_CMYK_device;
10562
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10563
13
            pdevproto->sep_device = false;
10564
13
            if (deep) {
10565
0
                pdevproto->color_info.depth = 4*16;
10566
0
                pdevproto->color_info.max_color = 65535;
10567
0
                pdevproto->color_info.max_gray = 65535;
10568
0
                pdevproto->color_info.dither_colors = 65536;
10569
0
                pdevproto->color_info.dither_grays = 65536;
10570
0
            }
10571
13
            break;
10572
1.23k
        case PDF14_DeviceCMYKspot:
10573
1.23k
            *pdevproto = pdf14_clist_CMYKspot_device;
10574
            /*
10575
             * The number of components for the PDF14 device is the sum
10576
             * of the process components and the number of spot colors
10577
             * for the page. If we are using an NCLR ICC profile at
10578
             * the output device, those spot colors are skipped. They
10579
             * do not appear in the transparency buffer, but appear
10580
             * during put image transform of the page group to the target
10581
             * color space.
10582
             */
10583
1.23k
            if (num_spots >= 0) {
10584
1.23k
                pdevproto->devn_params.page_spot_colors = num_spots;
10585
1.23k
                pdevproto->color_info.num_components =
10586
1.23k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10587
1.23k
                if (pdevproto->color_info.num_components >
10588
1.23k
                              pdevproto->color_info.max_components)
10589
0
                    pdevproto->color_info.num_components =
10590
0
                              pdevproto->color_info.max_components;
10591
1.23k
                pdevproto->color_info.depth =
10592
1.23k
                              pdevproto->color_info.num_components * (8<<deep);
10593
1.23k
            }
10594
1.23k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10595
1.23k
            pdevproto->sep_device = true;
10596
1.23k
            break;
10597
0
        case PDF14_DeviceRGBspot:
10598
0
            *pdevproto = pdf14_clist_RGBspot_device;
10599
            /*
10600
             * The number of components for the PDF14 device is the sum
10601
             * of the process components and the number of spot colors
10602
             * for the page. If we are using an NCLR ICC profile at
10603
             * the output device, those spot colors are skipped. They
10604
             * do not appear in the transparency buffer, but appear
10605
             * during put image transform of the page group to the target
10606
             * color space.
10607
             */
10608
0
            if (num_spots >= 0) {
10609
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10610
0
                pdevproto->color_info.num_components =
10611
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10612
0
                if (pdevproto->color_info.num_components >
10613
0
                    pdevproto->color_info.max_components)
10614
0
                    pdevproto->color_info.num_components =
10615
0
                        pdevproto->color_info.max_components;
10616
0
                pdevproto->color_info.depth =
10617
0
                    pdevproto->color_info.num_components * (8 << deep);
10618
0
            }
10619
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10620
0
            pdevproto->sep_device = true;
10621
0
            break;
10622
0
        case PDF14_DeviceCustom:
10623
            /*
10624
             * We are using the output device's process color model.  The
10625
             * color_info for the PDF 1.4 compositing device needs to match
10626
             * the output device.
10627
             */
10628
0
            *pdevproto = pdf14_clist_custom_device;
10629
0
            pdevproto->color_info = dev->color_info;
10630
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10631
0
            pdevproto->color_info.depth =
10632
0
                pdevproto->color_info.num_components * (8<<deep);
10633
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10634
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10635
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10636
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10637
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10638
0
            break;
10639
0
        default:      /* Should not occur */
10640
0
            return_error(gs_error_rangecheck);
10641
11.2k
    }
10642
11.2k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10643
11.2k
    pdevproto->blend_cs_state = blend_cs_state;
10644
11.2k
    return 0;
10645
11.2k
}
10646
10647
static  int
10648
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10649
                                gx_device ** ppdev, gx_device * target,
10650
                                const gs_pdf14trans_t * pdf14pct)
10651
11.2k
{
10652
11.2k
    pdf14_clist_device dev_proto;
10653
11.2k
    pdf14_clist_device * pdev;
10654
11.2k
    int code;
10655
11.2k
    bool has_tags = device_encodes_tags(target);
10656
11.2k
    cmm_profile_t *target_profile;
10657
11.2k
    gsicc_rendering_param_t render_cond;
10658
11.2k
    cmm_dev_profile_t *dev_profile;
10659
11.2k
    uchar k;
10660
11.2k
    bool deep = device_is_deep(target);
10661
11.2k
    cmm_profile_t *icc_profile;
10662
11.2k
    int nc;
10663
10664
11.2k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10665
11.2k
    if (code < 0)
10666
0
        return code;
10667
11.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10668
11.2k
                          &render_cond);
10669
11.2k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10670
    /* Prototypes never include tags. We add those in later. */
10671
11.2k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10672
11.2k
                                        pgs, pdf14pct, false);
10673
11.2k
    if (code < 0)
10674
0
        return code;
10675
11.2k
    code = gs_copydevice((gx_device **) &pdev,
10676
11.2k
                         (const gx_device *) &dev_proto, mem);
10677
11.2k
    if (code < 0)
10678
0
        return code;
10679
10680
11.2k
    nc = pdev->color_info.num_components;
10681
    /* If we are not using a blending color space, the number of color planes
10682
       should not exceed that of the target */
10683
11.2k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10684
11.2k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10685
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10686
11.2k
        if (pdev->color_info.max_components > target->color_info.max_components)
10687
1.30k
            pdev->color_info.max_components = target->color_info.max_components;
10688
11.2k
    }
10689
11.2k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10690
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10691
10692
11.2k
    pdev->color_info.num_components = nc;
10693
11.2k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10694
11.2k
    pdev->pad = target->pad;
10695
11.2k
    pdev->log2_align_mod = target->log2_align_mod;
10696
10697
11.2k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10698
10699
11.2k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10700
10701
11.2k
    if (deep) {
10702
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10703
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10704
0
    }
10705
    /* If we have a tag device then go ahead and do a special encoder decoder
10706
       for the pdf14 device to make sure we maintain this information in the
10707
       encoded color information.  We could use the target device's methods but
10708
       the PDF14 device has to maintain 8 bit color always and we could run
10709
       into other issues if the number of colorants became large.  If we need to
10710
       do compressed color with tags that will be a special project at that time */
10711
11.2k
    if (has_tags) {
10712
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10713
0
    }
10714
11.2k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10715
11.2k
    gx_device_fill_in_procs((gx_device *)pdev);
10716
    /* Copying the params adds the tags to the color_info if required. */
10717
11.2k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10718
11.2k
    if (target->num_planar_planes > 0)
10719
1.34k
        pdev->num_planar_planes = pdev->color_info.num_components;
10720
11.2k
    gx_device_set_target((gx_device_forward *)pdev, target);
10721
10722
    /* Components shift, etc have to be based upon 8 bit */
10723
39.2k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10724
28.0k
        pdev->color_info.comp_bits[k] = 8<<deep;
10725
28.0k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10726
28.0k
    }
10727
11.2k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10728
11.2k
    if (code < 0)
10729
0
        return code;
10730
11.2k
    pdev->pclist_device = target;
10731
10732
11.2k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10733
11.2k
    if (code < 0)
10734
0
        return code;
10735
11.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10736
11.2k
        &render_cond);
10737
11.2k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10738
10739
    /* Simulated overprint case.  We have to use CMYK-based profile
10740
       Also if the target profile is NCLR, we are going to use a pdf14
10741
       device that is CMYK based and do the mapping to the NCLR profile
10742
       when the put_image occurs */
10743
11.2k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10744
11.2k
         icc_profile->data_cs == gsNCHANNEL) {
10745
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10746
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10747
0
            -1, "pdf14_create_clist_device");
10748
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10749
11.2k
    } else {
10750
        /* If the target profile was CIELAB, then overide with default RGB for
10751
           proper blending.  During put_image we will convert from RGB to
10752
           CIELAB */
10753
11.2k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10754
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10755
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10756
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10757
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10758
0
        }
10759
11.2k
    }
10760
10761
11.2k
    if (pdf14pct->params.overprint_sim_push &&
10762
0
        pdf14pct->params.num_spot_colors_int > 0) {
10763
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10764
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10765
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10766
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10767
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10768
0
    }
10769
    /* if the device has separations already defined (by SeparationOrderNames) */
10770
    /* we need to copy them (allocating new names) so the colorants are in the */
10771
    /* same order as the target device.                                        */
10772
11.2k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10773
1.34k
        code = devn_copy_params(target, (gx_device *)pdev);
10774
1.34k
        if (code < 0)
10775
0
            return code;
10776
1.34k
    }
10777
11.2k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10778
11.2k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10779
11.2k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10780
11.2k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10781
11.2k
    pdev->color_info.separable_and_linear =
10782
11.2k
        target->color_info.separable_and_linear;
10783
11.2k
    *ppdev = (gx_device *) pdev;
10784
11.2k
    return code;
10785
11.2k
}
10786
10787
/*
10788
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10789
 * compositor device is never removed.  (We do not have a remove compositor
10790
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10791
 * routine implements that action.
10792
 */
10793
static  int
10794
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10795
                                gx_device * dev)
10796
10.8k
{
10797
10.8k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10798
10.8k
    gx_device * target = pdev->target;
10799
10800
10.8k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10801
10802
    /*
10803
     * To disable the action of this device, we forward all device
10804
     * procedures to the target except the composite and copy
10805
     * the target's color_info.
10806
     */
10807
10.8k
    dev->color_info = target->color_info;
10808
10.8k
    pdf14_forward_device_procs(dev);
10809
10.8k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10810
10.8k
    return 0;
10811
10.8k
}
10812
10813
/*
10814
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10815
 * compositor device is never removed.  (We do not have a remove compositor
10816
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10817
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10818
 * again.
10819
 */
10820
static  int
10821
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10822
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10823
0
{
10824
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10825
0
    gx_device * target = pdev->target;
10826
0
    pdf14_clist_device dev_proto;
10827
0
    int code;
10828
10829
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10830
    /*
10831
     * We will not use the entire prototype device but we will set the
10832
     * color related info to match the prototype.
10833
     */
10834
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10835
0
                                        pgs, pdf14pct, false);
10836
0
    if (code < 0)
10837
0
        return code;
10838
0
    pdev->color_info = dev_proto.color_info;
10839
10840
0
    if (dev_proto.initialize_device_procs != NULL)
10841
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10842
10843
0
    pdev->procs = dev_proto.procs;
10844
0
    pdev->pad = target->pad;
10845
0
    pdev->log2_align_mod = target->log2_align_mod;
10846
10847
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10848
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10849
0
    else
10850
0
        pdev->num_planar_planes = target->num_planar_planes;
10851
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10852
10853
0
    copy_tag_setup(dev, target);
10854
10855
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10856
0
    gx_device_fill_in_procs((gx_device *)pdev);
10857
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10858
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10859
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10860
0
    check_device_separable((gx_device *)pdev);
10861
0
    return code;
10862
0
}
10863
10864
/*
10865
 * devicen params
10866
 */
10867
gs_devn_params *
10868
pdf14_ret_devn_params(gx_device *pdev)
10869
2.35M
{
10870
2.35M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10871
10872
2.35M
    return &(p14dev->devn_params);
10873
2.35M
}
10874
10875
/*
10876
 * devicen params
10877
 */
10878
gs_devn_params *
10879
pdf14_accum_ret_devn_params(gx_device *pdev)
10880
0
{
10881
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10882
10883
0
    return &(p14dev->devn_params);
10884
0
}
10885
10886
static int
10887
pdf14_accum_get_color_comp_index(gx_device * dev,
10888
    const char * pname, int name_size, int component_type)
10889
0
{
10890
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10891
0
    gx_device *target = p14dev->target;
10892
0
    int colorant_number = devn_get_color_comp_index(dev,
10893
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10894
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10895
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10896
10897
0
    if (target != NULL)
10898
        /* colorant_number returned here _should_ be the same as from above */
10899
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10900
0
                              (target, (const char *)pname, name_size, component_type);
10901
0
    return colorant_number;
10902
0
}
10903
10904
/*
10905
 * The following procedures are used to map the standard color spaces into
10906
 * the separation color components for the pdf14_accum device.
10907
 */
10908
static void
10909
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10910
0
{
10911
0
    int * map =
10912
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10913
10914
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10915
0
}
10916
10917
static void
10918
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10919
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10920
0
{
10921
0
    int * map =
10922
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10923
10924
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10925
0
}
10926
10927
static void
10928
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10929
    frac c, frac m, frac y, frac k, frac out[])
10930
0
{
10931
0
    const int * map =
10932
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10933
10934
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10935
0
}
10936
10937
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10938
    pdf14_accum_gray_cs_to_cmyk_cm,
10939
    pdf14_accum_rgb_cs_to_cmyk_cm,
10940
    pdf14_accum_cmyk_cs_to_cmyk_cm
10941
};
10942
10943
static const gx_cm_color_map_procs *
10944
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10945
0
{
10946
0
    *map_dev = dev;
10947
0
    return &pdf14_accum_cm_procs;
10948
0
}
10949
10950
/*
10951
 *  Device proc for updating the equivalent CMYK color for spot colors.
10952
 */
10953
static int
10954
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10955
0
{
10956
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10957
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10958
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10959
0
                                              &pdev->equiv_cmyk_colors);
10960
10961
0
    if (code >= 0 && tdev != NULL)
10962
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10963
0
    return code;
10964
0
}
10965
10966
/* Used when doing overprint simulation and have spot colors */
10967
static int
10968
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10969
0
{
10970
0
    pdf14_device *pdev = (pdf14_device *)dev;
10971
0
    int code;
10972
10973
    /* Make sure we are not All or None */
10974
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10975
0
        pcs->params.separation.sep_type != SEP_OTHER)
10976
0
            return 0;
10977
10978
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10979
0
        &pdev->op_pequiv_cmyk_colors);
10980
0
    return code;
10981
0
}
10982
10983
/*
10984
 * Retrieve a list of spot color names for the PDF14 device.
10985
 */
10986
int
10987
put_param_pdf14_spot_names(gx_device * pdev,
10988
                gs_separations * pseparations, gs_param_list * plist)
10989
107k
{
10990
107k
    int code, num_spot_colors, i;
10991
107k
    gs_param_string str;
10992
10993
    /* Check if the given keyname is present. */
10994
107k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10995
107k
                                                &num_spot_colors);
10996
107k
    switch (code) {
10997
0
        default:
10998
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10999
0
            break;
11000
107k
        case 1:
11001
107k
            return 0;
11002
0
        case 0:
11003
0
            if (num_spot_colors < 1 ||
11004
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11005
0
                return_error(gs_error_rangecheck);
11006
0
            for (i = 0; i < num_spot_colors; i++) {
11007
0
                char buff[20];
11008
0
                byte * sep_name;
11009
11010
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11011
0
                code = param_read_string(plist, buff, &str);
11012
0
                switch (code) {
11013
0
                    default:
11014
0
                        param_signal_error(plist, buff, code);
11015
0
                        break;
11016
0
                    case 0:
11017
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11018
0
                                str.size, "put_param_pdf14_spot_names");
11019
0
                        if (sep_name == NULL)
11020
0
                            return_error(gs_error_VMerror);
11021
11022
0
                        memcpy(sep_name, str.data, str.size);
11023
0
                        pseparations->names[i].size = str.size;
11024
0
                        pseparations->names[i].data = sep_name;
11025
0
                }
11026
0
            }
11027
0
            pseparations->num_separations = num_spot_colors;
11028
0
            break;
11029
107k
    }
11030
0
    return 0;;
11031
0
}
11032
11033
/*
11034
 * This procedure will have information from the PDF 1.4 clist writing
11035
 * clist compositior device.  This is information output the compressed
11036
 * color list info which is needed for the support of spot colors in
11037
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11038
 * clist reading compositor.  However this device is not created until
11039
 * the clist is read.  To get this info to that device, we have to
11040
 * temporarily store that info in the output device.  This routine saves
11041
 * that info in the output device.
11042
 */
11043
int
11044
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11045
                                        gs_param_list * plist)
11046
107k
{
11047
107k
    int code;
11048
107k
    code = put_param_pdf14_spot_names(pdev,
11049
107k
                       &pdevn_params->pdf14_separations, plist);
11050
107k
    return code;
11051
107k
}
11052
11053
/*
11054
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11055
 * when we are creating the clist.  The second is for imaging the data from
11056
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11057
 * This routine is only called once the PDF 1.4 clist write compositor already
11058
 * exists.
11059
 */
11060
static  int
11061
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11062
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11063
    gx_device *cdev)
11064
1.63M
{
11065
1.63M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11066
1.63M
    int code, is_pdf14_compositor;
11067
1.63M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11068
1.63M
    bool deep = device_is_deep(dev);
11069
11070
    /* We only handle a few PDF 1.4 transparency operations */
11071
1.63M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11072
1.00M
        switch (pdf14pct->params.pdf14_op) {
11073
0
            case PDF14_PUSH_DEVICE:
11074
                /* Re-activate the PDF 1.4 compositor */
11075
/*
11076
                We previously did:
11077
11078
                pdev->saved_target_color_info = pdev->target->color_info;
11079
11080
                Here, but since we already saved and modified the the color_info
11081
                of the target clist device in gs_pdf14_clist_device_push() this is
11082
                overwriting saved_target_color_info that we already saved with the
11083
                group color_info, meaning when we set it back again, it's incorrect.
11084
*/
11085
0
                pdev->target->color_info = pdev->color_info;
11086
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11087
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11088
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11089
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11090
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11091
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11092
0
                pdev->saved_target_get_color_mapping_procs =
11093
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11094
0
                pdev->saved_target_get_color_comp_index =
11095
0
                                        dev_proc(pdev->target, get_color_comp_index);
11096
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11097
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11098
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11099
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11100
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11101
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11102
0
                gx_set_cmap_procs(pgs, dev);
11103
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11104
0
                pdev->blend_mode = pdev->text_knockout = 0;
11105
0
                pdev->opacity = pdev->shape = 0.0;
11106
0
                if (code < 0)
11107
0
                    return code;
11108
                /*
11109
                 * This routine is part of the PDF 1.4 clist write device.
11110
                 * Change the compositor procs to not create another since we
11111
                 * do not need to create a chain of identical devices.
11112
                 */
11113
0
                {
11114
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11115
11116
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11117
0
                    code = dev_proc(pdev->target, composite)
11118
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11119
                    /* We should never have created a new device here. */
11120
0
                    assert(code != 1);
11121
0
                    return code;
11122
0
                }
11123
10.8k
            case PDF14_POP_DEVICE:
11124
10.8k
            {
11125
10.8k
                gx_device *clistdev = pdev->target;
11126
11127
                /* Find the clist device */
11128
10.8k
                while (1) {
11129
10.8k
                    gxdso_device_child_request req;
11130
                    /* Ignore any errors here, that's expected as non-clist
11131
                     * devices don't implement it. */
11132
10.8k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11133
10.8k
                    if (code == 1)
11134
10.8k
                        break;
11135
0
                    req.n = 0;
11136
0
                    req.target = clistdev;
11137
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11138
0
                    if (code < 0)
11139
0
                        return code;
11140
0
                    clistdev = req.target;
11141
0
                }
11142
11143
                /* If we have overprint simulation spot color information, store
11144
                   it in a pseudo-band of the clist */
11145
10.8k
                if (pdev->overprint_sim &&
11146
0
                    pdev->devn_params.page_spot_colors > 0) {
11147
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11148
0
                        &pdev->op_pequiv_cmyk_colors);
11149
0
                    if (code < 0)
11150
0
                        return code;
11151
0
                }
11152
11153
                /* If we hit an error during an SMask, we need to undo the color
11154
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11155
                 * for itself if it needs to take action.
11156
                 */
11157
10.8k
                pdf14_decrement_smask_color(pgs, dev);
11158
                /* Restore the color_info for the clist device */
11159
10.8k
                clistdev->color_info = pdev->saved_target_color_info;
11160
10.8k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11161
10.8k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11162
10.8k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11163
10.8k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11164
10.8k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11165
10.8k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11166
10.8k
                gx_set_cmap_procs(pgs, clistdev);
11167
10.8k
                gx_device_decache_colors(clistdev);
11168
                /* Disable the PDF 1.4 compositor */
11169
10.8k
                pdf14_disable_clist_device(mem, pgs, dev);
11170
                /*
11171
                 * Make sure that the transfer funtions, etc. are current.
11172
                 */
11173
10.8k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11174
10.8k
                if (code < 0)
11175
0
                    return code;
11176
10.8k
                break;
11177
10.8k
            }
11178
10.8k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11179
42.6k
            case PDF14_BEGIN_TRANS_GROUP:
11180
42.6k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11181
20.3k
                    pdev->depth_within_smask++;
11182
42.6k
                pdev->smask_constructed = 0;
11183
                /*
11184
                 * Keep track of any changes made in the blending parameters.
11185
                   These need to be written out in the same bands as the group
11186
                   information is written.  Hence the passing of the dimensions
11187
                   for the group. */
11188
42.6k
                code = pdf14_clist_update_params(pdev, pgs, true,
11189
42.6k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11190
42.6k
                if (code < 0)
11191
0
                    return code;
11192
42.6k
                if (pdf14pct->params.Background_components != 0 &&
11193
0
                    pdf14pct->params.Background_components !=
11194
0
                    pdev->color_info.num_components)
11195
0
                    return_error(gs_error_rangecheck);
11196
11197
                /* We need to update the clist writer device procs based upon the
11198
                   the group color space. This ensures the proper color data is
11199
                   written out to the device. For simplicity, the list item is
11200
                   created even if the color space did not change */
11201
42.6k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11202
42.6k
                if (code < 0)
11203
0
                    return code;
11204
11205
42.6k
                break;
11206
45.0k
            case PDF14_BEGIN_TRANS_MASK:
11207
                /* We need to update the clist writer device procs based upon the
11208
                   the group color space.  For simplicity, the list item is created
11209
                   even if the color space did not change */
11210
                /* First store the current ones */
11211
45.0k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11212
24.5k
                    break;
11213
11214
                /* Update the color settings of the clist writer.  Store information in stack */
11215
20.4k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11216
20.4k
                if (code < 0)
11217
0
                    return code;
11218
11219
                /* Also, if the BC is a value that may end up as something other
11220
                  than transparent. We must use the parent colors bounding box in
11221
                  determining the range of bands in which this mask can affect.
11222
                  So, if needed change the masks bounding box at this time */
11223
20.4k
                pdev->in_smask_construction++;
11224
20.4k
                break;
11225
391k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11226
391k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11227
21
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11228
21
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11229
21
                } else
11230
391k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11231
391k
                *pcdev = dev;
11232
391k
                return 0; /* Never put into clist. Only used during writing */
11233
393k
            case PDF14_END_TRANS_TEXT_GROUP:
11234
393k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11235
390k
                    *pcdev = dev;
11236
390k
                    return 0; /* Avoids spurious ET calls in interpreter */
11237
390k
                }
11238
2.93k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11239
2.93k
                code = pdf14_clist_pop_color_model(dev, pgs);
11240
2.93k
                if (code < 0)
11241
0
                    return code;
11242
2.93k
                break;
11243
20.4k
            case PDF14_END_TRANS_MASK:
11244
20.4k
                pdev->in_smask_construction--;
11245
20.4k
                if (pdev->in_smask_construction < 0)
11246
0
                    pdev->in_smask_construction = 0;
11247
20.4k
                if (pdev->in_smask_construction == 0)
11248
20.4k
                    pdev->smask_constructed = 1;
11249
                /* fallthrough */
11250
60.1k
            case PDF14_END_TRANS_GROUP:
11251
                /* We need to update the clist writer device procs based upon the
11252
                   the group color space. */
11253
60.1k
                code = pdf14_clist_pop_color_model(dev, pgs);
11254
60.1k
                if (pdev->depth_within_smask)
11255
20.3k
                    pdev->depth_within_smask--;
11256
60.1k
                if (code < 0)
11257
0
                    return code;
11258
60.1k
                break;
11259
60.1k
            case PDF14_PUSH_TRANS_STATE:
11260
0
                break;
11261
19.9k
            case PDF14_POP_TRANS_STATE:
11262
19.9k
                break;
11263
20.4k
            case PDF14_PUSH_SMASK_COLOR:
11264
20.4k
                code = pdf14_increment_smask_color(pgs,dev);
11265
20.4k
                *pcdev = dev;
11266
20.4k
                return code;  /* Note, this are NOT put in the clist */
11267
0
                break;
11268
20.4k
            case PDF14_POP_SMASK_COLOR:
11269
20.4k
                code = pdf14_decrement_smask_color(pgs,dev);
11270
20.4k
                *pcdev = dev;
11271
20.4k
                return code;  /* Note, this are NOT put in the clist */
11272
0
                break;
11273
0
            case PDF14_SET_BLEND_PARAMS:
11274
                /* If there is a change we go ahead and apply it to the target */
11275
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11276
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11277
0
                *pcdev = dev;
11278
0
                return code;
11279
0
                break;
11280
0
            case PDF14_ABORT_DEVICE:
11281
0
                code = gx_abort_trans_device(pgs, dev);
11282
0
                if (pdev->free_devicen) {
11283
0
                    devn_free_params(dev);
11284
0
                }
11285
0
                pdf14_disable_device(dev);
11286
0
                pdf14_close(dev);
11287
0
                *pcdev = dev;
11288
0
                return code;
11289
0
                break;
11290
0
            default:
11291
0
                break;   /* Pass remaining ops to target */
11292
1.00M
        }
11293
1.00M
    }
11294
810k
    code = dev_proc(pdev->target, composite)
11295
810k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11296
    /* If we were accumulating into a pdf14-clist-accum device, */
11297
    /* we now have to render the page into it's target device */
11298
810k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11299
10.8k
        pdev->target->stype == &st_gx_devn_accum_device) {
11300
11301
3.96k
        int i, y, rows_used;
11302
3.96k
        byte *linebuf;
11303
3.96k
        byte *actual_data;
11304
3.96k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11305
        /* get the target device we want to send the image to */
11306
3.96k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11307
3.96k
        gs_image1_t image;
11308
3.96k
        gs_color_space *pcs;
11309
3.96k
        gx_image_enum_common_t *info = NULL;
11310
3.96k
        gx_image_plane_t planes;
11311
3.96k
        gsicc_rendering_param_t render_cond;
11312
3.96k
        cmm_dev_profile_t *dev_profile;
11313
3.96k
        bool save_planar = pdev->num_planar_planes;
11314
3.96k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11315
3.96k
        int save_num_separations;
11316
3.96k
        gs_int_rect rect;
11317
11318
3.96k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11319
3.96k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11320
3.96k
        pdev->num_planar_planes = save_planar;
11321
11322
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11323
         * colors do require devn support
11324
         */
11325
3.96k
        if (tdev->color_info.num_components <= 4 ||
11326
3.96k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11327
            /*
11328
             * Set color space in preparation for sending an image.
11329
             */
11330
3.96k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11331
3.96k
            if (code < 0)
11332
0
                goto put_accum_error;
11333
11334
            /* Need to set this to avoid color management during the
11335
               image color render operation.  Exception is for the special case
11336
               when the destination was CIELAB.  Then we need to convert from
11337
               default RGB to CIELAB in the put image operation.  That will happen
11338
               here as we should have set the profile for the pdf14 device to RGB
11339
               and the target will be CIELAB */
11340
3.96k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11341
3.96k
            if (code < 0)
11342
0
                goto put_accum_error;
11343
3.96k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11344
3.96k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11345
            /* pcs takes a reference to the profile data it just retrieved. */
11346
3.96k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11347
3.96k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11348
3.96k
        } else {
11349
             /* DeviceN case -- need to handle spot colors */
11350
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11351
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11352
0
            if (code < 0)
11353
0
                goto put_accum_error;
11354
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11355
0
            pcs->params.device_n.use_alt_cspace = false;
11356
11357
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11358
0
                goto put_accum_error;
11359
0
            }
11360
            /* One last thing -- we need to fudge the pgs->color_component_map */
11361
0
            for (i=0; i < tdev->color_info.num_components; i++)
11362
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11363
            /* copy devn_params that were accumulated into the target device's devn_params */
11364
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11365
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11366
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11367
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11368
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11369
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11370
0
            target_devn_params->separations = tdev->devn_params.separations;
11371
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11372
0
                   sizeof(gs_separation_map));
11373
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11374
0
        }
11375
3.96k
        if (linebuf == NULL) {
11376
0
            code = gs_error_VMerror;
11377
0
            goto put_accum_error;
11378
0
        }
11379
3.96k
        gs_image_t_init_adjust(&image, pcs, false);
11380
3.96k
        image.ImageMatrix.xx = (float)pdev->width;
11381
3.96k
        image.ImageMatrix.yy = (float)pdev->height;
11382
3.96k
        image.Width = pdev->width;
11383
3.96k
        image.Height = pdev->height;
11384
3.96k
        image.BitsPerComponent = 8<<deep;
11385
3.96k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11386
3.96k
        ctm_only_writable(pgs).xy = 0;
11387
3.96k
        ctm_only_writable(pgs).yx = 0;
11388
3.96k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11389
3.96k
        ctm_only_writable(pgs).tx = 0.0;
11390
3.96k
        ctm_only_writable(pgs).ty = 0.0;
11391
3.96k
        code = dev_proc(target, begin_typed_image) (target,
11392
3.96k
                                                    pgs, NULL,
11393
3.96k
                                                    (gs_image_common_t *)&image,
11394
3.96k
                                                    NULL, NULL, NULL,
11395
3.96k
                                                    pgs->memory, &info);
11396
3.96k
        if (code < 0)
11397
0
            goto put_accum_error;
11398
3.96k
        rect.p.x = 0;
11399
3.96k
        rect.q.x = tdev->width;
11400
8.50M
        for (y=0; y < tdev->height; y++) {
11401
8.50M
            gs_get_bits_params_t params;
11402
11403
8.50M
            params.options = (GB_ALIGN_ANY |
11404
8.50M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11405
8.50M
                              GB_OFFSET_0 |
11406
8.50M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11407
8.50M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11408
8.50M
            params.x_offset = 0;
11409
8.50M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11410
8.50M
            params.data[0] = linebuf;
11411
8.50M
            rect.p.y = y;
11412
8.50M
            rect.q.y = y+1;
11413
8.50M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11414
8.50M
                                                      &rect, &params);
11415
8.50M
            if (code < 0)
11416
7
                goto put_accum_error;
11417
8.50M
            actual_data = params.data[0];
11418
8.50M
            planes.data = actual_data;
11419
8.50M
            planes.data_x = 0;
11420
8.50M
            planes.raster = tdev->width * tdev->color_info.num_components;
11421
8.50M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11422
0
                goto put_accum_error;
11423
8.50M
        }
11424
11425
3.96k
put_accum_error:
11426
3.96k
        if (info != NULL) {
11427
3.96k
            if (code < 0)
11428
7
                (void)info->procs->end_image(info, true);
11429
3.95k
            else
11430
3.95k
                code = info->procs->end_image(info, true);
11431
3.96k
        }
11432
11433
3.96k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11434
        /* This will also decrement the device profile */
11435
3.96k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11436
3.96k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11437
        /* Now unhook the clist device and hook to the original so we can clean up */
11438
3.96k
        gx_device_set_target((gx_device_forward *)pdev,
11439
3.96k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11440
3.96k
        pdev->pclist_device = pdev->target;
11441
3.96k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11442
3.96k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11443
3.96k
        if (target_devn_params != NULL) {
11444
            /* prevent devn_free_params from freeing names still in use by target device */
11445
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11446
0
            tdev->devn_params.separations.num_separations = 0;
11447
0
        }
11448
3.96k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11449
3.96k
        if (target_devn_params != NULL) {
11450
0
            target_devn_params->separations.num_separations = save_num_separations;
11451
0
        }
11452
3.96k
        return code;    /* DON'T perform set_target */
11453
3.96k
    }
11454
806k
    if (code == 1) {
11455
        /* We just wrapped pdev->target, so we need to update that.*/
11456
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11457
0
        code = 0; /* We did not wrap dev. */
11458
0
    }
11459
806k
    *pcdev = dev;
11460
806k
    return code;
11461
810k
}
11462
11463
/*
11464
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11465
 * compositor' method.  However the compositor is disabled when we are not
11466
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11467
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11468
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11469
 * to the targer.
11470
 */
11471
static  int
11472
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11473
        const gs_composite_t * pct, gs_gstate * pgs,
11474
        gs_memory_t * mem, gx_device *cdev)
11475
0
{
11476
0
    pdf14_device *pdev = (pdf14_device *)dev;
11477
0
    gx_device * tdev = pdev->target;
11478
0
    gx_device * ndev;
11479
0
    int code;
11480
11481
0
    *pcdev = dev;
11482
0
    if (gs_is_pdf14trans_compositor(pct)) {
11483
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11484
11485
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11486
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11487
0
        return 0;
11488
0
    }
11489
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11490
0
    if (code == 1) {
11491
        /* We just wrapped tdev, so update our target. */
11492
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11493
0
        code = 0; /* We did not wrap dev. */
11494
0
    }
11495
0
    return code;
11496
0
}
11497
11498
/*
11499
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11500
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11501
 */
11502
static  int
11503
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11504
                          bool crop_blend_params,
11505
                          gs_pdf14trans_params_t *group_params)
11506
3.86M
{
11507
3.86M
    gs_pdf14trans_params_t params = { 0 };
11508
3.86M
    gx_device * pcdev;
11509
3.86M
    int changed = 0;
11510
3.86M
    int code = 0;
11511
3.86M
    gs_composite_t *pct_new = NULL;
11512
11513
3.86M
    params.crop_blend_params = crop_blend_params;
11514
11515
3.86M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11516
3.86M
    if (pgs->blend_mode != pdev->blend_mode) {
11517
21.9k
        changed |= PDF14_SET_BLEND_MODE;
11518
21.9k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11519
21.9k
    }
11520
3.86M
    if (pgs->text_knockout != pdev->text_knockout) {
11521
10.4k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11522
10.4k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11523
10.4k
    }
11524
3.86M
    if (pgs->alphaisshape != pdev->ais) {
11525
1.37k
        changed |= PDF14_SET_AIS;
11526
1.37k
        params.ais = pdev->ais = pgs->alphaisshape;
11527
1.37k
    }
11528
3.86M
    if (pgs->overprint != pdev->overprint) {
11529
12.9k
        changed |= PDF14_SET_OVERPRINT;
11530
12.9k
        params.overprint = pdev->overprint = pgs->overprint;
11531
12.9k
    }
11532
3.86M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11533
12.8k
        changed |= PDF14_SET_STROKEOVERPRINT;
11534
12.8k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11535
12.8k
    }
11536
3.86M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11537
24.1k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11538
24.1k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11539
24.1k
    }
11540
3.86M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11541
15.8k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11542
15.8k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11543
15.8k
    }
11544
3.86M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11545
26.1k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11546
26.1k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11547
26.1k
        if_debug0m('v', pgs->memory,
11548
26.1k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11549
26.1k
    }
11550
3.86M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11551
27.2k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11552
27.2k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11553
27.2k
        if_debug0m('v', pgs->memory,
11554
27.2k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11555
27.2k
    }
11556
3.86M
    if (crop_blend_params) {
11557
42.6k
        params.ctm = group_params->ctm;
11558
42.6k
        params.bbox = group_params->bbox;
11559
42.6k
    }
11560
3.86M
    params.changed = changed;
11561
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11562
       now to the target.  Otherwise we send the compositor action
11563
       to the pdf14 device at this time.  This is due to the fact that we
11564
       need to often perform this operation when we are already starting to
11565
       do a compositor action */
11566
3.86M
    if (changed != 0) {
11567
107k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11568
107k
        if (code < 0)
11569
0
            return code;
11570
107k
        code = dev_proc(pdev->target, composite)
11571
107k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11572
107k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11573
107k
    }
11574
3.86M
    return code;
11575
3.86M
}
11576
11577
/*
11578
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11579
 * writing the clist.
11580
 */
11581
static  int
11582
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11583
                           gx_path *ppath, const gx_fill_params *params,
11584
                           const gx_drawing_color *pdcolor,
11585
                           const gx_clip_path *pcpath)
11586
981k
{
11587
981k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11588
981k
    gs_gstate new_pgs = *pgs;
11589
981k
    int code;
11590
981k
    gs_pattern2_instance_t *pinst = NULL;
11591
981k
    gx_device_forward * fdev = (gx_device_forward *)dev;
11592
981k
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11593
981k
    gsicc_rendering_param_t render_cond;
11594
981k
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11595
981k
    int push_group = 0;
11596
11597
981k
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11598
981k
    if (code < 0)
11599
0
        return code;
11600
981k
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11601
981k
    if (code < 0)
11602
0
        return code;
11603
11604
981k
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11605
1.02k
        check_device_separable(dev);
11606
11607
981k
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11608
981k
                          &render_cond);
11609
981k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11610
981k
                          &render_cond);
11611
11612
    /*
11613
     * Ensure that that the PDF 1.4 reading compositor will have the current
11614
     * blending parameters.  This is needed since the fill_rectangle routines
11615
     * do not have access to the gs_gstate.  Thus we have to pass any
11616
     * changes explictly.
11617
     */
11618
981k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11619
981k
    if (code < 0)
11620
0
        return code;
11621
    /* If we are doing a shading fill and we are in a transparency group of a
11622
       different color space, then we do not want to do the shading in the
11623
       device color space. It must occur in the source space.  To handle it in
11624
       the device space would require knowing all the nested transparency group
11625
       color space as well as the transparency.  Some of the shading code ignores
11626
       this, so we have to pass on the clist_writer device to enable proper
11627
       mapping to the transparency group color space. */
11628
11629
981k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11630
        /* Non-idempotent blends require a transparency
11631
         * group to be pushed because shadings might
11632
         * paint several pixels twice. */
11633
4.85k
        push_group = pgs->fillconstantalpha != 1.0 ||
11634
4.78k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11635
4.85k
        pinst =
11636
4.85k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11637
4.85k
           pinst->saved->has_transparency = true;
11638
           /* The transparency color space operations are driven by the pdf14
11639
              clist writer device.  */
11640
4.85k
           pinst->saved->trans_device = dev;
11641
4.85k
    }
11642
981k
    if (push_group) {
11643
76
        gs_fixed_rect box;
11644
76
        gs_fixed_rect dev_bbox;
11645
11646
76
        if (pcpath) {
11647
76
            gx_cpath_outer_box(pcpath, &box);
11648
76
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11649
76
            rect_intersect(box, dev_bbox);
11650
76
        } else
11651
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11652
11653
76
        if (ppath) {
11654
20
            gs_fixed_rect path_box;
11655
11656
20
            gx_path_bbox(ppath, &path_box);
11657
20
            if (box.p.x < path_box.p.x)
11658
20
                box.p.x = path_box.p.x;
11659
20
            if (box.p.y < path_box.p.y)
11660
20
                box.p.y = path_box.p.y;
11661
20
            if (box.q.x > path_box.q.x)
11662
20
                box.q.x = path_box.q.x;
11663
20
            if (box.q.y > path_box.q.y)
11664
20
                box.q.y = path_box.q.y;
11665
20
        }
11666
11667
76
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11668
            /* No need to do anything */
11669
36
            if (pinst != NULL) {
11670
36
                pinst->saved->trans_device = NULL;
11671
36
            }
11672
36
            return 0;
11673
36
        }
11674
11675
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11676
40
        code = push_shfill_group(pdev, &new_pgs, &box);
11677
40
    } else
11678
980k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11679
980k
    if (code >= 0) {
11680
980k
        new_pgs.trans_device = dev;
11681
980k
        new_pgs.has_transparency = true;
11682
980k
        if (gx_dc_is_pattern2_color(pdcolor))
11683
4.81k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11684
976k
        else
11685
976k
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11686
980k
        new_pgs.trans_device = NULL;
11687
980k
        new_pgs.has_transparency = false;
11688
980k
    }
11689
980k
    if (code >= 0 && push_group) {
11690
38
        code = pop_shfill_group(&new_pgs);
11691
38
        if (code >= 0)
11692
38
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11693
38
    }
11694
980k
    if (pinst != NULL){
11695
4.81k
        pinst->saved->trans_device = NULL;
11696
4.81k
    }
11697
980k
    return code;
11698
981k
}
11699
11700
/*
11701
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11702
 * writing the clist.
11703
 */
11704
static  int
11705
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11706
                             gx_path *ppath, const gx_stroke_params *params,
11707
                             const gx_drawing_color *pdcolor,
11708
                             const gx_clip_path *pcpath)
11709
341k
{
11710
341k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11711
341k
    gs_gstate new_pgs = *pgs;
11712
341k
    int code = 0;
11713
341k
    gs_pattern2_instance_t *pinst = NULL;
11714
341k
    int push_group = 0;
11715
11716
    /*
11717
     * Ensure that that the PDF 1.4 reading compositor will have the current
11718
     * blending parameters.  This is needed since the fill_rectangle routines
11719
     * do not have access to the gs_gstate.  Thus we have to pass any
11720
     * changes explictly.
11721
     */
11722
341k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11723
341k
    if (code < 0)
11724
0
        return code;
11725
    /* If we are doing a shading stroke and we are in a transparency group of a
11726
       different color space, then we need to get the proper device information
11727
       passed along so that we use the correct color procs and colorinfo about
11728
       the transparency device and not the final target device */
11729
341k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11730
        /* Non-idempotent blends require a transparency
11731
         * group to be pushed because shadings might
11732
         * paint several pixels twice. */
11733
40
        push_group = pgs->strokeconstantalpha != 1.0 ||
11734
40
               !blend_is_idempotent(gs_currentblendmode(pgs));
11735
40
        if (pdev->color_model_stack != NULL) {
11736
40
            pinst =
11737
40
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11738
40
            pinst->saved->has_transparency = true;
11739
            /* The transparency color space operations are driven
11740
              by the pdf14 clist writer device.  */
11741
40
            pinst->saved->trans_device = dev;
11742
40
        }
11743
40
    }
11744
341k
    if (push_group) {
11745
0
        gs_fixed_rect box;
11746
0
        if (pcpath)
11747
0
            gx_cpath_outer_box(pcpath, &box);
11748
0
        else
11749
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11750
0
        if (ppath) {
11751
0
            gs_fixed_rect path_box;
11752
0
            gs_fixed_point expansion;
11753
11754
0
            gx_path_bbox(ppath, &path_box);
11755
            /* Expand the path bounding box by the scaled line width. */
11756
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11757
                /* The expansion is so large it caused a limitcheck. */
11758
0
                path_box.p.x = path_box.p.y = min_fixed;
11759
0
                path_box.q.x = path_box.q.y = max_fixed;
11760
0
            } else {
11761
0
                expansion.x += pgs->fill_adjust.x;
11762
0
                expansion.y += pgs->fill_adjust.y;
11763
                /*
11764
                 * It's theoretically possible for the following computations to
11765
                 * overflow, so we need to check for this.
11766
                 */
11767
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11768
0
                                path_box.p.x - expansion.x);
11769
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11770
0
                                path_box.p.y - expansion.y);
11771
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11772
0
                                path_box.q.x + expansion.x);
11773
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11774
0
                                path_box.q.y + expansion.y);
11775
0
            }
11776
0
            if (box.p.x < path_box.p.x)
11777
0
                box.p.x = path_box.p.x;
11778
0
            if (box.p.y < path_box.p.y)
11779
0
                box.p.y = path_box.p.y;
11780
0
            if (box.q.x > path_box.q.x)
11781
0
                box.q.x = path_box.q.x;
11782
0
            if (box.q.y > path_box.q.y)
11783
0
                box.q.y = path_box.q.y;
11784
0
        }
11785
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11786
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11787
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11788
0
    } else
11789
341k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11790
11791
341k
    if (code >= 0) {
11792
341k
        new_pgs.trans_device = dev;
11793
341k
        new_pgs.has_transparency = true;
11794
341k
        if (gx_dc_is_pattern2_color(pdcolor))
11795
40
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11796
341k
        else
11797
341k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11798
341k
        new_pgs.trans_device = NULL;
11799
341k
        new_pgs.has_transparency = false;
11800
341k
    }
11801
341k
    if (code >= 0 && push_group) {
11802
0
        code = pop_shfill_group(&new_pgs);
11803
0
        if (code >= 0)
11804
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11805
0
    }
11806
341k
    if (pinst != NULL)
11807
40
        pinst->saved->trans_device = NULL;
11808
341k
    return code;
11809
341k
}
11810
11811
/* Set up work for doing shading patterns in fill stroke through
11812
   the clist.  We have to do all the dirty work now since we are
11813
   going through the default fill and stroke operations individually */
11814
static int
11815
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11816
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11817
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11818
    const gx_clip_path* pcpath)
11819
0
{
11820
0
    union {
11821
0
        const gs_gstate *cpgs;
11822
0
        gs_gstate *pgs;
11823
0
    } const_breaker;
11824
0
    gs_gstate *pgs;
11825
0
    int code, code2;
11826
0
    gs_transparency_group_params_t params = { 0 };
11827
0
    gs_fixed_rect clip_bbox;
11828
0
    gs_rect bbox, group_stroke_box;
11829
0
    float fill_alpha;
11830
0
    float stroke_alpha;
11831
0
    gs_blend_mode_t blend_mode;
11832
0
    gs_fixed_rect path_bbox;
11833
0
    int expansion_code;
11834
0
    gs_fixed_point expansion;
11835
11836
    /* Break const just once, neatly */
11837
0
    const_breaker.cpgs = cpgs;
11838
0
    pgs = const_breaker.pgs;
11839
11840
0
    fill_alpha = pgs->fillconstantalpha;
11841
0
    stroke_alpha = pgs->strokeconstantalpha;
11842
0
    blend_mode = pgs->blend_mode;
11843
11844
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11845
0
    if (code < 0 && code != gs_error_unknownerror)
11846
0
        return code;
11847
0
    if (code == gs_error_unknownerror) {
11848
        /* didn't get clip box from gx_curr_fixed_bbox */
11849
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11850
0
        clip_bbox.q.x = int2fixed(dev->width);
11851
0
        clip_bbox.q.y = int2fixed(dev->height);
11852
0
    }
11853
0
    if (pcpath)
11854
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11855
11856
    /* expand the ppath using stroke expansion rule, then intersect it */
11857
0
    code = gx_path_bbox(ppath, &path_bbox);
11858
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11859
0
        return 0;   /* ignore empty path */
11860
0
    if (code < 0)
11861
0
        return code;
11862
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11863
0
    if (expansion_code >= 0) {
11864
0
        path_bbox.p.x -= expansion.x;
11865
0
        path_bbox.p.y -= expansion.y;
11866
0
        path_bbox.q.x += expansion.x;
11867
0
        path_bbox.q.y += expansion.y;
11868
0
    }
11869
0
    rect_intersect(path_bbox, clip_bbox);
11870
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11871
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11872
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11873
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11874
11875
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11876
0
    if (code < 0)
11877
0
        return code;
11878
11879
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11880
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11881
0
        pgs->overprint && pgs->stroke_overprint &&
11882
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11883
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11884
11885
0
        params.Isolated = false;
11886
0
        params.group_color_type = UNKNOWN;
11887
0
        params.Knockout = false;
11888
0
        params.page_group = false;
11889
0
        params.group_opacity = fill_alpha;
11890
0
        params.group_shape = 1.0;
11891
11892
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11893
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11894
0
        if (code < 0)
11895
0
            return code;
11896
11897
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11898
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11899
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11900
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11901
11902
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11903
0
        if (code < 0)
11904
0
            goto cleanup;
11905
11906
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11907
0
        if (code < 0)
11908
0
            goto cleanup;
11909
11910
0
    } else {
11911
        /* Push a non-isolated knockout group. Do not change the alpha or
11912
           blend modes */
11913
0
        params.Isolated = false;
11914
0
        params.group_color_type = UNKNOWN;
11915
0
        params.Knockout = true;
11916
0
        params.page_group = false;
11917
0
        params.group_opacity = 1.0;
11918
0
        params.group_shape = 1.0;
11919
11920
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11921
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11922
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11923
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11924
11925
        /* restore blend mode for actual drawing in the group */
11926
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11927
11928
0
        if (fill_alpha > 0.0) {
11929
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11930
11931
            /* If we are in an overprint situation, set the blend mode to compatible
11932
               overprint */
11933
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11934
0
                pgs->overprint &&
11935
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11936
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11937
11938
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11939
0
            if (code < 0)
11940
0
                goto cleanup;
11941
11942
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11943
0
                pgs->overprint &&
11944
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11945
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11946
0
        }
11947
11948
0
        if (stroke_alpha > 0.0) {
11949
            /* Note that the stroke can end up looking like a fill here */
11950
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11951
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11952
11953
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11954
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11955
11956
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11957
0
            if (code < 0)
11958
0
                goto cleanup;
11959
11960
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11961
0
                pgs->overprint &&
11962
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11963
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11964
0
        }
11965
0
    }
11966
11967
0
cleanup:
11968
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11969
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11970
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11971
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11972
11973
    /* Restore where we were. If an error occured while in the group push
11974
       return that error code but try to do the cleanup */
11975
0
    code2 = gs_end_transparency_group(pgs);
11976
0
    if (code2 < 0) {
11977
        /* At this point things have gone very wrong. We should just shut down */
11978
0
        code = gs_abort_pdf14trans_device(pgs);
11979
0
        return code2;
11980
0
    }
11981
11982
    /* Restore if there were any changes */
11983
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11984
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11985
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11986
11987
0
    return code;
11988
0
}
11989
11990
/*
11991
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11992
 * writing the clist.
11993
 */
11994
static  int
11995
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11996
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11997
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11998
                             const gx_clip_path *pcpath)
11999
8.80k
{
12000
8.80k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12001
8.80k
    gs_gstate new_pgs = *pgs;
12002
8.80k
    int code;
12003
12004
8.80k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12005
8.71k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12006
95
        return 0;
12007
12008
    /*
12009
     * Ensure that that the PDF 1.4 reading compositor will have the current
12010
     * blending parameters.  This is needed since the fill_rectangle routines
12011
     * do not have access to the gs_gstate.  Thus we have to pass any
12012
     * changes explictly.
12013
     */
12014
8.70k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12015
8.70k
    if (code < 0)
12016
0
        return code;
12017
    /* If we are doing a shading fill or stroke, the clist can't
12018
       deal with this and end up in the pdf_fill_stroke operation.
12019
       We will need to break up the fill stroke now and do
12020
       the appropriate group pushes and set up. */
12021
12022
8.70k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12023
8.70k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12024
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12025
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12026
0
    }
12027
8.70k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12028
8.70k
    new_pgs.trans_device = dev;
12029
8.70k
    new_pgs.has_transparency = true;
12030
8.70k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12031
8.70k
                                       params_stroke, pdevc_stroke, pcpath);
12032
8.70k
    new_pgs.trans_device = NULL;
12033
8.70k
    new_pgs.has_transparency = false;
12034
8.70k
    return code;
12035
8.70k
}
12036
12037
/*
12038
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12039
 * writing the clist.
12040
 */
12041
static  int
12042
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12043
                 const gs_text_params_t * text, gs_font * font,
12044
                 const gx_clip_path * pcpath,
12045
                 gs_text_enum_t ** ppenum)
12046
2.43M
{
12047
2.43M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12048
2.43M
    gs_text_enum_t *penum;
12049
2.43M
    int code;
12050
2.43M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12051
2.43M
    float opacity = pgs->fillconstantalpha;
12052
2.43M
    float shape = 1.0;
12053
2.43M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12054
2.43M
    bool draw = !(text->operation & TEXT_DO_NONE);
12055
2.43M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12056
2.43M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12057
2.43M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12058
12059
2.43M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12060
    /*
12061
     * Ensure that that the PDF 1.4 reading compositor will have the current
12062
     * blending parameters.  This is needed since the fill_rectangle routines
12063
     * do not have access to the gs_gstate.  Thus we have to pass any
12064
     * changes explictly.
12065
     */
12066
2.43M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12067
2.43M
    if (code < 0)
12068
0
        return code;
12069
    /* Pass text_begin to the target */
12070
2.43M
    code = gx_forward_text_begin(dev, pgs, text, font,
12071
2.43M
                                 pcpath, &penum);
12072
2.43M
    if (code < 0)
12073
546
        return code;
12074
12075
   /* Catch case where we already pushed a group and are trying to push another one.
12076
   In that case, we will pop the current one first, as we don't want to be left
12077
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12078
   will not be caught until we do the put_image and notice that the stack is not
12079
   empty. */
12080
2.43M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12081
0
        code = gs_end_transparency_group(pgs);
12082
0
        if (code < 0)
12083
0
            return code;
12084
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12085
0
    }
12086
12087
    /* We may need to push a non-isolated transparency group if the following
12088
    is true.
12089
    1) We are not currently in one that we pushed for text.  This is
12090
    is determined by looking at the pdf14 device.
12091
    2) The blend mode is not Normal or the opacity is not 1.0
12092
    3) Text knockout is set to true
12093
    4) And we are actually drawing text
12094
    */
12095
12096
2.43M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12097
2.43M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12098
2.42M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12099
12.8k
        text_mode != 3 && /* don't bother with invisible text */
12100
12.7k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12101
2.96k
        if (draw) {
12102
2.96k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12103
2.96k
            if (code == 0)
12104
2.96k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12105
2.96k
        }
12106
2.96k
    }
12107
2.43M
    *ppenum = (gs_text_enum_t *)penum;
12108
2.43M
    return code;
12109
2.43M
}
12110
12111
static  int
12112
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12113
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12114
                           const gs_int_rect * prect,
12115
                           const gx_drawing_color * pdcolor,
12116
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12117
                           gx_image_enum_common_t ** pinfo)
12118
46.9k
{
12119
46.9k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12120
46.9k
    int code;
12121
46.9k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12122
46.9k
    const gs_image_t *pim = (const gs_image_t *)pic;
12123
46.9k
    gx_image_enum *penum;
12124
46.9k
    gx_color_tile *ptile;
12125
46.9k
    gs_rect bbox_in, bbox_out;
12126
46.9k
    gs_transparency_group_params_t tgp;
12127
    /*
12128
     * Ensure that that the PDF 1.4 reading compositor will have the current
12129
     * blending parameters.  This is needed since the fill_rectangle routines
12130
     * do not have access to the gs_gstate.  Thus we have to pass any
12131
     * changes explictly.
12132
     */
12133
46.9k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12134
46.9k
    if (code < 0)
12135
0
        return code;
12136
    /* Pass image to the target */
12137
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12138
       case the clist writer cannot handle this image itself.  In such a case,
12139
       we want to make sure we dont use the target device.  I don't necc. like
12140
       doing it this way.  Probably need to go back and do something a bit
12141
       more elegant. */
12142
46.9k
    pgs_noconst->has_transparency = true;
12143
46.9k
    pgs_noconst->trans_device = dev;
12144
12145
    /* If we are filling an image mask with a pattern that has a transparency
12146
       then we need to do some special handling */
12147
46.9k
    if (pim->ImageMask) {
12148
106
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12149
28
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12150
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12151
0
                    ptile = pdcolor->colors.pattern.p_tile;
12152
                    /* Set up things in the ptile so that we get the proper
12153
                       blending etc */
12154
                    /* Set the blending procs and the is_additive setting based
12155
                       upon the number of channels */
12156
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12157
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12158
0
                        ptile->ttrans->is_additive = true;
12159
0
                    } else {
12160
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12161
0
                        ptile->ttrans->is_additive = false;
12162
0
                    }
12163
                    /* Set the blending mode in the ptile based upon the current
12164
                       setting in the gs_gstate */
12165
0
                    ptile->blending_mode = pgs->blend_mode;
12166
                    /* Set the procs so that we use the proper filling method. */
12167
                    /* Let the imaging stuff get set up */
12168
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12169
0
                                                        prect, pdcolor,
12170
0
                                                        pcpath, mem, pinfo);
12171
0
                    if (code < 0)
12172
0
                        return code;
12173
12174
0
                    penum = (gx_image_enum *) *pinfo;
12175
                    /* Apply inverse of the image matrix to our
12176
                       image size to get our bounding box. */
12177
0
                    bbox_in.p.x = 0;
12178
0
                    bbox_in.p.y = 0;
12179
0
                    bbox_in.q.x = pim->Width;
12180
0
                    bbox_in.q.y = pim->Height;
12181
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12182
0
                                                     &bbox_out);
12183
0
                    if (code < 0)
12184
0
                        return code;
12185
                    /* Set up a compositor action for pushing the group */
12186
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12187
0
                    tgp.Isolated = true;
12188
0
                    tgp.Knockout = false;
12189
0
                    tgp.page_group = false;
12190
0
                    tgp.mask_id = 0;
12191
0
                    tgp.image_with_SMask = false;
12192
0
                    tgp.idle = false;
12193
0
                    tgp.iccprofile = NULL;
12194
0
                    tgp.icc_hashcode = 0;
12195
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12196
0
                    tgp.ColorSpace = NULL;
12197
0
                    tgp.text_group = 0;
12198
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12199
0
                    tgp.group_shape = 1.0;
12200
                    /* This will handle the compositor command */
12201
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12202
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12203
0
                    ptile->ttrans->image_render = penum->render;
12204
0
                    penum->render = &pdf14_pattern_trans_render;
12205
0
                    ptile->trans_group_popped = false;
12206
0
                    pgs_noconst->has_transparency = false;
12207
0
                    pgs_noconst->trans_device = NULL;
12208
0
                    return code;
12209
0
                }
12210
0
            }
12211
28
        }
12212
106
    }
12213
    /* This basically tries high level images for clist. If that fails
12214
       then we do the default */
12215
46.9k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12216
46.9k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12217
46.9k
    if (code < 0){
12218
11.6k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12219
11.6k
                                        pdcolor, pcpath, mem, pinfo);
12220
11.6k
        pgs_noconst->has_transparency = false;
12221
11.6k
        pgs_noconst->trans_device = NULL;
12222
11.6k
        return code;
12223
35.3k
    } else {
12224
35.3k
        pgs_noconst->has_transparency = false;
12225
35.3k
        pgs_noconst->trans_device = NULL;
12226
35.3k
        return code;
12227
35.3k
    }
12228
46.9k
}
12229
12230
static int
12231
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12232
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12233
2.45k
{
12234
2.45k
    int code;
12235
12236
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12237
2.45k
                                  x, y, w, h, plane_height);
12238
2.45k
    return code;
12239
2.45k
}
12240
12241
static int
12242
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12243
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12244
11.2k
{
12245
11.2k
    int code;
12246
11.2k
    pdf14_clist_device *p14dev;
12247
11.2k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12248
12249
11.2k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12250
11.2k
    if (code < 0)
12251
0
        return code;
12252
    /*
12253
     * Set the color_info of the clist device to match the compositing
12254
     * device.  We will restore it when the compositor is popped.
12255
     * See pdf14_clist_composite for the restore.  Do the
12256
     * same with the gs_gstate's get_cmap_procs.  We do not want
12257
     * the gs_gstate to use transfer functions on our color values.
12258
     * The transfer functions will be applied at the end after we
12259
     * have done our PDF 1.4 blend operations.
12260
     */
12261
11.2k
    p14dev = (pdf14_clist_device *)(*pcdev);
12262
11.2k
    p14dev->saved_target_color_info = dev->color_info;
12263
11.2k
    dev->color_info = (*pcdev)->color_info;
12264
    /* Make sure that we keep the anti-alias information though */
12265
11.2k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12266
11.2k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12267
12268
    /* adjust the clist_color_info now */
12269
11.2k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12270
11.2k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12271
11.2k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12272
11.2k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12273
11.2k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12274
12275
11.2k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12276
11.2k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12277
11.2k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12278
11.2k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12279
11.2k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12280
11.2k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12281
11.2k
    p14dev->saved_target_get_color_mapping_procs =
12282
11.2k
                              dev_proc(dev, get_color_mapping_procs);
12283
11.2k
    p14dev->saved_target_get_color_comp_index =
12284
11.2k
                              dev_proc(dev, get_color_comp_index);
12285
11.2k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12286
11.2k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12287
11.2k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12288
11.2k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12289
11.2k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12290
11.2k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12291
11.2k
    gx_set_cmap_procs(pgs, dev);
12292
11.2k
    return code;
12293
11.2k
}
12294
/*
12295
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12296
 * to create a compositing device for clist writing.  The primary purpose of
12297
 * this device is to provide support for the process color model in which
12298
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12299
 * model of the output device.)  The actual work of compositing the image is
12300
 * done on the output (reader) side of the clist.
12301
 */
12302
static  int
12303
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12304
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12305
300k
{
12306
300k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12307
300k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12308
300k
    int code = 0;
12309
12310
    /* We only handle the push/pop operations */
12311
300k
    switch (pdf14pct->params.pdf14_op) {
12312
11.2k
        case PDF14_PUSH_DEVICE:
12313
11.2k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12314
            /* Change (non-error) code to 1 to indicate that we created
12315
             * a device. */
12316
11.2k
            if (code >= 0)
12317
11.2k
                code = 1;
12318
11.2k
            return code;
12319
12320
10.8k
        case PDF14_POP_DEVICE:
12321
10.8k
            code = clist_writer_check_empty_cropping_stack(cdev);
12322
10.8k
            break;
12323
12324
4.01k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12325
42.6k
        case PDF14_BEGIN_TRANS_GROUP:
12326
42.6k
            { /* HACK: store mask_id into our params for subsequent
12327
                   calls of c_pdf14trans_write. To do this we must
12328
                   break const. */
12329
42.6k
                gs_pdf14trans_t * pdf14pct_noconst;
12330
12331
42.6k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12332
                /* What ever the current mask ID is, that is the
12333
                   softmask group through which this transparency
12334
                   group must be rendered. Store it now. */
12335
42.6k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12336
42.6k
                if_debug1m('v', pgs->memory,
12337
42.6k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12338
42.6k
                           cdev->mask_id);
12339
42.6k
            }
12340
42.6k
            break;
12341
39.6k
        case PDF14_END_TRANS_GROUP:
12342
42.6k
        case PDF14_END_TRANS_TEXT_GROUP:
12343
42.6k
            code = 0; /* A place for breakpoint. */
12344
42.6k
            break;
12345
45.0k
        case PDF14_BEGIN_TRANS_MASK:
12346
            /* A new mask has been started */
12347
45.0k
            cdev->mask_id = ++cdev->mask_id_count;
12348
            /* replacing is set everytime that we
12349
               have a zpushtransparencymaskgroup */
12350
45.0k
            { /* HACK: store mask_id into our params for subsequent
12351
                   calls of c_pdf14trans_write. To do this we must
12352
                   break const. */
12353
45.0k
                gs_pdf14trans_t * pdf14pct_noconst;
12354
12355
45.0k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12356
45.0k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12357
45.0k
                if_debug1m('v', pgs->memory,
12358
45.0k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12359
45.0k
                           cdev->mask_id);
12360
45.0k
            }
12361
45.0k
            break;
12362
20.4k
        case PDF14_END_TRANS_MASK:
12363
20.4k
            code = 0; /* A place for breakpoint. */
12364
20.4k
            break;
12365
0
        case PDF14_PUSH_TRANS_STATE:
12366
0
            code = 0; /* A place for breakpoint. */
12367
0
            break;
12368
19.9k
        case PDF14_POP_TRANS_STATE:
12369
19.9k
            code = 0; /* A place for breakpoint. */
12370
19.9k
            break;
12371
0
        case PDF14_ABORT_DEVICE:
12372
0
            code = 0;
12373
0
            break;
12374
0
        case PDF14_PUSH_SMASK_COLOR:
12375
0
            *pcdev = dev;
12376
0
            return 0;
12377
0
            break;
12378
0
        case PDF14_POP_SMASK_COLOR:
12379
0
            *pcdev = dev;
12380
0
            return 0;
12381
0
            break;
12382
107k
        default:
12383
107k
            break;   /* do nothing for remaining ops */
12384
300k
    }
12385
289k
    *pcdev = dev;
12386
289k
    if (code < 0)
12387
0
        return code;
12388
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12389
       apply_composite. */
12390
289k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12391
    /* Wrote an extra ctm. */
12392
289k
    cmd_clear_known(cdev, ctm_known);
12393
12394
289k
    return code;
12395
289k
}
12396
12397
/*
12398
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12399
 * device color_info data match the compositing device.  We need to do this
12400
 * since the PDF 1.4 transparency compositing device may use a different
12401
 * process color model than the output device.  We do not need to modify the
12402
 * color related device procs since the compositing device has its own.  We
12403
 * restore the color_info data when the transparency device is popped.
12404
 */
12405
static  int
12406
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12407
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12408
22.7M
{
12409
22.7M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12410
22.7M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12411
22.7M
    gs_devn_params * pclist_devn_params;
12412
22.7M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12413
22.7M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12414
22.7M
    gsicc_rendering_param_t render_cond;
12415
22.7M
    cmm_dev_profile_t *dev_profile;
12416
12417
22.7M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12418
22.7M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12419
22.7M
                          &render_cond);
12420
12421
    /* If we are using the blending color space, then be sure to use that. */
12422
22.7M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12423
0
        dev_profile->blend_profile != NULL)
12424
0
        cl_icc_profile = dev_profile->blend_profile;
12425
22.7M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12426
0
        dev_profile->oi_profile != NULL)
12427
0
        cl_icc_profile = dev_profile->oi_profile;
12428
12429
22.7M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12430
22.7M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12431
22.7M
                          &render_cond);
12432
    /*
12433
     * We only handle the push/pop operations. Save and restore the color_info
12434
     * field for the clist device.  This is needed since the process color
12435
     * model of the clist device needs to match the PDF 1.4 compositing
12436
     * device.
12437
     */
12438
22.7M
    switch (pdf14pct->params.pdf14_op) {
12439
1.14M
    case PDF14_PUSH_DEVICE:
12440
        /* Overprint simulation sets the profile at prototype creation, as does
12441
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12442
1.14M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12443
1.14M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12444
1.14M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12445
1.14M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12446
1.14M
                -1, "c_pdf14trans_clist_read_update");
12447
1.14M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12448
1.14M
        }
12449
            /*
12450
             * If we are blending using spot colors (i.e. the output device
12451
             * supports spot colors) then we need to transfer
12452
             * color info from the clist PDF 1.4 compositing reader device
12453
             * to the clist writer PDF 1.4 compositing device.
12454
             * This info was transfered from that device to the output
12455
             * device as a set of device parameters.  However the clist
12456
             * reader PDF 1.4 compositing device did not exist when the
12457
             * device parameters were read from the clist.  So that info
12458
             * was buffered into the output device.
12459
             */
12460
1.14M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12461
1.14M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12462
846
                int num_comp = p14dev->color_info.num_components;
12463
846
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12464
                /*
12465
                 * The number of components for the PDF14 device is the sum
12466
                 * of the process components and the number of spot colors
12467
                 * for the page.  If the color capabilities of the parent
12468
                 * device (which coming into this are the same as the p14dev)
12469
                 * are smaller than the number of page spot colors then
12470
                 * use that for the number of components. Otherwise use
12471
                 * the page_spot_colors.  The exception is, if we had used
12472
                 * the sICCOutputColors setting, then just use that, which
12473
                 * should be already baked into num_comp. With clist patterns,
12474
                 * cdev->icc_struct may be null.
12475
                 */
12476
12477
846
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12478
846
                    p14dev->devn_params.page_spot_colors =
12479
846
                        pclist_devn_params->page_spot_colors;
12480
846
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12481
0
                        if (p14dev->num_planar_planes > 0)
12482
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12483
0
                        p14dev->color_info.num_components = num_comp;
12484
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12485
846
                    } else {
12486
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12487
846
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12488
846
                            int n = p14dev->num_std_colorants +
12489
846
                                    p14dev->devn_params.page_spot_colors + has_tags;
12490
846
                            if (p14dev->num_planar_planes > 0)
12491
846
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12492
846
                            p14dev->color_info.num_components = n;
12493
846
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12494
846
                        }
12495
846
                    }
12496
846
                }
12497
                /* limit the num_components to the max. */
12498
846
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12499
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12500
                /* Transfer the data for the spot color names
12501
                   But we have to free what may be there before we do this */
12502
846
                devn_free_params((gx_device*) p14dev);
12503
846
                p14dev->devn_params.separations =
12504
846
                    pclist_devn_params->pdf14_separations;
12505
846
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12506
846
                if (num_comp != p14dev->color_info.num_components) {
12507
                    /* Historically, there has been a comment here:
12508
                       "When the pdf14 device is opened it creates a context and some
12509
                       soft mask related objects.  The push device compositor action
12510
                       will have already created these but they are the wrong size.
12511
                       We must destroy them though before reopening the device."
12512
                       I can't see why this is the case, and testing in the cluster
12513
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12514
                       shows that this freeing/NULLing the ctx here causes problems
12515
                       when the freed ctx is reinserted at the end of clist pattern
12516
                       files. Accordingly, I'm removing the freeing/NULLing for now
12517
                       at least. */
12518
0
                    int code = dev_proc(tdev, open_device) (tdev);
12519
0
                    if (code < 0)
12520
0
                        return code;
12521
0
                }
12522
846
            }
12523
            /* Check if we need to swap out the ICC profile for the pdf14
12524
               device.  This will occur if our source profile for our device
12525
               happens to be something like CIELAB.  Then we will blend in
12526
               RGB (unless a trans group is specified) */
12527
1.14M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12528
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12529
0
                                        -1, "c_pdf14trans_clist_read_update");
12530
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12531
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12532
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12533
                /* Keep a pointer to the clist device */
12534
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12535
0
            }
12536
1.14M
            break;
12537
12538
1.14M
        case PDF14_POP_DEVICE:
12539
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12540
                    the clist playback. This code is not executed while clist
12541
                    writing. */
12542
            cdev->color_info = p14dev->saved_target_color_info;
12543
#     endif
12544
1.14M
           break;
12545
12546
20.4M
        default:
12547
20.4M
            break;   /* do nothing for remaining ops */
12548
22.7M
    }
12549
12550
22.7M
    return 0;
12551
22.7M
}
12552
12553
/*
12554
 * Get cropping for the compositor command.
12555
 */
12556
static  int
12557
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12558
                          int cropping_min, int cropping_max)
12559
300k
{
12560
300k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12561
300k
    switch (pdf14pct->params.pdf14_op) {
12562
11.2k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12563
10.8k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12564
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12565
4.01k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12566
42.6k
        case PDF14_BEGIN_TRANS_GROUP:
12567
42.6k
            { gs_int_rect rect;
12568
12569
                /* Text group always uses parents size*/
12570
42.6k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12571
2.96k
                    *ry = cropping_min;
12572
2.96k
                    *rheight = cropping_max - *ry;
12573
39.6k
                } else {
12574
39.6k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12575
39.6k
                        &pdf14pct->params.bbox, &rect);
12576
                    /* We have to crop this by the parent object.   */
12577
39.6k
                    *ry = max(rect.p.y, cropping_min);
12578
39.6k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12579
39.6k
                }
12580
42.6k
                return PUSHCROP; /* Push cropping. */
12581
4.01k
            }
12582
45.0k
        case PDF14_BEGIN_TRANS_MASK:
12583
45.0k
            { gs_int_rect rect;
12584
12585
45.0k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12586
45.0k
                                                    &pdf14pct->params.bbox, &rect);
12587
                /* We have to crop this by the parent object and worry about the BC outside
12588
                   the range, except for image SMask which don't affect areas outside the image.
12589
                   The presence of a transfer function opens the possibility of issues with this */
12590
45.0k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12591
19.3k
                      pdf14pct->params.function_is_identity)) {
12592
                    /* In this case there will not be a background effect to
12593
                       worry about.  The mask will not have any effect outside
12594
                       the bounding box.  This is NOT the default or common case. */
12595
19.3k
                    *ry = max(rect.p.y, cropping_min);
12596
19.3k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12597
19.3k
                    return PUSHCROP; /* Push cropping. */
12598
25.6k
                }  else {
12599
                    /* We need to make the soft mask range as large as the parent
12600
                       due to the fact that the background color can have an impact
12601
                       OUTSIDE the bounding box of the soft mask */
12602
25.6k
                    *ry = cropping_min;
12603
25.6k
                    *rheight = cropping_max - cropping_min;
12604
25.6k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12605
24.5k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12606
1.15k
                    else
12607
1.15k
                        return PUSHCROP; /* Push cropping. */
12608
25.6k
                }
12609
45.0k
            }
12610
39.6k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12611
2.93k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12612
20.4k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12613
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12614
19.9k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12615
107k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12616
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12617
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12618
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12619
300k
    }
12620
0
    return ALLBANDS;
12621
300k
}
12622
12623
/*
12624
 * This routine will check to see if the color component name matches those
12625
 * that are available amoung the current device's color components.  If the
12626
 * color name is known to the output device then we add it to the list of
12627
 * colorants for the PDF 1.4 transparency compositor.
12628
 *
12629
 * Notes:  There are currently three different versions of The PDF 1.4
12630
 * transparency compositor device.  The choice of which one is being used
12631
 * depends upon the process color model of the output device.  This procedure
12632
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12633
 * plus spot color process color model.
12634
 *
12635
 * Parameters:
12636
 *   dev - pointer to device data structure.
12637
 *   pname - pointer to name (zero termination not required)
12638
 *   nlength - length of the name
12639
 *   number of process colorants (either 1, 3, or 4)
12640
 *
12641
 * This routine returns a positive value (0 to n) which is the device colorant
12642
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12643
 * the colorant is not being used due to a SeparationOrder device parameter.
12644
 * It returns a negative value if not found.
12645
 */
12646
static int
12647
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12648
    int name_size, int component_type, int num_process_colors, int cmyk)
12649
6.94k
{
12650
6.94k
    pdf14_device *pdev = (pdf14_device *)dev;
12651
6.94k
    gx_device *tdev = pdev->target;
12652
6.94k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12653
6.94k
    gs_separations *pseparations;
12654
6.94k
    int comp_index;
12655
6.94k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12656
6.94k
    int offset;
12657
12658
6.94k
    while (tdev->child) {
12659
0
        tdev = tdev->child;
12660
0
    }
12661
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12662
    /* get the devn_params from the target to avoid accessing using the wrong  */
12663
    /* pointer. Bug 696372.                                                    */
12664
6.94k
    if (tdev == (gx_device *)pdev)
12665
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12666
6.94k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12667
6.94k
    pseparations = &pdevn_params->separations;
12668
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12669
     * where we are in a blend color space that is RGB or Gray based and we
12670
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12671
     * Yellow or Black, then we should use the alternate tint transform */
12672
6.94k
    if (num_process_colors < 4) {
12673
594
        int k;
12674
2.97k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12675
2.37k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12676
0
                return -1;
12677
2.37k
        }
12678
594
    }
12679
12680
6.94k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12681
12682
    /* The pdf14_clist_composite may have set the color procs.
12683
       We need the real target procs. */
12684
6.94k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12685
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12686
6.94k
        target_get_color_comp_index =
12687
6.94k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12688
    /*
12689
    * If this is not a separation name then simply forward it to the target
12690
    * device or return -1 if we are doing overprint simulation.
12691
    * The halftone setup expects this.
12692
    */
12693
6.94k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12694
6.94k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12695
6.15k
            if (target_get_color_comp_index != NULL)
12696
6.15k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12697
0
            else
12698
0
                return -1;
12699
6.15k
    }
12700
794
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12701
0
        return -1;
12702
0
    }
12703
12704
    /*
12705
    * Check if the component is in either the process color model list
12706
    * or in the SeparationNames list.
12707
    */
12708
794
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12709
794
        name_size, component_type);
12710
12711
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12712
     * This is a decision we take here to avoid problems with PDFI not
12713
     * counting such colorants as spots. */
12714
794
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12715
36
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12716
0
            return -1;
12717
36
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12718
0
            return -1;
12719
36
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12720
0
            return -1;
12721
36
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12722
0
            return -1;
12723
36
    }
12724
    /* A psdrgb device, with simulate overprint will have become a cmyk
12725
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12726
     * either, but we need to return real numbers for them as the underlying
12727
     * routine won't know about these. */
12728
794
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12729
2
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12730
0
            return 3;
12731
2
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12732
0
            return 0;
12733
2
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12734
0
            return 1;
12735
2
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12736
0
            return 2;
12737
2
    }
12738
12739
    /*
12740
    * Return the colorant number if we know this name.  Note adjustment for
12741
    * compensating of blend color space.
12742
    */
12743
794
    if (comp_index >= 0)
12744
756
        return comp_index - offset;
12745
12746
    /* Only worry about the target if we are not doing an overprint simulation */
12747
38
    if (!pdev->overprint_sim) {
12748
        /*
12749
        * If we do not know this color, check if the output (target) device does.
12750
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12751
        * the colorant so we will only get < 0 returned when we hit the max. for
12752
        * the target device.
12753
        */
12754
38
        if (target_get_color_comp_index != NULL)
12755
38
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12756
0
        else
12757
0
            return -1;
12758
        /*
12759
        * Ignore color if unknown to the output device or if color is not being
12760
        * imaged due to the SeparationOrder device parameter.
12761
        */
12762
38
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12763
0
            return comp_index - offset;
12764
38
    }
12765
12766
    /*
12767
    * This is a new colorant.  Add it to our list of colorants.
12768
    * The limit accounts for the number of process colors (at least 4).
12769
    */
12770
38
    if ((pseparations->num_separations + 1) <
12771
38
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12772
38
        int sep_num = pseparations->num_separations++;
12773
38
        int color_component_number;
12774
38
        byte * sep_name;
12775
12776
38
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12777
38
            name_size, "pdf14_spot_get_color_comp_index");
12778
38
        if (sep_name == NULL) {
12779
0
            pseparations->num_separations--;  /* we didn't add it */
12780
0
            return -1;
12781
0
        }
12782
38
        memcpy(sep_name, pname, name_size);
12783
38
        pseparations->names[sep_num].size = name_size;
12784
38
        pseparations->names[sep_num].data = sep_name;
12785
38
        color_component_number = sep_num + num_process_colors;
12786
38
        if (color_component_number >= dev->color_info.max_components)
12787
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12788
38
        else
12789
38
            pdevn_params->separation_order_map[color_component_number] =
12790
38
            color_component_number;
12791
12792
        /* Indicate that we need to find equivalent CMYK color. */
12793
38
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12794
38
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12795
12796
        /* If we're doing an overprint simulation, then the target device
12797
         * (for instance) might not know about this colorant. This is annoying
12798
         * as the target can't then output the correct names. Call the target
12799
         * get_color_comp_index routine and ignore the result to give it a
12800
         * chance to stash it. */
12801
38
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12802
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12803
12804
38
        return color_component_number;
12805
38
    }
12806
12807
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12808
38
}
12809
12810
12811
/* CMYK process + spots */
12812
static int
12813
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12814
    int name_size, int component_type)
12815
6.35k
{
12816
6.35k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12817
6.35k
}
12818
12819
/* RGB process + spots */
12820
static int
12821
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12822
    int name_size, int component_type)
12823
594
{
12824
594
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12825
594
}
12826
12827
/* Gray process + spots */
12828
static int
12829
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12830
    int name_size, int component_type)
12831
0
{
12832
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12833
0
}
12834
12835
/* These functions keep track of when we are dealing with soft masks.
12836
   In such a case, we set the default color profiles to ones that ensure
12837
   proper soft mask rendering. */
12838
static int
12839
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12840
24.7k
{
12841
24.7k
    pdf14_device * pdev = (pdf14_device *) dev;
12842
24.7k
    pdf14_smaskcolor_t *result;
12843
24.7k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12844
24.7k
    int k;
12845
12846
    /* See if we have profiles already in place.   Note we also have to
12847
       worry about a corner case where this device does not have a
12848
       smaskcolor stucture to store the profiles AND the profiles were
12849
       already swapped out in the icc_manager.  This can occur when we
12850
       pushed a transparency mask and then inside the mask we have a pattern
12851
       which also has a transparency mask.   The state of the icc_manager
12852
       is that it already has done the swap and there is no need to fool
12853
       with any of this while dealing with the soft mask within the pattern */
12854
24.7k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12855
24.7k
        pgs->icc_manager->smask_profiles->swapped) {
12856
0
            return 0;
12857
0
    }
12858
24.7k
    if (pdev->smaskcolor != NULL) {
12859
22
        pdev->smaskcolor->ref_count++;
12860
22
        if_debug1m(gs_debug_flag_icc, dev->memory,
12861
22
                   "[icc] Increment smask color now %d\n",
12862
22
                   pdev->smaskcolor->ref_count);
12863
24.7k
    } else {
12864
        /* Allocate and swap out the current profiles.  The softmask
12865
           profiles should already be in place */
12866
24.7k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12867
24.7k
                                &st_pdf14_smaskcolor,
12868
24.7k
                                "pdf14_increment_smask_color");
12869
24.7k
        if (result == NULL)
12870
0
            return gs_error_VMerror;
12871
12872
24.7k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12873
24.7k
        if (result->profiles == NULL)
12874
0
            return gs_error_VMerror;
12875
12876
24.7k
        pdev->smaskcolor = result;
12877
12878
24.7k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12879
24.7k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12880
24.7k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12881
24.7k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12882
24.7k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12883
24.7k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12884
24.7k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12885
24.7k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12886
24.7k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12887
24.7k
        pgs->icc_manager->smask_profiles->swapped = true;
12888
24.7k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12889
24.7k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12890
24.7k
        pdev->smaskcolor->ref_count = 1;
12891
        /* We also need to update the profile that is currently in the
12892
           color spaces of the graphic state.  Otherwise this can be
12893
           referenced, which will result in a mismatch.  What we want to do
12894
           is see if it was the original default and only swap in that case. */
12895
74.2k
        for (k = 0; k < 2; k++) {
12896
49.4k
            gs_color_space *pcs     = pgs->color[k].color_space;
12897
49.4k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12898
49.4k
            if (profile != NULL) {
12899
47.8k
                switch(profile->data_cs) {
12900
27.6k
                    case gsGRAY:
12901
27.6k
                        if (profile->hashcode ==
12902
27.6k
                            result->profiles->smask_gray->hashcode) {
12903
25.4k
                                profile = pgs->icc_manager->default_gray;
12904
25.4k
                        }
12905
27.6k
                        break;
12906
19.9k
                    case gsRGB:
12907
19.9k
                        if (profile->hashcode ==
12908
19.9k
                            result->profiles->smask_rgb->hashcode) {
12909
12.2k
                                profile = pgs->icc_manager->default_rgb;
12910
12.2k
                        }
12911
19.9k
                        break;
12912
186
                    case gsCMYK:
12913
186
                        if (profile->hashcode ==
12914
186
                            result->profiles->smask_cmyk->hashcode) {
12915
186
                                profile = pgs->icc_manager->default_cmyk;
12916
186
                        }
12917
186
                        break;
12918
0
                    default:
12919
12920
0
                        break;
12921
47.8k
                }
12922
47.8k
                if (pcs->cmm_icc_profile_data != profile) {
12923
37.8k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12924
37.8k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12925
37.8k
                    pcs->cmm_icc_profile_data = profile;
12926
37.8k
                }
12927
47.8k
            }
12928
49.4k
        }
12929
24.7k
    }
12930
24.7k
    return 0;
12931
24.7k
}
12932
12933
static int
12934
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12935
35.5k
{
12936
35.5k
    pdf14_device * pdev = (pdf14_device *) dev;
12937
35.5k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12938
35.5k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12939
35.5k
    int k;
12940
12941
    /* See comment in pdf14_increment_smask_color to understand this one */
12942
35.5k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12943
4.49k
        pgs->icc_manager->smask_profiles->swapped) {
12944
0
            return 0;
12945
0
    }
12946
35.5k
    if (smaskcolor != NULL) {
12947
24.7k
        smaskcolor->ref_count--;
12948
24.7k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12949
24.7k
                   "[icc] Decrement smask color.  Now %d\n",
12950
24.7k
                   smaskcolor->ref_count);
12951
24.7k
        if (smaskcolor->ref_count == 0) {
12952
24.7k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12953
            /* Lets return the profiles and clean up */
12954
            /* First see if we need to "reset" the profiles that are in
12955
               the graphic state */
12956
24.7k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12957
74.2k
            for (k = 0; k < 2; k++) {
12958
49.4k
                gs_color_space *pcs = pgs->color[k].color_space;
12959
49.4k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12960
49.4k
                if (profile != NULL) {
12961
47.8k
                    switch(profile->data_cs) {
12962
27.6k
                        case gsGRAY:
12963
27.6k
                            if (profile->hashcode ==
12964
27.6k
                                pgs->icc_manager->default_gray->hashcode) {
12965
25.4k
                                    profile =
12966
25.4k
                                        smaskcolor->profiles->smask_gray;
12967
25.4k
                            }
12968
27.6k
                            break;
12969
19.9k
                        case gsRGB:
12970
19.9k
                            if (profile->hashcode ==
12971
19.9k
                                pgs->icc_manager->default_rgb->hashcode) {
12972
12.2k
                                    profile =
12973
12.2k
                                        smaskcolor->profiles->smask_rgb;
12974
12.2k
                            }
12975
19.9k
                            break;
12976
186
                        case gsCMYK:
12977
186
                            if (profile->hashcode ==
12978
186
                                pgs->icc_manager->default_cmyk->hashcode) {
12979
186
                                    profile =
12980
186
                                        smaskcolor->profiles->smask_cmyk;
12981
186
                            }
12982
186
                            break;
12983
0
                        default:
12984
12985
0
                            break;
12986
47.8k
                    }
12987
47.8k
                    if (pcs->cmm_icc_profile_data != profile) {
12988
37.8k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12989
37.8k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12990
37.8k
                        pcs->cmm_icc_profile_data = profile;
12991
37.8k
                    }
12992
47.8k
                }
12993
49.4k
            }
12994
12995
24.7k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12996
24.7k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12997
24.7k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12998
24.7k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12999
24.7k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13000
24.7k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13001
24.7k
            icc_manager->smask_profiles->swapped = false;
13002
            /* We didn't increment the reference count when we assigned these
13003
             * so NULL them to avoid decrementing when smaskcolor is freed
13004
             */
13005
24.7k
            smaskcolor->profiles->smask_gray =
13006
24.7k
              smaskcolor->profiles->smask_rgb =
13007
24.7k
              smaskcolor->profiles->smask_cmyk = NULL;
13008
13009
24.7k
            pdf14_free_smask_color(pdev);
13010
24.7k
        }
13011
24.7k
    }
13012
35.5k
    return 0;
13013
35.5k
}
13014
13015
static void
13016
pdf14_free_smask_color(pdf14_device * pdev)
13017
24.7k
{
13018
24.7k
    if (pdev->smaskcolor != NULL) {
13019
24.7k
        if ( pdev->smaskcolor->profiles != NULL) {
13020
            /* Do not decrement the profiles - the references were moved
13021
               here and moved back again, so the ref counts don't change
13022
             */
13023
24.7k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13024
24.7k
                        "pdf14_free_smask_color");
13025
24.7k
        }
13026
24.7k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13027
24.7k
        pdev->smaskcolor = NULL;
13028
24.7k
    }
13029
24.7k
}
13030
13031
static void
13032
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13033
1.15M
{
13034
1.15M
    gx_device * const dev = (gx_device *)vptr;
13035
1.15M
    pdf14_device * pdev = (pdf14_device *)dev;
13036
1.15M
    int k;
13037
13038
1.15M
    pdf14_cleanup_group_color_profiles (pdev);
13039
13040
1.15M
    if (pdev->ctx) {
13041
20
        pdf14_ctx_free(pdev->ctx);
13042
20
        pdev->ctx = NULL;
13043
20
    }
13044
13045
1.15M
    while (pdev->color_model_stack) {
13046
39
        pdf14_pop_group_color(dev, NULL);
13047
39
    }
13048
13049
1.15M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13050
38
        if (pdev->devn_params.separations.names[k].data) {
13051
38
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13052
38
            pdev->devn_params.separations.names[k].data = NULL;
13053
38
        }
13054
38
    }
13055
13056
1.15M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13057
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13058
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13059
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13060
0
        }
13061
0
    }
13062
13063
1.15M
    gx_device_finalize(cmem, vptr);
13064
1.15M
}
13065
13066
#if DUMP_MASK_STACK
13067
13068
static void
13069
dump_mask_stack(pdf14_mask_t *mask_stack)
13070
{
13071
    pdf14_mask_t *curr_mask = mask_stack;
13072
    int level = 0;
13073
13074
    while (curr_mask != NULL) {
13075
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13076
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13077
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13078
        level++;
13079
        curr_mask = curr_mask->previous;
13080
    }
13081
}
13082
13083
/* A function to display the current state of the mask stack */
13084
static void
13085
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13086
{
13087
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13088
    if (ctx->mask_stack != NULL) {
13089
        dump_mask_stack(ctx->mask_stack);
13090
    }
13091
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13092
    if (ctx->stack != NULL) {
13093
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13094
        if (ctx->stack->mask_stack != NULL) {
13095
            dump_mask_stack(ctx->stack->mask_stack);
13096
        }
13097
    }
13098
}
13099
13100
#else
13101
13102
#ifdef DEBUG
13103
static void
13104
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13105
{
13106
    return;
13107
}
13108
#endif
13109
13110
#endif /* DUMP_MASK_STACK */