Coverage Report

Created: 2026-04-01 07:17

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
4.65M
{
240
4.65M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
4.65M
    set_dev_proc(dev, open_device, pdf14_open);
242
4.65M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
4.65M
    set_dev_proc(dev, close_device, pdf14_close);
244
4.65M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
4.65M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
4.65M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
4.65M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
4.65M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
4.65M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
4.65M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
4.65M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
4.65M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
4.65M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
4.65M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
4.65M
    set_dev_proc(dev, composite, pdf14_composite);
256
4.65M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
4.65M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
4.65M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
4.65M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
4.65M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
4.65M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
4.65M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
4.65M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
4.65M
    set_dev_proc(dev, encode_color, encode_color);
265
4.65M
    set_dev_proc(dev, decode_color, decode_color);
266
4.65M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
4.65M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
4.65M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
4.65M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
4.65M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
4.65M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
4.65M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
4.65M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
4.65M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
4.65M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
4.65M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
4.65M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.35M
{
282
1.35M
    pdf14_procs_initialize(dev,
283
1.35M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.35M
                           gx_default_DevGray_get_color_comp_index,
285
1.35M
                           pdf14_encode_color,
286
1.35M
                           pdf14_decode_color);
287
1.35M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
2.98M
{
292
2.98M
    pdf14_procs_initialize(dev,
293
2.98M
                           gx_default_DevRGB_get_color_mapping_procs,
294
2.98M
                           gx_default_DevRGB_get_color_comp_index,
295
2.98M
                           pdf14_encode_color,
296
2.98M
                           pdf14_decode_color);
297
2.98M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
83.2k
{
302
83.2k
    pdf14_procs_initialize(dev,
303
83.2k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
83.2k
                           gx_default_DevCMYK_get_color_comp_index,
305
83.2k
                           pdf14_encode_color,
306
83.2k
                           pdf14_decode_color);
307
83.2k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
166k
{
312
166k
    pdf14_procs_initialize(dev,
313
166k
                           pdf14_cmykspot_get_color_mapping_procs,
314
166k
                           pdf14_cmykspot_get_color_comp_index,
315
166k
                           pdf14_encode_color,
316
166k
                           pdf14_decode_color);
317
166k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
74.3k
{
322
74.3k
    pdf14_procs_initialize(dev,
323
74.3k
                           pdf14_rgbspot_get_color_mapping_procs,
324
74.3k
                           pdf14_rgbspot_get_color_comp_index,
325
74.3k
                           pdf14_encode_color,
326
74.3k
                           pdf14_decode_color);
327
74.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
8.50M
{
650
8.50M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
8.50M
    if (dev_spec_op == gxdso_device_child) {
653
2.43k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
2.43k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
2.43k
        req->target = adev->save_p14dev;
657
2.43k
        req->n = 0;
658
2.43k
        return 0;
659
2.43k
    }
660
661
8.50M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
8.50M
}
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
835
{
671
835
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
835
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
835
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
835
}
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
2.96k
{
695
2.96k
    gdev_prn_initialize_device_procs_rgb(dev);
696
2.96k
}
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
912
{
814
912
    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
912
    } else {
856
912
        int x, y, i;
857
912
        byte *mask_row_ptr  = maskbuf->data;
858
912
        byte *src_row_ptr   = src_data;
859
912
        byte *mask_tr_fn    = maskbuf->transfer_fn;
860
861
11.7k
        for (y = 0; y < height; y++) {
862
10.8k
            byte *mask_curr_ptr = mask_row_ptr;
863
10.8k
            byte *src_curr_ptr = src_row_ptr;
864
13.6M
            for (x = 0; x < width; x++) {
865
13.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
866
13.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
867
7.82M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
5.86M
                        byte matte = maskbuf->matte[i]>>8;
869
5.86M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
5.86M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
5.86M
                        if (temp > 0xff)
874
4.28M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
1.57M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
1.57M
                        else
878
1.57M
                            src_curr_ptr[i * src_planestride] = temp;
879
5.86M
                    }
880
1.95M
                }
881
13.6M
                mask_curr_ptr++;
882
13.6M
                src_curr_ptr++;
883
13.6M
            }
884
10.8k
            src_row_ptr += src_rowstride;
885
10.8k
            mask_row_ptr += maskbuf->rowstride;
886
10.8k
        }
887
912
    }
888
912
}
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.8k
{
908
11.8k
    gsicc_rendering_param_t rendering_params;
909
11.8k
    gsicc_link_t *icc_link;
910
11.8k
    gsicc_bufferdesc_t src_buff_desc;
911
11.8k
    gsicc_bufferdesc_t des_buff_desc;
912
11.8k
    intptr_t src_planestride = src_buf->planestride;
913
11.8k
    intptr_t src_rowstride = src_buf->rowstride;
914
11.8k
    int src_n_planes = src_buf->n_planes;
915
11.8k
    int src_n_chan = src_buf->n_chan;
916
11.8k
    intptr_t des_planestride = src_planestride;
917
11.8k
    intptr_t des_rowstride = src_rowstride;
918
11.8k
    int des_n_planes = src_n_planes;
919
11.8k
    int des_n_chan = src_n_chan;
920
11.8k
    int diff;
921
11.8k
    int k, j;
922
11.8k
    byte *des_data = NULL;
923
11.8k
    pdf14_buf *output = src_buf;
924
11.8k
    pdf14_mask_t *mask_stack;
925
11.8k
    pdf14_buf *maskbuf;
926
11.8k
    int code;
927
928
11.8k
    *did_alloc = false;
929
930
    /* Same profile */
931
11.8k
    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.8k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
936
11.8k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
937
11.8k
    rendering_params.override_icc = false;
938
11.8k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
939
11.8k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
940
11.8k
    rendering_params.cmm = gsCMM_DEFAULT;
941
11.8k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
942
11.8k
        &rendering_params, pgs->memory, false);
943
11.8k
    if (icc_link == NULL)
944
0
        return NULL;
945
946
    /* If different data sizes, we have to do an allocation */
947
11.8k
    diff = des_profile->num_comps - src_profile->num_comps;
948
11.8k
    if (diff != 0) {
949
11.4k
        byte *src_ptr;
950
11.4k
        byte *des_ptr;
951
952
11.4k
        *did_alloc = true;
953
11.4k
        des_rowstride = ((width + 3) & -4)<<deep;
954
11.4k
        des_planestride = height * des_rowstride;
955
11.4k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
11.4k
        des_n_chan = src_n_chan + diff;
957
11.4k
        des_data = gs_alloc_bytes(ctx->memory,
958
11.4k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
11.4k
                                  "pdf14_transform_color_buffer");
960
11.4k
        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.4k
        src_ptr = src_data;
966
11.4k
        des_ptr = des_data;
967
123k
        for (j = 0; j < height; j++) {
968
223k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
112k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
112k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
112k
                       width<<deep);
972
112k
            }
973
111k
            src_ptr += src_rowstride;
974
111k
            des_ptr += des_rowstride;
975
111k
        }
976
11.4k
    } else
977
444
        des_data = src_data;
978
979
    /* Set up the buffer descriptors. */
980
11.8k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
981
11.8k
                      false, true, src_planestride, src_rowstride, height, width);
982
11.8k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
983
11.8k
                      false, true, des_planestride, des_rowstride, height, width);
984
985
11.8k
    src_buff_desc.endian_swap = endian_swap;
986
11.8k
    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.8k
    if (has_matte &&
992
        /* Should always happen, but check for safety */
993
1.20k
        ((mask_stack = ctx->mask_stack) != NULL) &&
994
1.20k
        ((maskbuf = mask_stack->mask_buf) != NULL) &&
995
1.20k
         (maskbuf->data != NULL))
996
912
    {
997
912
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
998
912
    }
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.8k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1004
11.8k
        src_data, des_data);
1005
11.8k
    gsicc_release_link(icc_link);
1006
11.8k
    if (code < 0)
1007
0
        return NULL;
1008
1009
11.8k
    output->planestride = des_planestride;
1010
11.8k
    output->rowstride = des_rowstride;
1011
11.8k
    output->n_planes = des_n_planes;
1012
11.8k
    output->n_chan = des_n_chan;
1013
    /* If not in-place conversion, then release. */
1014
11.8k
    if (des_data != src_data) {
1015
11.4k
        gs_free_object(ctx->memory, output->data,
1016
11.4k
            "pdf14_transform_color_buffer");
1017
11.4k
        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.4k
        output->rect.p.x = x0;
1021
11.4k
        output->rect.p.y = y0;
1022
11.4k
        output->rect.q.x = x0 + width;
1023
11.4k
        output->rect.q.y = y0 + height;
1024
11.4k
    }
1025
11.8k
    return output;
1026
11.8k
}
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.6k
{
1063
10.6k
    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.6k
    else
1067
10.6k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
10.6k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
10.6k
}
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.20k
{
1077
1.20k
    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.20k
    else
1081
1.20k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1082
1.20k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1083
1.20k
}
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.00M
{
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.00M
    pdf14_buf *result;
1104
3.00M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
3.00M
    int64_t height = (rect->q.y - rect->p.y);
1106
3.00M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
3.00M
                   (has_tags ? 1 : 0);
1108
3.00M
    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.00M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
3.00M
                             "pdf14_buf_new");
1118
3.00M
    if (result == NULL)
1119
0
        return result;
1120
1121
3.00M
    result->memory = memory;
1122
3.00M
    result->backdrop = NULL;
1123
3.00M
    result->saved = NULL;
1124
3.00M
    result->isolated = false;
1125
3.00M
    result->knockout = false;
1126
3.00M
    result->has_alpha_g = has_alpha_g;
1127
3.00M
    result->has_shape = has_shape;
1128
3.00M
    result->has_tags = has_tags;
1129
3.00M
    result->rect = *rect;
1130
3.00M
    result->n_chan = n_chan;
1131
3.00M
    result->n_planes = n_planes;
1132
3.00M
    result->rowstride = rowstride;
1133
3.00M
    result->transfer_fn = NULL;
1134
3.00M
    result->is_ident = true;
1135
3.00M
    result->matte_num_comps = 0;
1136
3.00M
    result->matte = NULL;
1137
3.00M
    result->mask_stack = NULL;
1138
3.00M
    result->idle = idle;
1139
3.00M
    result->mask_id = 0;
1140
3.00M
    result->num_spots = num_spots;
1141
3.00M
    result->deep = deep;
1142
3.00M
    result->page_group = false;
1143
3.00M
    result->group_color_info = NULL;
1144
3.00M
    result->group_popped = false;
1145
1146
3.00M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.30M
        result->planestride = 0;
1149
1.30M
        result->data = 0;
1150
1.70M
    } else {
1151
1.70M
        planestride = rowstride * height;
1152
1.70M
        result->planestride = planestride;
1153
1.70M
        result->data = gs_alloc_bytes(memory,
1154
1.70M
                                      planestride * n_planes + CAL_SLOP,
1155
1.70M
                                      "pdf14_buf_new");
1156
1.70M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.70M
        if (has_alpha_g) {
1161
415k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
415k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
415k
        }
1165
1.70M
        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.70M
    }
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.00M
    result->dirty.p.x = rect->q.x;
1176
3.00M
    result->dirty.p.y = rect->q.y;
1177
3.00M
    result->dirty.q.x = rect->p.x;
1178
3.00M
    result->dirty.q.y = rect->p.y;
1179
3.00M
    return result;
1180
3.00M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
3.00M
{
1185
3.00M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
3.00M
    gs_memory_t *memory = buf->memory;
1187
1188
3.00M
    if (buf->mask_stack)
1189
3.00M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
3.00M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
3.00M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
3.00M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
6.00M
    while (group_color_info) {
1196
3.00M
       if (group_color_info->icc_profile != NULL) {
1197
3.00M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
3.00M
       }
1199
3.00M
       buf->group_color_info = group_color_info->previous;
1200
3.00M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
3.00M
       group_color_info = buf->group_color_info;
1202
3.00M
    }
1203
1204
3.00M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
3.00M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
3.00M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
1.07M
{
1211
1.07M
    pdf14_ctx *result;
1212
1.07M
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
1.07M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
1.07M
    if (result == NULL)
1216
0
        return result;
1217
1.07M
    result->stack = NULL;
1218
1.07M
    result->mask_stack = pdf14_mask_element_new(memory);
1219
1.07M
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
1.07M
    result->memory = memory;
1224
1.07M
    result->smask_depth = 0;
1225
1.07M
    result->smask_blend = false;
1226
1.07M
    result->deep = deep;
1227
1.07M
    result->base_color = NULL;
1228
1.07M
    return result;
1229
1.07M
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
1.07M
{
1234
1.07M
    pdf14_buf *buf, *next;
1235
1236
1.07M
    if (ctx->base_color) {
1237
575k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
575k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
575k
    }
1240
1.07M
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
523k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
523k
    }
1244
1.99M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
914k
        next = buf->saved;
1246
914k
        pdf14_buf_free(buf);
1247
914k
    }
1248
1.07M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
1.07M
}
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
953k
{
1260
    /* Our new buffer is buf */
1261
953k
    pdf14_buf *buf = ctx->stack;
1262
1263
953k
    *is_backdrop = false;
1264
1265
953k
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
953k
        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
415k
        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
16
            *is_backdrop = true;
1280
16
            return buf->saved;
1281
16
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
415k
        if (buf->saved != NULL) {
1285
415k
            return buf->saved;
1286
415k
        }
1287
415k
    }
1288
0
    return NULL;
1289
953k
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
575k
{
1294
575k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
575k
    pdf14_group_color_t* group_color;
1296
575k
    bool deep = pdev->ctx->deep;
1297
575k
    bool has_tags = device_encodes_tags(dev);
1298
1299
575k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
575k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
575k
        pdf14_group_color_t, &st_pdf14_clr,
1303
575k
        "pdf14_make_base_group_color");
1304
1305
575k
    if (group_color == NULL)
1306
0
        return NULL;
1307
575k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
575k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
575k
    group_color->blend_procs = pdev->blend_procs;
1311
575k
    group_color->polarity = pdev->color_info.polarity;
1312
575k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
575k
    group_color->isadditive = pdev->ctx->additive;
1314
575k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
575k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
575k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
575k
    group_color->depth = pdev->color_info.depth;
1318
575k
    group_color->decode = dev_proc(pdev, decode_color);
1319
575k
    group_color->encode = dev_proc(pdev, encode_color);
1320
575k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
575k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
575k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
575k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
575k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
575k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
575k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
575k
    group_color->icc_profile =
1328
575k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
575k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
575k
    return group_color;
1332
575k
}
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
366M
{
1341
366M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
366M
    bool has_tags = device_encodes_tags(dev);
1343
366M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
366M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
366M
    int num_spots = pdev->ctx->num_spots;
1346
366M
    pdf14_buf* buf;
1347
366M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
366M
    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
366M
    if (pdev->ctx->stack != NULL)
1357
366M
        return 0;
1358
1359
366M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
496k
        dev->width, dev->height);
1361
1362
496k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
496k
        num_spots, memory, pdev->ctx->deep);
1364
496k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
496k
    if_debug5m('v', memory,
1368
496k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
496k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
496k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
496k
    buf->saved = NULL;
1373
496k
    pdev->ctx->stack = buf;
1374
496k
    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
496k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
496k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
496k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
496k
    if (pgs != NULL)
1384
255k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
240k
    else
1386
240k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
496k
    buf->group_color_info->group_color_mapping_procs =
1389
496k
        dev_proc(pdev, get_color_mapping_procs);
1390
496k
    buf->group_color_info->group_color_comp_index =
1391
496k
        dev_proc(pdev, get_color_comp_index);
1392
496k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
496k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
496k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
496k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
496k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
496k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
496k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
496k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
496k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
496k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
496k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
496k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
496k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
496k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
496k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
496k
    buf->group_color_info->icc_profile =
1408
496k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
496k
    if (buf->group_color_info->icc_profile != NULL)
1410
496k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
496k
    return 0;
1413
496k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
19.0k
{
1418
19.0k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
19.0k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
19.0k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
19.0k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
19.0k
    if (des->icc_profile != NULL)
1425
19.0k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
19.0k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
19.0k
    return des;
1429
19.0k
}
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.10M
{
1440
2.10M
    pdf14_buf *tos = ctx->stack;
1441
2.10M
    pdf14_buf *buf, * pdf14_backdrop;
1442
2.10M
    bool has_shape = false;
1443
2.10M
    bool is_backdrop;
1444
2.10M
    int num_spots;
1445
1446
2.10M
    if_debug1m('v', ctx->memory,
1447
2.10M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
2.10M
    if (tos != NULL)
1450
1.68M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
2.10M
    if (ctx->smask_depth > 0)
1453
985
        num_spots = 0;
1454
2.10M
    else
1455
2.10M
        num_spots = ctx->num_spots;
1456
1457
1458
2.10M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
2.10M
                        num_spots, ctx->memory, ctx->deep);
1460
2.10M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
2.10M
    if_debug4m('v', ctx->memory,
1464
2.10M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
2.10M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
2.10M
    buf->isolated = isolated;
1467
2.10M
    buf->knockout = knockout;
1468
2.10M
    buf->alpha = alpha;
1469
2.10M
    buf->shape = shape;
1470
2.10M
    buf->opacity = opacity;
1471
2.10M
    buf->blend_mode = blend_mode;
1472
2.10M
    buf->mask_id = mask_id;
1473
2.10M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
2.10M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
2.10M
    buf->saved = tos;
1478
2.10M
    buf->group_color_info = group_color;
1479
1480
2.10M
    if (tos == NULL)
1481
418k
        buf->page_group = true;
1482
1483
2.10M
    ctx->stack = buf;
1484
2.10M
    if (buf->data == NULL)
1485
1.14M
        return 0;
1486
953k
    if (idle)
1487
0
        return 0;
1488
953k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
953k
    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
538k
        memset(buf->data, 0, buf->planestride *
1495
538k
                                          (buf->n_chan +
1496
538k
                                           (buf->has_shape ? 1 : 0) +
1497
538k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
538k
    } else {
1499
415k
        if (!cm_back_drop) {
1500
415k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
415k
                                    );
1505
415k
        } 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
415k
    }
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
953k
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
34.8k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
34.8k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
34.8k
                                       "pdf14_push_transparency_group");
1525
34.8k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
34.8k
        memcpy(buf->backdrop, buf->data,
1530
34.8k
               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
34.8k
    }
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
953k
    return 0;
1552
953k
}
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.10M
{
1559
2.10M
    pdf14_buf *tos = ctx->stack;
1560
2.10M
    pdf14_buf *nos = tos->saved;
1561
2.10M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
2.10M
    pdf14_buf *maskbuf;
1563
2.10M
    int x0, x1, y0, y1;
1564
2.10M
    int nos_num_color_comp;
1565
2.10M
    bool no_icc_match;
1566
2.10M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
2.10M
    bool overprint = pdev->overprint;
1568
2.10M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
2.10M
    bool has_matte = false;
1570
2.10M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
2.10M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
2.10M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
3.71k
        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.10M
    if (nos == NULL && maskbuf == NULL) {
1589
417k
        tos->group_popped = true;
1590
417k
        return 0;
1591
417k
    }
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.68M
    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.68M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
1.68M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
1.68M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
1.68M
    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.68M
    rect_intersect(tos->dirty, tos->rect);
1647
1.68M
    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.68M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
1.68M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
1.68M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
1.68M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
1.68M
    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
66
        rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_group");
1663
66
        ctx->mask_stack = NULL;
1664
66
    }
1665
1.68M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
1.68M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
1.68M
    if (tos->idle)
1668
1.11M
        goto exit;
1669
565k
    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
565k
    if (nos->group_color_info->icc_profile != NULL) {
1689
565k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
565k
    } 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
565k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
565k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
3.66k
        if (x0 < x1 && y0 < y1) {
1699
3.11k
            pdf14_buf *result;
1700
3.11k
            bool did_alloc; /* We don't care here */
1701
1702
3.11k
            if (has_matte) {
1703
1.20k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1704
1.20k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1705
1.20k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1706
1.20k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1707
1.20k
                has_matte = false;
1708
1.91k
            } else {
1709
1.91k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
1.91k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
1.91k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
1.91k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
1.91k
            }
1714
3.11k
            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.11k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
3.11k
                 nos->group_color_info->isadditive,
1732
3.11k
                 nos->group_color_info->blend_procs,
1733
3.11k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
3.11k
        }
1735
561k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
561k
        if (x0 < x1 && y0 < y1)
1738
342k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
342k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
342k
                                drawn_comps, ctx->memory, dev);
1741
561k
    }
1742
1.68M
exit:
1743
1.68M
    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.68M
    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
555
        ctx->smask_blend = true;
1751
555
    }
1752
1.68M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
1.68M
    pdf14_buf_free(tos);
1754
1.68M
    if (code < 0)
1755
0
        return_error(code);
1756
1.68M
    return 0;
1757
1.68M
}
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
404k
{
1775
404k
    pdf14_buf *buf;
1776
404k
    int i;
1777
1778
404k
    if_debug2m('v', ctx->memory,
1779
404k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
404k
               idle, replacing);
1781
404k
    ctx->smask_depth += 1;
1782
1783
404k
    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
404k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
404k
                        ctx->memory, ctx->deep);
1796
404k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
404k
    buf->alpha = bg_alpha;
1799
404k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
404k
    buf->isolated = true;
1802
404k
    buf->knockout = false;
1803
404k
    buf->shape = 0xffff;
1804
404k
    buf->blend_mode = BLEND_MODE_Normal;
1805
404k
    buf->transfer_fn = transfer_fn;
1806
404k
    buf->matte_num_comps = Matte_components;
1807
404k
    buf->group_color_info = group_color;
1808
1809
404k
    if (Matte_components) {
1810
3.71k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
3.71k
                                                "pdf14_push_transparency_mask");
1812
3.71k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
14.8k
        for (i = 0; i < Matte_components; i++) {
1815
11.1k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
11.1k
        }
1817
3.71k
    }
1818
404k
    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
404k
    buf->mask_stack = ctx->mask_stack;
1824
404k
    if (buf->mask_stack)
1825
404k
        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
404k
    buf->saved = ctx->stack;
1838
404k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
404k
    buf->SMask_SubType = subtype;
1842
404k
    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
253k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
160
            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
160
            } else {
1859
160
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
160
                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
160
                memset(buf->data + buf->planestride, 255,
1865
160
                       buf->planestride * (buf->n_chan - 1));
1866
160
            }
1867
253k
        } else {
1868
            /* Compose mask with opaque background */
1869
253k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
253k
        }
1871
253k
    }
1872
404k
    return 0;
1873
404k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
404k
{
1878
404k
    pdf14_buf* tos = ctx->stack;
1879
404k
    pdf14_buf* nos = tos->saved;
1880
404k
    byte *new_data_buf;
1881
404k
    int icc_match;
1882
404k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
404k
    cmm_profile_t *src_profile;
1884
404k
    gsicc_rendering_param_t rendering_params;
1885
404k
    gsicc_link_t *icc_link;
1886
404k
    gsicc_rendering_param_t render_cond;
1887
404k
    cmm_dev_profile_t *dev_profile;
1888
404k
    int code = 0;
1889
1890
404k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
404k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
404k
                          &render_cond);
1893
404k
    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
404k
    if (des_profile != NULL && src_profile != NULL ) {
1898
404k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
404k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
404k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
404k
               tos->idle);
1904
404k
    ctx->stack = tos->saved;
1905
404k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
404k
    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
108k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
108k
        tos->mask_stack = NULL;
1915
108k
    }
1916
1917
404k
    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
151k
        if (ctx->mask_stack != NULL) {
1924
46.4k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
46.4k
            ctx->mask_stack = NULL;
1926
46.4k
        }
1927
151k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
151k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
4.68k
            pdf14_buf_free(tos);
1930
146k
        } else {
1931
            /* Assign as mask buffer */
1932
146k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
146k
            if (ctx->mask_stack == NULL)
1934
0
                return gs_note_error(gs_error_VMerror);
1935
146k
            ctx->mask_stack->mask_buf = tos;
1936
146k
        }
1937
151k
        ctx->smask_blend = false;  /* just in case */
1938
253k
    } 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
253k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1946
253k
                                        "pdf14_pop_transparency_mask");
1947
253k
        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
253k
        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
253k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1956
38.8k
            ctx->smask_blend = false;  /* not used in this case */
1957
38.8k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1958
38.8k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1959
38.8k
                       tos->rowstride,
1960
38.8k
                       (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
214k
        } else {
1972
214k
            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
214k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1994
214k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1995
214k
                            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
214k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2007
214k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2008
214k
                           tos->rowstride, tos->data, new_data_buf);
2009
214k
            } 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
214k
        }
2041
        /* Free the old object, NULL test was above */
2042
253k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2043
253k
        tos->data = new_data_buf;
2044
        /* Data is single channel now */
2045
253k
        tos->n_chan = 1;
2046
253k
        tos->n_planes = 1;
2047
        /* Assign as reference counted mask buffer */
2048
253k
        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
62.6k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2054
62.6k
        }
2055
253k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2056
253k
        if (ctx->mask_stack == NULL)
2057
0
            return gs_note_error(gs_error_VMerror);
2058
253k
        ctx->mask_stack->mask_buf = tos;
2059
253k
    }
2060
404k
    return code;
2061
404k
}
2062
2063
static void
2064
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2065
1.47M
{
2066
    /* Ending the mask buffer. */
2067
1.47M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2068
    /* free the pdf14 buffer. */
2069
1.47M
    if (mask->mask_buf != NULL) {
2070
89.1k
        pdf14_buf_free(mask->mask_buf);
2071
89.1k
    }
2072
1.47M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2073
1.47M
}
2074
2075
static pdf14_mask_t *
2076
pdf14_mask_element_new(gs_memory_t *memory)
2077
1.47M
{
2078
1.47M
    pdf14_mask_t *result;
2079
2080
1.47M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2081
1.47M
                             "pdf14_mask_element_new");
2082
1.47M
    if (result == NULL)
2083
0
        return NULL;
2084
2085
1.47M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2086
2087
1.47M
    result->mask_buf = NULL;
2088
1.47M
    result->memory = memory;
2089
1.47M
    result->previous = NULL;
2090
2091
1.47M
    return result;
2092
1.47M
}
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
2.72M
{
2125
    /* Pop the soft mask.  It is no longer needed. Likely due to
2126
       a Q that has occurred. */
2127
2.72M
    pdf14_device *pdev = (pdf14_device *)dev;
2128
2.72M
    pdf14_ctx *ctx = pdev->ctx;
2129
2.72M
    pdf14_mask_t *old_mask;
2130
2131
2.72M
    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
2.72M
    if (ctx->mask_stack != NULL) {
2136
424k
        old_mask = ctx->mask_stack;
2137
424k
        ctx->mask_stack = ctx->mask_stack->previous;
2138
424k
        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
424k
        if (ctx->smask_depth > 0) {
2143
455
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2144
444
                ctx->stack->mask_stack = ctx->mask_stack;
2145
444
            }
2146
455
        }
2147
424k
    }
2148
#ifdef DEBUG
2149
    pdf14_debug_mask_stack_state(pdev->ctx);
2150
#endif
2151
2.72M
    return 0;
2152
2.72M
}
2153
2154
static  int
2155
pdf14_open(gx_device *dev)
2156
1.07M
{
2157
1.07M
    pdf14_device *pdev = (pdf14_device *)dev;
2158
2159
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2160
1.07M
    if (pdev->ctx == NULL) {
2161
1.07M
        bool has_tags = device_encodes_tags(dev);
2162
1.07M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2163
1.07M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2164
1.07M
        if (pdev->ctx == NULL)
2165
0
            return_error(gs_error_VMerror);
2166
2167
1.07M
        pdev->ctx->rect.p.x = 0;
2168
1.07M
        pdev->ctx->rect.p.y = 0;
2169
1.07M
        pdev->ctx->rect.q.x = dev->width;
2170
1.07M
        pdev->ctx->rect.q.y = dev->height;
2171
1.07M
        pdev->ctx->has_tags = has_tags;
2172
1.07M
        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.07M
        if (pdev->ctx->num_spots < 0)
2176
0
            pdev->ctx->num_spots = 0;
2177
1.07M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2178
1.07M
    }
2179
1.07M
    pdev->free_devicen = true;
2180
1.07M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2181
1.07M
    return 0;
2182
1.07M
}
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.09M
{
2206
3.09M
    *tdev = dev;
2207
3.09M
    return &pdf14_DeviceRGBspot_procs;
2208
3.09M
}
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.1k
{
2238
24.1k
    const pdf14_device * pdev = (pdf14_device *)dev;
2239
24.1k
    pdf14_buf *buf;
2240
24.1k
    gs_int_rect rect;
2241
24.1k
    int x1,y1,width,height;
2242
2243
24.1k
    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.1k
    buf = pdev->ctx->stack;
2250
24.1k
    rect = buf->rect;
2251
24.1k
    transbuff->buf = (free_device ? NULL : buf);
2252
24.1k
    x1 = min(pdev->width, rect.q.x);
2253
24.1k
    y1 = min(pdev->height, rect.q.y);
2254
24.1k
    width = x1 - rect.p.x;
2255
24.1k
    height = y1 - rect.p.y;
2256
2257
24.1k
    transbuff->n_chan    = buf->n_chan;
2258
24.1k
    transbuff->has_tags  = buf->has_tags;
2259
24.1k
    transbuff->has_shape = buf->has_shape;
2260
24.1k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2261
24.1k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2262
24.1k
    transbuff->deep      = buf->deep;
2263
2264
24.1k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2265
8.02k
        transbuff->planestride = 0;
2266
8.02k
        transbuff->rowstride = 0;
2267
8.02k
        return 0;
2268
8.02k
    }
2269
2270
16.0k
    if (free_device) {
2271
5.03k
        transbuff->pdev14 = NULL;
2272
5.03k
        transbuff->rect = rect;
2273
5.03k
        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
5.03k
        } 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
5.03k
            transbuff->planestride = buf->planestride;
2323
5.03k
            transbuff->rowstride = buf->rowstride;
2324
5.03k
            transbuff->transbytes = buf->data;
2325
5.03k
            transbuff->mem = buf->memory;
2326
5.03k
            buf->data = NULL;  /* So that the buffer is not freed */
2327
5.03k
            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
5.03k
        }
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
5.03k
        dev_proc(dev, close_device)((gx_device *)dev);
2358
11.0k
    } else {
2359
        /* Here we are coming from one of the fill image / pattern / mask
2360
           operations */
2361
11.0k
        transbuff->pdev14 = dev;
2362
11.0k
        transbuff->planestride = buf->planestride;
2363
11.0k
        transbuff->rowstride = buf->rowstride;
2364
11.0k
        transbuff->transbytes = buf->data;
2365
11.0k
        transbuff->mem = buf->memory;
2366
11.0k
        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.0k
    }
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.76k
{
2390
8.76k
    pdf14_buf* cm_result = NULL;
2391
8.76k
    cmm_profile_t* des_profile;
2392
8.76k
    gsicc_rendering_param_t render_cond;
2393
8.76k
    bool did_alloc;
2394
8.76k
    bool endian_swap;
2395
2396
8.76k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2397
8.76k
        &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.76k
    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.76k
    } else {
2426
        /* Data is in native format. No swap needed for CMM */
2427
8.76k
        endian_swap = false;
2428
8.76k
    }
2429
2430
8.76k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2431
8.76k
        *buf_ptr, src_profile, des_profile, x, y, width,
2432
8.76k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2433
2434
8.76k
    if (cm_result == NULL)
2435
0
        return_error(gs_error_VMerror);
2436
2437
    /* Update */
2438
8.76k
    *buf = cm_result;
2439
2440
    /* Make sure our buf_ptr is pointing to the proper location */
2441
8.76k
    if (did_alloc)
2442
8.76k
        *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.76k
    return 0;
2451
8.76k
}
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
989k
{
2467
989k
    const pdf14_device * pdev = (pdf14_device *)dev;
2468
989k
    int code;
2469
989k
    gs_image1_t image;
2470
989k
    gx_image_enum_common_t *info;
2471
989k
    pdf14_buf *buf = pdev->ctx->stack;
2472
989k
    gs_int_rect rect;
2473
989k
    int y;
2474
989k
    int num_comp;
2475
989k
    byte *linebuf, *linebuf_unaligned;
2476
989k
    gs_color_space *pcs;
2477
989k
    int x1, y1, width, height;
2478
989k
    byte *buf_ptr;
2479
989k
    int num_rows_left;
2480
989k
    cmm_profile_t* src_profile = NULL;
2481
989k
    cmm_profile_t* des_profile = NULL;
2482
989k
    cmm_dev_profile_t *pdf14dev_profile;
2483
989k
    cmm_dev_profile_t *dev_target_profile;
2484
989k
    uint16_t bg;
2485
989k
    bool has_tags = device_encodes_tags(dev);
2486
989k
    bool deep = pdev->ctx->deep;
2487
989k
    intptr_t planestride;
2488
989k
    intptr_t rowstride;
2489
989k
    blend_image_row_proc_t *blend_row;
2490
989k
    bool color_mismatch = false;
2491
989k
    bool supports_alpha = false;
2492
989k
    int i;
2493
989k
    int alpha_offset, tag_offset;
2494
989k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2495
989k
    int rendering_intent_saved;
2496
989k
    int additive;
2497
2498
    /* Nothing was ever drawn. */
2499
989k
    if (buf == NULL)
2500
127k
        return 0;
2501
2502
861k
    additive = buf->group_color_info->isadditive;
2503
2504
861k
    src_profile = buf->group_color_info->icc_profile;
2505
2506
861k
    num_comp = buf->n_chan - 1;
2507
861k
    rect = buf->rect;
2508
861k
    planestride = buf->planestride;
2509
861k
    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
861k
    if (buf->saved != NULL) {
2514
15
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2515
15
    }
2516
861k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2517
861k
    rect_intersect(rect, buf->dirty);
2518
861k
    x1 = min(pdev->width, rect.q.x);
2519
861k
    y1 = min(pdev->height, rect.q.y);
2520
861k
    width = x1 - rect.p.x;
2521
861k
    height = y1 - rect.p.y;
2522
#ifdef DUMP_TO_PNG
2523
    dump_planar_rgba(pdev->memory, buf);
2524
#endif
2525
861k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2526
220k
        return 0;
2527
640k
    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
640k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2534
640k
    if (code < 0)
2535
0
        return code;
2536
640k
    if (dev_target_profile == NULL)
2537
0
        return gs_throw_code(gs_error_Fatal);
2538
2539
640k
    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
640k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2549
640k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2550
103k
        color_mismatch = true;
2551
2552
    /* Check if target supports alpha */
2553
640k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2554
640k
    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
640k
    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
640k
    } 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
640k
    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
640k
    planestride = buf->planestride;
2681
640k
    rowstride = buf->rowstride;
2682
640k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2683
640k
    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
640k
    pcs->cmm_icc_profile_data = src_profile;
2693
2694
    /* pcs takes a reference to the profile data it just retrieved. */
2695
640k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2696
640k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
2697
0
        return_error(gs_error_rangecheck);
2698
2699
640k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2700
640k
    gs_image_t_init_adjust(&image, pcs, false);
2701
640k
    image.ImageMatrix.xx = (float)width;
2702
640k
    image.ImageMatrix.yy = (float)height;
2703
640k
    image.Width = width;
2704
640k
    image.Height = height;
2705
640k
    image.BitsPerComponent = deep ? 16 : 8;
2706
640k
    image.ColorSpace = pcs;
2707
640k
    ctm_only_writable(pgs).xx = (float)width;
2708
640k
    ctm_only_writable(pgs).xy = 0;
2709
640k
    ctm_only_writable(pgs).yx = 0;
2710
640k
    ctm_only_writable(pgs).yy = (float)height;
2711
640k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2712
640k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2713
    /* Make sure that the relative colorimetric rendering intent is
2714
       used for this image. */
2715
640k
    rendering_intent_saved = pgs->renderingintent;
2716
640k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2717
640k
    code = dev_proc(target, begin_typed_image) (target,
2718
640k
                                                pgs, NULL,
2719
640k
                                                (gs_image_common_t *)&image,
2720
640k
                                                NULL, NULL, NULL,
2721
640k
                                                pgs->memory, &info);
2722
640k
    pgs->renderingintent = rendering_intent_saved;
2723
640k
    if (code < 0) {
2724
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2725
0
        return code;
2726
0
    }
2727
#if RAW_DUMP
2728
    /* Dump the current buffer to see what we have. */
2729
    dump_raw_buffer(pdev->ctx->memory,
2730
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2731
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2732
                    pdev->ctx->stack->n_planes,
2733
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2734
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2735
    dump_raw_buffer(pdev->ctx->memory,
2736
                    height, width, buf->n_planes,
2737
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2738
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2739
    global_index++;
2740
    clist_band_count++;
2741
#endif
2742
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2743
    /* 28 byte overflow for AVX CMYK case. */
2744
640k
#define SSE_ALIGN 32
2745
640k
#define SSE_OVERFLOW 28
2746
640k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2747
640k
    if (linebuf_unaligned == NULL)
2748
0
        return gs_error_VMerror;
2749
640k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2750
2751
640k
    blend_row = deep ? gx_build_blended_image_row16 :
2752
640k
                       gx_build_blended_image_row;
2753
#ifdef WITH_CAL
2754
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2755
                                  blend_row, num_comp, deep);
2756
#endif
2757
2758
640k
    bg = additive ? (deep ? 65535 : 255) : 0;
2759
7.10M
    for (y = 0; y < height; y++) {
2760
6.46M
        gx_image_plane_t planes;
2761
6.46M
        int rows_used;
2762
2763
6.46M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2764
6.46M
        planes.data = linebuf;
2765
6.46M
        planes.data_x = 0;
2766
6.46M
        planes.raster = width * num_comp;
2767
6.46M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2768
        /* todo: check return value */
2769
6.46M
        buf_ptr += buf->rowstride;
2770
6.46M
    }
2771
640k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2772
640k
    info->procs->end_image(info, true);
2773
    /* This will also decrement the device profile */
2774
640k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2775
640k
    return code;
2776
640k
}
2777
2778
/* Overprint simulation with spots.  Collapse to CMYK */
2779
static void
2780
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2781
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2782
    cmyk_composite_map *map, bool keep_alpha)
2783
0
{
2784
0
    int comp_num;
2785
0
    uint cyan, magenta, yellow, black;
2786
0
    cmyk_composite_map *cmyk_map_entry;
2787
0
    int x, y;
2788
0
    intptr_t position;
2789
0
    byte comp, a;
2790
2791
0
    for (y = 0; y < height; y++) {
2792
0
        position = y * rowstride;
2793
0
        for (x = 0; x < width; x++) {
2794
0
            a = buf_ptr[position + planestride * num_comp];
2795
0
            if (a != 0) {
2796
0
                cyan = buf_ptr[position] * frac_1;
2797
0
                magenta = buf_ptr[position + planestride] * frac_1;
2798
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2799
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2800
0
                cmyk_map_entry = &(map[4]);
2801
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2802
0
                    comp = buf_ptr[position + planestride * comp_num];
2803
0
                    cyan += cmyk_map_entry->c * comp;
2804
0
                    magenta += cmyk_map_entry->m * comp;
2805
0
                    yellow += cmyk_map_entry->y * comp;
2806
0
                    black += cmyk_map_entry->k * comp;
2807
0
                    cmyk_map_entry++;
2808
0
                }
2809
0
                cyan /= frac_1;
2810
0
                magenta /= frac_1;
2811
0
                yellow /= frac_1;
2812
0
                black /= frac_1;
2813
2814
0
                if (cyan > 255)
2815
0
                    cyan = 255;
2816
0
                if (magenta > 255)
2817
0
                    magenta = 255;
2818
0
                if (yellow > 255)
2819
0
                    yellow = 255;
2820
0
                if (black > 255)
2821
0
                    black = 255;
2822
2823
0
                buf_ptr[position] = cyan;
2824
0
                buf_ptr[position + planestride] = magenta;
2825
0
                buf_ptr[position + planestride * 2] = yellow;
2826
0
                buf_ptr[position + planestride * 3] = black;
2827
0
            }
2828
0
            if (keep_alpha) {
2829
                /* Move the alpha and tag data */
2830
0
                buf_ptr[position + planestride * 4] = a;
2831
0
                if (tag_offset > 0) {
2832
0
                    buf_ptr[position + planestride * 5] =
2833
0
                        buf_ptr[position + planestride * tag_offset];
2834
0
                }
2835
0
            } else {
2836
                /* Remove alpha but keep tags */
2837
0
                if (tag_offset > 0) {
2838
0
                    buf_ptr[position + planestride * 4] =
2839
0
                        buf_ptr[position + planestride * tag_offset];
2840
0
                }
2841
2842
0
            }
2843
0
            position += 1;
2844
0
        }
2845
0
    }
2846
0
}
2847
2848
static void
2849
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2850
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2851
    cmyk_composite_map *map, bool keep_alpha)
2852
0
{
2853
0
    int comp_num;
2854
0
    ulong cyan, magenta, yellow, black;
2855
0
    cmyk_composite_map *cmyk_map_entry;
2856
0
    int x, y;
2857
0
    intptr_t position;
2858
0
    ulong comp, a;
2859
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2860
2861
    /* planestride and rowstride are in bytes, and we want them in shorts */
2862
0
    planestride >>= 1;
2863
0
    rowstride >>= 1;
2864
2865
0
    for (y = 0; y < height; y++) {
2866
0
        position = y * rowstride;
2867
0
        for (x = 0; x < width; x++) {
2868
0
            a = buf_ptr[position + planestride * num_comp];
2869
0
            if (a != 0) {
2870
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2871
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2872
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2873
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2874
0
                cmyk_map_entry = &(map[4]);
2875
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2876
0
                    comp = buf_ptr[position + planestride * comp_num];
2877
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2878
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2879
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2880
0
                    black += (ulong)cmyk_map_entry->k * comp;
2881
0
                    cmyk_map_entry++;
2882
0
                }
2883
0
                cyan /= frac_1_long;
2884
0
                magenta /= frac_1_long;
2885
0
                yellow /= frac_1_long;
2886
0
                black /= frac_1_long;
2887
2888
0
                if (cyan > 65535)
2889
0
                    cyan = 65535;
2890
0
                if (magenta > 65535)
2891
0
                    magenta = 65535;
2892
0
                if (yellow > 65535)
2893
0
                    yellow = 65535;
2894
0
                if (black > 65535)
2895
0
                    black = 65535;
2896
2897
#if ARCH_IS_BIG_ENDIAN
2898
                buf_ptr[position] = cyan;
2899
                buf_ptr[position + planestride] = magenta;
2900
                buf_ptr[position + planestride * 2] = yellow;
2901
                buf_ptr[position + planestride * 3] = black;
2902
#else
2903
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2904
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2905
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2906
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2907
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2908
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2909
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2910
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2911
0
#endif
2912
0
            }
2913
            /* Move the alpha and tag data */
2914
#if ARCH_IS_BIG_ENDIAN
2915
            if (keep_alpha) {
2916
                buf_ptr[position + planestride * 4] = a;
2917
                if (tag_offset > 0) {
2918
                    buf_ptr[position + planestride * 5] =
2919
                        buf_ptr[position + planestride * tag_offset];
2920
                }
2921
            } else {
2922
                if (tag_offset > 0) {
2923
                    buf_ptr[position + planestride * 4] =
2924
                        buf_ptr[position + planestride * tag_offset];
2925
                }
2926
            }
2927
#else
2928
0
            if (keep_alpha) {
2929
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2930
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2931
0
                if (tag_offset > 0) {
2932
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2933
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2934
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2935
0
                        buf_ptr[position + planestride * tag_offset];
2936
0
                }
2937
0
            } else {
2938
0
                if (tag_offset > 0) {
2939
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2940
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2941
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2942
0
                        buf_ptr[position + planestride * tag_offset];
2943
0
                }
2944
0
            }
2945
0
#endif
2946
0
            position += 1;
2947
0
        }
2948
0
    }
2949
0
}
2950
2951
static void
2952
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2953
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2954
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2955
0
{
2956
0
    if (deep) {
2957
0
        if (keep_alpha) {
2958
0
            if (tag_offset > 0) {
2959
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2960
0
                    planestride, num_comp, spot_start, tag_offset,
2961
0
                    map, true);
2962
0
            } else {
2963
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2964
0
                    planestride, num_comp, spot_start, 0,
2965
0
                    map, true);
2966
0
            }
2967
0
        } else {
2968
0
            if (tag_offset > 0) {
2969
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2970
0
                    planestride, num_comp, spot_start, tag_offset,
2971
0
                    map, false);
2972
0
            } else {
2973
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2974
0
                    planestride, num_comp, spot_start, 0,
2975
0
                    map, false);
2976
0
            }
2977
0
        }
2978
0
    } else {
2979
0
        if (keep_alpha) {
2980
0
            if (tag_offset > 0) {
2981
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2982
0
                    planestride, num_comp, spot_start, tag_offset,
2983
0
                    map, true);
2984
0
            } else {
2985
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2986
0
                    planestride, num_comp, spot_start, 0,
2987
0
                    map, true);
2988
0
            }
2989
0
        } else {
2990
0
            if (tag_offset > 0) {
2991
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2992
0
                    planestride, num_comp, spot_start, tag_offset,
2993
0
                    map, false);
2994
0
            } else {
2995
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2996
0
                    planestride, num_comp, spot_start, 0,
2997
0
                    map, false);
2998
0
            }
2999
0
        }
3000
0
    }
3001
0
}
3002
3003
/* This is for the case where we have mixture of spots and additive color.
3004
   For example, RGB + spots or Gray + spots */
3005
static void
3006
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3007
    intptr_t planestride, int num_comp, int spot_start)
3008
8.76k
{
3009
8.76k
    int x, y;
3010
8.76k
    intptr_t position;
3011
8.76k
    byte comp, a;
3012
8.76k
    int tmp, comp_num;
3013
3014
90.5k
    for (y = 0; y < height; y++) {
3015
81.8k
        position = y * rowstride;
3016
67.4M
        for (x = 0; x < width; x++) {
3017
67.3M
            a = buf_ptr[position + planestride * num_comp];
3018
67.3M
            if ((a + 1) & 0xfe) {
3019
867k
                a ^= 0xff;
3020
3.46M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3021
2.60M
                    comp = buf_ptr[position + planestride * comp_num];
3022
2.60M
                    tmp = ((0xff - comp) * a) + 0x80;
3023
2.60M
                    comp += (tmp + (tmp >> 8)) >> 8;
3024
2.60M
                    buf_ptr[position + planestride * comp_num] = comp;
3025
2.60M
                }
3026
867k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3027
0
                    comp = buf_ptr[position + planestride * comp_num];
3028
0
                    tmp = ((-comp) * a) + 0x80;
3029
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3030
0
                    buf_ptr[position + planestride * comp_num] = comp;
3031
0
                }
3032
66.4M
            } else if (a == 0) {
3033
71.1M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3034
53.3M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3035
53.3M
                }
3036
17.8M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3037
51.1k
                    buf_ptr[position + planestride * comp_num] = 0;
3038
51.1k
                }
3039
17.7M
            }
3040
67.3M
            position += 1;
3041
67.3M
        }
3042
81.8k
    }
3043
8.76k
}
3044
3045
static void
3046
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3047
    intptr_t planestride, int num_comp, int spot_start)
3048
0
{
3049
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3050
0
    int x, y;
3051
0
    intptr_t position;
3052
0
    int comp, a;
3053
0
    int tmp, comp_num;
3054
3055
    /* planestride and rowstride are in bytes, and we want them in shorts */
3056
0
    planestride >>= 1;
3057
0
    rowstride >>= 1;
3058
3059
    /* Note that the input here is native endian, and the output must be in big endian! */
3060
0
    for (y = 0; y < height; y++) {
3061
0
        position = y * rowstride;
3062
0
        for (x = 0; x < width; x++) {
3063
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3064
0
            a = buf_ptr[position + planestride * num_comp];
3065
0
            if (a == 0) {
3066
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3067
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3068
0
                }
3069
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3070
0
                    buf_ptr[position + planestride * comp_num] = 0;
3071
0
                }
3072
0
            } else if (a == 0xffff) {
3073
#if ARCH_IS_BIG_ENDIAN
3074
#else
3075
                /* Convert from native -> big endian */
3076
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3077
0
                    comp = buf_ptr[position + planestride * comp_num];
3078
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3079
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3080
0
                }
3081
0
#endif
3082
0
            } else {
3083
0
                a ^= 0xffff;
3084
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3085
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3086
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3087
0
                    comp = buf_ptr[position + planestride * comp_num];
3088
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3089
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3090
                    /* Store as big endian */
3091
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3092
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3093
0
                }
3094
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3095
0
                    comp = buf_ptr[position + planestride * comp_num];
3096
0
                    tmp = ((0 - comp) * a) + 0x4000;
3097
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3098
                    /* Store as big endian */
3099
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3100
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3101
0
                }
3102
0
            }
3103
0
            position += 1;
3104
0
        }
3105
0
    }
3106
0
}
3107
3108
static int
3109
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3110
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3111
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3112
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3113
    gs_separations* pseparations, bool deep)
3114
24.7k
{
3115
24.7k
    pdf14_device* pdev = (pdf14_device*)dev;
3116
24.7k
    int code = 0;
3117
24.7k
    int y;
3118
24.7k
    int num_rows_left;
3119
24.7k
    int i;
3120
24.7k
    gs_int_rect rect = rect_in;
3121
24.7k
    intptr_t planestride = planestride_in;
3122
24.7k
    intptr_t rowstride = rowstride_in;
3123
24.7k
    byte* buf_ptr = NULL;
3124
24.7k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3125
24.7k
    cmm_profile_t* des_profile = NULL;
3126
24.7k
    cmm_dev_profile_t* dev_target_profile;
3127
24.7k
    cmm_dev_profile_t* pdf14dev_profile;
3128
24.7k
    bool color_mismatch = false;
3129
24.7k
    bool supports_alpha = false;
3130
24.7k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3131
24.7k
    int alpha_offset = num_comp;
3132
24.7k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3133
24.7k
    gs_color_space *pcs;
3134
24.7k
    gs_image1_t image;
3135
24.7k
    gx_image_enum_common_t *info;
3136
24.7k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3137
24.7k
    pdf14_buf *cm_result = NULL;
3138
24.7k
    bool did_alloc;
3139
24.7k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3140
24.7k
    bool has_spots = pdev->ctx->num_spots > 0;
3141
24.7k
    bool blend_spots = !target_sep_device && has_spots;
3142
24.7k
    bool lose_channels = false;
3143
3144
    /* Check if group color space is CMYK based */
3145
24.7k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3146
24.7k
    if (code < 0)
3147
0
        return code;
3148
24.7k
    if (dev_target_profile == NULL)
3149
0
        return gs_throw_code(gs_error_Fatal);
3150
3151
24.7k
    if (src_profile == NULL) {
3152
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3153
0
        if (code < 0) {
3154
0
            return code;
3155
0
        }
3156
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3157
0
    }
3158
3159
    /* If the target device does not support spot colors and we have spot colors
3160
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3161
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3162
24.7k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3163
3164
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3165
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3166
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3167
0
        if (cm_result == NULL)
3168
0
            return_error(gs_error_VMerror);
3169
3170
        /* Update */
3171
0
        buf = cm_result;
3172
0
        src_profile = pgs->icc_manager->default_cmyk;
3173
0
        num_comp = buf->n_chan - 1;
3174
0
        additive = 0;
3175
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3176
0
        alpha_offset = num_comp;
3177
3178
#if RAW_DUMP
3179
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3180
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3181
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3182
        global_index++;
3183
#endif
3184
0
    }
3185
3186
    /* Fix order map if needed */
3187
114k
    for (i = 0; i < num_comp; i++) {
3188
90.1k
        pdev->devn_params.separation_order_map[i] = i;
3189
90.1k
    }
3190
3191
    /* Check if we have a color conversion issue */
3192
24.7k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3193
24.7k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3194
8.76k
        color_mismatch = true;
3195
24.7k
    if (des_profile->data_cs == gsNCHANNEL)
3196
0
        lose_channels = true;
3197
3198
    /* Check if target supports alpha */
3199
24.7k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3200
24.7k
    code = 0;
3201
3202
24.7k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3203
3204
    /* Note. The logic below will need a little rework if we ever
3205
       have a device that has tags and alpha support */
3206
24.7k
    if (supports_alpha) {
3207
3208
        /* If doing simulated overprint, Bring the spot color channels into
3209
           CMYK. Data is planar and 16 bit data in native format. */
3210
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3211
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3212
3213
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3214
0
            if (pdev->pclist_device != NULL) {
3215
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3216
3217
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3218
0
                if (code < 0)
3219
0
                    return code;
3220
0
            }
3221
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3222
3223
            /* Now we go to big endian */
3224
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3225
0
                planestride, num_comp, src_profile->num_comps,
3226
0
                tag_offset, cmyk_map, true, deep);
3227
3228
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3229
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3230
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3231
0
            buf->num_spots = 0;
3232
0
            num_comp = buf->n_chan - 1;
3233
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3234
0
        }
3235
3236
0
        if (!color_mismatch) {
3237
0
            for (i = 0; i < buf->n_planes; i++)
3238
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3239
0
            for (; i < target->color_info.num_components; i++)
3240
0
                buf_ptrs[i] = 0;
3241
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3242
0
                rect.p.x, rect.p.y, width, height,
3243
0
                rowstride, alpha_offset, tag_offset);
3244
            /* Right now code has number of rows written */
3245
0
        } else {
3246
            /* In this case, just color convert and maintain alpha.
3247
               This is a case where we either either blend in the
3248
               right color space and have no alpha for the output
3249
               device or hand back the wrong color space with
3250
               alpha data.  We choose the later. */
3251
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3252
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3253
0
                        rect.p.y, width, height, false);
3254
0
            if (code < 0)
3255
0
                return code;
3256
3257
            /* reset */
3258
0
            rowstride = buf->rowstride;
3259
0
            planestride = buf->planestride;
3260
0
            num_comp = buf->n_chan - 1;
3261
0
            alpha_offset = num_comp;
3262
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3263
3264
            /* And then out */
3265
0
            for (i = 0; i < buf->n_planes; i++)
3266
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3267
0
            for (; i < target->color_info.num_components; i++)
3268
0
                buf_ptrs[i] = 0;
3269
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3270
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3271
0
                tag_offset);
3272
            /* Right now code has number of rows written.  Writing continues below */
3273
0
        }
3274
24.7k
    } else {
3275
        /* Device could not handle the alpha data (we actually don't have
3276
           a device that does spot colorants and has an alpha channel so
3277
           the above code is untested.  Go ahead and preblend now and then
3278
           color convert if needed */
3279
#if RAW_DUMP
3280
           /* Dump before and after the blend to make sure we are doing that ok */
3281
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3282
            "pre_put_image_blend_image", buf_ptr, deep);
3283
        global_index++;
3284
#endif
3285
3286
24.7k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3287
8.76k
            if (deep) {
3288
            /* In this case, we are NOT going to bring the spots into the CMYK
3289
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3290
               16 bit data will be converted now from native endian to big endian during
3291
               the blending process */
3292
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3293
0
                    planestride, num_comp, src_profile->num_comps);
3294
8.76k
            } else {
3295
8.76k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3296
8.76k
                    planestride, num_comp, src_profile->num_comps);
3297
8.76k
            }
3298
15.9k
        } else {
3299
15.9k
            if (deep) {
3300
            /* In this case, if blend_spots == true, we will shortly be bringing
3301
               the spot colors to CMYK equivalent colors. It is at that time that
3302
               we will convert from native endian to big endian. In all other
3303
               cases this blending will due to conversion from native to BE */
3304
0
                bool keep_native = (blend_spots == true);
3305
3306
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3307
0
                    planestride, num_comp, additive, keep_native);
3308
15.9k
            } else {
3309
15.9k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3310
15.9k
                    planestride, num_comp, additive);
3311
15.9k
            }
3312
15.9k
        }
3313
3314
24.7k
        if (deep && has_tags)
3315
0
        {
3316
            /* We still need to convert the tags from Native to BE */
3317
#if ARCH_IS_BIG_ENDIAN
3318
#else
3319
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3320
0
            int i, j;
3321
0
            for (j = 0; j < height; j++)
3322
0
            {
3323
0
                for (i = 0; i < width; i++)
3324
0
                {
3325
0
                    uint16_t tag = *tags++;
3326
0
                    ((byte *)tags)[-2] = tag >> 8;
3327
0
                    ((byte *)tags)[-1] = tag;
3328
0
                }
3329
0
                tags += (buf->rowstride>>1) - width;
3330
0
            }
3331
0
#endif
3332
0
        }
3333
3334
#if RAW_DUMP
3335
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3336
            "post_put_image_blend_image", buf_ptr, deep);
3337
        global_index++;
3338
#endif
3339
3340
        /* If doing simulated overprint and we are not going to a sep device and
3341
           we have spot colors, then bring the spot color channels into CMYK
3342
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3343
           At this point, data is planar and 16 bit data is still in native format. It is
3344
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3345
           above during the alpha blend operation. */
3346
24.7k
        if (blend_spots) {
3347
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3348
3349
            /* In the clist case, we need to get equiv spots out of the
3350
               pseudo-band. */
3351
0
            if (pdev->pclist_device != NULL) {
3352
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3353
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3354
0
                if (code < 0)
3355
0
                    return code;
3356
0
            }
3357
3358
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3359
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3360
0
                planestride, num_comp, src_profile->num_comps,
3361
0
                tag_offset, cmyk_map, false, deep);
3362
3363
            /* Reset buffer information. We have CMYK and maybe tags */
3364
0
            num_comp = 4;
3365
0
            alpha_offset = 0;
3366
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3367
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3368
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3369
0
            buf->num_spots = 0;
3370
3371
#if RAW_DUMP
3372
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3373
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3374
            global_index++;
3375
#endif
3376
0
        }
3377
3378
        /* Map to the destination color space */
3379
24.7k
        if (color_mismatch) {
3380
            /* We started out with the original process colorants, and spots. If we have an
3381
             * nchannel output profile, this can mean that the first few spots might come from
3382
             * that and the rest from the document itself. e.g:
3383
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3384
             * Then we might have a blend space that changes the process colorants:
3385
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3386
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3387
             * If we're not careful, we'll end up with:
3388
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3389
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3390
             */
3391
8.76k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3392
8.76k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3393
8.76k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3394
8.76k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3395
8.76k
            if (code < 0)
3396
0
                return code;
3397
3398
            /* reset */
3399
8.76k
            rowstride = buf->rowstride;
3400
8.76k
            planestride = buf->planestride;
3401
8.76k
            num_comp = buf->n_chan;
3402
8.76k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3403
8.76k
        }
3404
3405
#if RAW_DUMP
3406
        /* Dump after the CS transform */
3407
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3408
            "post_put_image_color_convert", buf_ptr, deep);
3409
        global_index++;
3410
        /* clist_band_count++; */
3411
#endif
3412
3413
        /* Try put_image again. This can occur if the
3414
           target, like psdcmyk and tiffsep, support put_image */
3415
24.7k
        alpha_offset = 0;
3416
148k
        for (i = 0; i < buf->n_planes; i++)
3417
123k
            buf_ptrs[i] = buf_ptr + i * planestride;
3418
24.7k
        for (; i < target->color_info.num_components; i++)
3419
0
            buf_ptrs[i] = 0;
3420
24.7k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3421
24.7k
            rect.p.x, rect.p.y, width, height,
3422
24.7k
            rowstride, alpha_offset, tag_offset);
3423
24.7k
    }
3424
3425
    /* Put image was succesful.  We processed some or all of the rows.
3426
       Continue until we are done */
3427
24.7k
    if (code > 0) {
3428
114
        num_rows_left = height - code;
3429
114
        while (num_rows_left > 0) {
3430
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3431
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3432
0
                alpha_offset, tag_offset);
3433
0
            if (code < 0) {
3434
0
                return code;
3435
0
            }
3436
0
            num_rows_left = num_rows_left - code;
3437
0
        }
3438
114
        return 0;
3439
114
    }
3440
3441
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3442
       as well as those devices that support alpha (pngalpha,
3443
       png16malpha). If we are here, then we are doing an
3444
       overprint simulation on some other device. Image data
3445
       is aleady blended and in device color space. */
3446
24.6k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3447
24.6k
    if (code < 0)
3448
0
        return code;
3449
3450
    /* Already in destination CS */
3451
24.6k
    pcs->cmm_icc_profile_data = des_profile;
3452
3453
    /* pcs takes a reference to the profile data it just retrieved. */
3454
24.6k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3455
24.6k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
3456
0
        return_error(gs_error_rangecheck);
3457
24.6k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3458
3459
    /* If we have more components to write out than are in the des_profile,
3460
     * then just using a PCS based on des_profile, will result in us dropping
3461
     * the spot colors.
3462
     * So, if our target supports devn colors, we instead construct a
3463
     * DevN device space with colors names taken from the devn_params, and
3464
     * use that instead. */
3465
24.6k
    if (des_profile->num_comps != target->color_info.num_components &&
3466
33
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3467
33
    {
3468
33
        int num_std;
3469
33
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3470
33
        gs_color_space *pcs2 = pcs;
3471
33
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3472
33
                                     pcs2, pgs->memory->non_gc_memory);
3473
33
        if (code < 0)
3474
0
            return code;
3475
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3476
33
        pcs->params.device_n.use_alt_cspace = false;
3477
33
        num_std = devn_params->num_std_colorant_names;
3478
165
        for (i = 0; i < num_std; i++) {
3479
132
            const char *name = devn_params->std_colorant_names[i];
3480
132
            size_t len = strlen(name);
3481
132
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3482
132
            if (pcs->params.device_n.names[i] == NULL) {
3483
0
                int j = 0;
3484
0
                for (j = 0;j < i; j++) {
3485
0
                    if (pcs->params.device_n.names[j] != NULL)
3486
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3487
0
                    pcs->params.device_n.names[j] = NULL;
3488
0
                }
3489
0
                return_error(gs_error_VMerror);
3490
0
            }
3491
132
            strcpy(pcs->params.device_n.names[i], name);
3492
132
        }
3493
33
        for (; i < devn_params->separations.num_separations; i++) {
3494
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3495
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");
3496
0
            if (pcs->params.device_n.names[i] == NULL) {
3497
0
                int j = 0;
3498
0
                for (j = 0;j < i; j++) {
3499
0
                    if (pcs->params.device_n.names[j] != NULL)
3500
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3501
0
                    pcs->params.device_n.names[j] = NULL;
3502
0
                }
3503
0
                return_error(gs_error_VMerror);
3504
0
            }
3505
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3506
0
            pcs->params.device_n.names[i][name->size] = 0;
3507
0
        }
3508
33
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3509
0
            return code;
3510
0
        }
3511
        /* One last thing -- we need to fudge the pgs->color_component_map */
3512
198
        for (i=0; i < dev->color_info.num_components; i++)
3513
165
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3514
33
    }
3515
3516
24.6k
    gs_image_t_init_adjust(&image, pcs, false);
3517
24.6k
    image.ImageMatrix.xx = (float)width;
3518
24.6k
    image.ImageMatrix.yy = (float)height;
3519
24.6k
    image.Width = width;
3520
24.6k
    image.Height = height;
3521
24.6k
    image.BitsPerComponent = deep ? 16 : 8;
3522
24.6k
    image.ColorSpace = pcs;
3523
24.6k
    image.format = gs_image_format_component_planar;
3524
3525
24.6k
    ctm_only_writable(pgs).xx = (float)width;
3526
24.6k
    ctm_only_writable(pgs).xy = 0;
3527
24.6k
    ctm_only_writable(pgs).yx = 0;
3528
24.6k
    ctm_only_writable(pgs).yy = (float)height;
3529
24.6k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3530
24.6k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3531
24.6k
    code = dev_proc(target, begin_typed_image) (target,
3532
24.6k
        pgs, NULL, (gs_image_common_t *)&image,
3533
24.6k
        NULL, NULL, NULL, pgs->memory, &info);
3534
24.6k
    if (code < 0) {
3535
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3536
0
        return code;
3537
0
    }
3538
#if RAW_DUMP
3539
    /* Dump the current buffer to see what we have. */
3540
    dump_raw_buffer(pdev->ctx->memory,
3541
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3542
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3543
        pdev->ctx->stack->n_planes,
3544
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3545
        "put_image_final_big", pdev->ctx->stack->data, deep);
3546
    dump_raw_buffer(pdev->ctx->memory,
3547
        height, width, buf->n_planes,
3548
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3549
        "put_image_final_small", buf_ptr, deep);
3550
    global_index++;
3551
    clist_band_count++;
3552
#endif
3553
3554
131k
    for (i = 0; i < num_comp; i++) {
3555
107k
        planes[i].data = buf_ptr + i * planestride;
3556
107k
        planes[i].data_x = 0;
3557
107k
        planes[i].raster = buf->rowstride;
3558
107k
    }
3559
3560
268k
    for (y = 0; y < height; y++) {
3561
244k
        int rows_used;
3562
3563
244k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3564
3565
1.30M
        for (i = 0; i < num_comp; i++) {
3566
1.05M
            planes[i].data += buf->rowstride;
3567
1.05M
        }
3568
244k
    }
3569
24.6k
    info->procs->end_image(info, true);
3570
3571
    /* This will also decrement the profile */
3572
24.6k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3573
24.6k
    return code;
3574
24.6k
}
3575
3576
/**
3577
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3578
 * @pdev: The PDF 1.4 rendering device.
3579
 * @pgs: State for image draw operation.
3580
 * @target: The target device.
3581
 *
3582
 * Puts the rendered image in @pdev's buffer to @target. This is called
3583
 * as part of the sequence of popping the PDF 1.4 device filter.
3584
 *
3585
 * Return code: negative on error.
3586
 **/
3587
static  int
3588
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3589
75.4k
{
3590
75.4k
    pdf14_device *pdev = (pdf14_device *)dev;
3591
75.4k
    pdf14_buf *buf = pdev->ctx->stack;
3592
75.4k
    gs_int_rect rect;
3593
75.4k
    int x1, y1, width, height;
3594
75.4k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3595
75.4k
    gs_separations *pseparations = &pdevn_params->separations;
3596
75.4k
    intptr_t planestride;
3597
75.4k
    intptr_t rowstride;
3598
75.4k
    bool deep = pdev->ctx->deep;
3599
75.4k
    int num_comp;
3600
3601
    /* Nothing was ever drawn. */
3602
75.4k
    if (buf == NULL)
3603
28.9k
        return 0;
3604
3605
46.5k
    num_comp = buf->n_chan - 1;
3606
46.5k
    rect = buf->rect;
3607
46.5k
    planestride = buf->planestride;
3608
46.5k
    rowstride = buf->rowstride;
3609
3610
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3611
       potential problem. Bug 694190 */
3612
46.5k
    if (buf->saved != NULL) {
3613
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3614
1
    }
3615
46.5k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3616
46.5k
    rect_intersect(rect, buf->dirty);
3617
46.5k
    x1 = min(pdev->width, rect.q.x);
3618
46.5k
    y1 = min(pdev->height, rect.q.y);
3619
46.5k
    width = x1 - rect.p.x;
3620
46.5k
    height = y1 - rect.p.y;
3621
46.5k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3622
21.7k
        return 0;
3623
3624
#if RAW_DUMP
3625
    /* Dump the current buffer to see what we have. */
3626
    dump_raw_buffer(pdev->ctx->memory,
3627
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3628
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3629
                    pdev->ctx->stack->n_planes,
3630
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3631
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3632
                    pdev->ctx->stack->deep);
3633
3634
    global_index++;
3635
    clist_band_count++;
3636
#endif
3637
3638
24.7k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3639
24.7k
                      buf, planestride, rowstride,
3640
24.7k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3641
24.7k
                      buf->has_tags, rect, pseparations, deep);
3642
46.5k
}
3643
3644
/**
3645
 * pdf14_custom_put_image: Put rendered image to target device.
3646
 * @pdev: The PDF 1.4 rendering device.
3647
 * @pgs: State for image draw operation.
3648
 * @target: The target device.
3649
 *
3650
 * Puts the rendered image in @pdev's buffer to @target. This is called
3651
 * as part of the sequence of popping the PDF 1.4 device filter.
3652
 *
3653
 * Return code: negative on error.
3654
 **/
3655
static  int
3656
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3657
0
{
3658
0
    pdf14_device * pdev = (pdf14_device *)dev;
3659
0
    pdf14_buf *buf = pdev->ctx->stack;
3660
0
    bool deep = pdev->ctx->deep;
3661
0
    gs_int_rect rect;
3662
0
    int x0, y0;
3663
0
    intptr_t planestride;
3664
0
    intptr_t rowstride;
3665
0
    int num_comp;
3666
0
    uint16_t bg;
3667
0
    int x1, y1, width, height;
3668
0
    byte *buf_ptr;
3669
3670
    /* Nothing was ever drawn. */
3671
0
    if (buf == NULL)
3672
0
        return 0;
3673
3674
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3675
0
    num_comp = buf->n_chan - 1;
3676
0
    rect = buf->rect;
3677
0
    x0 = rect.p.x;
3678
0
    y0 = rect.p.y;
3679
0
    planestride = buf->planestride;
3680
0
    rowstride = buf->rowstride;
3681
3682
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3683
       potential problem. Bug 694190 */
3684
0
    if (buf->saved != NULL) {
3685
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3686
0
    }
3687
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3688
0
    rect_intersect(rect, buf->dirty);
3689
0
    x1 = min(pdev->width, rect.q.x);
3690
0
    y1 = min(pdev->height, rect.q.y);
3691
0
    width = x1 - rect.p.x;
3692
0
    height = y1 - rect.p.y;
3693
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3694
0
        return 0;
3695
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3696
3697
0
    return gx_put_blended_image_custom(target, buf_ptr,
3698
0
                      planestride, rowstride,
3699
0
                      x0, y0, width, height, num_comp, bg, deep);
3700
0
}
3701
3702
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3703
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3704
 * putting everything back how it was, and cleaning up the reference counts.
3705
 */
3706
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3707
2.16M
{
3708
2.16M
    if (pdev->ctx && pdev->ctx->stack) {
3709
914k
        pdf14_buf *buf, *next;
3710
3711
914k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3712
19
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3713
19
            next = buf->saved;
3714
38
            while (group_color_info) {
3715
19
               if (group_color_info->icc_profile != NULL) {
3716
19
                   cmm_profile_t *group_profile;
3717
19
                   gsicc_rendering_param_t render_cond;
3718
19
                   cmm_dev_profile_t *dev_profile;
3719
19
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3720
3721
19
                   if (code >= 0) {
3722
19
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3723
19
                                             &render_cond);
3724
3725
19
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3726
19
                                               -1, "pdf14_end_transparency_group");
3727
19
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3728
19
                           group_color_info->icc_profile;
3729
19
                       group_color_info->icc_profile = NULL;
3730
19
                   }
3731
19
               }
3732
3733
19
               group_color_info = group_color_info->previous;
3734
19
            }
3735
19
        }
3736
914k
    }
3737
2.16M
}
3738
3739
static  int
3740
pdf14_close(gx_device *dev)
3741
1.08M
{
3742
1.08M
    pdf14_device *pdev = (pdf14_device *)dev;
3743
3744
1.08M
    pdf14_cleanup_group_color_profiles(pdev);
3745
3746
1.08M
    if (pdev->ctx) {
3747
1.07M
        pdf14_ctx_free(pdev->ctx);
3748
1.07M
        pdev->ctx = NULL;
3749
1.07M
    }
3750
1.08M
    return 0;
3751
1.08M
}
3752
3753
/* This is called when something has gone wrong and the interpreter received a
3754
   stop while in the middle of doing something with the PDF14 device.  We need
3755
   to clean up and end this in a graceful manner */
3756
static int
3757
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3758
0
{
3759
0
    pdf14_device *pdev = (pdf14_device *)dev;
3760
    /* The things that need to be cleaned up */
3761
0
    pdf14_ctx *ctx = pdev->ctx;
3762
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3763
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3764
3765
    /* Free up the smask color */
3766
0
    if (smaskcolor != NULL) {
3767
0
        smaskcolor->ref_count = 1;
3768
0
        pdf14_decrement_smask_color(pgs, dev);
3769
0
        pdev->smaskcolor = NULL;
3770
0
    }
3771
3772
    /* Free up the nested color procs and decrement the profiles */
3773
0
    if (group_color != NULL) {
3774
0
        while (group_color->previous != NULL)
3775
0
            pdf14_pop_group_color(dev, pgs);
3776
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3777
0
        pdev->color_model_stack = NULL;
3778
0
    }
3779
3780
    /* Start the context clean up */
3781
0
    if (ctx != NULL) {
3782
0
        pdf14_buf *buf, *next;
3783
0
        pdf14_group_color_t *procs, *prev_procs;
3784
3785
0
        if (ctx->mask_stack != NULL) {
3786
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3787
0
        }
3788
3789
        /* Now the stack of buffers */
3790
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3791
0
            next = buf->saved;
3792
3793
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3794
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3795
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3796
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3797
            /* During the soft mask push, the mask_stack was copied (not moved) from
3798
               the ctx to the tos mask_stack. We are done with this now so it is safe
3799
               to free this one object */
3800
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3801
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3802
0
                prev_procs = procs->previous;
3803
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3804
0
            }
3805
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3806
0
        }
3807
        /* Finally the context itself */
3808
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3809
0
        pdev->ctx = NULL;
3810
0
    }
3811
0
    return 0;
3812
0
}
3813
3814
static  int
3815
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3816
0
{
3817
0
    pdf14_device * pdev = (pdf14_device *)dev;
3818
3819
0
    if (pdev->target != NULL)
3820
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3821
0
    return 0;
3822
0
}
3823
3824
8.71M
#define COPY_PARAM(p) dev->p = target->p
3825
5.44M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3826
3827
static void
3828
copy_tag_setup(gx_device *dev, const gx_device *target)
3829
1.08M
{
3830
1.08M
    bool deep = device_is_deep(target);
3831
1.08M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3832
1.08M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3833
1.08M
    COPY_PARAM(graphics_type_tag);
3834
1.08M
    if (had_tags && !has_tags)
3835
0
    {
3836
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3837
0
        dev->color_info.num_components--;
3838
0
        dev->color_info.depth -= deep ? 16 : 8;
3839
0
    }
3840
1.08M
    else if (!had_tags && has_tags)
3841
0
    {
3842
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3843
0
        dev->color_info.num_components++;
3844
0
        dev->color_info.depth += deep ? 16 : 8;
3845
0
    }
3846
1.08M
}
3847
3848
/*
3849
 * Copy device parameters back from a target.  This copies all standard
3850
 * parameters related to page size and resolution, but not any of the
3851
 * color-related parameters, as the pdf14 device retains its own color
3852
 * handling. This routine is parallel to gx_device_copy_params().
3853
 * Note that it DOES copy the devn_params since these are required to
3854
 * keep agreement with colorant name->number mapping, and don't change
3855
 * with the pdf14 color handling.
3856
 */
3857
static  int
3858
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3859
1.08M
{
3860
1.08M
    cmm_dev_profile_t *profile_targ;
3861
1.08M
    cmm_dev_profile_t *profile_dev14;
3862
1.08M
    pdf14_device *pdev = (pdf14_device*) dev;
3863
1.08M
    cmm_profile_t *blend_profile = NULL;
3864
1.08M
    int k;
3865
3866
1.08M
    COPY_PARAM(width);
3867
1.08M
    COPY_PARAM(height);
3868
1.08M
    COPY_ARRAY_PARAM(MediaSize);
3869
1.08M
    COPY_ARRAY_PARAM(ImagingBBox);
3870
1.08M
    COPY_PARAM(ImagingBBox_set);
3871
1.08M
    COPY_ARRAY_PARAM(HWResolution);
3872
1.08M
    COPY_ARRAY_PARAM(Margins);
3873
1.08M
    COPY_ARRAY_PARAM(HWMargins);
3874
1.08M
    COPY_PARAM(PageCount);
3875
1.08M
    COPY_PARAM(MaxPatternBitmap);
3876
3877
3878
    /* Supposedly this function isn't supposed to change the color setup of dev.
3879
     * BUT... if we change the tags value, we have to change the color setup to
3880
     * keep it valid. This is because num_components and depth include tags. */
3881
1.08M
    copy_tag_setup(dev, target);
3882
1.08M
    COPY_PARAM(interpolate_control);
3883
1.08M
    COPY_PARAM(non_strict_bounds);
3884
1.08M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3885
3886
1.08M
    if (dev->icc_struct == NULL) {
3887
1.08M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3888
1.08M
        if (dev->icc_struct == NULL)
3889
0
            return_error(gs_error_VMerror);
3890
1.08M
        profile_dev14 = dev->icc_struct;
3891
1.08M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3892
1.08M
                                          &(profile_targ));
3893
3894
5.44M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3895
4.35M
            if (profile_targ->device_profile[k] != NULL) {
3896
1.08M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3897
1.08M
            }
3898
4.35M
            if (profile_dev14->device_profile[k] != NULL) {
3899
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3900
0
            }
3901
4.35M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3902
4.35M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3903
4.35M
        }
3904
3905
1.08M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3906
1.08M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3907
1.08M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3908
1.08M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3909
1.08M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3910
1.08M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3911
1.08M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3912
1.08M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3913
1.08M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3914
3915
1.08M
        switch (pdev->blend_cs_state) {
3916
1.08M
            case PDF14_BLEND_CS_UNSPECIFIED:
3917
1.08M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3918
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3919
                   during the device push, when we have
3920
                   access to the pgs */
3921
1.08M
                break;
3922
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3923
0
                blend_profile = profile_targ->oi_profile;
3924
0
                break;
3925
0
            case PDF14_BLEND_CS_SPECIFIED:
3926
0
                blend_profile = profile_targ->blend_profile;
3927
0
                break;
3928
0
            default:
3929
0
                break;
3930
1.08M
        }
3931
3932
1.08M
        if (blend_profile != NULL) {
3933
            /* Set the device profile to the blend profile. Note only default profile is set */
3934
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3935
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3936
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3937
0
        }
3938
3939
1.08M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3940
1.08M
    }
3941
1.08M
#undef COPY_ARRAY_PARAM
3942
1.08M
#undef COPY_PARAM
3943
1.08M
    return 0;
3944
1.08M
}
3945
3946
/*
3947
 * This is a forwarding version of the put_params device proc.  It is only
3948
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3949
 * check if the target device has closed and, if so, close itself.  The routine
3950
 * also sync the device parameters.
3951
 */
3952
static  int
3953
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3954
0
{
3955
0
    pdf14_device * pdev = (pdf14_device *)dev;
3956
0
    gx_device * tdev = pdev->target;
3957
0
    bool was_open = tdev->is_open;
3958
0
    int code = 0;
3959
3960
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3961
0
        gx_device_decache_colors(dev);
3962
0
        if (!tdev->is_open) {
3963
0
            code = gs_closedevice(dev);
3964
0
            if (code == 0)
3965
0
                code = was_open ? 1 : 0;   /* target device closed */
3966
0
        }
3967
0
        gx_device_copy_params(dev, tdev);
3968
0
    }
3969
0
    return code;
3970
0
}
3971
3972
/* Function prototypes */
3973
int put_param_pdf14_spot_names(gx_device * pdev,
3974
                gs_separations * pseparations, gs_param_list * plist);
3975
108k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3976
3977
/*
3978
 * The put_params method for the PDF 1.4 device will check if the
3979
 * target device has closed and, if so, close itself.  Note:  This routine is
3980
 * currently being used by both the pdf14_clist_device and the pdf_device.
3981
 * Please make sure that any changes are either applicable to both devices
3982
 * or clone the routine for each device.
3983
 */
3984
static  int
3985
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3986
0
{
3987
0
    pdf14_device * pdev = (pdf14_device *)dev;
3988
0
    gx_device * tdev = pdev->target;
3989
0
    bool was_open = tdev->is_open;
3990
0
    int code = 0, code2 = 0;
3991
3992
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3993
0
        gx_device_decache_colors(dev);
3994
0
        if (!tdev->is_open) {
3995
0
            code = gs_closedevice(dev);
3996
0
            if (code == 0)
3997
0
                code = was_open ? 1 : 0;   /* target device closed */
3998
0
        }
3999
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4000
0
        if (code2 < 0)
4001
0
            code = code2;
4002
0
    }
4003
0
    return code;
4004
0
}
4005
4006
/*
4007
 * Copy marking related parameters into the PDF 1.4 device structure for use
4008
 * by pdf14_fill_rectangle.
4009
 */
4010
static  void
4011
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4012
27.1M
{
4013
27.1M
    pdf14_device * pdev = (pdf14_device *)dev;
4014
4015
27.1M
    if (pgs->alphaisshape) {
4016
386k
        pdev->opacity = 1.0;
4017
386k
        if (pgs->is_fill_color) {
4018
376k
            pdev->shape = pgs->fillconstantalpha;
4019
376k
        } else {
4020
9.43k
            pdev->shape = pgs->strokeconstantalpha;
4021
9.43k
        }
4022
26.8M
    } else {
4023
26.8M
        pdev->shape = 1.0;
4024
26.8M
        if (pgs->is_fill_color) {
4025
11.6M
            pdev->opacity = pgs->fillconstantalpha;
4026
15.1M
        } else {
4027
15.1M
            pdev->opacity = pgs->strokeconstantalpha;
4028
15.1M
        }
4029
26.8M
    }
4030
27.1M
    pdev->alpha = pdev->opacity * pdev->shape;
4031
27.1M
    pdev->blend_mode = pgs->blend_mode;
4032
27.1M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4033
27.1M
        pdev->overprint = pgs->overprint;
4034
27.1M
        pdev->stroke_overprint = pgs->stroke_overprint;
4035
27.1M
    } else {
4036
0
        pdev->overprint = false;
4037
0
        pdev->stroke_overprint = false;
4038
0
    }
4039
4040
27.1M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4041
27.1M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4042
4043
27.1M
    if (pgs->is_fill_color)
4044
11.9M
        pdev->op_state = PDF14_OP_STATE_FILL;
4045
15.1M
    else
4046
15.1M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4047
4048
27.1M
    if_debug6m('v', dev->memory,
4049
27.1M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4050
27.1M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4051
27.1M
               pdev->stroke_effective_op_mode);
4052
27.1M
}
4053
4054
static  void
4055
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4056
18.5M
{
4057
18.5M
    bool hastrans = false;
4058
4059
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4060
     * makes other operations much slower. We have no option however, if the
4061
     * current colour involves transparency, or if it's anything other than
4062
     * a completely solid (or transparent) operation in the normal blend mode.
4063
     */
4064
18.5M
    if (pdcolor != NULL)
4065
18.5M
    {
4066
18.5M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4067
535k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4068
5.04k
            hastrans = true;
4069
18.5M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4070
            /* FIXME: Here we assume that ALL type 2 patterns are
4071
             * transparent - this test could be better. */
4072
7.73k
            hastrans = true;
4073
7.73k
        }
4074
18.5M
    }
4075
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4076
       This appears to be the only place where this test is done so
4077
       not adding a is_idempotent method */
4078
18.5M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4079
154k
        pgs->blend_mode != BLEND_MODE_Darken &&
4080
149k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4081
18.4M
        (pgs->fillconstantalpha != 1.0) ||
4082
18.2M
        (pgs->strokeconstantalpha != 1.0) ||
4083
18.1M
        (hastrans))
4084
409k
    {
4085
        /*
4086
         * The blend operations are not idempotent.  Force non-idempotent
4087
         * filling and stroking operations.
4088
         */
4089
409k
        pgs->log_op |= lop_pdf14;
4090
409k
    }
4091
18.5M
}
4092
4093
static int
4094
push_shfill_group(pdf14_clist_device *pdev,
4095
                  gs_gstate *pgs,
4096
                  gs_fixed_rect *box)
4097
182
{
4098
182
    gs_transparency_group_params_t params = { 0 };
4099
182
    int code;
4100
182
    gs_rect cb;
4101
182
    gs_gstate fudged_pgs = *pgs;
4102
4103
182
    params.shade_group = true;
4104
4105
    /* gs_begin_transparency_group takes a bbox that it then
4106
     * transforms by ctm. Our bbox has already been transformed,
4107
     * so clear out the ctm. */
4108
182
    fudged_pgs.ctm.xx = 1.0;
4109
182
    fudged_pgs.ctm.xy = 0;
4110
182
    fudged_pgs.ctm.yx = 0;
4111
182
    fudged_pgs.ctm.yy = 1.0;
4112
182
    fudged_pgs.ctm.tx = 0;
4113
182
    fudged_pgs.ctm.ty = 0;
4114
182
    cb.p.x = fixed2int_pixround(box->p.x);
4115
182
    cb.p.y = fixed2int_pixround(box->p.y);
4116
182
    cb.q.x = fixed2int_pixround(box->q.x);
4117
182
    cb.q.y = fixed2int_pixround(box->q.y);
4118
4119
182
    params.Isolated = false;
4120
182
    params.Knockout = true;
4121
182
    params.page_group = false;
4122
182
    params.group_opacity = fudged_pgs.fillconstantalpha;
4123
182
    params.group_shape = 1.0;
4124
182
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4125
4126
    /* We have the group handle the blendmode and the opacity,
4127
     * and continue with the existing graphics state reset
4128
     * to normal, opaque operation. We could do it the other
4129
     * way around, but this way means that if we push a knockout
4130
     * group for a stroke, and then the code calls back into
4131
     * the fill operation as part of doing the stroking, we don't
4132
     * push another one. */
4133
182
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4134
182
    gs_setfillconstantalpha(pgs, 1.0);
4135
182
    gs_setstrokeconstantalpha(pgs, 1.0);
4136
182
    if (pdev) {
4137
182
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4138
182
        if (code < 0)
4139
0
            return code;
4140
182
    }
4141
4142
182
    return code;
4143
182
}
4144
4145
static int
4146
pop_shfill_group(gs_gstate *pgs)
4147
180
{
4148
180
     return gs_end_transparency_group(pgs);
4149
180
}
4150
4151
static int
4152
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4153
                           gx_path *ppath, const gx_fill_params *params,
4154
                           const gx_drawing_color *pdcolor,
4155
                           const gx_clip_path *pcpath)
4156
15.4M
{
4157
15.4M
    gs_gstate new_pgs = *pgs;
4158
15.4M
    int code = 0;
4159
15.4M
    gs_pattern2_instance_t *pinst = NULL;
4160
15.4M
    int push_group = 0;
4161
4162
15.4M
    code = pdf14_initialize_ctx(dev, pgs);
4163
15.4M
    if (code < 0)
4164
0
        return code;
4165
4166
15.4M
    if (pdcolor == NULL)
4167
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4168
15.4M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4169
15.4M
    if (gx_dc_is_pattern1_color(pdcolor)){
4170
600k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4171
581k
            gx_pattern1_clist_has_trans(pdcolor) ){
4172
            /* In this case, we need to push a transparency group
4173
               and tile the pattern color, which is stored in
4174
               a pdf14 device buffer in the ctile object memember
4175
               variable ttrans */
4176
#if RAW_DUMP
4177
            /* Since we do not get a put_image to view what
4178
               we have do it now */
4179
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4180
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4181
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4182
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4183
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4184
                        ppatdev14->ctx->stack->rect.p.y *
4185
                        ppatdev14->ctx->stack->rowstride +
4186
                        ppatdev14->ctx->stack->rect.p.x;
4187
                    dump_raw_buffer(ppatdev14->ctx->memory,
4188
                                    (ppatdev14->ctx->stack->rect.q.y -
4189
                                     ppatdev14->ctx->stack->rect.p.y),
4190
                                    (ppatdev14->ctx->stack->rect.q.x -
4191
                                     ppatdev14->ctx->stack->rect.p.x),
4192
                                    ppatdev14->ctx->stack->n_planes,
4193
                                    ppatdev14->ctx->stack->planestride,
4194
                                    ppatdev14->ctx->stack->rowstride,
4195
                                    "Pattern_Fill", buf_ptr,
4196
                                    ppatdev14->ctx->stack->deep);
4197
                    global_index++;
4198
                } else {
4199
                     gx_pattern_trans_t *patt_trans =
4200
                                        pdcolor->colors.pattern.p_tile->ttrans;
4201
                     dump_raw_buffer(patt_trans->mem,
4202
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4203
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4204
                                     patt_trans->n_chan,
4205
                                     patt_trans->planestride, patt_trans->rowstride,
4206
                                     "Pattern_Fill_clist",
4207
                                     patt_trans->transbytes +
4208
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4209
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4210
                                     patt_trans->deep);
4211
                    global_index++;
4212
                }
4213
            }
4214
#endif
4215
75.1k
            pdf14_set_marking_params(dev, &new_pgs);
4216
75.1k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4217
75.1k
                params, pdcolor, pcpath);
4218
75.1k
            new_pgs.trans_device = NULL;
4219
75.1k
            new_pgs.has_transparency = false;
4220
75.1k
            return code;
4221
75.1k
        }
4222
600k
    }
4223
15.3M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4224
15.3M
        pdcolor->type == &gx_dc_devn_masked) {
4225
        /* Non-idempotent blends require a transparency
4226
         * group to be pushed because shadings might
4227
         * paint several pixels twice. */
4228
14
        push_group = pgs->fillconstantalpha != 1.0 ||
4229
14
               !blend_is_idempotent(gs_currentblendmode(pgs));
4230
14
        pinst =
4231
14
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4232
14
        pinst->saved->has_transparency = true;
4233
        /* The transparency color space operations are driven
4234
           by the pdf14 clist writer device.  */
4235
14
        pinst->saved->trans_device = dev;
4236
14
    }
4237
15.3M
    if (push_group) {
4238
0
        gs_fixed_rect box;
4239
0
        if (pcpath)
4240
0
            gx_cpath_outer_box(pcpath, &box);
4241
0
        else
4242
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4243
0
        if (ppath) {
4244
0
            gs_fixed_rect path_box;
4245
4246
0
            gx_path_bbox(ppath, &path_box);
4247
0
            if (box.p.x < path_box.p.x)
4248
0
                box.p.x = path_box.p.x;
4249
0
            if (box.p.y < path_box.p.y)
4250
0
                box.p.y = path_box.p.y;
4251
0
            if (box.q.x > path_box.q.x)
4252
0
                box.q.x = path_box.q.x;
4253
0
            if (box.q.y > path_box.q.y)
4254
0
                box.q.y = path_box.q.y;
4255
0
        }
4256
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4257
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4258
0
    } else
4259
15.3M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4260
15.3M
    pdf14_set_marking_params(dev, &new_pgs);
4261
15.3M
    if (code >= 0) {
4262
15.3M
        new_pgs.trans_device = dev;
4263
15.3M
        new_pgs.has_transparency = true;
4264
        /* ppath can permissibly be NULL here, if we want to have a
4265
         * shading or a pattern fill the clipping path. This upsets
4266
         * coverity, which is not smart enough to realise that the
4267
         * validity of a NULL ppath depends on the type of pdcolor.
4268
         * We'll mark it as a false positive. */
4269
15.3M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4270
15.3M
        new_pgs.trans_device = NULL;
4271
15.3M
        new_pgs.has_transparency = false;
4272
15.3M
    }
4273
15.3M
    if (code >= 0 && push_group) {
4274
0
        code = pop_shfill_group(&new_pgs);
4275
0
        pdf14_set_marking_params(dev, pgs);
4276
0
    }
4277
15.3M
    if (pinst != NULL){
4278
14
        pinst->saved->trans_device = NULL;
4279
14
    }
4280
15.3M
    return code;
4281
15.4M
}
4282
4283
static  int
4284
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4285
                             gx_path *ppath, const gx_stroke_params *params,
4286
                             const gx_drawing_color *pdcolor,
4287
                             const gx_clip_path *pcpath)
4288
1.79M
{
4289
1.79M
    gs_gstate new_pgs = *pgs;
4290
1.79M
    int push_group = 0;
4291
1.79M
    int code = 0;
4292
4293
1.79M
    if (pdcolor == NULL)
4294
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4295
4296
1.79M
    code = pdf14_initialize_ctx(dev, pgs);
4297
1.79M
    if (code < 0)
4298
0
        return code;
4299
4300
1.79M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4301
        /* Non-idempotent blends require a transparency
4302
         * group to be pushed because shadings might
4303
         * paint several pixels twice. */
4304
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4305
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4306
0
    }
4307
1.79M
    if (push_group) {
4308
0
        gs_fixed_rect box;
4309
0
        if (pcpath)
4310
0
            gx_cpath_outer_box(pcpath, &box);
4311
0
        else
4312
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4313
4314
        /* For fill_path, we accept ppath == NULL to mean
4315
         * fill the entire clipping region. That makes no
4316
         * sense for stroke_path, hence ppath is always non
4317
         * NULL here. */
4318
0
        {
4319
0
            gs_fixed_rect path_box;
4320
0
            gs_fixed_point expansion;
4321
4322
0
            gx_path_bbox(ppath, &path_box);
4323
            /* Expand the path bounding box by the scaled line width. */
4324
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4325
                /* The expansion is so large it caused a limitcheck. */
4326
0
                path_box.p.x = path_box.p.y = min_fixed;
4327
0
                path_box.q.x = path_box.q.y = max_fixed;
4328
0
            } else {
4329
0
                expansion.x += pgs->fill_adjust.x;
4330
0
                expansion.y += pgs->fill_adjust.y;
4331
                /*
4332
                 * It's theoretically possible for the following computations to
4333
                 * overflow, so we need to check for this.
4334
                 */
4335
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4336
0
                                path_box.p.x - expansion.x);
4337
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4338
0
                                path_box.p.y - expansion.y);
4339
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4340
0
                                path_box.q.x + expansion.x);
4341
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4342
0
                                path_box.q.y + expansion.y);
4343
0
            }
4344
0
            if (box.p.x < path_box.p.x)
4345
0
                box.p.x = path_box.p.x;
4346
0
            if (box.p.y < path_box.p.y)
4347
0
                box.p.y = path_box.p.y;
4348
0
            if (box.q.x > path_box.q.x)
4349
0
                box.q.x = path_box.q.x;
4350
0
            if (box.q.y > path_box.q.y)
4351
0
                box.q.y = path_box.q.y;
4352
0
        }
4353
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4354
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4355
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4356
0
    } else
4357
1.79M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4358
1.79M
    pdf14_set_marking_params(dev, &new_pgs);
4359
1.79M
    if (code >= 0) {
4360
1.79M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4361
4362
1.79M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4363
1.79M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4364
1.79M
        ((pdf14_device*)dev)->op_state = save_op_state;
4365
1.79M
    }
4366
1.79M
    if (code >= 0 && push_group) {
4367
0
        code = pop_shfill_group(&new_pgs);
4368
0
        pdf14_set_marking_params(dev, pgs);
4369
0
    }
4370
4371
1.79M
    return code;
4372
1.79M
}
4373
4374
/* Pull out steps of transparency updates for fill/stroke
4375
   so that they can be invoked elsewhere (e.g.
4376
   when the abuf device is handling the stroke/fill */
4377
4378
/* Set-up prior to fill operation in fill-stroke */
4379
static int
4380
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4381
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4382
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4383
23.7k
{
4384
23.7k
    int code = 0;
4385
23.7k
    gs_transparency_group_params_t params = { 0 };
4386
23.7k
    gs_fixed_rect clip_bbox;
4387
23.7k
    gs_rect bbox, group_stroke_box;
4388
23.7k
    gs_fixed_rect path_bbox;
4389
23.7k
    int expansion_code;
4390
23.7k
    gs_fixed_point expansion;
4391
23.7k
    pdf14_device* p14dev = (pdf14_device*)dev;
4392
4393
23.7k
    *path_empty = false;
4394
4395
23.7k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4396
23.7k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4397
59
    {
4398
59
        *op_ca_eq_CA = true;
4399
59
        *path_empty = true;
4400
59
        return 0;
4401
59
    }
4402
4403
    /* The clip box returned here is scaled up by path_log2scale, so we need
4404
     * to scale down by this later. */
4405
23.7k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4406
23.7k
    if (code < 0 && code != gs_error_unknownerror)
4407
0
        return code;
4408
4409
23.7k
    if (code == gs_error_unknownerror) {
4410
        /* didn't get clip box from gx_curr_fixed_bbox */
4411
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4412
         * scaling down by this in a moment. */
4413
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4414
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4415
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4416
0
    }
4417
    /* pcpath->outer_box is scaled by path_log2scale too. */
4418
23.7k
    if (pcpath)
4419
23.7k
        rect_intersect(clip_bbox, pcpath->outer_box);
4420
4421
    /* expand the ppath using stroke expansion rule, then intersect it */
4422
23.7k
    code = gx_path_bbox(ppath, &path_bbox);
4423
4424
    /* If we are coming from the abuf device, the path has been scaled
4425
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4426
       on the path_bbox so that we get the proper bounding box for our group. */
4427
23.7k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4428
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4429
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4430
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4431
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4432
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4433
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4434
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4435
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4436
0
    }
4437
4438
23.7k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4439
2.17k
        *path_empty = true;
4440
2.17k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4441
                     there are simply too many return cases that I can't account for. */
4442
2.17k
    }
4443
21.5k
    if (code < 0)
4444
0
        return code;
4445
4446
21.5k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4447
21.5k
    if (expansion_code >= 0) {
4448
21.5k
        path_bbox.p.x -= expansion.x;
4449
21.5k
        path_bbox.p.y -= expansion.y;
4450
21.5k
        path_bbox.q.x += expansion.x;
4451
21.5k
        path_bbox.q.y += expansion.y;
4452
21.5k
    }
4453
21.5k
    rect_intersect(path_bbox, clip_bbox);
4454
21.5k
    bbox.p.x = fixed2float(path_bbox.p.x);
4455
21.5k
    bbox.p.y = fixed2float(path_bbox.p.y);
4456
21.5k
    bbox.q.x = fixed2float(path_bbox.q.x);
4457
21.5k
    bbox.q.y = fixed2float(path_bbox.q.y);
4458
4459
21.5k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4460
21.5k
    if (code < 0)
4461
2
        return code;
4462
4463
21.5k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4464
0
        p14dev->overprint = pgs->overprint;
4465
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4466
0
    }
4467
4468
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4469
21.5k
    if (fill_alpha == stroke_alpha &&
4470
4.71k
        p14dev->overprint && p14dev->stroke_overprint &&
4471
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4472
4473
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4474
           compatible overprint mode.  Group will be composited with
4475
           original alpha and blend mode */
4476
0
        *op_ca_eq_CA = true;
4477
0
        params.Isolated = false;
4478
0
        params.group_color_type = UNKNOWN;
4479
0
        params.Knockout = false;
4480
0
        params.page_group = false;
4481
0
        params.group_opacity = 1.0;
4482
0
        params.group_shape = fill_alpha;
4483
4484
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4485
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4486
0
        if (code < 0)
4487
0
            return code;
4488
4489
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4490
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4491
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4492
4493
21.5k
    } else {
4494
        /* Push a non-isolated knockout group. Do not change the alpha or
4495
            blend modes. Note: we need to draw those that have alpha = 0 */
4496
21.5k
        *op_ca_eq_CA = false;
4497
21.5k
        params.Isolated = false;
4498
21.5k
        params.group_color_type = UNKNOWN;
4499
21.5k
        params.Knockout = true;
4500
21.5k
        params.page_group = false;
4501
21.5k
        params.group_shape = 1.0;
4502
21.5k
        params.group_opacity = 1.0;
4503
4504
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4505
21.5k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4506
21.5k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4507
21.5k
        if (code < 0)
4508
0
            return code;
4509
4510
        /* restore blend mode for actual drawing in the group */
4511
21.5k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4512
4513
        /* If we are in an overprint situation, set the blend mode to compatible
4514
            overprint */
4515
21.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4516
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4517
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4518
21.5k
    }
4519
21.5k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4520
21.5k
    return code;
4521
21.5k
}
4522
4523
/* Set-up prior to stroke operation in fill-stroke */
4524
static void
4525
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4526
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4527
21.5k
{
4528
21.5k
    pdf14_device* p14dev = (pdf14_device*)dev;
4529
4530
21.5k
    if (op_ca_eq_CA) {
4531
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4532
21.5k
    } else {
4533
21.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4534
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4535
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4536
4537
        /* Note that the stroke can end up doing fill methods */
4538
21.5k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4539
4540
21.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4541
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4542
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4543
21.5k
    }
4544
21.5k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4545
21.5k
}
4546
4547
/* Cleanup after the stroke in fill-stroke  */
4548
static int
4549
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4550
21.5k
{
4551
21.5k
    int code;
4552
4553
21.5k
    if (!op_ca_eq_CA) {
4554
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4555
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4556
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4557
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4558
          * We therefore need to make sure it is set according to the current fill state.
4559
          */
4560
21.5k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4561
21.5k
        code = gs_update_trans_marking_params(pgs);
4562
21.5k
        if (code < 0)
4563
0
            return code;
4564
21.5k
        pdf14_set_marking_params(dev, pgs);
4565
21.5k
    }
4566
4567
21.5k
    return 0;
4568
21.5k
}
4569
4570
/* cleanup in fill-stroke  */
4571
static int
4572
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4573
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4574
21.5k
{
4575
21.5k
    pdf14_device* p14dev = (pdf14_device*)dev;
4576
21.5k
    int code2;
4577
21.5k
    int code = 0;
4578
4579
    /* Restore the state */
4580
21.5k
    p14dev->op_state = save_op_state;
4581
21.5k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4582
21.5k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4583
21.5k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4584
4585
21.5k
    code2 = gs_end_transparency_group(pgs);
4586
21.5k
    if (code2 < 0) {
4587
        /* At this point things have gone very wrong. We should just shut down */
4588
0
        code = gs_abort_pdf14trans_device(pgs);
4589
0
        return code2;
4590
0
    }
4591
21.5k
    return code;
4592
21.5k
}
4593
4594
static int
4595
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4596
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4597
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4598
    const gx_clip_path *pcpath)
4599
122k
{
4600
122k
    bool op_ca_eq_CA;
4601
122k
    bool path_empty;
4602
122k
    int code;
4603
122k
    float stroke_alpha = cpgs->strokeconstantalpha;
4604
122k
    float fill_alpha = cpgs->fillconstantalpha;
4605
122k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4606
122k
    pdf14_device* p14dev = (pdf14_device*)dev;
4607
122k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4608
122k
    gs_log2_scale_point path_log2scale;
4609
122k
    bool group_needed = true;
4610
122k
    gx_device* curr_pgs_dev = cpgs->device;
4611
4612
122k
    union {
4613
122k
        const gs_gstate* cpgs;
4614
122k
        gs_gstate* pgs;
4615
122k
    } const_breaker;
4616
122k
    gs_gstate* pgs;
4617
4618
    /* Break const just once, neatly */
4619
122k
    const_breaker.cpgs = cpgs;
4620
122k
    pgs = const_breaker.pgs;
4621
122k
    path_log2scale.x = 0;
4622
122k
    path_log2scale.y = 0;
4623
4624
122k
    code = pdf14_initialize_ctx(dev, pgs);
4625
122k
    if (code < 0)
4626
0
        return code;
4627
4628
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4629
     * blend is normal we don't do a group push. Just do the stroke
4630
     * and the fill, even with overprint */
4631
122k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4632
98.9k
        group_needed = false;
4633
4634
122k
    if (group_needed) {
4635
23.7k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4636
                              can be called on the clist writer side when dealing
4637
                              with the abuf/pdf14 interaction. Those calls have to
4638
                              go through the gs_trans API not the gx_trans or pdf14
4639
                              methods.  Perhaps these methods should have a different
4640
                              suffix, but they are static methods here in the pdf14
4641
                              file. */
4642
23.7k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4643
23.7k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4644
23.7k
        pgs->device = curr_pgs_dev;
4645
23.7k
        if (code < 0)
4646
2
            goto cleanup;
4647
23.7k
        if (path_empty)
4648
2.23k
            return 0;
4649
23.7k
    }
4650
4651
120k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4652
120k
    if (code < 0)
4653
0
        goto cleanup;
4654
4655
120k
    if (group_needed)
4656
21.5k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4657
120k
    gs_swapcolors_quick(pgs);
4658
4659
4660
#if RAW_DUMP
4661
    /* Dump the current buffer to see what we have. */
4662
    dump_raw_buffer(p14dev->ctx->memory,
4663
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4664
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4665
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4666
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4667
    global_index++;
4668
#endif
4669
4670
120k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4671
120k
    gs_swapcolors_quick(pgs);
4672
120k
    if (code < 0) {
4673
0
        goto cleanup;
4674
0
    }
4675
4676
#if RAW_DUMP
4677
    /* Dump the current buffer to see what we have. */
4678
    dump_raw_buffer(p14dev->ctx->memory,
4679
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4680
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4681
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4682
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4683
    global_index++;
4684
#endif
4685
120k
    if (group_needed)
4686
21.5k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4687
4688
120k
cleanup:
4689
120k
    if (group_needed) {
4690
21.5k
        int code1;
4691
21.5k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4692
21.5k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4693
21.5k
            save_op_state);
4694
21.5k
        if (code1 < 0)
4695
0
            code = code1;
4696
21.5k
        pgs->device = curr_pgs_dev;
4697
21.5k
    }
4698
120k
    return code;
4699
120k
}
4700
4701
static int
4702
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4703
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4704
                      gx_color_index color, int depth)
4705
0
{
4706
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4707
0
                                  color, NULL, depth, false);
4708
0
}
4709
4710
static int
4711
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4712
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4713
                      const gx_drawing_color *pdcolor, int depth)
4714
0
{
4715
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4716
0
                                  0, pdcolor, depth, true);
4717
0
}
4718
4719
static int
4720
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4721
                          int aa_raster, gx_bitmap_id id, int x, int y,
4722
                          int w, int h, gx_color_index color,
4723
                          const gx_device_color *pdc, int depth, bool devn)
4724
0
{
4725
0
    const byte *aa_row;
4726
0
    pdf14_device *pdev = (pdf14_device *)dev;
4727
0
    pdf14_buf *buf = pdev->ctx->stack;
4728
0
    int i, j, k;
4729
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4730
0
    byte src[PDF14_MAX_PLANES];
4731
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4732
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4733
0
    bool additive = pdev->ctx->additive;
4734
0
    intptr_t rowstride = buf->rowstride;
4735
0
    intptr_t planestride = buf->planestride;
4736
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4737
0
    bool has_alpha_g = buf->has_alpha_g;
4738
0
    bool has_shape = buf->has_shape;
4739
0
    bool has_tags = buf->has_tags;
4740
0
    bool knockout = buf->knockout;
4741
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4742
0
        blend_mode == BLEND_MODE_Compatible ||
4743
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4744
0
    int num_chan = buf->n_chan;
4745
0
    int num_comp = num_chan - 1;
4746
0
    intptr_t shape_off = num_chan * planestride;
4747
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4748
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4749
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4750
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4751
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4752
0
    gx_color_index comps;
4753
0
    byte shape = 0; /* Quiet compiler. */
4754
0
    byte src_alpha;
4755
0
    int alpha2_aa, alpha_aa, sx;
4756
0
    int alpha_aa_act;
4757
0
    int xoff;
4758
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4759
0
    int shift = 8;
4760
0
    bool has_backdrop = buf->backdrop != NULL;
4761
4762
0
    if (buf->data == NULL)
4763
0
        return 0;
4764
0
    aa_row = data;
4765
0
    if (has_tags) {
4766
0
        if (devn)
4767
0
            curr_tag = pdc->tag;
4768
0
        else
4769
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4770
0
    }
4771
4772
0
    if (devn) {
4773
0
        if (additive) {
4774
0
            for (j = 0; j < num_comp; j++) {
4775
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4776
0
            }
4777
0
        } else {
4778
0
            for (j = 0; j < num_comp; j++) {
4779
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4780
0
            }
4781
0
        }
4782
0
    } else
4783
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4784
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4785
0
    if (has_shape)
4786
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4787
    /* Limit the area we write to the bounding rectangle for this buffer */
4788
0
    if (x < buf->rect.p.x) {
4789
0
        xoff = data_x + buf->rect.p.x - x;
4790
0
        w += x - buf->rect.p.x;
4791
0
        x = buf->rect.p.x;
4792
0
    } else {
4793
0
        xoff = data_x;
4794
0
    }
4795
0
    if (y < buf->rect.p.y) {
4796
0
      h += y - buf->rect.p.y;
4797
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4798
0
      y = buf->rect.p.y;
4799
0
    }
4800
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4801
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4802
    /* Update the dirty rectangle. */
4803
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4804
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4805
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4806
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4807
4808
    /* composite with backdrop only. */
4809
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4810
0
    if (knockout && has_backdrop)
4811
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4812
0
    else
4813
0
        bline = line;
4814
4815
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4816
0
        back_ptr = bline;
4817
0
        dst_ptr = line;
4818
0
        sx = xoff;
4819
0
        for (i = 0; i < w; ++i, ++sx) {
4820
            /* Complement the components for subtractive color spaces */
4821
0
            if (additive) {
4822
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4823
0
                    dst[k] = back_ptr[k * planestride];
4824
0
            } else { /* Complement the components for subtractive color spaces */
4825
0
                for (k = 0; k < num_comp; ++k)
4826
0
                    dst[k] = 255 - back_ptr[k * planestride];
4827
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4828
0
            }
4829
            /* Get the aa alpha from the buffer */
4830
0
            switch(depth)
4831
0
            {
4832
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4833
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4834
0
                break;
4835
0
            case 4:
4836
0
                alpha2_aa = aa_row[sx >> 1];
4837
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4838
0
                break;
4839
0
            case 8:
4840
0
                alpha_aa = aa_row[sx];
4841
0
                break;
4842
0
            default:
4843
0
                return_error(gs_error_rangecheck);
4844
0
            }
4845
0
            if (alpha_aa != 0) {  /* This does happen */
4846
0
                if (alpha_aa != 255) {
4847
                    /* We have an alpha value from aa */
4848
0
                    alpha_aa_act = alpha_aa;
4849
0
                    if (src_alpha != 255) {
4850
                        /* Need to combine it with the existing alpha */
4851
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4852
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4853
0
                    }
4854
                    /* Set our source alpha value appropriately */
4855
0
                    src[num_comp] = alpha_aa_act;
4856
0
                } else {
4857
                    /* We may have to reset this is it was changed as we
4858
                       moved across the row */
4859
0
                    src[num_comp] = src_alpha;
4860
0
                }
4861
0
                if (knockout) {
4862
0
                    if (buf->isolated) {
4863
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4864
0
                    } else {
4865
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4866
0
                            blend_mode, pdev->blend_procs, pdev);
4867
0
                    }
4868
0
                } else {
4869
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4870
0
                                                    pdev->blend_procs, pdev);
4871
0
                }
4872
                /* Complement the results for subtractive color spaces */
4873
0
                if (additive) {
4874
0
                    for (k = 0; k < num_chan; ++k)
4875
0
                        dst_ptr[k * planestride] = dst[k];
4876
0
                } else {
4877
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4878
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4879
0
                                ++k, comps >>= 1) {
4880
0
                            if ((comps & 0x1) != 0) {
4881
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4882
0
                            }
4883
0
                        }
4884
                        /* The alpha channel */
4885
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4886
0
                    } else {
4887
0
                        for (k = 0; k < num_comp; ++k)
4888
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4889
                        /* The alpha channel */
4890
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4891
0
                    }
4892
0
                }
4893
0
                if (has_alpha_g) {
4894
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4895
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4896
0
                }
4897
0
                if (has_shape) {
4898
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4899
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4900
0
                }
4901
0
                if (has_tags) {
4902
                    /* If alpha is 100% then set to curr_tag, else or */
4903
                    /* other than Normal BM, we always OR */
4904
0
                    if (src[num_comp] == 255 && tag_blend) {
4905
0
                        dst_ptr[tag_off] = curr_tag;
4906
0
                    } else {
4907
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4908
0
                    }
4909
0
                }
4910
0
            }
4911
0
            ++dst_ptr;
4912
0
            ++back_ptr;
4913
0
        }
4914
0
        line += rowstride;
4915
0
        bline += rowstride;
4916
0
    }
4917
0
    return 0;
4918
0
}
4919
4920
static int
4921
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4922
                             int aa_raster, gx_bitmap_id id, int x, int y,
4923
                             int w, int h, gx_color_index color,
4924
                             const gx_device_color *pdc, int depth, bool devn)
4925
0
{
4926
0
    const byte *aa_row;
4927
0
    pdf14_device *pdev = (pdf14_device *)dev;
4928
0
    pdf14_buf *buf = pdev->ctx->stack;
4929
0
    int i, j, k;
4930
0
    byte *bline, *line;
4931
0
    uint16_t *dst_ptr, *back_ptr;
4932
0
    uint16_t src[PDF14_MAX_PLANES];
4933
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4934
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4935
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4936
0
        blend_mode == BLEND_MODE_Compatible ||
4937
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4938
0
    bool additive = pdev->ctx->additive;
4939
0
    intptr_t rowstride = buf->rowstride;
4940
0
    int planestride = buf->planestride;
4941
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4942
0
    bool has_alpha_g = buf->has_alpha_g;
4943
0
    bool has_shape = buf->has_shape;
4944
0
    bool has_tags = buf->has_tags;
4945
0
    bool knockout = buf->knockout;
4946
0
    int num_chan = buf->n_chan;
4947
0
    int num_comp = num_chan - 1;
4948
0
    intptr_t shape_off = num_chan * planestride;
4949
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4950
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4951
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4952
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4953
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4954
0
    gx_color_index comps;
4955
0
    uint16_t shape = 0; /* Quiet compiler. */
4956
0
    uint16_t src_alpha;
4957
0
    int alpha2_aa, alpha_aa, sx;
4958
0
    int alpha_aa_act;
4959
0
    int xoff;
4960
0
    bool has_backdrop = buf->backdrop != NULL;
4961
4962
0
    if (buf->data == NULL)
4963
0
        return 0;
4964
0
    aa_row = data;
4965
0
    if (has_tags) {
4966
0
        if (devn)
4967
0
            curr_tag = pdc->tag;
4968
0
        else
4969
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4970
0
    }
4971
4972
0
    if (devn) {
4973
0
        if (additive) {
4974
0
            for (j = 0; j < num_comp; j++) {
4975
0
                src[j] = pdc->colors.devn.values[j];
4976
0
            }
4977
0
        } else {
4978
0
            for (j = 0; j < num_comp; j++) {
4979
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4980
0
            }
4981
0
        }
4982
0
    } else
4983
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4984
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4985
0
    if (has_shape)
4986
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4987
    /* Limit the area we write to the bounding rectangle for this buffer */
4988
0
    if (x < buf->rect.p.x) {
4989
0
        xoff = data_x + buf->rect.p.x - x;
4990
0
        w += x - buf->rect.p.x;
4991
0
        x = buf->rect.p.x;
4992
0
    } else {
4993
0
        xoff = data_x;
4994
0
    }
4995
0
    if (y < buf->rect.p.y) {
4996
0
      h += y - buf->rect.p.y;
4997
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4998
0
      y = buf->rect.p.y;
4999
0
    }
5000
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5001
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5002
    /* Update the dirty rectangle. */
5003
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5004
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5005
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5006
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5007
5008
    /* composite with backdrop only. */
5009
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5010
0
    if (knockout && has_backdrop)
5011
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5012
0
    else
5013
0
        bline = line;
5014
5015
0
    planestride >>= 1;
5016
0
    rowstride   >>= 1;
5017
0
    alpha_g_off >>= 1;
5018
0
    shape_off   >>= 1;
5019
0
    tag_off     >>= 1;
5020
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5021
0
        back_ptr = (uint16_t *)(void *)bline;
5022
0
        dst_ptr = (uint16_t *)(void *)line;
5023
0
        sx = xoff;
5024
0
        for (i = 0; i < w; ++i, ++sx) {
5025
            /* Complement the components for subtractive color spaces */
5026
0
            if (additive) {
5027
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5028
0
                    dst[k] = back_ptr[k * planestride];
5029
0
            } else { /* Complement the components for subtractive color spaces */
5030
0
                for (k = 0; k < num_comp; ++k)
5031
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5032
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5033
0
            }
5034
            /* Get the aa alpha from the buffer */
5035
0
            switch(depth)
5036
0
            {
5037
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5038
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5039
0
                break;
5040
0
            case 4:
5041
0
                alpha2_aa = aa_row[sx >> 1];
5042
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5043
0
                break;
5044
0
            case 8:
5045
0
                alpha_aa = aa_row[sx];
5046
0
                break;
5047
0
            default:
5048
0
                return_error(gs_error_rangecheck);
5049
0
            }
5050
0
            if (alpha_aa != 0) {  /* This does happen */
5051
0
                if (alpha_aa != 255) {
5052
                    /* We have an alpha value from aa */
5053
0
                    alpha_aa_act = alpha_aa * 0x101;
5054
0
                    if (src_alpha != 65535) {
5055
                        /* Need to combine it with the existing alpha */
5056
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5057
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5058
0
                    }
5059
                    /* Set our source alpha value appropriately */
5060
0
                    src[num_comp] = alpha_aa_act;
5061
0
                } else {
5062
                    /* We may have to reset this is it was changed as we
5063
                       moved across the row */
5064
0
                    src[num_comp] = src_alpha;
5065
0
                }
5066
0
                if (knockout) {
5067
0
                    if (buf->isolated) {
5068
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5069
0
                    } else {
5070
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5071
0
                            blend_mode, pdev->blend_procs, pdev);
5072
0
                    }
5073
0
                } else {
5074
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5075
0
                                                     pdev->blend_procs, pdev);
5076
0
                }
5077
                /* Complement the results for subtractive color spaces */
5078
0
                if (additive) {
5079
0
                    for (k = 0; k < num_chan; ++k)
5080
0
                        dst_ptr[k * planestride] = dst[k];
5081
0
                } else {
5082
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5083
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5084
0
                                ++k, comps >>= 1) {
5085
0
                            if ((comps & 0x1) != 0) {
5086
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5087
0
                            }
5088
0
                        }
5089
                        /* The alpha channel */
5090
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5091
0
                    } else {
5092
0
                        for (k = 0; k < num_comp; ++k)
5093
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5094
                        /* The alpha channel */
5095
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5096
0
                    }
5097
0
                }
5098
0
                if (has_alpha_g) {
5099
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5100
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5101
0
                }
5102
0
                if (has_shape) {
5103
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5104
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5105
0
                }
5106
0
                if (has_tags) {
5107
                    /* If alpha is 100% then set to curr_tag, else or */
5108
                    /* other than Normal BM, we always OR */
5109
0
                    if (src[num_comp] == 65535 && tag_blend) {
5110
0
                        dst_ptr[tag_off] = curr_tag;
5111
0
                    } else {
5112
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5113
0
                    }
5114
0
                }
5115
0
            }
5116
0
            ++dst_ptr;
5117
0
            ++back_ptr;
5118
0
        }
5119
0
        line += rowstride;
5120
0
        bline += rowstride;
5121
0
    }
5122
0
    return 0;
5123
0
}
5124
5125
static int
5126
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5127
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5128
                      gx_color_index color, const gx_device_color *pdc,
5129
                      int depth, bool devn)
5130
0
{
5131
0
    bool deep = device_is_deep(dev);
5132
0
    int code;
5133
5134
0
    code = pdf14_initialize_ctx(dev, NULL);
5135
0
    if (code < 0)
5136
0
        return code;
5137
5138
0
    if (deep)
5139
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5140
0
                                            id, x, y, w, h,
5141
0
                                            color, pdc, depth, devn);
5142
0
    else
5143
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5144
0
                                         id, x, y, w, h,
5145
0
                                         color, pdc, depth, devn);
5146
0
}
5147
5148
static  int
5149
pdf14_fill_mask(gx_device * orig_dev,
5150
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5151
                     int x, int y, int w, int h,
5152
                     const gx_drawing_color * pdcolor, int depth,
5153
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5154
12.1M
{
5155
12.1M
    gx_device *dev;
5156
12.1M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5157
12.1M
    gx_device_clip cdev;
5158
12.1M
    gx_color_tile *ptile = NULL;
5159
12.1M
    int code = 0;
5160
12.1M
    gs_int_rect group_rect;
5161
12.1M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5162
12.1M
    bool has_pattern_trans = false;
5163
12.1M
    cmm_dev_profile_t *dev_profile;
5164
5165
12.1M
    if (pdcolor == NULL)
5166
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5167
5168
12.1M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5169
12.1M
    if (code < 0)
5170
0
        return code;
5171
5172
    /* If we are doing a fill with a pattern that has a transparency then
5173
       go ahead and do a push and a pop of the transparency group */
5174
12.1M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5175
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5176
0
            ptile = pdcolor->colors.pattern.p_tile;
5177
            /* Set up things in the ptile so that we get the proper
5178
               blending etc */
5179
            /* Set the blending procs and the is_additive setting based
5180
               upon the number of channels */
5181
0
            if (ptile->ttrans->n_chan-1 < 4) {
5182
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5183
0
                ptile->ttrans->is_additive = true;
5184
0
            } else {
5185
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5186
0
                ptile->ttrans->is_additive = false;
5187
0
            }
5188
            /* Set the procs so that we use the proper filling method. */
5189
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5190
            /* Based upon if the tiles overlap pick the type of rect
5191
               fill that we will want to use */
5192
0
            if (ptile->has_overlap) {
5193
                /* This one does blending since there is tile overlap */
5194
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5195
0
            } else {
5196
                /* This one does no blending since there is no tile overlap */
5197
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5198
0
            }
5199
            /* Push the group */
5200
0
            group_rect.p.x = x;
5201
0
            group_rect.p.y = max(0,y);
5202
0
            group_rect.q.x = x + w;
5203
0
            group_rect.q.y = y + h;
5204
0
            if (!(w <= 0 || h <= 0)) {
5205
5206
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5207
0
                if (group_color_info == NULL)
5208
0
                    return_error(gs_error_VMerror);
5209
5210
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5211
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5212
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5213
0
                     group_color_info, NULL, NULL);
5214
0
                if (code < 0)
5215
0
                    return code;
5216
                /* Set up the output buffer information now that we have
5217
                   pushed the group */
5218
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5219
0
                if (fill_trans_buffer == NULL)
5220
0
                    return_error(gs_error_VMerror);
5221
5222
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5223
0
                                              fill_trans_buffer, NULL, false);
5224
                /* Store this in the appropriate place in pdcolor.  This
5225
                   is released later after the mask fill */
5226
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5227
0
                has_pattern_trans = true;
5228
0
            }
5229
0
        }
5230
0
    }
5231
12.1M
    if (pcpath != 0) {
5232
1.49M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5233
1.49M
        dev = (gx_device *) & cdev;
5234
1.49M
    } else
5235
10.6M
        dev = orig_dev;
5236
12.1M
    if (depth > 1) {
5237
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5238
0
        code = (*dev_proc(dev, copy_alpha))
5239
0
            (dev, data, dx, raster, id, x, y, w, h,
5240
0
             gx_dc_pure_color(pdcolor), depth);
5241
12.1M
    } else {
5242
12.1M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5243
12.1M
                                          x, y, w, h, dev, lop, false);
5244
12.1M
    }
5245
12.1M
    if (has_pattern_trans) {
5246
0
        bool has_tags = device_encodes_tags(dev);
5247
0
        if (code >= 0)
5248
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5249
0
        if (code >= 0)
5250
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5251
0
                                                p14dev->blend_procs,
5252
0
                                                p14dev->color_info.num_components - has_tags,
5253
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5254
0
                                                orig_dev);
5255
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5256
0
                       "pdf14_fill_mask");
5257
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5258
0
    }
5259
12.1M
    if (pcpath != 0)
5260
1.49M
        gx_destroy_clip_device_on_stack(&cdev);
5261
12.1M
    return code;
5262
12.1M
}
5263
5264
5265
5266
/* Used for filling rects when we are doing a fill with a pattern that
5267
   has transparency */
5268
static  int
5269
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5270
                        gx_path * ppath, const gx_fill_params * params,
5271
                        const gx_device_color * pdevc,
5272
                        const gx_clip_path * pcpath)
5273
75.1k
{
5274
75.1k
    int code;
5275
75.1k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5276
75.1k
    gs_fixed_rect clip_box;
5277
75.1k
    gs_fixed_rect outer_box;
5278
75.1k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5279
75.1k
    gs_int_rect rect;
5280
75.1k
    gx_clip_rect *curr_clip_rect;
5281
75.1k
    gx_color_tile *ptile = NULL;
5282
75.1k
    int k;
5283
75.1k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5284
75.1k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5285
75.1k
    int n_chan_tile;
5286
75.1k
    gx_clip_path cpath_intersection;
5287
75.1k
    gx_path path_ttrans;
5288
75.1k
    pdf14_group_color_t *group_color_info;
5289
75.1k
    bool has_tags = device_encodes_tags(pdev);
5290
5291
75.1k
    if (ppath == NULL)
5292
0
        return_error(gs_error_unknownerror);  /* should not happen */
5293
75.1k
    if (pcpath != NULL) {
5294
71.2k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5295
71.2k
    } else {
5296
3.88k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5297
3.88k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5298
3.88k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5299
3.88k
    }
5300
75.1k
    if (code < 0)
5301
0
        return code;
5302
75.1k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5303
75.1k
                                          params->rule, pgs_noconst, params);
5304
75.1k
    if (code < 0)
5305
0
        return code;
5306
    /* One (common) case worth optimising for is where we have a pattern that
5307
     * is positioned such that only one repeat of the tile is actually
5308
     * visible. In this case, we can restrict the size of the blending group
5309
     * we need to produce to be that of the actual area of the tile that is
5310
     * used. */
5311
75.1k
    ptile = pdevc->colors.pattern.p_tile;
5312
75.1k
    if (ptile->ttrans != NULL)
5313
19.0k
    {
5314
19.0k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5315
19.0k
            (cpath_intersection.outer_box.p.y < 0) ||
5316
19.0k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5317
11.5k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5318
8.01k
        {
5319
            /* More than one repeat of the tile would be visible, so we can't
5320
             * use the optimisation here. (Actually, this test isn't quite
5321
             * right - it actually tests whether more than the '0th' repeat
5322
             * of the tile is visible. A better test would test if just one
5323
             * repeat of the tile was visible, irrespective of which one.
5324
             * This is (hopefully) relatively rare, and would make the code
5325
             * below more complex too, so we're ignoring that for now. If it
5326
             * becomes evident that it's a case that matters we can revisit
5327
             * it.) */
5328
11.0k
        } else {
5329
            /* Only the 0th repeat is visible. Restrict the size further to
5330
             * just the used area of that patch. */
5331
11.0k
            gx_path_init_local(&path_ttrans, ppath->memory);
5332
11.0k
            code = gx_path_add_rectangle(&path_ttrans,
5333
11.0k
                                         int2fixed(ptile->ttrans->rect.p.x),
5334
11.0k
                                         int2fixed(ptile->ttrans->rect.p.y),
5335
11.0k
                                         int2fixed(ptile->ttrans->rect.q.x),
5336
11.0k
                                         int2fixed(ptile->ttrans->rect.q.y));
5337
11.0k
            if (code < 0)
5338
0
                return code;
5339
11.0k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5340
11.0k
                                      params->rule, pgs_noconst);
5341
11.0k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5342
11.0k
            if (code < 0)
5343
0
                return code;
5344
11.0k
        }
5345
19.0k
    }
5346
    /* Now let us push a transparency group into which we are
5347
     * going to tile the pattern.  */
5348
75.1k
    if (ppath != NULL) {
5349
75.1k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5350
5351
75.1k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5352
75.1k
        rect.p.x = fixed2int(outer_box.p.x);
5353
75.1k
        rect.p.y = fixed2int(outer_box.p.y);
5354
75.1k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5355
75.1k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5356
5357
        /* The color space of this group must be the same as that of the
5358
           tile.  Then when we pop the group, if there is a mismatch between
5359
           the tile color space and the current context we will do the proper
5360
           conversion.  In this way, we ensure that if the tile has any overlapping
5361
           occuring it will be blended in the proper manner i.e in the tile
5362
           underlying color space. */
5363
75.1k
        if (ptile->cdev == NULL) {
5364
19.0k
            if (ptile->ttrans == NULL)
5365
0
                return_error(gs_error_unknownerror);  /* should not happen */
5366
19.0k
            n_chan_tile = ptile->ttrans->n_chan;
5367
56.0k
        } else {
5368
56.0k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5369
56.0k
        }
5370
75.1k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5371
5372
        /* Transparency handling with patterns confuses me, so some notes...
5373
         *
5374
         * For simple, non-transparent patterns, like you'd get in PS, we've
5375
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5376
         * times. To cope with unmarked pixels, we have a "transparency" plane
5377
         * (simple on/off) that says whether a pixel is marked or not.
5378
         *
5379
         * For patterns with transparency (but not blending), we can create an
5380
         * isolated transparency group, tile all the bitmap tiles into that, and
5381
         * then blend that back with the required alpha at the end. This works
5382
         * because the alpha values of the individual objects within the tile are
5383
         * recorded in that group.
5384
         *
5385
         * We can't do that for groups that use blending though, as each object
5386
         * in the pattern might use a different blend, and we don't (can't) record
5387
         * the blending mode. An isolated group doesn't even allow us to actually
5388
         * do the blending at all. So, for such patterns (any patterns that sets (or
5389
         * just has a resource that mentions) a non-normal blend mode), we use
5390
         * a pattern clist.
5391
         */
5392
75.1k
        if (ptile->cdev == NULL) {
5393
19.0k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5394
19.0k
            if (group_color_info == NULL)
5395
0
                return gs_error_VMerror;
5396
5397
19.0k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5398
19.0k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5399
19.0k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5400
19.0k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5401
19.0k
            if (code < 0)
5402
0
                return code;
5403
19.0k
        }
5404
5405
        /* Set the blending procs and the is_additive setting based
5406
           upon the number of channels */
5407
75.1k
        if (ptile->cdev == NULL) {
5408
19.0k
            if (n_chan_tile-1 < 4) {
5409
18.3k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5410
18.3k
                ptile->ttrans->is_additive = true;
5411
18.3k
            } else {
5412
690
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5413
690
                ptile->ttrans->is_additive = false;
5414
690
            }
5415
19.0k
        }
5416
        /* Now lets go through the rect list and fill with the pattern */
5417
        /* First get the buffer that we will be filling */
5418
75.1k
        if (ptile->cdev == NULL) {
5419
19.0k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5420
19.0k
            if (fill_trans_buffer == NULL) {
5421
0
                p14dev->pclist_device = NULL;
5422
0
                return_error(gs_error_VMerror);
5423
0
            }
5424
19.0k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5425
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5426
               want to use */
5427
19.0k
            if (ptile->has_overlap) {
5428
                /* This one does blending since there is tile overlap */
5429
1.41k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5430
17.6k
            } else {
5431
                /* This one does no blending since there is no tile overlap */
5432
17.6k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5433
17.6k
            }
5434
            /* fill the rectangles */
5435
19.0k
            phase.x = pdevc->phase.x;
5436
19.0k
            phase.y = pdevc->phase.y;
5437
19.0k
            if (cpath_intersection.rect_list->list.head != NULL){
5438
992
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5439
16.5k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5440
15.5k
                    if_debug5m('v', pgs->memory,
5441
15.5k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5442
15.5k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5443
15.5k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5444
15.5k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5445
15.5k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5446
15.5k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5447
15.5k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5448
15.5k
                    curr_clip_rect = curr_clip_rect->next;
5449
15.5k
                }
5450
18.0k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5451
                /* The case when there is just a single rect */
5452
17.7k
                if_debug5m('v', pgs->memory,
5453
17.7k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5454
17.7k
                           cpath_intersection.rect_list->list.single.xmin,
5455
17.7k
                           cpath_intersection.rect_list->list.single.ymin,
5456
17.7k
                           cpath_intersection.rect_list->list.single.xmax-
5457
17.7k
                              cpath_intersection.rect_list->list.single.xmin,
5458
17.7k
                           cpath_intersection.rect_list->list.single.ymax-
5459
17.7k
                              cpath_intersection.rect_list->list.single.ymin,
5460
17.7k
                           (int)ptile->id);
5461
17.7k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5462
17.7k
                                                  cpath_intersection.rect_list->list.single.ymin,
5463
17.7k
                                                  cpath_intersection.rect_list->list.single.xmax,
5464
17.7k
                                                  cpath_intersection.rect_list->list.single.ymax,
5465
17.7k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5466
17.7k
            }
5467
56.0k
        } else {
5468
            /* Clist pattern with transparency.  Create a clip device from our
5469
               cpath_intersection.  The above non-clist case could probably be
5470
               done this way too, which will reduce the amount of code here.
5471
               That is for another day though due to time constraints*/
5472
56.0k
            gx_device *dev;
5473
56.0k
            gx_device_clip clipdev;
5474
5475
56.0k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5476
56.0k
            dev = (gx_device *)&clipdev;
5477
56.0k
            phase.x = pdevc->phase.x;
5478
56.0k
            phase.y = pdevc->phase.y;
5479
56.0k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5480
56.0k
                                              ptile, fill_trans_buffer, phase,
5481
56.0k
                                              dev, pdevc, 1);
5482
56.0k
            gx_destroy_clip_device_on_stack(&clipdev);
5483
56.0k
        }
5484
        /* We're done drawing with the pattern, remove the reference to the
5485
         * pattern device
5486
         */
5487
75.1k
        p14dev->pclist_device = NULL;
5488
75.1k
        if (code < 0)
5489
0
            return code;
5490
5491
        /* free our buffer object */
5492
75.1k
        if (fill_trans_buffer != NULL) {
5493
19.0k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5494
19.0k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5495
19.0k
        }
5496
75.1k
        if (ptile->cdev == NULL) {
5497
            /* pop our transparency group which will force the blending.
5498
               This was all needed for Bug 693498 */
5499
19.0k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5500
19.0k
                                                p14dev->blend_procs,
5501
19.0k
                                                p14dev->color_info.num_components - has_tags,
5502
19.0k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5503
19.0k
                                                pdev);
5504
19.0k
        }
5505
75.1k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5506
75.1k
        p14dev->pclist_device = NULL;
5507
75.1k
    }
5508
75.1k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5509
75.1k
    return code;
5510
75.1k
}
5511
5512
/* Useful function that should probably go elsewhere.
5513
 * Call this function to find the topmost pdf14 device in the device chain,
5514
 * or NULL if there is not one.
5515
 */
5516
static pdf14_device *find_pdf14_device(gx_device *dev)
5517
0
{
5518
0
    pdf14_device *pdev;
5519
5520
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5521
0
        return NULL;
5522
0
    return pdev;
5523
0
}
5524
5525
/* Imager render for pattern transparency filling.  This is just here to catch
5526
   the final flush, at which time we will pop the group and reset a few items */
5527
static  int
5528
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5529
                    uint w, int h, gx_device * dev)
5530
0
{
5531
0
    int code;
5532
0
    pdf14_device * p14dev;
5533
0
    const gs_gstate * pgs = penum->pgs;
5534
0
    gx_device_color * pdcolor = (penum->icolor1);
5535
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5536
0
    bool has_tags = device_encodes_tags(dev);
5537
5538
    /* Pass along to the original renderer */
5539
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5540
0
    if (code < 0)
5541
0
        return code;
5542
    /* On our final time through here, go ahead and pop the transparency
5543
       group and reset the procs in the device color. And free the fill
5544
       trans buffer object */
5545
0
    if (h == 0 && ptile->trans_group_popped == false) {
5546
0
        p14dev = find_pdf14_device(dev);
5547
5548
0
        if (p14dev->pclist_device == NULL) {
5549
            /* Used if we are on clist writing phase.  Would only
5550
               occur if we somehow failed in high level clist
5551
               image writing */
5552
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5553
0
        } else {
5554
            /* Used if we are on clist reading phase.  If we had high level
5555
               image in clist */
5556
0
            cmm_dev_profile_t *dev_profile;
5557
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5558
0
            if (code < 0)
5559
0
                return code;
5560
5561
0
            if_debug2m('v', p14dev->ctx->memory,
5562
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5563
0
                       ptile->uid.id, ptile->id);
5564
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5565
0
                    p14dev->color_info.num_components - has_tags,
5566
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5567
0
                    (gx_device *) p14dev);
5568
0
        }
5569
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5570
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5571
0
                       "pdf14_pattern_trans_render");
5572
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5573
0
    }
5574
0
    return code;
5575
0
}
5576
5577
/* This function is used to get things in place for filling a mask image
5578
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5579
   and pdf14_clist_begin_type_image */
5580
static int
5581
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5582
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5583
                           const gs_int_rect * prect,
5584
                           const gx_drawing_color * pdcolor,
5585
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5586
                           gx_image_enum_common_t ** pinfo)
5587
0
{
5588
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5589
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5590
0
    gx_color_tile *ptile;
5591
0
    int code;
5592
0
    gs_int_rect group_rect;
5593
0
    gx_image_enum *penum;
5594
0
    gs_rect bbox_in, bbox_out;
5595
0
    gx_pattern_trans_t *fill_trans_buffer;
5596
5597
0
    ptile = pdcolor->colors.pattern.p_tile;
5598
    /* Set up things in the ptile so that we get the proper
5599
       blending etc */
5600
    /* Set the blending procs and the is_additive setting based
5601
       upon the number of channels */
5602
0
    if (ptile->ttrans->n_chan-1 < 4) {
5603
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5604
0
        ptile->ttrans->is_additive = true;
5605
0
    } else {
5606
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5607
0
        ptile->ttrans->is_additive = false;
5608
0
    }
5609
    /* Set the blending mode in the ptile based upon the current
5610
       setting in the gs_gstate */
5611
0
    ptile->blending_mode = pgs->blend_mode;
5612
    /* Based upon if the tiles overlap pick the type of rect
5613
       fill that we will want to use */
5614
0
    if (ptile->has_overlap) {
5615
        /* This one does blending since there is tile overlap */
5616
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5617
0
    } else {
5618
        /* This one does no blending since there is no tile overlap */
5619
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5620
0
    }
5621
    /* Set the procs so that we use the proper filling method. */
5622
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5623
    /* Let the imaging stuff get set up */
5624
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5625
0
                            prect, pdcolor,pcpath, mem, pinfo);
5626
0
    if (code < 0)
5627
0
        return code;
5628
    /* Now Push the group */
5629
    /* First apply the inverse of the image matrix to our
5630
       image size to get our bounding box. */
5631
0
    bbox_in.p.x = 0;
5632
0
    bbox_in.p.y = 0;
5633
0
    bbox_in.q.x = pim->Width;
5634
0
    bbox_in.q.y = pim->Height;
5635
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5636
0
                                &bbox_out);
5637
0
    if (code < 0)
5638
0
        return code;
5639
    /* That in turn will get hit by the matrix in the gs_gstate */
5640
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5641
0
                                            &bbox_out, (gs_gstate *)pgs);
5642
0
    if (code < 0)
5643
0
        return code;
5644
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5645
0
        if_debug2m('v', p14dev->ctx->memory,
5646
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5647
0
                   ptile->uid.id, ptile->id);
5648
5649
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5650
0
                                             65535, pgs->blend_mode, 0, 0,
5651
0
                                             ptile->ttrans->n_chan-1, false, false,
5652
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5653
5654
        /* Set up the output buffer information now that we have
5655
           pushed the group */
5656
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5657
0
        if (fill_trans_buffer == NULL)
5658
0
            return_error(gs_error_VMerror);
5659
5660
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5661
5662
        /* Store this in the appropriate place in pdcolor.  This
5663
           is released later in pdf14_pattern_trans_render when
5664
           we are all done with the mask fill */
5665
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5666
5667
        /* Change the renderer to handle this case so we can catch the
5668
           end.  We will then pop the group and reset the pdcolor proc.
5669
           Keep the base renderer also. */
5670
0
        penum = (gx_image_enum *) *pinfo;
5671
0
        ptile->ttrans->image_render = penum->render;
5672
0
        penum->render = &pdf14_pattern_trans_render;
5673
0
        ptile->trans_group_popped = false;
5674
0
    }
5675
0
    return code;
5676
0
}
5677
5678
static  int
5679
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5680
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5681
                           const gs_int_rect * prect,
5682
                           const gx_drawing_color * pdcolor,
5683
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5684
                           gx_image_enum_common_t ** pinfo)
5685
349k
{
5686
349k
    const gs_image_t *pim = (const gs_image_t *)pic;
5687
349k
    int code;
5688
5689
349k
    code = pdf14_initialize_ctx(dev, pgs);
5690
349k
    if (code < 0)
5691
0
        return code;
5692
5693
    /* If we are filling an image mask with a pattern that has a transparency
5694
       then we need to do some special handling */
5695
349k
    if (pim->ImageMask) {
5696
96
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5697
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5698
                /* If we are in a final run through here for this case then
5699
                   go ahead and push the transparency group.   Also, update
5700
                   the proc for the pattern color so that we used the
5701
                   appropriate fill operation.  Note that the group
5702
                   is popped and the proc will be reset when we flush the
5703
                   image data.  This is handled in a special pdf14 image
5704
                   renderer which will end up installed for this case.
5705
                   Detect setting of begin_image to gx_no_begin_image.
5706
                   (final recursive call) */
5707
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5708
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5709
0
                                                prect, pdcolor, pcpath, mem,
5710
0
                                                pinfo);
5711
0
                    return code;
5712
0
                }
5713
0
            }
5714
0
        }
5715
96
    }
5716
349k
    pdf14_set_marking_params(dev, pgs);
5717
349k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5718
349k
                                        pcpath, mem, pinfo);
5719
349k
}
5720
5721
static  void
5722
pdf14_set_params(gs_gstate * pgs,
5723
                 gx_device * dev,
5724
                 const gs_pdf14trans_params_t * pparams)
5725
8.52M
{
5726
8.52M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5727
8.52M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5728
2.15M
        pgs->blend_mode = pparams->blend_mode;
5729
8.52M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5730
1.07M
        pgs->text_knockout = pparams->text_knockout;
5731
8.52M
    if (pparams->changed & PDF14_SET_AIS)
5732
271k
        pgs->alphaisshape = pparams->ais;
5733
8.52M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5734
2.56M
        pgs->overprint = pparams->overprint;
5735
8.52M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5736
2.56M
        pgs->stroke_overprint = pparams->stroke_overprint;
5737
8.52M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5738
2.65M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5739
8.52M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5740
1.80M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5741
8.52M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5742
1.91M
        gs_swapcolors_quick(pgs);
5743
1.91M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5744
689k
            pgs->is_fill_color = false;
5745
1.22M
        else
5746
1.22M
            pgs->is_fill_color = true;
5747
1.91M
    }
5748
8.52M
    pdf14_set_marking_params(dev, pgs);
5749
8.52M
}
5750
5751
/*
5752
 * This open_device method for the PDF 1.4 compositor devices is only used
5753
 * when these devices are disabled.  This routine is about as close to
5754
 * a pure "forwarding" open_device operation as is possible. Its only
5755
 * significant function is to ensure that the is_open field of the
5756
 * PDF 1.4 compositor devices matches that of the target device.
5757
 *
5758
 * We assume this procedure is called only if the device is not already
5759
 * open, and that gs_opendevice will take care of the is_open flag.
5760
 */
5761
static  int
5762
pdf14_forward_open_device(gx_device * dev)
5763
0
{
5764
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5765
0
    gx_device * tdev = pdev->target;
5766
0
    int code;
5767
5768
    /* The PDF 1.4 compositing devices must have a target */
5769
0
    if (tdev == 0)
5770
0
        return_error(gs_error_unknownerror);
5771
0
    if ((code = gs_opendevice(tdev)) >= 0)
5772
0
        gx_device_copy_params(dev, tdev);
5773
0
    return code;
5774
0
}
5775
5776
/*
5777
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5778
 * for setting any device procs that should not be forwarded.
5779
 */
5780
static  void
5781
pdf14_forward_device_procs(gx_device * dev)
5782
1.07M
{
5783
1.07M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5784
1.07M
    pdf14_device *p14dev = (pdf14_device*)dev;
5785
5786
    /* If doing simulated overprint with spot colors
5787
       then makes sure to reset devn setting */
5788
1.07M
    if (p14dev->overprint_sim &&
5789
0
        p14dev->color_info.num_components > 4)
5790
0
        p14dev->icc_struct->supports_devn =
5791
0
            p14dev->target_support_devn;
5792
5793
    /*
5794
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5795
     * This will ensure that any new device procs are also set.  However that
5796
     * routine only changes procs which are NULL.  Thus we start by setting all
5797
     * procs to NULL.
5798
     */
5799
1.07M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5800
1.07M
    gx_device_forward_fill_in_procs(pdev);
5801
    /*
5802
     * gx_device_forward_fill_in_procs does not forward all procs.
5803
     * Set the remainding procs to also forward.
5804
     */
5805
1.07M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5806
1.07M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5807
1.07M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5808
1.07M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5809
1.07M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5810
1.07M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5811
1.07M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5812
1.07M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5813
1.07M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5814
1.07M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5815
    /* These are forwarding devices with minor tweaks. */
5816
1.07M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5817
1.07M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5818
1.07M
}
5819
5820
/*
5821
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5822
 * compositor device is never removed.  (We do not have a remove compositor
5823
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5824
 * routine implements that action.
5825
 */
5826
int
5827
pdf14_disable_device(gx_device * dev)
5828
1.06M
{
5829
1.06M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5830
5831
1.06M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5832
1.06M
    dev->color_info = pdev->target->color_info;
5833
1.06M
    pdf14_forward_device_procs(dev);
5834
1.06M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5835
1.06M
    return 0;
5836
1.06M
}
5837
5838
/*
5839
 * The default color space for PDF 1.4 blend modes is based upon the process
5840
 * color model of the output device.
5841
 */
5842
static  pdf14_default_colorspace_t
5843
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5844
                                 pdf14_blend_cs_t *blend_cs_state)
5845
3.26M
{
5846
    /* If a blend color space was specified, then go ahead and use that to
5847
       define the default color space for the blend modes.  Only Gray, RGB
5848
       or CMYK blend color spaces are allowed.  Note we do not allow this
5849
       setting if we are dealing with a separation device. */
5850
3.26M
    cmm_dev_profile_t *dev_profile;
5851
3.26M
    cmm_profile_t *blend_profile = NULL;
5852
3.26M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5853
3.26M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5854
3.26M
    bool valid_blend_cs = false;
5855
3.26M
    int has_tags = device_encodes_tags(pdev);
5856
5857
3.26M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5858
5859
    /* Are we using a blend color space or the output intent color space? Also
5860
       is there a conflict in the settings. i.e. has someone set a blend color
5861
       space and tried to use the output intent with simulate overprint setting.
5862
    */
5863
3.26M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5864
0
        dev_profile->oi_profile != NULL &&
5865
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5866
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5867
           possible conflicting command line settings and we will err on using the blend profile
5868
           if one was specified. */
5869
0
        if (dev_profile->blend_profile != NULL &&
5870
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5871
0
            blend_profile = dev_profile->blend_profile;
5872
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5873
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5874
0
        } else {
5875
            /* All good, use the output intent profile as we have one
5876
               and are doing simulate overprint with a different device
5877
               profile set. */
5878
0
            blend_profile = dev_profile->oi_profile;
5879
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5880
0
        }
5881
3.26M
    } else if (dev_profile->blend_profile != NULL &&
5882
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5883
        /* Blend profile is different than device profile */
5884
0
        blend_profile = dev_profile->blend_profile;
5885
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5886
0
    }
5887
5888
    /* Make sure any blend color space is valid along with other cond */
5889
3.26M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5890
0
        if (!blend_profile->isdevlink &&
5891
0
            !blend_profile->islab &&
5892
0
            (blend_profile->data_cs == gsGRAY ||
5893
0
             blend_profile->data_cs == gsRGB ||
5894
0
             blend_profile->data_cs == gsCMYK)) {
5895
            /* Also, do not allow the use of the blend space when we are pushing
5896
               a pattern pdf14 device.  Those should inherit from the parent */
5897
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5898
0
                  gx_device_is_pattern_accum(pdev))) {
5899
0
                valid_blend_cs = true;
5900
0
            }
5901
0
        }
5902
0
    }
5903
5904
    /* If num components is one, just go ahead and use gray.  This avoids
5905
       issues with additive/subtractive mono color devices  */
5906
3.26M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5907
3.01M
        pdev->color_info.num_components == 1) {
5908
        /*
5909
        * Note:  We do not allow the SeparationOrder device parameter for
5910
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5911
        * and 3 colorants for DeviceRGB.
5912
        */
5913
3.01M
        if (valid_blend_cs) {
5914
0
            *blend_cs_state = temp_cs_state;
5915
0
            switch (blend_profile->num_comps) {
5916
0
            case 1:
5917
0
                return PDF14_DeviceGray;
5918
0
            case 3:
5919
0
                return PDF14_DeviceRGB;
5920
0
            case 4:
5921
0
                return PDF14_DeviceCMYK;
5922
0
            }
5923
0
        }
5924
3.01M
        if (pdev->color_info.num_components - has_tags == 1)
5925
1.02M
            return PDF14_DeviceGray;
5926
1.98M
        else if (pdev->color_info.num_components - has_tags == 3)
5927
1.98M
            return PDF14_DeviceRGB;
5928
0
        else
5929
0
            return PDF14_DeviceRGBspot;
5930
3.01M
    } else {
5931
        /*
5932
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5933
         * the CMYK plus spot colors will not support the blend color space
5934
         */
5935
256k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5936
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5937
        return PDF14_DeviceCustom;
5938
#endif
5939
        /*
5940
         * Count the number of CMYK process components supported by the output
5941
         * device.
5942
         */
5943
1.28M
        for (i = 0; i < 4; i++) {
5944
1.02M
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5945
5946
1.02M
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5947
1.02M
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5948
1.02M
            if (output_comp_num >= 0) {
5949
1.02M
                num_cmyk++;
5950
1.02M
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5951
1.02M
                    num_cmyk_used++;
5952
1.02M
            }
5953
1.02M
        }
5954
        /*
5955
         * Check if the device supports only CMYK.  Otherewise we assume that
5956
         * the output device supports spot colors.  Note:  This algorithm can
5957
         * be fooled if the SeparationOrder device parameter is being used by
5958
         * the output device device to only select CMYK.
5959
         */
5960
256k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5961
243k
            && pdev->color_info.max_components == 4) {
5962
48.6k
            if (valid_blend_cs) {
5963
0
                *blend_cs_state = temp_cs_state;
5964
0
                switch (blend_profile->num_comps) {
5965
0
                case 1:
5966
0
                    return PDF14_DeviceGray;
5967
0
                case 3:
5968
0
                    return PDF14_DeviceRGB;
5969
0
                case 4:
5970
0
                    return PDF14_DeviceCMYK;
5971
0
                }
5972
0
            }
5973
48.6k
            return PDF14_DeviceCMYK;
5974
48.6k
        }
5975
        /*
5976
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5977
         * This device is only needed for those devices which do not support
5978
         * a basic CMYK process color model.
5979
         */
5980
207k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5981
207k
        if (num_cmyk != 4)
5982
0
            return PDF14_DeviceCustom;
5983
207k
#endif
5984
        /*
5985
         * Otherewise we use a CMYK plus spot colors for blending.
5986
         */
5987
207k
        if (valid_blend_cs)
5988
0
            *blend_cs_state = temp_cs_state;
5989
207k
        return PDF14_DeviceCMYKspot;
5990
207k
    }
5991
3.26M
}
5992
5993
/*
5994
 * the PDF 1.4 transparency spec says that color space for blending
5995
 * operations can be based upon either a color space specified in the
5996
 * group or a default value based upon the output device.  We are
5997
 * currently only using a color space based upon the device.
5998
 */
5999
static  int
6000
get_pdf14_device_proto(gx_device       *dev,
6001
                       pdf14_device    *pdevproto,
6002
                       gs_gstate       *pgs,
6003
                 const gs_pdf14trans_t *pdf14pct,
6004
                       bool             use_pdf14_accum)
6005
1.07M
{
6006
1.07M
    pdf14_blend_cs_t blend_cs_state;
6007
1.07M
    pdf14_default_colorspace_t dev_cs =
6008
1.07M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6009
1.07M
                                                 &blend_cs_state);
6010
1.07M
    bool deep = device_is_deep(dev);
6011
1.07M
    int num_spots = pdf14pct->params.num_spot_colors;
6012
1.07M
    bool has_tags = device_encodes_tags(dev);
6013
6014
    /* overprint overide */
6015
1.07M
    if (pdf14pct->params.overprint_sim_push &&
6016
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6017
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6018
0
            dev_cs = PDF14_DeviceCMYKspot;
6019
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6020
0
        } else
6021
0
            dev_cs = PDF14_DeviceCMYK;
6022
0
    }
6023
6024
1.07M
    switch (dev_cs) {
6025
367k
        case PDF14_DeviceGray:
6026
367k
            *pdevproto = gs_pdf14_Gray_device;
6027
367k
            pdevproto->color_info.max_components = 1 + has_tags;
6028
367k
            pdevproto->color_info.num_components =
6029
367k
                                    pdevproto->color_info.max_components + has_tags;
6030
367k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6031
367k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6032
367k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6033
367k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6034
367k
            pdevproto->sep_device = false;
6035
367k
            break;
6036
628k
        case PDF14_DeviceRGB:
6037
628k
            *pdevproto = gs_pdf14_RGB_device;
6038
628k
            pdevproto->color_info.max_components += has_tags;
6039
628k
            pdevproto->color_info.num_components += has_tags;
6040
628k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6041
628k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6042
628k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6043
628k
            pdevproto->sep_device = false;
6044
628k
            break;
6045
2.59k
        case PDF14_DeviceCMYK:
6046
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6047
2.59k
            pdevproto->color_info.max_components += has_tags;
6048
2.59k
            pdevproto->color_info.num_components += has_tags;
6049
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6050
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6051
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6052
2.59k
            pdevproto->sep_device = false;
6053
2.59k
            break;
6054
76.9k
        case PDF14_DeviceCMYKspot:
6055
76.9k
            *pdevproto = gs_pdf14_CMYKspot_device;
6056
            /* Need to figure out how we want to handle the device profile
6057
               for this case */
6058
            /*
6059
             * The number of components for the PDF14 device is the sum
6060
             * of the process components and the number of spot colors
6061
             * for the page.
6062
             */
6063
76.9k
            if (num_spots >= 0) {
6064
76.9k
                pdevproto->color_info.num_components =
6065
76.9k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6066
76.9k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6067
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6068
76.9k
                pdevproto->color_info.depth =
6069
76.9k
                                    pdevproto->color_info.num_components * (8<<deep);
6070
76.9k
                pdevproto->sep_device = true;
6071
76.9k
            }
6072
0
            else
6073
0
            {
6074
0
                pdevproto->color_info.max_components += has_tags;
6075
0
                pdevproto->color_info.num_components += has_tags;
6076
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6077
0
            }
6078
76.9k
            break;
6079
0
        case PDF14_DeviceRGBspot:
6080
0
            *pdevproto = gs_pdf14_RGBspot_device;
6081
            /* Need to figure out how we want to handle the device profile
6082
               for this case */
6083
            /*
6084
             * The number of components for the PDF14 device is the sum
6085
             * of the process components and the number of spot colors
6086
             * for the page.
6087
             */
6088
0
            if (num_spots >= 0) {
6089
0
                pdevproto->color_info.num_components =
6090
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6091
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6092
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6093
0
                pdevproto->color_info.depth =
6094
0
                    pdevproto->color_info.num_components * (8 << deep);
6095
0
                pdevproto->sep_device = true;
6096
0
            }
6097
0
            else
6098
0
            {
6099
0
                pdevproto->color_info.max_components += has_tags;
6100
0
                pdevproto->color_info.num_components += has_tags;
6101
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6102
0
            }
6103
0
            break;
6104
0
        case PDF14_DeviceCustom:
6105
            /*
6106
             * We are using the output device's process color model.  The
6107
             * color_info for the PDF 1.4 compositing device needs to match
6108
             * the output device.
6109
             */
6110
0
            *pdevproto = gs_pdf14_custom_device;
6111
0
            pdevproto->color_info = dev->color_info;
6112
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6113
0
            pdevproto->color_info.depth =
6114
0
                       pdevproto->color_info.num_components * (8<<deep);
6115
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6116
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6117
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6118
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6119
0
            break;
6120
0
        default:      /* Should not occur */
6121
0
            return_error(gs_error_rangecheck);
6122
1.07M
    }
6123
1.07M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6124
1.07M
    pdevproto->blend_cs_state = blend_cs_state;
6125
1.07M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6126
1.07M
    return 0;
6127
1.07M
}
6128
6129
/* When playing back the clist, we need to know if the buffer device is compatible */
6130
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6131
/* depth are critical since these must match when reading back colors.             */
6132
bool
6133
pdf14_ok_to_optimize(gx_device *dev)
6134
2.18M
{
6135
2.18M
    pdf14_blend_cs_t blend_cs_state;
6136
2.18M
    pdf14_default_colorspace_t pdf14_cs =
6137
2.18M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6138
2.18M
    gsicc_colorbuffer_t dev_icc_cs;
6139
2.18M
    bool ok = false;
6140
2.18M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6141
2.18M
    cmm_dev_profile_t *dev_profile;
6142
2.18M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6143
2.18M
    bool deep = device_is_deep(dev);
6144
6145
2.18M
    if (code < 0)
6146
0
        return false;
6147
6148
2.18M
    check_device_compatible_encoding(dev);
6149
6150
2.18M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6151
923k
        return false;
6152
6153
1.25M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6154
    /* If the outputprofile is not "standard" then colors converted to device color */
6155
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6156
1.25M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6157
0
        return false;                           /* can't handle funky output profiles */
6158
6159
1.25M
    switch (pdf14_cs) {
6160
354k
        case PDF14_DeviceGray:
6161
354k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6162
354k
            break;
6163
775k
        case PDF14_DeviceRGB:
6164
775k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6165
775k
            break;
6166
0
        case PDF14_DeviceCMYK:
6167
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6168
0
            break;
6169
129k
        case PDF14_DeviceCMYKspot:
6170
129k
            ok = false;     /* punt for this case */
6171
129k
            break;
6172
0
        case PDF14_DeviceRGBspot:
6173
0
            ok = false;     /* punt for this case */
6174
0
            break;
6175
0
        case PDF14_DeviceCustom:
6176
            /*
6177
             * We are using the output device's process color model.  The
6178
             * color_info for the PDF 1.4 compositing device needs to match
6179
             * the output device, but it may not have been contone.
6180
             */
6181
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6182
0
            break;
6183
0
        default:      /* Should not occur */
6184
0
            ok = false;
6185
1.25M
    }
6186
1.25M
    return ok;
6187
1.25M
}
6188
6189
/*
6190
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6191
 * compositor device is never removed.  (We do not have a remove compositor
6192
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6193
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6194
 * again.
6195
 */
6196
static  int
6197
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6198
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6199
0
{
6200
0
    pdf14_device * pdev = (pdf14_device *)dev;
6201
0
    gx_device * target = pdev->target;
6202
0
    pdf14_device dev_proto;
6203
0
    bool has_tags = device_encodes_tags(dev);
6204
0
    int code;
6205
0
    bool deep = device_is_deep(dev);
6206
6207
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6208
6209
    /*
6210
     * We will not use the entire prototype device but we will set the
6211
     * color related info and the device procs to match the prototype.
6212
     */
6213
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6214
0
                                  pdf14pct, false);
6215
0
    if (code < 0)
6216
0
        return code;
6217
0
    pdev->color_info = dev_proto.color_info;
6218
0
    pdev->pad = target->pad;
6219
0
    pdev->log2_align_mod = target->log2_align_mod;
6220
6221
    /* The prototype has the color setup without tags. If we are
6222
     * using tags, then we need to extend num_components and depth.
6223
     */
6224
0
    if (has_tags) {
6225
0
        pdev->color_info.num_components++;
6226
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6227
0
    }
6228
6229
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6230
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6231
0
    else
6232
0
        pdev->num_planar_planes = target->num_planar_planes;
6233
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6234
6235
0
    if (dev_proto.initialize_device_procs != NULL)
6236
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6237
0
    pdev->procs = dev_proto.procs;
6238
0
    if (deep) {
6239
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6240
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6241
0
    }
6242
0
    if (has_tags) {
6243
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6244
0
    }
6245
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6246
0
    gx_device_fill_in_procs((gx_device *)pdev);
6247
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6248
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6249
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6250
0
    check_device_separable(dev);
6251
0
    return dev_proc(pdev, open_device)(dev);
6252
0
}
6253
6254
/*
6255
 * Implement the various operations that can be specified via the PDF 1.4
6256
 * create compositor request.
6257
 */
6258
static  int
6259
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6260
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6261
20.9M
{
6262
20.9M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6263
20.9M
    gs_pdf14trans_params_t params = pdf14pct->params;
6264
20.9M
    int code = 0;
6265
6266
20.9M
    params.idle = pdf14pct->idle;
6267
20.9M
    switch (params.pdf14_op) {
6268
0
        default:      /* Should not occur. */
6269
0
            break;
6270
14.3k
        case PDF14_PUSH_DEVICE:
6271
14.3k
            if (!(params.is_pattern)) {
6272
0
                p14dev->blend_mode = 0;
6273
0
                p14dev->opacity = p14dev->shape = 0.0;
6274
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6275
0
            }
6276
14.3k
            break;
6277
0
        case PDF14_ABORT_DEVICE:
6278
            /* Something has gone very wrong.  Let transparency device clean up
6279
               what ever it has allocated and then we are shutting it down */
6280
0
            code = gx_abort_trans_device(pgs, pdev);
6281
0
            if (p14dev->free_devicen) {
6282
0
                devn_free_params(pdev);
6283
0
            }
6284
0
            pdf14_disable_device(pdev);
6285
0
            pdf14_close(pdev);
6286
0
            break;
6287
1.07M
        case PDF14_POP_DEVICE:
6288
1.07M
            if (!(params.is_pattern)) {
6289
1.06M
                if_debug0m('v', pdev->memory,
6290
1.06M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6291
1.06M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6292
1.06M
                gx_set_cmap_procs(pgs, p14dev->target);
6293
                /* Send image out raster data to output device */
6294
1.06M
                {
6295
                    /* Make a copy so we can change the ROP */
6296
1.06M
                    gs_gstate new_pgs = *pgs;
6297
6298
                    /* We don't use the gs_gstate log_op since this is for the */
6299
                    /* clist playback. Putting the image (band in the case of the */
6300
                    /* clist) only needs to use the default ROP to copy the data  */
6301
1.06M
                    new_pgs.log_op = rop3_default;
6302
1.06M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6303
1.06M
                }
6304
                /* Before we disable the device release any deviceN structures.
6305
                    free_devicen is set if the pdf14 device had inherited its
6306
                    deviceN parameters from the target clist device.  In this
6307
                    case they should not be freed */
6308
1.06M
                if (p14dev->free_devicen) {
6309
1.06M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6310
1.06M
                    if (devn_params) {
6311
1.06M
                        gxdso_spot_info si;
6312
1.06M
                        si.params = devn_params;
6313
1.06M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6314
1.06M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6315
1.06M
                    }
6316
1.06M
                    devn_free_params(pdev);
6317
1.06M
                }
6318
1.06M
                pdf14_disable_device(pdev);
6319
1.06M
                pdf14_close(pdev);
6320
1.06M
            }
6321
1.07M
            break;
6322
418k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6323
2.08M
        case PDF14_BEGIN_TRANS_GROUP:
6324
2.08M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6325
304k
                p14dev->depth_within_smask++;
6326
2.08M
            p14dev->smask_constructed = 0;
6327
2.08M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6328
2.08M
            break;
6329
1.62M
        case PDF14_END_TRANS_GROUP:
6330
1.62M
            code = gx_end_transparency_group(pgs, pdev);
6331
1.62M
            if (p14dev->depth_within_smask)
6332
304k
                p14dev->depth_within_smask--;
6333
1.62M
            break;
6334
150
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6335
150
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6336
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6337
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6338
0
            } else
6339
150
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6340
150
            break;
6341
460k
        case PDF14_END_TRANS_TEXT_GROUP:
6342
460k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6343
460k
                code = gx_end_transparency_group(pgs, pdev);
6344
460k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6345
460k
            break;
6346
4.04M
        case PDF14_BEGIN_TRANS_MASK:
6347
4.04M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6348
4.04M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6349
404k
                p14dev->in_smask_construction++;
6350
4.04M
            break;
6351
404k
        case PDF14_END_TRANS_MASK:
6352
404k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6353
404k
            if (code >= 0) {
6354
404k
                p14dev->in_smask_construction--;
6355
404k
                if (p14dev->in_smask_construction < 0)
6356
0
                    p14dev->in_smask_construction = 0;
6357
404k
                if (p14dev->in_smask_construction == 0)
6358
403k
                    p14dev->smask_constructed = 1;
6359
404k
            }
6360
404k
            break;
6361
8.52M
        case PDF14_SET_BLEND_PARAMS:
6362
8.52M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6363
8.52M
            break;
6364
0
        case PDF14_PUSH_TRANS_STATE:
6365
0
            code = gx_push_transparency_state(pgs, pdev);
6366
0
            break;
6367
2.72M
        case PDF14_POP_TRANS_STATE:
6368
2.72M
            code = gx_pop_transparency_state(pgs, pdev);
6369
2.72M
            break;
6370
4.37k
        case PDF14_PUSH_SMASK_COLOR:
6371
4.37k
            code = pdf14_increment_smask_color(pgs, pdev);
6372
4.37k
            break;
6373
4.37k
        case PDF14_POP_SMASK_COLOR:
6374
4.37k
            code = pdf14_decrement_smask_color(pgs, pdev);
6375
4.37k
            break;
6376
20.9M
    }
6377
20.9M
    return code;
6378
20.9M
}
6379
6380
/*
6381
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6382
 * compositor' method.  However the compositor is disabled when we are not
6383
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6384
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6385
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6386
 * to the target.
6387
 */
6388
static  int
6389
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6390
        const gs_composite_t * pct, gs_gstate * pgs,
6391
        gs_memory_t * mem, gx_device *cdev)
6392
1.38k
{
6393
1.38k
    pdf14_device *pdev = (pdf14_device *)dev;
6394
1.38k
    gx_device * tdev = pdev->target;
6395
1.38k
    int code;
6396
6397
1.38k
    *pcdev = dev;
6398
1.38k
    if (gs_is_pdf14trans_compositor(pct)) {
6399
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6400
6401
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6402
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6403
0
        return 0;
6404
0
    }
6405
1.38k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6406
1.38k
    if (code == 1) {
6407
        /* We have created a new compositor that wrapped tdev. This means
6408
         * that our target should be updated to point to that. */
6409
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6410
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6411
0
    }
6412
1.38k
    return code;
6413
1.38k
}
6414
6415
/*
6416
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6417
 * and return. Since the gs_pdf14_device only supports the high-level routines
6418
 * of the interface, don't bother trying to handle any other compositor.
6419
 */
6420
static int
6421
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6422
        const gs_composite_t * pct, gs_gstate * pgs,
6423
        gs_memory_t * mem, gx_device *cdev)
6424
117M
{
6425
117M
    pdf14_device *p14dev = (pdf14_device *)dev;
6426
117M
    if (gs_is_pdf14trans_compositor(pct)) {
6427
20.9M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6428
20.9M
        *pcdev = dev;
6429
        /* cdev, may be the clist reader device which may contain information that
6430
           we will need related to the ICC color spaces that define transparency
6431
           groups.  We want this propogated through all the pdf14 functions.  Store
6432
           a pointer to it in the pdf14 device */
6433
20.9M
        p14dev->pclist_device = cdev;
6434
20.9M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6435
96.3M
    } else if (gs_is_overprint_compositor(pct)) {
6436
                /* If we had an overprint compositer action, then the
6437
                   color components that were drawn should be updated.
6438
                   The overprint compositor logic and its interactions
6439
                   with the clist is a little odd as it passes uninitialized
6440
                   values around a fair amount.  Hence the forced assignement here.
6441
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6442
96.3M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6443
96.3M
                gx_color_index drawn_comps;
6444
96.3M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6445
6446
96.3M
                p14dev->op_state = op_pct->params.op_state;
6447
96.3M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6448
48.2M
                    if (op_pct->params.retain_any_comps) {
6449
22.6k
                        drawn_comps = op_pct->params.drawn_comps;
6450
48.2M
                    } else {
6451
                        /* Draw everything. If this parameter was not set, clist does
6452
                           not fill it in.  */
6453
48.2M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6454
48.2M
                    }
6455
6456
48.2M
                    if (op_pct->params.is_fill_color) {
6457
26.5M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6458
26.5M
                        p14dev->drawn_comps_fill = drawn_comps;
6459
26.5M
                    } else {
6460
21.6M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6461
21.6M
                        p14dev->drawn_comps_stroke = drawn_comps;
6462
21.6M
                    }
6463
                    /* We restore the NONE states as that is used just to force
6464
                       overprint settings in the overprint compositor communication */
6465
48.2M
                    p14dev->op_state = curr_state;
6466
48.2M
                }
6467
96.3M
                *pcdev = dev;
6468
96.3M
                return 0;
6469
96.3M
    } else
6470
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6471
117M
}
6472
6473
static int
6474
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6475
                      gs_blend_mode_t blend_mode, float opacity,
6476
                      float shape, bool is_clist)
6477
2.71k
{
6478
2.71k
    int code;
6479
2.71k
    gs_transparency_group_params_t params = { 0 };
6480
2.71k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6481
2.71k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6482
2.71k
    float alpha = pgs->fillconstantalpha;
6483
6484
    /* Push a non-isolated knock-out group making sure the opacity and blend
6485
       mode are correct */
6486
2.71k
    params.Isolated = false;
6487
2.71k
    params.Knockout = true;
6488
2.71k
    params.page_group = false;
6489
2.71k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6490
2.71k
    params.group_opacity = 1.0;
6491
2.71k
    params.group_shape = 1.0;
6492
6493
2.71k
    gs_setfillconstantalpha(pgs, 1.0);
6494
2.71k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6495
6496
2.71k
    if (is_clist) {
6497
2.71k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6498
2.71k
        if (code < 0)
6499
0
            return code;
6500
2.71k
    }
6501
6502
2.71k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6503
2.71k
    gs_setfillconstantalpha(pgs, alpha);
6504
2.71k
    gs_setblendmode(pgs, blend_mode);
6505
2.71k
    if (code < 0)
6506
0
        return code;
6507
6508
2.71k
    if (is_clist) {
6509
2.71k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6510
2.71k
    }
6511
2.71k
    return code;
6512
2.71k
}
6513
6514
static  int
6515
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6516
                 const gs_text_params_t * text, gs_font * font,
6517
                 const gx_clip_path * pcpath,
6518
                 gs_text_enum_t ** ppenum)
6519
326
{
6520
326
    int code;
6521
326
    gs_text_enum_t *penum;
6522
326
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6523
326
    float opacity = pgs->fillconstantalpha;
6524
326
    float shape = 1.0;
6525
326
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6526
326
    pdf14_device *pdev = (pdf14_device*)dev;
6527
326
    bool draw = !(text->operation & TEXT_DO_NONE);
6528
326
    uint text_mode = gs_currenttextrenderingmode(pgs);
6529
326
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6530
326
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6531
6532
326
    code = pdf14_initialize_ctx(dev, pgs);
6533
326
    if (code < 0)
6534
0
        return code;
6535
6536
326
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6537
326
    pdf14_set_marking_params(dev, pgs);
6538
326
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6539
326
    if (code < 0)
6540
0
        return code;
6541
6542
    /* We may need to push a non-isolated transparency group if the following
6543
       is true.
6544
       1) We are not currently in one that we pushed for text and we are in
6545
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6546
       2) The blend mode is not Normal or the opacity is not 1.0
6547
       3) Text knockout is set to true
6548
       4) We are actually doing a text drawing
6549
6550
       Special note:  If text-knockout is set to false while we are within a
6551
       BT ET pair, we should pop the group.  I need to create a test file for
6552
       this case.  */
6553
6554
       /* Catch case where we already pushed a group and are trying to push another one.
6555
       In that case, we will pop the current one first, as we don't want to be left
6556
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6557
       will not be caught until we do the put_image and notice that the stack is not
6558
       empty. */
6559
326
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6560
0
        code = gs_end_transparency_group(pgs);
6561
0
        if (code < 0)
6562
0
            return code;
6563
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6564
0
    }
6565
6566
326
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6567
325
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6568
325
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6569
1
         text_mode != 3 && /* don't bother with invisible text */
6570
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6571
1
        if (draw) {
6572
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6573
1
                false);
6574
1
        }
6575
326
    *ppenum = (gs_text_enum_t *)penum;
6576
326
    return code;
6577
326
}
6578
6579
static  int
6580
pdf14_initialize_device(gx_device *new_dev)
6581
1.07M
{
6582
1.07M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6583
6584
1.07M
    pdev->ctx = NULL;
6585
1.07M
    pdev->color_model_stack = NULL;
6586
1.07M
    pdev->smaskcolor = NULL;
6587
6588
1.07M
    return 0;
6589
1.07M
}
6590
6591
/*
6592
 * Implement copy_mono by filling lots of small rectangles.
6593
 */
6594
static int
6595
pdf14_copy_mono(gx_device * dev,
6596
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6597
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6598
12.2M
{
6599
12.2M
    const byte *sptr;
6600
12.2M
    const byte *line;
6601
12.2M
    int sbit, first_bit;
6602
12.2M
    int code, sbyte, bit, count;
6603
12.2M
    int run_length, startx, current_bit, bit_value;
6604
12.2M
    gx_color_index current_color;
6605
6606
12.2M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6607
12.2M
    line = base + (sourcex >> 3);
6608
12.2M
    sbit = sourcex & 7;
6609
12.2M
    first_bit = 7 - sbit;
6610
6611
    /* Loop through the height of the specified area. */
6612
92.6M
    while (h-- > 0) {
6613
        /* Set up for the start of each line of the area. */
6614
80.3M
        sptr = line;
6615
80.3M
        sbyte = *sptr++;
6616
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6617
         * the loop below so adding 1 means that we don't fall into the bit == 0
6618
         * case and incorrectly read a new byte from the source. This weirdness is because
6619
         * the original code wouold read off the end of the buffer if the number of bits in
6620
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6621
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6622
         * of the loop to the beginning meant we would not read past the end of the buffer
6623
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6624
         * reading another byte.
6625
         */
6626
80.3M
        bit = first_bit + 1;
6627
80.3M
        count = w;
6628
80.3M
        run_length = 0;
6629
80.3M
        startx = x;
6630
80.3M
        current_bit = 0;
6631
80.3M
        current_color = zero;
6632
6633
        /* Loop across each pixel of a line. */
6634
1.15G
        do {
6635
            /* Move to the next input bit. */
6636
1.15G
            if (bit == 0) {
6637
99.3M
                bit = 7;
6638
99.3M
                sbyte = *sptr++;
6639
99.3M
            }
6640
1.05G
            else
6641
1.05G
                bit--;
6642
1.15G
            bit_value = (sbyte >> bit) & 1;
6643
1.15G
            if (bit_value == current_bit) {
6644
                /* The value did not change, simply increment our run length */
6645
949M
                run_length++;
6646
949M
            } else {
6647
                /* The value changed, fill the current rectangle. */
6648
200M
                if (run_length != 0) {
6649
191M
                    if (current_color != gx_no_color_index) {
6650
82.4M
                        code = (*dev_proc(dev, fill_rectangle))
6651
82.4M
                                (dev, startx, y, run_length, 1, current_color);
6652
82.4M
                        if (code < 0)
6653
0
                            return code;
6654
82.4M
                    }
6655
191M
                    startx += run_length;
6656
191M
                }
6657
200M
                run_length = 1;
6658
200M
                current_color = bit_value ? one : zero;
6659
200M
                current_bit = bit_value;
6660
200M
            }
6661
1.15G
        } while (--count > 0);
6662
        /* Fill the last rectangle in the line. */
6663
80.3M
        if (run_length != 0 && current_color != gx_no_color_index) {
6664
35.6M
            code = (*dev_proc(dev, fill_rectangle))
6665
35.6M
                        (dev, startx, y, run_length, 1, current_color);
6666
35.6M
            if (code < 0)
6667
0
                return code;
6668
35.6M
        }
6669
        /* Move to the next line */
6670
80.3M
        line += sraster;
6671
80.3M
        y++;
6672
80.3M
    }
6673
12.2M
    return 0;
6674
12.2M
}
6675
6676
/* Added to avoid having to go back and forth between fixed and int
6677
   in some of the internal methods used for dealing with tiling
6678
   and devn colors */
6679
static int
6680
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6681
    const gx_drawing_color *pdcolor)
6682
2.44k
{
6683
2.44k
    pdf14_device *pdev = (pdf14_device *)dev;
6684
2.44k
    pdf14_buf *buf;
6685
2.44k
    int code;
6686
6687
2.44k
    fit_fill_xywh(dev, x, y, w, h);
6688
2.44k
    if (w <= 0 || h <= 0)
6689
0
        return 0;
6690
6691
2.44k
    code = pdf14_initialize_ctx(dev, NULL);
6692
2.44k
    if (code < 0)
6693
0
        return code;
6694
2.44k
    buf = pdev->ctx->stack;
6695
6696
2.44k
    if (buf->knockout)
6697
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6698
0
            true);
6699
2.44k
    else
6700
2.44k
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6701
2.44k
}
6702
6703
/* Step through and do rect fills with the devn colors as
6704
   we hit each transition in the bitmap. It is possible
6705
   that one of the colors is not devn, but is pure and
6706
   is set to gx_no_color_index. This type of mix happens
6707
   for example from tile_clip_fill_rectangle_hl_color */
6708
static int
6709
pdf14_copy_mono_devn(gx_device *dev,
6710
    const byte *base, int sourcex, int sraster,
6711
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6712
    const gx_drawing_color *pdcolor1)
6713
668
{
6714
668
    const byte *sptr;
6715
668
    const byte *line;
6716
668
    int sbit, first_bit;
6717
668
    int code, sbyte, bit, count;
6718
668
    int run_length, startx, current_bit, bit_value;
6719
668
    const gx_drawing_color *current_color;
6720
6721
668
    if ((x | y) < 0) {
6722
0
        if (x < 0) {
6723
0
            w += x;
6724
0
            sourcex -= x;
6725
0
            x = 0;
6726
0
        }
6727
0
        if (y < 0) {
6728
0
            h += y;
6729
0
            base -= (int)(y * sraster);
6730
0
            y = 0;
6731
0
        }
6732
0
    }
6733
668
    if (w > (dev)->width - x)
6734
0
        w = (dev)->width - x;
6735
668
    if (h > (dev)->height - y)
6736
0
        h = (dev)->height - y;
6737
668
    if (w <= 0 || h <= 0)
6738
0
        return 0;
6739
6740
668
    line = base + (sourcex >> 3);
6741
668
    sbit = sourcex & 7;
6742
668
    first_bit = 7 - sbit;
6743
6744
    /* Loop through the height of the specified area. */
6745
2.10k
    while (h-- > 0) {
6746
        /* Set up for the start of each line of the area. */
6747
1.43k
        sptr = line;
6748
1.43k
        sbyte = *sptr++;
6749
1.43k
        bit = first_bit;
6750
1.43k
        count = w;
6751
1.43k
        run_length = 0;
6752
1.43k
        startx = x;
6753
1.43k
        current_bit = 0;
6754
1.43k
        current_color = pdcolor0;
6755
6756
        /* Loop across each pixel of a line. */
6757
15.6k
        do {
6758
15.6k
            bit_value = (sbyte >> bit) & 1;
6759
15.6k
            if (bit_value == current_bit) {
6760
                /* The value did not change, simply increment our run length */
6761
11.3k
                run_length++;
6762
11.3k
            } else {
6763
                /* The value changed, fill the current rectangle. */
6764
4.26k
                if (run_length != 0) {
6765
3.85k
                    if (current_color->type != gx_dc_type_pure &&
6766
1.82k
                        current_color->colors.pure != gx_no_color_index) {
6767
1.82k
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6768
1.82k
                            run_length, 1, current_color);
6769
1.82k
                        if (code < 0)
6770
0
                            return code;
6771
1.82k
                    }
6772
3.85k
                    startx += run_length;
6773
3.85k
                }
6774
4.26k
                run_length = 1;
6775
4.26k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6776
4.26k
                current_bit = bit_value;
6777
4.26k
            }
6778
6779
            /* Move to the next input bit. */
6780
15.6k
            if (bit == 0) {
6781
1.40k
                bit = 7;
6782
1.40k
                sbyte = *sptr++;
6783
1.40k
            } else
6784
14.2k
                bit--;
6785
15.6k
        } while (--count > 0);
6786
6787
        /* Fill the last rectangle in the line. */
6788
1.43k
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6789
619
            current_color->colors.pure != gx_no_color_index) {
6790
619
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6791
619
                run_length, 1, current_color);
6792
619
            if (code < 0)
6793
0
                return code;
6794
619
        }
6795
        /* Move to the next line */
6796
1.43k
        line += sraster;
6797
1.43k
        y++;
6798
1.43k
    }
6799
668
    return 0;
6800
668
}
6801
6802
/* Step through the tiles doing essentially copy_mono but with devn colors */
6803
static int
6804
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6805
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6806
    const gx_drawing_color *pdcolor1, int px, int py)
6807
668
{   /* Fill the rectangle in chunks. */
6808
668
    int width = tiles->size.x;
6809
668
    int height = tiles->size.y;
6810
668
    int raster = tiles->raster;
6811
668
    int rwidth = tiles->rep_width;
6812
668
    int rheight = tiles->rep_height;
6813
668
    int shift = tiles->shift;
6814
6815
668
    if (rwidth == 0 || rheight == 0)
6816
0
        return_error(gs_error_unregistered);
6817
668
    fit_fill_xy(dev, x, y, w, h);
6818
6819
668
     {
6820
668
        int xoff = (shift == 0 ? px :
6821
668
                px + (y + py) / rheight * tiles->rep_shift);
6822
668
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6823
0
            (x + xoff) & (rwidth - 1) :
6824
668
            (x + xoff) % rwidth);
6825
668
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6826
0
            (y + py) & (rheight - 1) :
6827
668
            (y + py) % rheight);
6828
668
        int icw = width - irx;
6829
668
        int ch = height - ry;
6830
668
        byte *row = tiles->data + ry * raster;
6831
668
        int code = 0;
6832
6833
668
        if (ch >= h) {      /* Shallow operation */
6834
668
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6835
668
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6836
668
                    w, h, pdcolor0, pdcolor1);
6837
668
                if (code < 0)
6838
0
                    return_error(code);
6839
668
            } else {
6840
0
                int ex = x + w;
6841
0
                int fex = ex - width;
6842
0
                int cx = x + icw;
6843
6844
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6845
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6846
0
                if (code < 0)
6847
0
                    return_error(code);
6848
6849
0
                while (cx <= fex) {
6850
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6851
0
                        width, h, pdcolor0, pdcolor1);
6852
0
                    if (code < 0)
6853
0
                        return_error(code);
6854
0
                    cx += width;
6855
0
                }
6856
0
                if (cx < ex) {
6857
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6858
0
                        ex - cx, h, pdcolor0, pdcolor1);
6859
0
                    if (code < 0)
6860
0
                        return_error(code);
6861
0
                }
6862
0
            }
6863
668
        } else if (icw >= w && shift == 0) {
6864
            /* Narrow operation, no shift */
6865
0
            int ey = y + h;
6866
0
            int fey = ey - height;
6867
0
            int cy = y + ch;
6868
6869
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6870
0
                x, y, w, ch, pdcolor0, pdcolor1);
6871
0
            if (code < 0)
6872
0
                return_error(code);
6873
0
            row = tiles->data;
6874
0
            do {
6875
0
                ch = (cy > fey ? ey - cy : height);
6876
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6877
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6878
0
                if (code < 0)
6879
0
                    return_error(code);
6880
0
            } while ((cy += ch) < ey);
6881
0
        } else {
6882
            /* Full operation.  If shift != 0, some scan lines */
6883
            /* may be narrow.  We could test shift == 0 in advance */
6884
            /* and use a slightly faster loop, but right now */
6885
            /* we don't bother. */
6886
0
            int ex = x + w, ey = y + h;
6887
0
            int fex = ex - width, fey = ey - height;
6888
0
            int cx, cy;
6889
6890
0
            for (cy = y;;) {
6891
0
                if (icw >= w) {
6892
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6893
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6894
0
                    if (code < 0)
6895
0
                        return_error(code);
6896
0
                } else {
6897
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6898
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6899
0
                    if (code < 0)
6900
0
                        return_error(code);
6901
0
                    cx = x + icw;
6902
0
                    while (cx <= fex) {
6903
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6904
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6905
0
                        if (code < 0)
6906
0
                            return_error(code);
6907
0
                        cx += width;
6908
0
                    }
6909
0
                    if (cx < ex) {
6910
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6911
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6912
0
                        if (code < 0)
6913
0
                            return_error(code);
6914
0
                    }
6915
0
                }
6916
0
                if ((cy += ch) >= ey)
6917
0
                    break;
6918
0
                ch = (cy > fey ? ey - cy : height);
6919
0
                if ((irx += shift) >= rwidth)
6920
0
                    irx -= rwidth;
6921
0
                icw = width - irx;
6922
0
                row = tiles->data;
6923
0
            }
6924
0
        }
6925
668
    }
6926
668
    return 0;
6927
668
}
6928
6929
/* pdf14 device supports devn */
6930
static int
6931
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6932
    int x, int y, int w, int h,
6933
    const gx_drawing_color *pdcolor0,
6934
    const gx_drawing_color *pdcolor1, int px, int py)
6935
668
{
6936
668
    pdf14_device *pdev = (pdf14_device *)dev;
6937
668
    pdf14_buf *buf;
6938
668
    int num_comp;
6939
668
    int k;
6940
668
    bool same = false;
6941
668
    int code;
6942
6943
668
    code = pdf14_initialize_ctx(dev, NULL);
6944
668
    if (code < 0)
6945
0
        return code;
6946
668
    buf = pdev->ctx->stack;
6947
668
    num_comp = buf->n_chan - 1;
6948
6949
    /* if color0 is identical to color1, do rect fill */
6950
668
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6951
0
        same = true;
6952
0
        for (k = 0; k < num_comp; k++) {
6953
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6954
0
                same = false;
6955
0
                break;
6956
0
            }
6957
0
        }
6958
0
    }
6959
6960
668
    if (same) {
6961
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6962
668
    } else {
6963
        /* Go through the tile stepping using code stolen from
6964
           gx_default_strip_tile_rectangle and call the rect fills
6965
           using code stolen from pdf14_copy_mono but using devn
6966
           colors */
6967
668
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6968
668
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6969
668
    }
6970
668
    return code;
6971
668
}
6972
6973
/* Used in a few odd cases where the target device is planar and we have
6974
   a planar tile (pattern) and we are copying it into place here */
6975
static int
6976
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6977
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6978
4.05k
{
6979
4.05k
    pdf14_device *pdev = (pdf14_device *)dev;
6980
4.05k
    pdf14_ctx *ctx;
6981
4.05k
    pdf14_buf *buf;
6982
4.05k
    int xo = x;
6983
4.05k
    int yo = y;
6984
4.05k
    pdf14_buf fake_tos;
6985
4.05k
    int deep;
6986
6987
4.05k
    int code = pdf14_initialize_ctx(dev, NULL);
6988
4.05k
    if (code < 0)
6989
0
        return code;
6990
6991
4.05k
    fit_fill_xywh(dev, x, y, w, h);
6992
4.05k
    if (w <= 0 || h <= 0)
6993
0
        return 0;
6994
6995
4.05k
    ctx = pdev->ctx;
6996
4.05k
    buf = ctx->stack;
6997
4.05k
    deep = ctx->deep;
6998
6999
4.05k
    fake_tos.deep = deep;
7000
4.05k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7001
4.05k
    fake_tos.backdrop = NULL;
7002
4.05k
    fake_tos.blend_mode = pdev->blend_mode;
7003
4.05k
    fake_tos.color_space = buf->color_space;
7004
4.05k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7005
4.05k
    fake_tos.dirty.p.x = x;
7006
4.05k
    fake_tos.dirty.p.y = y;
7007
4.05k
    fake_tos.dirty.q.x = x + w;
7008
4.05k
    fake_tos.dirty.q.y = y + h;
7009
4.05k
    fake_tos.has_alpha_g = 0;
7010
4.05k
    fake_tos.has_shape = 0;
7011
4.05k
    fake_tos.has_tags = 0;
7012
4.05k
    fake_tos.idle = false;
7013
4.05k
    fake_tos.isolated = false;
7014
4.05k
    fake_tos.knockout = false;
7015
4.05k
    fake_tos.mask_id = 0;
7016
4.05k
    fake_tos.mask_stack = NULL;
7017
4.05k
    fake_tos.matte = NULL;
7018
4.05k
    fake_tos.matte_num_comps = 0;
7019
4.05k
    fake_tos.memory = dev->memory;
7020
4.05k
    fake_tos.n_chan = dev->color_info.num_components;
7021
4.05k
    fake_tos.n_planes = dev->color_info.num_components;
7022
4.05k
    fake_tos.num_spots = 0;
7023
4.05k
    fake_tos.group_color_info = NULL;
7024
4.05k
    fake_tos.planestride = raster * (size_t)plane_height;
7025
4.05k
    fake_tos.rect.p.x = x;
7026
4.05k
    fake_tos.rect.p.y = y;
7027
4.05k
    fake_tos.rect.q.x = x + w;
7028
4.05k
    fake_tos.rect.q.y = y + h;
7029
4.05k
    fake_tos.rowstride = raster;
7030
4.05k
    fake_tos.saved = NULL;
7031
4.05k
    fake_tos.shape = 0xffff;
7032
4.05k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7033
4.05k
    fake_tos.transfer_fn = NULL;
7034
4.05k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7035
4.05k
                                  pdev->ctx->memory, dev);
7036
4.05k
    return 0;
7037
4.05k
}
7038
7039
static int
7040
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7041
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7042
    const gx_clip_path *pcpath)
7043
7.49M
{
7044
7.49M
    pdf14_device *pdev = (pdf14_device *)dev;
7045
7.49M
    pdf14_buf* buf;
7046
7.49M
    int code;
7047
7.49M
    int x = fixed2int(rect->p.x);
7048
7.49M
    int y = fixed2int(rect->p.y);
7049
7.49M
    int w = fixed2int(rect->q.x) - x;
7050
7.49M
    int h = fixed2int(rect->q.y) - y;
7051
7052
7.49M
    fit_fill_xywh(dev, x, y, w, h);
7053
7.49M
    if (w <= 0 || h <= 0)
7054
262k
        return 0;
7055
7056
7.22M
    code = pdf14_initialize_ctx(dev, pgs);
7057
7.22M
    if (code < 0)
7058
0
        return code;
7059
7.22M
    buf = pdev->ctx->stack;
7060
7061
7.22M
    if (buf->knockout)
7062
109k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7063
109k
                                                   true);
7064
7.11M
    else
7065
7.11M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7066
7.22M
}
7067
7068
static  int
7069
pdf14_fill_rectangle(gx_device * dev,
7070
                    int x, int y, int w, int h, gx_color_index color)
7071
332M
{
7072
332M
    pdf14_device *pdev = (pdf14_device *)dev;
7073
332M
    pdf14_buf *buf;
7074
332M
    int code;
7075
7076
332M
    fit_fill_xywh(dev, x, y, w, h);
7077
332M
    if (w <= 0 || h <= 0)
7078
7.51M
        return 0;
7079
7080
325M
    code = pdf14_initialize_ctx(dev, NULL);
7081
325M
    if (code < 0)
7082
0
        return code;
7083
7084
325M
    buf = pdev->ctx->stack;
7085
7086
325M
    if (buf->knockout)
7087
1.68M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7088
1.68M
                                                   false);
7089
323M
    else
7090
323M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7091
325M
}
7092
7093
static int
7094
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7095
                                    const gs_rect *pbbox, gs_int_rect *rect)
7096
2.10M
{
7097
2.10M
    gs_rect dev_bbox;
7098
2.10M
    int code;
7099
7100
2.10M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7101
2.10M
    if (code < 0)
7102
0
        return code;
7103
2.10M
    rect->p.x = (int)floor(dev_bbox.p.x);
7104
2.10M
    rect->p.y = (int)floor(dev_bbox.p.y);
7105
2.10M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7106
2.10M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7107
    /* Sanity check rect for insane ctms */
7108
2.10M
    if (rect->p.x < 0)
7109
85.1k
        rect->p.x = 0;
7110
2.10M
    if (rect->q.x < rect->p.x)
7111
2.07k
        rect->q.x = rect->p.x;
7112
2.10M
    if (rect->p.y < 0)
7113
1.92M
        rect->p.y = 0;
7114
2.10M
    if (rect->q.y < rect->p.y)
7115
49.1k
        rect->q.y = rect->p.y;
7116
2.10M
    return 0;
7117
2.10M
}
7118
7119
static  int
7120
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7121
                              const gs_rect *pbbox, gs_gstate *pgs)
7122
2.02M
{
7123
2.02M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7124
7125
2.02M
    if (code < 0)
7126
0
        return code;
7127
2.02M
    rect_intersect(*rect, pdev->ctx->rect);
7128
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7129
2.02M
    if (rect->q.x < rect->p.x)
7130
14.3k
        rect->q.x = rect->p.x;
7131
2.02M
    if (rect->q.y < rect->p.y)
7132
30.7k
        rect->q.y = rect->p.y;
7133
2.02M
    return 0;
7134
2.02M
}
7135
7136
static  int
7137
pdf14_begin_transparency_group(gx_device* dev,
7138
    const gs_transparency_group_params_t* ptgp,
7139
    const gs_rect* pbbox,
7140
    gs_gstate* pgs, gs_memory_t* mem)
7141
2.08M
{
7142
2.08M
    pdf14_device* pdev = (pdf14_device*)dev;
7143
2.08M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7144
2.08M
    gs_int_rect rect;
7145
2.08M
    int code;
7146
2.08M
    bool isolated = ptgp->Isolated;
7147
2.08M
    gs_transparency_color_t group_color_type;
7148
2.08M
    cmm_profile_t* group_profile;
7149
2.08M
    cmm_profile_t* tos_profile;
7150
2.08M
    gsicc_rendering_param_t render_cond;
7151
2.08M
    cmm_dev_profile_t* dev_profile;
7152
2.08M
    bool cm_back_drop = false;
7153
2.08M
    bool new_icc = false;
7154
2.08M
    pdf14_group_color_t* group_color_info;
7155
2.08M
    bool has_tags = device_encodes_tags(dev);
7156
7157
2.08M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7158
2.08M
    if (code < 0)
7159
0
        return code;
7160
2.08M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7161
7162
2.08M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7163
461k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7164
461k
    }
7165
7166
2.08M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7167
461k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7168
1.62M
    else
7169
1.62M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7170
7171
2.08M
    if (code < 0)
7172
0
        return code;
7173
2.08M
    if_debug5m('v', pdev->memory,
7174
2.08M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7175
2.08M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7176
7177
    /* If the group color is unknown then use the current device profile. */
7178
2.08M
    if (ptgp->group_color_type == UNKNOWN) {
7179
1.65M
        group_color_type = ICC;
7180
1.65M
        group_profile = tos_profile;
7181
1.65M
    }
7182
427k
    else {
7183
427k
        group_color_type = ptgp->group_color_type;
7184
427k
        group_profile = ptgp->iccprofile;
7185
427k
    }
7186
7187
    /* We have to handle case where the profile is in the clist */
7188
2.08M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7189
        /* Get the serialized data from the clist. */
7190
427k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7191
427k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7192
427k
        if (group_profile == NULL)
7193
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7194
        /* Keep a pointer to the clist device */
7195
427k
        group_profile->dev = (gx_device*)pcrdev;
7196
427k
        new_icc = true;
7197
427k
    }
7198
2.08M
    if (group_profile != NULL) {
7199
        /* If we have a non-isolated group and the color space is different,
7200
            we will need to CM the backdrop. */
7201
2.08M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7202
179k
            cm_back_drop = true;
7203
179k
        }
7204
2.08M
    }
7205
7206
    /* Always create the base color group information as it is only through
7207
       groups that we can have a color space change.  This will survive
7208
       the life of the context. */
7209
2.08M
    if (pdev->ctx->base_color == NULL) {
7210
575k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7211
575k
    }
7212
7213
    /* If this is not the page group and we don't yet have a group, we need
7214
       to create a buffer for the whole page so that we can handle stuff drawn
7215
       outside this current group (e.g. two non inclusive groups drawn independently) */
7216
2.08M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7217
75.6k
        code = pdf14_initialize_ctx(dev, NULL);
7218
75.6k
        if (code < 0)
7219
0
            return code;
7220
75.6k
        pdev->ctx->stack->isolated = true;
7221
75.6k
    }
7222
7223
2.08M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7224
2.08M
        group_profile, false);
7225
2.08M
    if (group_color_info == NULL)
7226
0
        return gs_error_VMerror;
7227
2.08M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7228
7229
2.08M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7230
2.08M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7231
2.08M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7232
2.08M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7233
2.08M
                                        pgs->blend_mode, ptgp->idle,
7234
2.08M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7235
2.08M
                                         cm_back_drop, ptgp->shade_group,
7236
2.08M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7237
2.08M
    if (new_icc)
7238
427k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7239
2.08M
    return code;
7240
2.08M
}
7241
7242
static void
7243
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7244
2.08M
{
7245
2.08M
    pdf14_device* pdev = (pdf14_device*)dev;
7246
7247
2.08M
    if (group_color != NULL &&
7248
2.08M
        !(group_color->group_color_mapping_procs == NULL &&
7249
2.08M
            group_color->group_color_comp_index == NULL)) {
7250
2.08M
        bool has_tags = device_encodes_tags(dev);
7251
2.08M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7252
2.08M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7253
2.08M
        pdev->color_info.polarity = group_color->polarity;
7254
2.08M
        if (pdev->num_planar_planes > 0)
7255
85.9k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7256
2.08M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7257
2.08M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7258
2.08M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7259
2.08M
        pdev->blend_procs = group_color->blend_procs;
7260
2.08M
        pdev->ctx->additive = group_color->isadditive;
7261
2.08M
        pdev->pdf14_procs = group_color->unpack_procs;
7262
2.08M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7263
2.08M
        pdev->color_info.depth = group_color->depth;
7264
2.08M
        pdev->color_info.max_color = group_color->max_color;
7265
2.08M
        pdev->color_info.max_gray = group_color->max_gray;
7266
2.08M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7267
2.08M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7268
2.08M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7269
2.08M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7270
2.08M
        if (group_color->icc_profile != NULL) {
7271
            /* make sure to decrement the device profile.  If it was allocated
7272
               with the push then it will be freed. */
7273
2.08M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7274
2.08M
                                    -1, "pdf14_pop_color_model");
7275
2.08M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7276
2.08M
                                    group_color->icc_profile;
7277
7278
2.08M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7279
2.08M
                                    1, "pdf14_pop_color_model");
7280
2.08M
        }
7281
2.08M
        pdev->num_std_colorants = group_color->num_std_colorants;
7282
2.08M
    }
7283
2.08M
}
7284
7285
static  int
7286
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7287
2.08M
{
7288
2.08M
    pdf14_device* pdev = (pdf14_device*)dev;
7289
2.08M
    int code;
7290
2.08M
    cmm_profile_t* group_profile;
7291
2.08M
    gsicc_rendering_param_t render_cond;
7292
2.08M
    cmm_dev_profile_t* dev_profile;
7293
2.08M
    int has_tags = device_encodes_tags(dev);
7294
7295
2.08M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7296
2.08M
    if (code < 0)
7297
0
        return code;
7298
7299
2.08M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7300
2.08M
        &render_cond);
7301
2.08M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7302
7303
2.08M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7304
2.08M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7305
2.08M
    if (code < 0)
7306
0
        return code;
7307
#ifdef DEBUG
7308
    pdf14_debug_mask_stack_state(pdev->ctx);
7309
#endif
7310
    /* If this group is the base group, then restore the color model
7311
       of the device at this time.  Note that during the actual device pop
7312
       we will need to use the profile of the buffer not the pdf14 device
7313
       as the source color space */
7314
2.08M
    if (pdev->ctx->stack->group_popped) {
7315
417k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7316
1.66M
    } else {
7317
1.66M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7318
1.66M
    }
7319
7320
2.08M
    return code;
7321
2.08M
}
7322
7323
static pdf14_group_color_t*
7324
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7325
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7326
                        bool is_mask)
7327
2.48M
{
7328
2.48M
    pdf14_device *pdevproto = NULL;
7329
2.48M
    pdf14_device *pdev = (pdf14_device *)dev;
7330
2.48M
    const pdf14_procs_t *new_14procs = NULL;
7331
2.48M
    pdf14_group_color_t *group_color;
7332
2.48M
    gx_color_polarity_t new_polarity;
7333
2.48M
    uchar new_num_comps;
7334
2.48M
    bool new_additive;
7335
2.48M
    gx_device_clist_reader *pcrdev;
7336
2.48M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7337
2.48M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7338
2.48M
    int k;
7339
2.48M
    bool has_tags = device_encodes_tags(dev);
7340
2.48M
    bool deep = pdev->ctx->deep;
7341
7342
2.48M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7343
7344
2.48M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7345
7346
2.48M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7347
2.48M
                               pdf14_group_color_t, &st_pdf14_clr,
7348
2.48M
                               "pdf14_push_color_model");
7349
2.48M
    if (group_color == NULL)
7350
0
        return NULL;
7351
7352
2.48M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7353
7354
2.48M
    switch (group_color_type) {
7355
0
        case GRAY_SCALE:
7356
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7357
0
            new_num_comps = 1;
7358
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7359
0
            new_additive = true;
7360
0
            new_14procs = &gray_pdf14_procs;
7361
0
            break;
7362
0
        case DEVICE_RGB:
7363
0
        case CIE_XYZ:
7364
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7365
0
            new_num_comps = 3;
7366
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7367
0
            new_additive = true;
7368
0
            new_14procs = &rgb_pdf14_procs;
7369
0
            break;
7370
0
        case DEVICE_CMYK:
7371
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7372
0
            new_num_comps = 4;
7373
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7374
0
            new_additive = false;
7375
            /* This is needed due to the mismatched compressed encode decode
7376
                between the device procs and the pdf14 procs */
7377
0
            if (dev->color_info.num_components > 4){
7378
0
                new_14procs = &cmykspot_pdf14_procs;
7379
0
            } else {
7380
0
                new_14procs = &cmyk_pdf14_procs;
7381
0
            }
7382
0
            break;
7383
2.48M
        case ICC:
7384
            /* If we are coming from the clist reader, then we need to get
7385
                the ICC data now  */
7386
2.48M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7387
                /* Get the serialized data from the clist.  Not the whole
7388
                    profile. */
7389
400k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7390
400k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7391
400k
                                                    icc_hashcode);
7392
400k
                if (iccprofile == NULL)
7393
0
                    return NULL;
7394
                /* Keep a pointer to the clist device */
7395
400k
                iccprofile->dev = (gx_device *) pcrdev;
7396
2.08M
            } else {
7397
                /* Go ahead and rc increment right now.  This way when
7398
                    we pop, we will make sure to decrement and avoid a
7399
                    leak for the above profile that we just created.  This
7400
                    goes with the assignment to the device's profile.
7401
                    Note that we still do the increment for the group_color
7402
                    assignment below. */
7403
2.08M
                if (iccprofile == NULL)
7404
0
                    return NULL;
7405
2.08M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7406
2.08M
            }
7407
2.48M
            new_num_comps = iccprofile->num_comps;
7408
2.48M
            if (new_num_comps == 4) {
7409
90.1k
                new_additive = false;
7410
90.1k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7411
2.39M
            } else {
7412
2.39M
                new_additive = true;
7413
2.39M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7414
2.39M
            }
7415
2.48M
            switch (new_num_comps) {
7416
598k
                case 1:
7417
598k
                    if (pdev->sep_device && !is_mask) {
7418
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7419
0
                        new_14procs = &grayspot_pdf14_procs;
7420
598k
                    } else {
7421
598k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7422
598k
                        new_14procs = &gray_pdf14_procs;
7423
598k
                    }
7424
598k
                    break;
7425
1.79M
                case 3:
7426
1.79M
                    if (pdev->sep_device) {
7427
73.7k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7428
73.7k
                        new_14procs = &rgbspot_pdf14_procs;
7429
73.7k
                    }
7430
1.72M
                    else {
7431
1.72M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7432
1.72M
                        new_14procs = &rgb_pdf14_procs;
7433
1.72M
                    }
7434
1.79M
                    break;
7435
90.1k
                case 4:
7436
90.1k
                    if (pdev->sep_device) {
7437
12.2k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7438
12.2k
                        new_14procs = &cmykspot_pdf14_procs;
7439
77.8k
                    } else {
7440
77.8k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7441
77.8k
                        new_14procs = &cmyk_pdf14_procs;
7442
77.8k
                    }
7443
90.1k
                    break;
7444
0
                default:
7445
0
                    return NULL;
7446
0
                    break;
7447
2.48M
            }
7448
2.48M
            break;
7449
2.48M
        default:
7450
0
            return NULL;
7451
0
            break;
7452
2.48M
    }
7453
7454
    /* We might just have changed the colorspace of the device, which means
7455
     * the number of colorants have changed. */
7456
2.48M
    group_color->num_std_colorants = new_num_comps;
7457
2.48M
    pdev->num_std_colorants = new_num_comps;
7458
7459
2.48M
    if (has_tags)
7460
0
        new_num_comps++;
7461
7462
2.48M
    if (group_color_type == ICC && iccprofile != NULL) {
7463
2.48M
        group_color->icc_profile = iccprofile;
7464
2.48M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7465
2.48M
    }
7466
7467
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7468
       spot colorants and know how to index into them */
7469
2.48M
    if (pdev->sep_device && !is_mask) {
7470
85.9k
        int num_spots = dev->color_info.num_components - has_tags -
7471
85.9k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7472
7473
85.9k
        if (num_spots > 0)
7474
690
            new_num_comps += num_spots;
7475
85.9k
    }
7476
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7477
8.84M
    for (k = 0; k < new_num_comps; k++) {
7478
6.35M
        comp_bits[k] = 8<<deep;
7479
6.35M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7480
6.35M
    }
7481
7482
    /* Set device values now and store settings in group_color.  Then they
7483
       are available when we pop the previous group */
7484
2.48M
    if_debug2m('v', pdev->memory,
7485
2.48M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7486
2.48M
                pdev->color_info.num_components,new_num_comps);
7487
2.48M
    {
7488
2.48M
        gx_device local_device;
7489
7490
2.48M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7491
2.48M
        local_device.initialize_device_procs((gx_device *)&local_device);
7492
2.48M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7493
2.48M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7494
2.48M
    }
7495
2.48M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7496
2.48M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7497
2.48M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7498
2.48M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7499
2.48M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7500
2.48M
    if (pdev->num_planar_planes > 0)
7501
114k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7502
2.48M
    group_color->num_components = new_num_comps - has_tags;
7503
2.48M
    pdev->color_info.num_components = new_num_comps;
7504
2.48M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7505
2.48M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7506
2.48M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7507
2.48M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7508
2.48M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7509
2.48M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7510
2.48M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7511
2.48M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7512
2.48M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7513
2.48M
    group_color->depth = pdev->color_info.depth;
7514
2.48M
    group_color->decode = dev_proc(pdev, decode_color);
7515
2.48M
    group_color->encode = dev_proc(pdev, encode_color);
7516
2.48M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7517
2.48M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7518
2.48M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7519
2.48M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7520
2.48M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7521
2.48M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7522
2.48M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7523
7524
    /* If the CS was ICC based, we need to update the device ICC profile
7525
        in the ICC manager, since that is the profile that is used for the
7526
        PDF14 device */
7527
2.48M
    if (group_color_type == ICC && iccprofile != NULL) {
7528
        /* iccprofile was incremented above if we had not just created it.
7529
           When we do the pop we will decrement and if we just created it, it
7530
           will be destroyed */
7531
2.48M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7532
2.48M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7533
2.48M
    }
7534
2.48M
    return group_color;
7535
2.48M
}
7536
7537
static int
7538
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7539
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7540
                             bool is_mask)
7541
57.1k
{
7542
57.1k
    pdf14_device* pdev = (pdf14_device*)dev;
7543
57.1k
    pdf14_group_color_t* new_group_color;
7544
57.1k
    gsicc_rendering_param_t render_cond;
7545
57.1k
    cmm_dev_profile_t* dev_profile;
7546
57.1k
    pdf14_device* pdevproto;
7547
57.1k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7548
57.1k
    const pdf14_procs_t* new_14procs;
7549
57.1k
    bool update_color_info;
7550
57.1k
    gx_color_polarity_t new_polarity;
7551
57.1k
    int new_num_comps;
7552
57.1k
    bool new_additive = false;
7553
57.1k
    byte new_depth;
7554
57.1k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7555
57.1k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7556
57.1k
    int k;
7557
57.1k
    bool has_tags = device_encodes_tags(dev);
7558
57.1k
    bool deep = device_is_deep(dev);
7559
57.1k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7560
57.1k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7561
57.1k
    cmm_profile_t *old_profile = NULL;
7562
7563
57.1k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7564
7565
57.1k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7566
57.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7567
57.1k
        &render_cond);
7568
57.1k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7569
7570
    /* Allocate a new one */
7571
57.1k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7572
57.1k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7573
7574
57.1k
    if (new_group_color == NULL)
7575
0
        return_error(gs_error_VMerror);
7576
7577
    /* Link to old one */
7578
57.1k
    new_group_color->previous = pdev->color_model_stack;
7579
7580
    /* Reassign new one to dev */
7581
57.1k
    pdev->color_model_stack = new_group_color;
7582
7583
    /* Initialize with values */
7584
57.1k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7585
57.1k
    new_group_color->group_color_mapping_procs =
7586
57.1k
        dev_proc(pdev, get_color_mapping_procs);
7587
57.1k
    new_group_color->group_color_comp_index =
7588
57.1k
        dev_proc(pdev, get_color_comp_index);
7589
57.1k
    new_group_color->blend_procs = pdev->blend_procs;
7590
57.1k
    new_group_color->polarity = pdev->color_info.polarity;
7591
57.1k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7592
57.1k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7593
57.1k
    new_group_color->depth = pdev->color_info.depth;
7594
57.1k
    new_group_color->max_color = pdev->color_info.max_color;
7595
57.1k
    new_group_color->max_gray = pdev->color_info.max_gray;
7596
57.1k
    new_group_color->decode = dev_proc(pdev, decode_color);
7597
57.1k
    new_group_color->encode = dev_proc(pdev, encode_color);
7598
57.1k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7599
57.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7600
57.1k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7601
57.1k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7602
7603
57.1k
    if (new_profile == NULL)
7604
34.7k
        new_group_color->icc_profile = NULL;
7605
7606
    /* isadditive is only used in ctx */
7607
57.1k
    if (pdev->ctx) {
7608
0
        new_group_color->isadditive = pdev->ctx->additive;
7609
0
    }
7610
7611
57.1k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7612
57.1k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7613
7614
57.1k
    if (group_color_type == ICC && new_profile == NULL)
7615
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7616
57.1k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7617
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7618
       are based upon the color space of the device.  We want to remain in the
7619
       color space defined by the color space of the soft mask or transparency
7620
       group as opposed to the device color space. Later, when we pop the softmask
7621
       we will collapse it to a single band and then compose with it to the device
7622
       color space (or the parent layer space).  In the case where we pop an
7623
       isolated transparency group, we will do the blending in the proper color
7624
       space and then transform the data when we pop the group.  Remember that only
7625
       isolated groups can have color spaces that are different than their parent. */
7626
57.1k
    update_color_info = false;
7627
57.1k
    switch (group_color_type) {
7628
0
    case GRAY_SCALE:
7629
0
        if (pdev->color_info.num_components != 1) {
7630
0
            update_color_info = true;
7631
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7632
0
            new_num_comps = 1;
7633
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7634
0
            new_additive = true;
7635
0
            new_14procs = &gray_pdf14_procs;
7636
0
            new_depth = 8 << deep;
7637
0
        }
7638
0
        break;
7639
0
    case DEVICE_RGB:
7640
0
    case CIE_XYZ:
7641
0
        if (pdev->color_info.num_components != 3) {
7642
0
            update_color_info = true;
7643
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7644
0
            new_num_comps = 3;
7645
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7646
0
            new_additive = true;
7647
0
            new_14procs = &rgb_pdf14_procs;
7648
0
            new_depth = 24 << deep;
7649
0
        }
7650
0
        break;
7651
0
    case DEVICE_CMYK:
7652
0
        if (pdev->color_info.num_components != 4) {
7653
0
            update_color_info = true;
7654
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7655
0
            new_num_comps = 4;
7656
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7657
0
            new_additive = false;
7658
            /* This is needed due to the mismatched compressed encode decode
7659
               between the device procs and the pdf14 procs */
7660
0
            if (dev->color_info.num_components > 4) {
7661
0
                new_14procs = &cmykspot_pdf14_procs;
7662
0
            }
7663
0
            else {
7664
0
                new_14procs = &cmyk_pdf14_procs;
7665
0
            }
7666
0
            new_depth = 32 << deep;
7667
0
        }
7668
0
        break;
7669
22.4k
    case ICC:
7670
        /* Check if the profile is different. */
7671
22.4k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7672
20.2k
            update_color_info = true;
7673
20.2k
            new_num_comps = new_profile->num_comps;
7674
20.2k
            new_depth = new_profile->num_comps * (8 << deep);
7675
20.2k
            switch (new_num_comps) {
7676
18.1k
            case 1:
7677
18.1k
                if (pdev->sep_device && !is_mask) {
7678
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7679
0
                    new_14procs = &grayspot_pdf14_procs;
7680
0
                }
7681
18.1k
                else {
7682
18.1k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7683
18.1k
                    new_14procs = &gray_pdf14_procs;
7684
18.1k
                }
7685
18.1k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7686
18.1k
                new_additive = true;
7687
18.1k
                break;
7688
1.92k
            case 3:
7689
1.92k
                if (pdev->sep_device) {
7690
542
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7691
542
                    new_14procs = &rgbspot_pdf14_procs;
7692
542
                }
7693
1.38k
                else {
7694
1.38k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7695
1.38k
                    new_14procs = &rgb_pdf14_procs;
7696
1.38k
                }
7697
1.92k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7698
1.92k
                new_additive = true;
7699
1.92k
                break;
7700
211
            case 4:
7701
211
                if (pdev->sep_device) {
7702
5
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7703
5
                    new_14procs = &cmykspot_pdf14_procs;
7704
5
                }
7705
206
                else {
7706
206
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7707
206
                    new_14procs = &cmyk_pdf14_procs;
7708
206
                }
7709
211
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7710
211
                new_additive = false;
7711
211
                break;
7712
0
            default:
7713
0
                return gs_throw(gs_error_undefinedresult,
7714
20.2k
                    "ICC Number of colorants illegal");
7715
20.2k
            }
7716
20.2k
        }
7717
22.4k
        break;
7718
34.7k
    case UNKNOWN:
7719
34.7k
        return 0;
7720
0
        break;
7721
0
    default:
7722
0
        return_error(gs_error_rangecheck);
7723
0
        break;
7724
57.1k
    }
7725
7726
22.4k
    if (!update_color_info) {
7727
        /* Profile not updated */
7728
2.11k
        new_group_color->icc_profile = NULL;
7729
2.11k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7730
2.11k
        return 0;
7731
2.11k
    }
7732
7733
20.2k
    if (has_tags) {
7734
0
        new_num_comps++;
7735
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7736
0
        if (pdev->num_planar_planes > 0)
7737
0
            new_depth += deep ? 16 : 8;
7738
0
        else
7739
0
            new_depth += 8;
7740
0
    }
7741
20.2k
    if (pdev->sep_device && !is_mask) {
7742
547
        int num_spots;
7743
7744
547
        if (old_profile == NULL)
7745
0
            return_error(gs_error_undefined);
7746
7747
547
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7748
7749
547
        if (num_spots > 0) {
7750
47
            new_num_comps += num_spots;
7751
47
            new_depth = (8 << deep) * new_num_comps;
7752
47
        }
7753
547
    }
7754
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7755
45.1k
    for (k = 0; k < new_num_comps; k++) {
7756
24.8k
        comp_bits[k] = 8 << deep;
7757
24.8k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7758
24.8k
    }
7759
20.2k
    if_debug2m('v', pdev->memory,
7760
20.2k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7761
20.2k
        pdev->color_info.num_components, new_num_comps);
7762
    /* Set new information in the device */
7763
20.2k
    {
7764
20.2k
        gx_device local_device;
7765
7766
20.2k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7767
20.2k
        local_device.initialize_device_procs((gx_device *)&local_device);
7768
20.2k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7769
20.2k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7770
20.2k
    }
7771
20.2k
    pdev->blend_procs = pdevproto->blend_procs;
7772
20.2k
    pdev->color_info.polarity = new_polarity;
7773
20.2k
    pdev->color_info.max_color = deep ? 65535 : 255;
7774
20.2k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7775
20.2k
    pdev->pdf14_procs = new_14procs;
7776
20.2k
    if (pdev->num_planar_planes > 0)
7777
2.75k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7778
20.2k
    pdev->color_info.num_components = new_num_comps;
7779
20.2k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7780
20.2k
    pdev->color_info.depth = new_depth;
7781
20.2k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7782
20.2k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7783
20.2k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7784
20.2k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7785
20.2k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7786
7787
    /* If we have a compressed color codec, and we are doing a soft mask
7788
       push operation then go ahead and update the color encode and
7789
       decode for the pdf14 device to not used compressed color
7790
       encoding while in the soft mask.  We will just check for gray
7791
       and compressed.  Note that we probably don't have_tags if we
7792
       are dealing with compressed color.  But is is possible so
7793
       we add it in to catch for future use. */
7794
20.2k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7795
20.2k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7796
20.2k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7797
20.2k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7798
20.2k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7799
20.2k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7800
    /* For the ICC profiles, we want to update the ICC profile for the
7801
       device.  We store the original in group_color.
7802
       That will be stored in the clist and restored during the reading phase. */
7803
20.2k
    if (group_color_type == ICC) {
7804
20.2k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7805
20.2k
        new_group_color->icc_profile =
7806
20.2k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7807
20.2k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7808
20.2k
    }
7809
20.2k
    if (pdev->ctx) {
7810
0
        pdev->ctx->additive = new_additive;
7811
0
    }
7812
20.2k
    return 1;  /* Lets us detect that we did do an update */
7813
20.2k
}
7814
7815
static int
7816
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7817
57.0k
{
7818
7819
57.0k
    pdf14_device *pdev = (pdf14_device *)dev;
7820
57.0k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7821
57.0k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7822
7823
57.0k
    if (group_color == NULL)
7824
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7825
7826
57.0k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7827
    /* The color procs are always pushed.  Simply restore them. */
7828
57.0k
    if (group_color->group_color_mapping_procs == NULL &&
7829
0
        group_color->group_color_comp_index == NULL) {
7830
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7831
57.0k
    } else {
7832
57.0k
        bool has_tags = device_encodes_tags(dev);
7833
57.0k
        if_debug2m('v', pdev->memory,
7834
57.0k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7835
57.0k
                   pdev->color_info.num_components,group_color->num_components);
7836
57.0k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7837
57.0k
        gx_set_cmap_procs(pgs, dev);
7838
57.0k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7839
57.0k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7840
57.0k
        pdev->color_info.polarity = group_color->polarity;
7841
57.0k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7842
57.0k
        pdev->color_info.depth = group_color->depth;
7843
57.0k
        if (pdev->num_planar_planes > 0)
7844
6.58k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7845
57.0k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7846
57.0k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7847
57.0k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7848
57.0k
        pdev->blend_procs = group_color->blend_procs;
7849
57.0k
        pdev->pdf14_procs = group_color->unpack_procs;
7850
57.0k
        pdev->color_info.max_color = group_color->max_color;
7851
57.0k
        pdev->color_info.max_gray = group_color->max_gray;
7852
57.0k
        set_dev_proc(pdev, encode_color, group_color->encode);
7853
57.0k
        set_dev_proc(pdev, decode_color, group_color->decode);
7854
57.0k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7855
57.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7856
57.0k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7857
57.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7858
7859
        /* clist writer fill rect has no access to gs_gstate */
7860
        /* and it forwards the target device.  this information */
7861
        /* is passed along to use in this case */
7862
57.0k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7863
57.0k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7864
57.0k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7865
57.0k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7866
57.0k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7867
57.0k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7868
57.0k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7869
57.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7870
57.0k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7871
57.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7872
57.0k
        if (pdev->ctx){
7873
0
            pdev->ctx->additive = group_color->isadditive;
7874
0
        }
7875
       /* The device profile must be restored. */
7876
57.0k
        if (group_color->icc_profile != NULL) {
7877
20.2k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7878
20.2k
                                    -1, "pdf14_clist_pop_color_model");
7879
20.2k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7880
20.2k
        }
7881
57.0k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7882
57.0k
    }
7883
57.0k
   pdf14_pop_group_color(dev, pgs);
7884
57.0k
    return 0;
7885
57.0k
}
7886
7887
/* When a transparency group is popped, the parent colorprocs must be restored.
7888
   Since the color mapping procs are all based upon the device, we must have a
7889
   nested list based upon the transparency group color space.  This nesting
7890
   must be outside the nested ctx structures to allow the nesting for the
7891
   clist writer */
7892
static void
7893
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7894
57.1k
{
7895
57.1k
    pdf14_device *pdev = (pdf14_device *)dev;
7896
57.1k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7897
7898
57.1k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7899
7900
    /* Update the link */
7901
57.1k
    pdev->color_model_stack = group_color->previous;
7902
7903
    /* Free the old one */
7904
57.1k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7905
57.1k
}
7906
7907
static  int
7908
pdf14_begin_transparency_mask(gx_device *dev,
7909
                              const gx_transparency_mask_params_t *ptmp,
7910
                              const gs_rect *pbbox,
7911
                              gs_gstate *pgs, gs_memory_t *mem)
7912
4.04M
{
7913
4.04M
    pdf14_device *pdev = (pdf14_device *)dev;
7914
4.04M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7915
4.04M
    byte *transfer_fn;
7916
4.04M
    gs_int_rect rect;
7917
4.04M
    int code;
7918
4.04M
    int group_color_numcomps;
7919
4.04M
    gs_transparency_color_t group_color_type;
7920
4.04M
    bool deep = device_is_deep(dev);
7921
4.04M
    pdf14_group_color_t* group_color_info;
7922
7923
4.04M
    code = pdf14_initialize_ctx(dev, pgs);
7924
4.04M
    if (code < 0)
7925
0
        return code;
7926
7927
4.04M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7928
3.64M
        pdf14_ctx *ctx = pdev->ctx;
7929
7930
        /* free up any maskbuf on the current tos */
7931
3.64M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7932
310k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7933
310k
            ctx->mask_stack->mask_buf = NULL;
7934
310k
        }
7935
3.64M
        return 0;
7936
3.64M
    }
7937
404k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7938
404k
                                         "pdf14_begin_transparency_mask");
7939
404k
    if (transfer_fn == NULL)
7940
0
        return_error(gs_error_VMerror);
7941
404k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7942
404k
    if (code < 0)
7943
0
        return code;
7944
    /* If we have background components the background alpha may be nonzero */
7945
404k
    if (ptmp->Background_components)
7946
56.2k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7947
404k
    if_debug1m('v', dev->memory,
7948
404k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7949
404k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7950
   /* If the group color is unknown, then we must use the previous group color
7951
       space or the device process color space */
7952
404k
    if (ptmp->group_color_type == UNKNOWN){
7953
0
        if (pdev->ctx->stack){
7954
            /* Use previous group color space */
7955
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7956
0
        } else {
7957
            /* Use process color space */
7958
0
            group_color_numcomps = pdev->color_info.num_components;
7959
0
        }
7960
0
        switch (group_color_numcomps) {
7961
0
            case 1:
7962
0
                group_color_type = GRAY_SCALE;
7963
0
                break;
7964
0
            case 3:
7965
0
                group_color_type = DEVICE_RGB;
7966
0
                break;
7967
0
            case 4:
7968
0
                group_color_type = DEVICE_CMYK;
7969
0
            break;
7970
0
            default:
7971
                /* We can end up here if we are in a deviceN color space and
7972
                   we have a sep output device */
7973
0
                group_color_type = DEVICEN;
7974
0
            break;
7975
0
         }
7976
404k
    } else {
7977
404k
        group_color_type = ptmp->group_color_type;
7978
404k
        group_color_numcomps = ptmp->group_color_numcomps;
7979
404k
    }
7980
7981
404k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7982
404k
                                               ptmp->iccprofile, true);
7983
404k
    if (group_color_info == NULL)
7984
0
        return gs_error_VMerror;
7985
7986
    /* Note that the soft mask always follows the group color requirements even
7987
       when we have a separable device */
7988
404k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7989
404k
                                        transfer_fn, ptmp->function_is_identity,
7990
404k
                                        ptmp->idle, ptmp->replacing,
7991
404k
                                        ptmp->mask_id, ptmp->subtype,
7992
404k
                                        group_color_numcomps,
7993
404k
                                        ptmp->Background_components,
7994
404k
                                        ptmp->Background,
7995
404k
                                        ptmp->Matte_components,
7996
404k
                                        ptmp->Matte,
7997
404k
                                        ptmp->GrayBackground,
7998
404k
                                        group_color_info);
7999
404k
    if (code < 0)
8000
0
        return code;
8001
8002
404k
    return 0;
8003
404k
}
8004
8005
static  int
8006
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8007
404k
{
8008
404k
    pdf14_device *pdev = (pdf14_device *)dev;
8009
404k
    pdf14_group_color_t *group_color;
8010
404k
    int ok;
8011
404k
    bool has_tags = device_encodes_tags(dev);
8012
8013
404k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8014
404k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8015
#ifdef DEBUG
8016
    pdf14_debug_mask_stack_state(pdev->ctx);
8017
#endif
8018
8019
    /* May need to reset some color stuff related
8020
     * to a mismatch between the Smask color space
8021
     * and the Smask blending space */
8022
404k
    if (pdev->ctx->stack != NULL ) {
8023
404k
        group_color = pdev->ctx->stack->group_color_info;
8024
404k
        if (!(group_color->group_color_mapping_procs == NULL &&
8025
404k
            group_color->group_color_comp_index == NULL)) {
8026
404k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8027
404k
            gx_set_cmap_procs(pgs, dev);
8028
404k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8029
404k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8030
404k
            pdev->color_info.polarity = group_color->polarity;
8031
404k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8032
404k
            if (pdev->num_planar_planes > 0)
8033
28.8k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8034
404k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8035
404k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8036
404k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8037
404k
            pdev->num_std_colorants = group_color->num_std_colorants;
8038
404k
            pdev->color_info.depth = group_color->depth;
8039
404k
            pdev->blend_procs = group_color->blend_procs;
8040
404k
            pdev->ctx->additive = group_color->isadditive;
8041
404k
            pdev->pdf14_procs = group_color->unpack_procs;
8042
404k
            pdev->color_info.max_color = group_color->max_color;
8043
404k
            pdev->color_info.max_gray = group_color->max_gray;
8044
404k
            set_dev_proc(pdev, encode_color, group_color->encode);
8045
404k
            set_dev_proc(pdev, decode_color, group_color->decode);
8046
404k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8047
404k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8048
404k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8049
404k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8050
            /* Take care of the ICC profile */
8051
404k
            if (group_color->icc_profile != NULL) {
8052
404k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8053
404k
                                        -1, "pdf14_end_transparency_mask");
8054
404k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8055
404k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8056
404k
                                         1, "pdf14_end_transparency_mask");
8057
404k
            }
8058
404k
        }
8059
404k
    }
8060
404k
    return ok;
8061
404k
}
8062
8063
static  int
8064
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8065
                                 gx_color_index color,
8066
                                 const gx_device_color *pdc, bool devn)
8067
1.79M
{
8068
1.79M
    pdf14_device *pdev = (pdf14_device *)dev;
8069
1.79M
    pdf14_buf *buf = pdev->ctx->stack;
8070
1.79M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8071
1.79M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8072
155k
        blend_mode == BLEND_MODE_Compatible ||
8073
155k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8074
1.79M
    int i, j, k;
8075
1.79M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8076
1.79M
    byte src[PDF14_MAX_PLANES];
8077
1.79M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8078
1.79M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8079
1.79M
    intptr_t rowstride = buf->rowstride;
8080
1.79M
    intptr_t planestride = buf->planestride;
8081
1.79M
    int num_chan = buf->n_chan;
8082
1.79M
    int num_comp = num_chan - 1;
8083
1.79M
    intptr_t shape_off = num_chan * planestride;
8084
1.79M
    bool has_shape = buf->has_shape;
8085
1.79M
    bool has_alpha_g = buf->has_alpha_g;
8086
1.79M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8087
1.79M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8088
1.79M
                                   (has_shape ? planestride : 0);
8089
1.79M
    bool has_tags = buf->has_tags;
8090
1.79M
    bool additive = pdev->ctx->additive;
8091
1.79M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8092
1.79M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8093
1.79M
    int shift = 8;
8094
1.79M
    byte shape = 0; /* Quiet compiler. */
8095
1.79M
    byte src_alpha;
8096
1.79M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8097
1.79M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8098
1.41M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8099
1.79M
    gx_color_index comps;
8100
1.79M
    bool has_backdrop = buf->backdrop != NULL;
8101
8102
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8103
       subtractive) and we are doing overprint with drawn_comps == 0
8104
       then this is a no-operation */
8105
1.79M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8106
0
        return 0;
8107
8108
1.79M
    if (buf->data == NULL)
8109
2
        return 0;
8110
#if 0
8111
    if (sizeof(color) <= sizeof(ulong))
8112
        if_debug6m('v', dev->memory,
8113
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8114
                   x, y, w, h, (ulong)color, num_chan);
8115
    else
8116
        if_debug7m('v', dev->memory,
8117
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8118
                   x, y, w, h,
8119
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8120
                   num_chan);
8121
#endif
8122
    /*
8123
     * Unpack the gx_color_index values.  Complement the components for subtractive
8124
     * color spaces.
8125
     */
8126
1.79M
    if (devn) {
8127
109k
        if (has_tags) {
8128
0
            curr_tag = pdc->tag;
8129
0
        }
8130
109k
        if (additive) {
8131
97.4k
            for (j = 0; j < num_comp; j++) {
8132
73.0k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8133
73.0k
            }
8134
85.5k
        } else {
8135
427k
            for (j = 0; j < num_comp; j++) {
8136
342k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8137
342k
            }
8138
85.5k
        }
8139
1.68M
    } else {
8140
1.68M
        if (has_tags) {
8141
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8142
0
        }
8143
1.68M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8144
1.68M
    }
8145
8146
1.79M
    if (!has_tags)
8147
1.79M
        tag_off = 0;
8148
8149
1.79M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8150
1.79M
    if (has_shape) {
8151
147
        shape = (byte)floor (255 * pdev->shape + 0.5);
8152
1.79M
    } else {
8153
1.79M
        shape_off = 0;
8154
1.79M
    }
8155
8156
1.79M
    if (!has_alpha_g)
8157
0
        alpha_g_off = 0;
8158
1.79M
    src_alpha = 255 - src_alpha;
8159
1.79M
    shape = 255 - shape;
8160
8161
    /* Fit the mark into the bounds of the buffer */
8162
1.79M
    if (x < buf->rect.p.x) {
8163
0
        w += x - buf->rect.p.x;
8164
0
        x = buf->rect.p.x;
8165
0
    }
8166
1.79M
    if (y < buf->rect.p.y) {
8167
10
      h += y - buf->rect.p.y;
8168
10
      y = buf->rect.p.y;
8169
10
    }
8170
1.79M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8171
1.79M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8172
    /* Update the dirty rectangle with the mark. */
8173
1.79M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8174
1.79M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8175
1.79M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8176
1.79M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8177
8178
    /* composite with backdrop only. */
8179
1.79M
    if (has_backdrop)
8180
1.79M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8181
0
    else
8182
0
        bline = NULL;
8183
8184
1.79M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8185
8186
3.75M
    for (j = 0; j < h; ++j) {
8187
1.95M
        bg_ptr = bline;
8188
1.95M
        dst_ptr = line;
8189
97.0M
        for (i = 0; i < w; ++i) {
8190
            /* Complement the components for subtractive color spaces */
8191
95.0M
            if (has_backdrop) {
8192
95.0M
                if (additive) {
8193
341M
                    for (k = 0; k < num_comp; ++k)
8194
246M
                        dst[k] = bg_ptr[k * planestride];
8195
94.0M
                } else {
8196
4.92M
                    for (k = 0; k < num_comp; ++k)
8197
3.94M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8198
985k
                }
8199
95.0M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8200
95.0M
            }
8201
95.0M
            if (buf->isolated || !has_backdrop) {
8202
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8203
95.0M
            } else {
8204
95.0M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8205
95.0M
                                            blend_mode, pdev->blend_procs, pdev);
8206
95.0M
            }
8207
            /* Complement the results for subtractive color spaces */
8208
95.0M
            if (additive) {
8209
94.0M
                if (!overprint) {
8210
435M
                    for (k = 0; k < num_chan; ++k)
8211
341M
                        dst_ptr[k * planestride] = dst[k];
8212
94.0M
                } else {
8213
                    /* Hybrid additive with subtractive spots */
8214
                    /* We may have to do the compatible overprint blending */
8215
8.51k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8216
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8217
0
                            blend_mode, pdev->blend_procs, pdev);
8218
0
                    }
8219
34.0k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8220
25.5k
                        if ((comps & 0x1) != 0) {
8221
25.5k
                            dst_ptr[k * planestride] = dst[k];
8222
25.5k
                        } else {
8223
                            /* Compatible overprint blend result. */
8224
0
                            dst_ptr[k * planestride] = dst2[k];
8225
0
                        }
8226
25.5k
                    }
8227
8.51k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8228
8.51k
                }
8229
94.0M
            } else {
8230
985k
                if (overprint) {
8231
                    /* We may have to do the compatible overprint blending */
8232
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8233
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8234
0
                            blend_mode, pdev->blend_procs, pdev);
8235
0
                    }
8236
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8237
0
                        if ((comps & 0x1) != 0) {
8238
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8239
0
                        } else {
8240
                            /* Compatible overprint blend result. */
8241
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8242
0
                        }
8243
0
                    }
8244
985k
                } else {
8245
4.92M
                    for (k = 0; k < num_comp; ++k)
8246
3.94M
                        dst_ptr[k * planestride] = 255 - dst[k];
8247
985k
                }
8248
985k
                dst_ptr[num_comp * planestride] = dst[num_comp];
8249
985k
            }
8250
95.0M
            if (tag_off) {
8251
                /* If src alpha is 100% then set to curr_tag, else or */
8252
                /* other than Normal BM, we always OR */
8253
0
                if (src[num_comp] == 255 && tag_blend) {
8254
0
                    dst_ptr[tag_off] = curr_tag;
8255
0
                } else {
8256
0
                    dst_ptr[tag_off] |= curr_tag;
8257
0
                }
8258
0
            }
8259
            /* Knockout group alpha and shape too */
8260
95.0M
            if (alpha_g_off)
8261
95.0M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8262
95.0M
            if (shape_off)
8263
306
                dst_ptr[shape_off] = 255 - shape;
8264
95.0M
            ++dst_ptr;
8265
95.0M
            if (has_backdrop)
8266
95.0M
                ++bg_ptr;
8267
95.0M
        }
8268
1.95M
        bline += rowstride;
8269
1.95M
        line += rowstride;
8270
1.95M
    }
8271
#if 0
8272
/* #if RAW_DUMP */
8273
    /* Dump the current buffer to see what we have. */
8274
    dump_raw_buffer(pdev->ctx->memory,
8275
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8276
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8277
                    pdev->ctx->stack->n_planes,
8278
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8279
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8280
                    pdev->ctx->stack->deep);
8281
    global_index++;
8282
#endif
8283
1.79M
    return 0;
8284
1.79M
}
8285
8286
static  int
8287
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8288
                                   gx_color_index color,
8289
                                   const gx_device_color *pdc, bool devn)
8290
0
{
8291
0
    pdf14_device *pdev = (pdf14_device *)dev;
8292
0
    pdf14_buf *buf = pdev->ctx->stack;
8293
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8294
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8295
0
        blend_mode == BLEND_MODE_Compatible ||
8296
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8297
0
    int i, j, k;
8298
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8299
0
    uint16_t src[PDF14_MAX_PLANES];
8300
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8301
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8302
0
    intptr_t rowstride = buf->rowstride;
8303
0
    intptr_t planestride = buf->planestride;
8304
0
    int num_chan = buf->n_chan;
8305
0
    int num_comp = num_chan - 1;
8306
0
    intptr_t shape_off = num_chan * planestride;
8307
0
    bool has_shape = buf->has_shape;
8308
0
    bool has_alpha_g = buf->has_alpha_g;
8309
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8310
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8311
0
                                   (has_shape ? planestride : 0);
8312
0
    bool has_tags = buf->has_tags;
8313
0
    bool additive = pdev->ctx->additive;
8314
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8315
0
    uint16_t shape = 0; /* Quiet compiler. */
8316
0
    uint16_t src_alpha;
8317
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8318
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8319
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8320
0
    gx_color_index comps;
8321
0
    bool has_backdrop = buf->backdrop != NULL;
8322
8323
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8324
       subtractive) and we are doing overprint with drawn_comps == 0
8325
       then this is a no-operation */
8326
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8327
0
        return 0;
8328
8329
0
    if (buf->data == NULL)
8330
0
        return 0;
8331
#if 0
8332
    if (sizeof(color) <= sizeof(ulong))
8333
        if_debug6m('v', dev->memory,
8334
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8335
                   x, y, w, h, (ulong)color, num_chan);
8336
    else
8337
        if_debug7m('v', dev->memory,
8338
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8339
                   x, y, w, h,
8340
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8341
                   num_chan);
8342
#endif
8343
    /*
8344
     * Unpack the gx_color_index values.  Complement the components for subtractive
8345
     * color spaces.
8346
     */
8347
0
    if (devn) {
8348
0
        if (has_tags) {
8349
0
            curr_tag = pdc->tag;
8350
0
        }
8351
0
        if (additive) {
8352
0
            for (j = 0; j < num_comp; j++) {
8353
0
                src[j] = pdc->colors.devn.values[j];
8354
0
            }
8355
0
        } else {
8356
0
            for (j = 0; j < num_comp; j++) {
8357
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8358
0
            }
8359
0
        }
8360
0
    } else {
8361
0
        if (has_tags) {
8362
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8363
0
        }
8364
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8365
0
    }
8366
8367
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8368
0
    if (has_shape) {
8369
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8370
0
    } else {
8371
0
        shape_off = 0;
8372
0
    }
8373
8374
0
    if (!has_tags) {
8375
0
        tag_off = 0;
8376
0
    }
8377
8378
0
    if (!has_alpha_g)
8379
0
        alpha_g_off = 0;
8380
0
    src_alpha = 65535 - src_alpha;
8381
0
    shape = 65535 - shape;
8382
8383
    /* Fit the mark into the bounds of the buffer */
8384
0
    if (x < buf->rect.p.x) {
8385
0
        w += x - buf->rect.p.x;
8386
0
        x = buf->rect.p.x;
8387
0
    }
8388
0
    if (y < buf->rect.p.y) {
8389
0
      h += y - buf->rect.p.y;
8390
0
      y = buf->rect.p.y;
8391
0
    }
8392
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8393
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8394
    /* Update the dirty rectangle with the mark. */
8395
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8396
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8397
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8398
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8399
8400
8401
    /* composite with backdrop only. */
8402
0
    if (has_backdrop)
8403
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8404
0
    else
8405
0
        bline = NULL;
8406
8407
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8408
0
    planestride >>= 1;
8409
0
    rowstride >>= 1;
8410
0
    alpha_g_off >>= 1;
8411
0
    shape_off >>= 1;
8412
0
    tag_off >>= 1;
8413
8414
0
    for (j = 0; j < h; ++j) {
8415
0
        bg_ptr = bline;
8416
0
        dst_ptr = line;
8417
0
        for (i = 0; i < w; ++i) {
8418
            /* Complement the components for subtractive color spaces */
8419
0
            if (has_backdrop) {
8420
0
                if (additive) {
8421
0
                    for (k = 0; k < num_comp; ++k)
8422
0
                        dst[k] = bg_ptr[k * planestride];
8423
0
                } else {
8424
0
                    for (k = 0; k < num_comp; ++k)
8425
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8426
0
                }
8427
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8428
0
            }
8429
0
            if (buf->isolated || !has_backdrop) {
8430
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8431
0
            } else {
8432
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8433
0
                                              blend_mode, pdev->blend_procs, pdev);
8434
0
            }
8435
            /* Complement the results for subtractive color spaces */
8436
0
            if (additive) {
8437
0
                if (!overprint) {
8438
0
                    for (k = 0; k < num_chan; ++k)
8439
0
                        dst_ptr[k * planestride] = dst[k];
8440
0
                } else {
8441
                    /* Hybrid additive with subtractive spots */
8442
                    /* We may have to do the compatible overprint blending */
8443
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8444
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8445
0
                            blend_mode, pdev->blend_procs, pdev);
8446
0
                    }
8447
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8448
0
                        if ((comps & 0x1) != 0) {
8449
0
                            dst_ptr[k * planestride] = dst[k];
8450
0
                        } else {
8451
                            /* Compatible overprint blend result. */
8452
0
                            dst_ptr[k * planestride] = dst2[k];
8453
0
                        }
8454
0
                    }
8455
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8456
0
                }
8457
0
            } else {
8458
0
                if (overprint) {
8459
                    /* We may have to do the compatible overprint blending */
8460
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8461
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8462
0
                            blend_mode, pdev->blend_procs, pdev);
8463
0
                    }
8464
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8465
0
                        if ((comps & 0x1) != 0) {
8466
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8467
0
                        } else {
8468
                            /* Compatible overprint blend result. */
8469
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8470
0
                        }
8471
0
                    }
8472
0
                } else {
8473
0
                    for (k = 0; k < num_comp; ++k)
8474
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8475
0
                }
8476
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8477
0
            }
8478
0
            if (tag_off) {
8479
                /* FIXME: As we are knocking out, possibly, we should be
8480
                 * always overwriting tag values here? */
8481
                /* If src alpha is 100% then set to curr_tag, else or */
8482
                /* other than Normal BM, we always OR */
8483
0
                if (src[num_comp] == 65535 && tag_blend) {
8484
0
                    dst_ptr[tag_off] = curr_tag;
8485
0
                } else {
8486
0
                    dst_ptr[tag_off] |= curr_tag;
8487
0
                }
8488
0
            }
8489
            /* Knockout group alpha and shape too */
8490
0
            if (alpha_g_off)
8491
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8492
0
            if (shape_off)
8493
0
                dst_ptr[shape_off] = 65535 - shape;
8494
0
            ++dst_ptr;
8495
0
            if (has_backdrop)
8496
0
                ++bg_ptr;
8497
0
        }
8498
0
        bline += rowstride;
8499
0
        line += rowstride;
8500
0
    }
8501
#if 0
8502
/* #if RAW_DUMP */
8503
    /* Dump the current buffer to see what we have. */
8504
    dump_raw_buffer(pdev->ctx->memory,
8505
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8506
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8507
                    pdev->ctx->stack->n_planes,
8508
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8509
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8510
                    pdev->ctx->stack->deep);
8511
    global_index++;
8512
#endif
8513
0
    return 0;
8514
0
}
8515
8516
static  int
8517
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8518
                                    gx_color_index color,
8519
                                    const gx_device_color *pdc, bool devn)
8520
1.79M
{
8521
1.79M
    pdf14_device *pdev = (pdf14_device *)dev;
8522
1.79M
    pdf14_buf *buf = pdev->ctx->stack;
8523
8524
1.79M
    if (buf->deep)
8525
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8526
1.79M
    else
8527
1.79M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8528
1.79M
}
8529
8530
/**
8531
 * Here we have logic to override the cmap_procs with versions that
8532
 * do not apply the transfer function. These copies should track the
8533
 * versions in gxcmap.c.
8534
 **/
8535
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8536
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8537
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8538
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8539
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8540
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8541
8542
static  const gx_color_map_procs pdf14_cmap_many = {
8543
     pdf14_cmap_gray_direct,
8544
     pdf14_cmap_rgb_direct,
8545
     pdf14_cmap_cmyk_direct,
8546
     pdf14_cmap_separation_direct,
8547
     pdf14_cmap_devicen_direct,
8548
     pdf14_cmap_is_halftoned
8549
    };
8550
8551
/**
8552
 * Note: copied from gxcmap.c because it's inlined.
8553
 **/
8554
static  inline void
8555
map_components_to_colorants(const frac * pcc,
8556
                            const gs_devicen_color_map * pcolor_component_map,
8557
                            frac * plist,
8558
                            int num_additives)
8559
327k
{
8560
327k
    int i = pcolor_component_map->num_colorants - 1;
8561
327k
    int pos;
8562
8563
    /* Clear all output colorants first */
8564
1.63M
    for (; i >= num_additives; i--) {
8565
1.30M
        plist[i] = frac_0;
8566
1.30M
    }
8567
330k
    for (; i >= 0; i--) {
8568
3.02k
        plist[i] = frac_1;
8569
3.02k
    }
8570
    /* Map color components into output list */
8571
672k
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8572
345k
        pos = pcolor_component_map->color_map[i];
8573
345k
        if (pos >= 0) {
8574
345k
            if (pos < num_additives)
8575
0
                plist[pos] = frac_1 - pcc[i];
8576
345k
            else
8577
345k
                plist[pos] = pcc[i];
8578
345k
        }
8579
345k
    }
8580
327k
}
8581
8582
/* See Section 7.6.4 of PDF 1.7 spec */
8583
static inline bool
8584
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8585
20.3M
{
8586
20.3M
    if (pgs->fillconstantalpha != 1.0 ||
8587
20.3M
        pgs->strokeconstantalpha != 1.0 ||
8588
20.2M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8589
208k
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8590
261k
        return 0;
8591
8592
    /* We can only be opaque if we're not in an SMask. */
8593
20.0M
    return dev_proc(pdev, dev_spec_op)(pdev,
8594
20.0M
                                       gxdso_in_smask,
8595
20.0M
                                       NULL, 0) != 1;
8596
20.3M
}
8597
8598
static  void
8599
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8600
                       gx_device * dev, gs_color_select_t select)
8601
8.95M
{
8602
8.95M
    int i, nc, ncomps;
8603
8.95M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8604
8.95M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8605
8.95M
    gx_color_index color;
8606
8.95M
    gx_device *trans_device;
8607
8.95M
    const gx_device *map_dev;
8608
8.95M
    const gx_cm_color_map_procs *procs;
8609
8610
    /* If trans device is set, we need to use its procs. */
8611
8.95M
    if (pgs->trans_device != NULL) {
8612
4.15M
        trans_device = pgs->trans_device;
8613
4.79M
    } else {
8614
4.79M
        trans_device = dev;
8615
4.79M
    }
8616
8.95M
    ncomps = trans_device->color_info.num_components;
8617
8618
    /* map to the color model */
8619
8.95M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8620
8.95M
    procs->map_gray(map_dev, gray, cm_comps);
8621
8622
8.95M
    nc = ncomps;
8623
8.95M
    if (device_encodes_tags(trans_device))
8624
0
        nc--;
8625
8.95M
    if (pdf14_state_opaque(trans_device, pgs)) {
8626
9.02M
        for (i = 0; i < nc; i++)
8627
4.51M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8628
4.50M
    } else {
8629
8.89M
        for (i = 0; i < nc; i++)
8630
4.44M
            cv[i] = frac2cv(cm_comps[i]);
8631
4.44M
    }
8632
    /* Copy tags untransformed. */
8633
8.95M
    if (nc < ncomps)
8634
0
        cv[nc] = dev->graphics_type_tag;
8635
8636
    /* If output device supports devn, we need to make sure we send it the
8637
       proper color type.  We now support Gray + spots as devn colors */
8638
8.95M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8639
375k
        for (i = 0; i < ncomps; i++)
8640
187k
            pdc->colors.devn.values[i] = cv[i];
8641
12.0M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8642
11.8M
            pdc->colors.devn.values[i] = 0;
8643
187k
        pdc->type = gx_dc_type_devn;
8644
8.76M
    } else {
8645
        /* encode as a color index */
8646
8.76M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8647
        /* check if the encoding was successful; we presume failure is rare */
8648
8.76M
        if (color != gx_no_color_index)
8649
8.76M
            color_set_pure(pdc, color);
8650
8.76M
    }
8651
8.95M
}
8652
8653
static  void
8654
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8655
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8656
4.17M
{
8657
4.17M
    int i, nc, ncomps;
8658
4.17M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8659
4.17M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8660
4.17M
    gx_color_index color;
8661
4.17M
    gx_device *trans_device;
8662
4.17M
    const gx_device *map_dev;
8663
4.17M
    const gx_cm_color_map_procs *procs;
8664
8665
    /* If trans device is set, we need to use its procs. */
8666
4.17M
    if (pgs->trans_device != NULL){
8667
628k
        trans_device = pgs->trans_device;
8668
3.55M
    } else {
8669
3.55M
        trans_device = dev;
8670
3.55M
    }
8671
4.17M
    ncomps = trans_device->color_info.num_components;
8672
    /* map to the color model */
8673
4.17M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8674
4.17M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8675
8676
4.17M
    nc = ncomps;
8677
4.17M
    if (device_encodes_tags(trans_device))
8678
0
        nc--;
8679
4.17M
    if (pdf14_state_opaque(trans_device, pgs)) {
8680
10.3M
        for (i = 0; i < nc; i++)
8681
7.79M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8682
2.59M
    } else {
8683
6.31M
        for (i = 0; i < nc; i++)
8684
4.73M
            cv[i] = frac2cv(cm_comps[i]);
8685
1.58M
    }
8686
    /* Copy tags untransformed. */
8687
4.17M
    if (nc < ncomps)
8688
0
        cv[nc] = dev->graphics_type_tag;
8689
8690
    /* If output device supports devn, we need to make sure we send it the
8691
       proper color type.  We now support RGB + spots as devn colors */
8692
4.17M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8693
12.3M
        for (i = 0; i < ncomps; i++)
8694
9.26M
            pdc->colors.devn.values[i] = cv[i];
8695
191M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8696
188M
            pdc->colors.devn.values[i] = 0;
8697
3.08M
        pdc->type = gx_dc_type_devn;
8698
3.08M
    } else {
8699
        /* encode as a color index */
8700
1.09M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8701
        /* check if the encoding was successful; we presume failure is rare */
8702
1.09M
        if (color != gx_no_color_index)
8703
1.09M
            color_set_pure(pdc, color);
8704
1.09M
    }
8705
4.17M
}
8706
8707
static  void
8708
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8709
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8710
     const gs_color_space *pcs)
8711
7.22M
{
8712
7.22M
    int i, nc, ncomps;
8713
7.22M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8714
7.22M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8715
7.22M
    gx_color_index color;
8716
7.22M
    gx_device *trans_device;
8717
7.22M
    const gx_device *map_dev;
8718
7.22M
    const gx_cm_color_map_procs *procs;
8719
8720
8721
    /* If trans device is set, we need to use its procs. */
8722
7.22M
    if (pgs->trans_device != NULL){
8723
4.56M
        trans_device = pgs->trans_device;
8724
4.56M
    } else {
8725
2.66M
        trans_device = dev;
8726
2.66M
    }
8727
7.22M
    ncomps = trans_device->color_info.num_components;
8728
8729
    /* Map to the color model. Transfer function is only used
8730
       if we are drawing with an opaque color. */
8731
7.22M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8732
7.22M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8733
8734
7.22M
    nc = ncomps;
8735
7.22M
    if (device_encodes_tags(trans_device))
8736
0
        nc--;
8737
7.22M
    if (pdf14_state_opaque(trans_device, pgs)) {
8738
28.8M
        for (i = 0; i < nc; i++)
8739
23.0M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8740
5.76M
    } else {
8741
7.26M
        for (i = 0; i < nc; i++)
8742
5.80M
            cv[i] = frac2cv(cm_comps[i]);
8743
1.45M
    }
8744
    /* Copy tags untransformed. */
8745
7.22M
    if (nc < ncomps)
8746
0
        cv[nc] = dev->graphics_type_tag;
8747
8748
    /* if output device supports devn, we need to make sure we send it the
8749
       proper color type */
8750
7.22M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8751
15.0M
        for (i = 0; i < ncomps; i++)
8752
12.0M
            pdc->colors.devn.values[i] = cv[i];
8753
183M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8754
180M
            pdc->colors.devn.values[i] = 0;
8755
3.01M
        pdc->type = gx_dc_type_devn;
8756
4.20M
    } else {
8757
        /* encode as a color index */
8758
4.20M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8759
        /* check if the encoding was successful; we presume failure is rare */
8760
4.20M
        if (color != gx_no_color_index)
8761
4.20M
            color_set_pure(pdc, color);
8762
4.20M
    }
8763
7.22M
}
8764
8765
static int
8766
pdf14_get_num_spots(gx_device * dev)
8767
327k
{
8768
327k
    cmm_dev_profile_t *dev_profile;
8769
327k
    cmm_profile_t *icc_profile;
8770
327k
    gsicc_rendering_param_t render_cond;
8771
8772
327k
    dev_proc(dev, get_profile)(dev, &dev_profile);
8773
327k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8774
327k
        &render_cond);
8775
327k
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8776
327k
}
8777
8778
static  void
8779
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8780
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8781
1.49k
{
8782
1.49k
    int i, nc, ncomps = dev->color_info.num_components;
8783
1.49k
    int num_spots = pdf14_get_num_spots(dev);
8784
1.49k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8785
1.49k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8786
1.49k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8787
1.49k
    gx_color_index color;
8788
1.49k
    int n = 0;
8789
8790
1.49k
    nc = ncomps;
8791
1.49k
    if (device_encodes_tags(dev))
8792
0
        nc--;
8793
8794
1.49k
    n = additive ? nc - num_spots : 0;
8795
1.49k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8796
0
        frac comp_value = all;
8797
8798
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8799
0
            cm_comps[i] = comp_value;
8800
        /*
8801
         * Invert the photometric interpretation for additive
8802
         * color spaces because separations are always subtractive.
8803
         */
8804
0
        if (additive)
8805
0
            comp_value = frac_1 - comp_value;
8806
        /* Use the "all" value for all components */
8807
0
        for (; i >= 0; i--)
8808
0
            cm_comps[i] = comp_value;
8809
1.49k
    } else {
8810
1.49k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8811
8812
1.49k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8813
0
            color_set_null(pdc);
8814
0
            return;
8815
0
        }
8816
8817
        /* map to the color model */
8818
2.98k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8819
1.49k
            comp_value[i] = all;
8820
1.49k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8821
1.49k
    }
8822
8823
    /* apply the transfer function(s); convert to color values */
8824
4.51k
    for (i = 0; i < n; i++)
8825
3.02k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8826
4.43k
    for (; i < nc; i++)
8827
2.94k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8828
8829
    /* Copy tags untransformed. */
8830
1.49k
    if (nc < ncomps)
8831
0
        cv[nc] = dev->graphics_type_tag;
8832
8833
    /* if output device supports devn, we need to make sure we send it the
8834
       proper color type */
8835
1.49k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8836
7.46k
        for (i = 0; i < ncomps; i++)
8837
5.96k
            pdc->colors.devn.values[i] = cv[i];
8838
91.0k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8839
89.5k
            pdc->colors.devn.values[i] = 0;
8840
1.49k
        pdc->type = gx_dc_type_devn;
8841
1.49k
    } else {
8842
        /* encode as a color index */
8843
0
        color = dev_proc(dev, encode_color)(dev, cv);
8844
        /* check if the encoding was successful; we presume failure is rare */
8845
0
        if (color != gx_no_color_index)
8846
0
            color_set_pure(pdc, color);
8847
0
    }
8848
1.49k
}
8849
8850
static  void
8851
pdf14_cmap_devicen_direct(const frac * pcc,
8852
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8853
    gs_color_select_t select, const gs_color_space *pcs)
8854
325k
{
8855
325k
    int i, nc, ncomps = dev->color_info.num_components;
8856
325k
    int num_spots = pdf14_get_num_spots(dev);
8857
325k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8858
325k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8859
325k
    gx_color_index color;
8860
325k
    gx_device *trans_device;
8861
325k
    int num_add_colorants = 0;
8862
8863
     /*  We may be coming from the clist writer which often forwards us the
8864
         target device. If this occurs we actually need to get to the color
8865
         space defined by the transparency group and we use the operators
8866
         defined by the transparency device to do the job.
8867
       */
8868
325k
    if (pgs->trans_device != NULL){
8869
325k
        trans_device = pgs->trans_device;
8870
325k
    } else {
8871
0
        trans_device = dev;
8872
0
    }
8873
325k
    ncomps = trans_device->color_info.num_components;
8874
325k
    nc = ncomps;
8875
325k
    if (device_encodes_tags(trans_device))
8876
0
        nc--;
8877
8878
325k
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8879
0
        num_add_colorants = nc - num_spots;
8880
8881
    /* map to the color model */
8882
325k
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8883
8884
    /* apply the transfer function(s); convert to color values */
8885
    /* The additive ones (if there are any) need to be inverted. */
8886
325k
    for (i = 0; i < num_add_colorants; i++)
8887
325k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8888
1.62M
    for (; i < nc; i++)
8889
1.30M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8890
    /* Copy tags untransformed. */
8891
325k
    if (nc < ncomps)
8892
0
        cv[nc] = dev->graphics_type_tag;
8893
8894
    /* if output device supports devn, we need to make sure we send it the
8895
       proper color type */
8896
325k
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8897
16.7k
        for (i = 0; i < ncomps; i++)
8898
13.3k
            pdc->colors.devn.values[i] = cv[i];
8899
203k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8900
200k
            pdc->colors.devn.values[i] = 0;
8901
3.34k
        pdc->type = gx_dc_type_devn;
8902
322k
    } else {
8903
    /* encode as a color index */
8904
322k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8905
        /* check if the encoding was successful; we presume failure is rare */
8906
322k
        if (color != gx_no_color_index)
8907
322k
            color_set_pure(pdc, color);
8908
322k
    }
8909
325k
}
8910
8911
static  bool
8912
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8913
63.9k
{
8914
63.9k
    return false;
8915
63.9k
}
8916
8917
static  const gx_color_map_procs *
8918
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8919
1.67M
{
8920
    /* The pdf14 marking device itself is always continuous tone. */
8921
1.67M
    return &pdf14_cmap_many;
8922
1.67M
}
8923
8924
static int
8925
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8926
                  void *data, int size)
8927
80.3M
{
8928
80.3M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8929
8930
80.3M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8931
910k
        return 1;
8932
79.4M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8933
7.89k
        return 1;
8934
79.4M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8935
957
        if (data != NULL && size == sizeof(gx_device *))
8936
319
            *(gx_device **)data = pdev;
8937
957
        return 1;
8938
957
    }
8939
79.4M
    if (dev_spec_op == gxdso_device_child) {
8940
2.58k
        pdf14_device *dev = (pdf14_device *)pdev;
8941
2.58k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8942
2.58k
        if (d->target == pdev) {
8943
2.58k
            d->target = dev->target;
8944
2.58k
            return 1;
8945
2.58k
        }
8946
2.58k
    }
8947
79.4M
    if (dev_spec_op == gxdso_supports_devn
8948
42.0M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8949
37.3M
        cmm_dev_profile_t *dev_profile;
8950
37.3M
        int code;
8951
37.3M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8952
37.3M
        if (code == 0) {
8953
37.3M
            return dev_profile->supports_devn;
8954
37.3M
        } else {
8955
0
            return 0;
8956
0
        }
8957
37.3M
    }
8958
42.0M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8959
346k
        pdf14_device* dev = (pdf14_device*)pdev;
8960
8961
346k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8962
346k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8963
161k
            return 1;
8964
185k
        return 0;
8965
346k
    }
8966
41.6M
    if (dev_spec_op == gxdso_is_encoding_direct)
8967
1.49M
        return 1;
8968
8969
    /* We don't want to pass on these spec_ops either, because the child might respond
8970
     * with an inappropriate response when the PDF14 device is active. For example; the
8971
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8972
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8973
     */
8974
40.1M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8975
359k
        return 0;
8976
39.8M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8977
1.17M
        return 0;
8978
38.6M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8979
7.87k
        return 0;
8980
38.6M
    if(dev_spec_op == gxdso_supports_hlcolor)
8981
917
        return 0;
8982
38.6M
    if(dev_spec_op == gxdso_pattern_can_accum)
8983
101k
        return 0;
8984
38.5M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8985
1.51k
        return 0;
8986
38.5M
    if (dev_spec_op == gxdso_overprint_active) {
8987
3.50M
        if (p14dev->pclist_device != NULL) {
8988
3.49M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8989
3.49M
        } else {
8990
10.1k
            return p14dev->overprint || p14dev->stroke_overprint;
8991
10.1k
        }
8992
3.50M
    }
8993
8994
    /* These should be coming only from the abuf device
8995
       during fill-stroke operation. Any other use will
8996
       result in bad things. */
8997
35.0M
    if (dev_spec_op == gxdso_abuf_optrans)
8998
0
    {
8999
0
        int ret = p14dev->op_state;
9000
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
9001
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
9002
0
        const gs_gstate* cpgs = state_data->pgs;
9003
0
        union {
9004
0
            const gs_gstate* cpgs;
9005
0
            gs_gstate* pgs;
9006
0
        } const_breaker;
9007
0
        gs_gstate* pgs;
9008
0
        int code = 0;
9009
0
        int code1 = 0;
9010
9011
        /* A compile time assert to check our storage types are appropriately sized. */
9012
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9013
9014
        /* I don't really like this, but there is no easy way around it. The device
9015
           in the pgs needs to be the pdf14 device to ensure that the compositor
9016
           actions occur with the gs_transparency calls. We have to call at that
9017
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9018
           operations are invoked. We could change the gs_trans calls to take a
9019
           device to avoid this dance but that changes the device procs. */
9020
0
        gx_device *curr_dev;
9021
9022
0
        const_breaker.cpgs = cpgs;
9023
0
        pgs = const_breaker.pgs;
9024
0
        curr_dev = pgs->device;
9025
0
        pgs->device = pdev;
9026
9027
0
        switch (state_data->op_trans) {
9028
9029
0
            case OP_FS_TRANS_PREFILL:
9030
0
                pdf14_abuf->orig_state = p14dev->op_state;
9031
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9032
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9033
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9034
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9035
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9036
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9037
0
                    pdf14_abuf->group_needed = false;
9038
0
                else
9039
0
                    pdf14_abuf->group_needed = true;
9040
9041
0
                if (pdf14_abuf->group_needed) {
9042
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9043
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9044
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9045
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9046
0
                        state_data->alpha_buf_path_scale);
9047
0
                    if (code < 0)
9048
0
                        goto cleanup;
9049
0
                    if (pdf14_abuf->path_empty)
9050
0
                        pdf14_abuf->group_needed = 0;
9051
0
                }
9052
0
                code = gs_update_trans_marking_params(pgs);
9053
0
                break;
9054
9055
0
            case OP_FS_TRANS_PRESTROKE:
9056
0
                if (pdf14_abuf->group_needed) {
9057
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9058
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9059
0
                }
9060
0
                code = gs_update_trans_marking_params(pgs);
9061
0
                break;
9062
9063
0
            case OP_FS_TRANS_POSTSTROKE:
9064
0
                if (pdf14_abuf->group_needed) {
9065
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9066
0
                                                        pdf14_abuf->op_ca_eq_CA);
9067
0
                }
9068
0
                if (code >= 0)
9069
0
                    code = gs_update_trans_marking_params(pgs);
9070
9071
                /* fallthrough */
9072
9073
0
            case OP_FS_TRANS_CLEANUP:
9074
0
cleanup:
9075
0
                if (pdf14_abuf->group_needed) {
9076
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9077
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9078
0
                    if (code1 < 0)
9079
0
                        code = gs_note_error(gs_error_Fatal);
9080
0
                }
9081
0
                break;
9082
0
        }
9083
0
        pgs->device = curr_dev;
9084
9085
0
        return (code < 0) ? code : ret;
9086
0
    }
9087
9088
35.0M
    if (dev_spec_op == gxdso_in_smask_construction)
9089
3.67M
        return p14dev->in_smask_construction > 0;
9090
31.3M
    if (dev_spec_op == gxdso_in_smask)
9091
21.0M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9092
10.3M
    if (dev_spec_op == gxdso_replacecolor) {
9093
10.1M
        gx_device *tdev = p14dev->target;
9094
10.1M
        cmm_dev_profile_t *tdev_profile;
9095
10.1M
        int code;
9096
9097
         /* If in a softmask or softmask construction do not allow
9098
           replacement. */
9099
10.1M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9100
233k
            return 0;
9101
9102
        /* If the target CS is different than the pdf14 profile add this information
9103
           for the target device that will be handling the replacement. While not
9104
           perfect this at least lets you do the replacehment and have some information
9105
           about what the situation is. */
9106
9.89M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9107
9.89M
        if (code != 0)
9108
0
            return 0;
9109
9110
9.89M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9111
9.89M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9112
4.38M
            color_replace_t* replace_data = (color_replace_t*)data;
9113
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9114
               color remap operation. */
9115
4.38M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9116
4.38M
        }
9117
9118
        /* Pass on to target device */
9119
9.89M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9120
9.89M
    }
9121
203k
    if (dev_spec_op == gxdso_device_insert_child) {
9122
158
        gx_device *tdev = p14dev->target;
9123
158
        p14dev->target = (gx_device *)data;
9124
158
        rc_increment(p14dev->target);
9125
158
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9126
158
        return 0;
9127
158
    }
9128
203k
    if (dev_spec_op == gxdso_interpolate_threshold)
9129
5.47k
        return p14dev->interpolate_threshold;
9130
9131
197k
    if (dev_spec_op == gxdso_overprintsim_state) {
9132
5.45k
        unsigned char *data_uchar = (unsigned char *) data;
9133
5.45k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9134
5.45k
        if (p14dev->ctx != NULL)
9135
16
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9136
5.44k
        else
9137
5.44k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9138
5.45k
        return 1;
9139
5.45k
    }
9140
9141
192k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9142
197k
}
9143
9144
/* Needed to set color monitoring in the target device's profile */
9145
int
9146
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9147
0
{
9148
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9149
0
    gx_device *targ = p14dev->target;
9150
0
    cmm_dev_profile_t *dev_profile;
9151
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9152
9153
0
    if (code == 0)
9154
0
        dev_profile->pageneutralcolor = monitoring;
9155
0
    return code;
9156
0
}
9157
9158
static int
9159
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9160
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9161
1.07M
{
9162
1.07M
    pdf14_device dev_proto;
9163
1.07M
    pdf14_device * p14dev;
9164
1.07M
    int code;
9165
1.07M
    bool has_tags;
9166
1.07M
    cmm_profile_t *icc_profile;
9167
1.07M
    gsicc_rendering_param_t render_cond;
9168
1.07M
    cmm_dev_profile_t *dev_profile;
9169
1.07M
    uchar k;
9170
1.07M
    int max_bitmap;
9171
1.07M
    bool use_pdf14_accum = false;
9172
1.07M
    bool deep;
9173
9174
    /* Guard against later seg faults, this should not be possible */
9175
1.07M
    if (target == NULL)
9176
0
        return gs_throw_code(gs_error_Fatal);
9177
9178
1.07M
    has_tags = device_encodes_tags(target);
9179
1.07M
    deep = device_is_deep(target);
9180
1.07M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9181
1.07M
                                 target->space_params.MaxBitmap;
9182
    /* If the device is not a printer class device, it won't support saved-pages */
9183
    /* and so we may need to make a clist device in order to prevent very large  */
9184
    /* or high resolution pages from having allocation problems.                 */
9185
    /* We use MaxBitmap to decide when a clist is needed.*/
9186
1.07M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9187
5.56k
        gx_device_is_pattern_clist(target) == 0 &&
9188
5.56k
        gx_device_is_pattern_accum(target) == 0 &&
9189
4.06k
        gs_device_is_memory(target) == 0) {
9190
9191
4.06k
        uint32_t pdf14_trans_buffer_size =
9192
4.06k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9193
4.06k
                                         target->color_info.num_components,
9194
4.06k
                                         deep ? 16 : 8) >> 3);
9195
9196
4.06k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9197
4.06k
                pdf14_trans_buffer_size *= target->height;
9198
0
        else
9199
0
                max_bitmap = 0;     /* Force decision to clist */
9200
4.06k
        if (pdf14_trans_buffer_size > max_bitmap)
9201
3.80k
            use_pdf14_accum = true;
9202
4.06k
    }
9203
1.07M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9204
1.07M
    if (code < 0)
9205
0
        return code;
9206
1.07M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9207
1.07M
                          &render_cond);
9208
1.07M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9209
9210
    /* Get the proto from which to copy the device. This will always
9211
     * ignore tags! */
9212
1.07M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9213
1.07M
                                  pdf14pct, use_pdf14_accum);
9214
1.07M
    if (code < 0)
9215
0
        return code;
9216
1.07M
    code = gs_copydevice((gx_device **) &p14dev,
9217
1.07M
                         (const gx_device *) &dev_proto, mem);
9218
1.07M
    if (code < 0)
9219
0
        return code;
9220
9221
1.07M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9222
9223
    /* Copying the params across will add tags to the colorinfo as required. */
9224
1.07M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9225
1.07M
    if (code < 0)
9226
0
        return code;
9227
9228
1.07M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9229
1.07M
    p14dev->pad = target->pad;
9230
1.07M
    p14dev->log2_align_mod = target->log2_align_mod;
9231
1.07M
    if (pdf14pct->params.overprint_sim_push) {
9232
0
        p14dev->color_info.num_components = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9233
0
        if (target->num_planar_planes == 0) {
9234
0
            p14dev->num_planar_planes = 0;
9235
0
        } else {
9236
0
            p14dev->num_planar_planes = p14dev->color_info.num_components;
9237
0
        }
9238
1.07M
    } else {
9239
1.07M
        p14dev->color_info.num_components = target->color_info.num_components;
9240
1.07M
        p14dev->num_planar_planes = target->num_planar_planes;
9241
1.07M
    }
9242
1.07M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9243
9244
1.07M
    p14dev->alpha = 1.0;
9245
1.07M
    p14dev->shape = 1.0;
9246
1.07M
    p14dev->opacity = 1.0;
9247
1.07M
    p14dev->fillconstantalpha = 1.0;
9248
1.07M
    p14dev->strokeconstantalpha = 1.0;
9249
9250
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9251
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9252
       do the mapping to the NCLR profile when the put_image occurs */
9253
1.07M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9254
1.07M
        icc_profile->data_cs == gsNCHANNEL) {
9255
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9256
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9257
0
            -1, "gs_pdf14_device_push");
9258
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9259
1.07M
    } else {
9260
        /* If the target profile was CIELAB (and we are not using a blend CS),
9261
           then overide with default RGB for proper blending.  During put_image
9262
           we will convert from RGB to CIELAB.  Need to check that we have a
9263
           default profile, which will not be the case if we are coming from the clist reader */
9264
1.07M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9265
0
            && pgs->icc_manager->default_rgb != NULL &&
9266
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9267
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9268
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9269
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9270
0
                -1, "gs_pdf14_device_push");
9271
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9272
0
        }
9273
1.07M
    }
9274
9275
1.07M
    if (pdf14pct->params.overprint_sim_push &&
9276
0
        pdf14pct->params.num_spot_colors_int > 0) {
9277
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9278
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9279
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9280
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9281
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9282
0
    }
9283
9284
    /* The number of color planes should not exceed that of the target.
9285
       Unless we are using a blend CS */
9286
1.07M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9287
1.07M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9288
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9289
1.07M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9290
76.9k
            p14dev->color_info.max_components = target->color_info.max_components;
9291
1.07M
    }
9292
1.07M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9293
    /* If we have a tag device then go ahead and do a special encoder
9294
       decoder for the pdf14 device to make sure we maintain this
9295
       information in the encoded color information.  We could use
9296
       the target device's methods but the PDF14 device has to maintain
9297
       8 bit color always and we could run into other issues if the number
9298
       of colorants became large.  If we need to do compressed color with
9299
       tags that will be a special project at that time */
9300
1.07M
    if (deep) {
9301
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9302
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9303
0
    }
9304
1.07M
    if (has_tags) {
9305
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9306
0
    }
9307
    /* if the device has separations already defined (by SeparationOrderNames) */
9308
    /* we need to copy them (allocating new names) so the colorants are in the */
9309
    /* same order as the target device.                                        */
9310
1.07M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9311
76.9k
        code = devn_copy_params(target, (gx_device *)p14dev);
9312
76.9k
        if (code < 0) {
9313
50
            *pdev = NULL;
9314
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9315
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9316
50
            return code;
9317
50
        }
9318
76.9k
    }
9319
    /* by definition pdf14_encode _is_ standard */
9320
1.07M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9321
1.07M
    gx_device_fill_in_procs((gx_device *)p14dev);
9322
1.07M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9323
1.07M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9324
1.07M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9325
9326
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9327
3.64M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9328
2.57M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9329
2.57M
        p14dev->color_info.comp_shift[k] =
9330
2.57M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9331
2.57M
    }
9332
1.07M
    if (use_pdf14_accum) {
9333
        /* we will disable this device later, but we don't want to allocate large buffers */
9334
3.80k
        p14dev->width = 1;
9335
3.80k
        p14dev->height = 1;
9336
3.80k
    }
9337
9338
1.07M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9339
1.07M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9340
1.07M
    *pdev = (gx_device *) p14dev;
9341
1.07M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9342
1.07M
    p14dev->color_model_stack = NULL;
9343
9344
    /* In case we have alphabits set */
9345
1.07M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9346
9347
1.07M
    if (pdf14pct->params.is_pattern) {
9348
6.56k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9349
6.56k
        if (code < 0) {
9350
0
            *pdev = NULL;
9351
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9352
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9353
0
            return code;
9354
0
        }
9355
6.56k
    }
9356
9357
    /* We should never go into this when using a blend color space */
9358
1.07M
    if (use_pdf14_accum) {
9359
3.80k
        const gx_device_pdf14_accum *accum_proto = NULL;
9360
3.80k
        gx_device *new_target = NULL;
9361
3.80k
        gx_device_color pdcolor;
9362
3.80k
        frac pconc_white = frac_1;
9363
3.80k
        bool UsePlanarBuffer = false;
9364
9365
3.80k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9366
9367
        /* get the prototype for the accumulator device based on colorspace */
9368
3.80k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9369
835
            case 1:
9370
835
                accum_proto = &pdf14_accum_Gray;
9371
835
                break;
9372
2.96k
            case 3:
9373
2.96k
                accum_proto = &pdf14_accum_RGB;
9374
2.96k
                break;
9375
0
            case 4:
9376
0
                accum_proto = &pdf14_accum_CMYK;
9377
0
                break;
9378
0
            default:
9379
0
                accum_proto = &pdf14_accum_CMYKspot;
9380
0
                UsePlanarBuffer = true;
9381
3.80k
        }
9382
3.80k
        if (accum_proto == NULL ||
9383
3.80k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9384
0
            goto no_clist_accum;
9385
9386
3.80k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9387
        /* Fill in values from the target device before opening */
9388
3.80k
        new_target->color_info = p14dev->color_info;
9389
3.80k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9390
3.80k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9391
3.80k
        set_linear_color_bits_mask_shift(new_target);
9392
3.80k
        gs_pdf14_device_copy_params(new_target, target);
9393
3.80k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9394
3.80k
        gx_device_fill_in_procs(new_target);
9395
9396
3.80k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9397
3.80k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9398
3.80k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9399
9400
        /* This is used to mark the various internal subclass devices as having already
9401
         * been pushed, so that opening the device won't result in us trying to push
9402
         * them again, which leads to trouble.
9403
         */
9404
3.80k
        code = mark_internal_subclass_devices(new_target);
9405
3.80k
        if (code < 0)
9406
0
            return code;
9407
9408
        /* if the device has separations already defined (by SeparationOrderNames) */
9409
        /* we need to copy them (allocating new names) so the colorants are in the */
9410
        /* same order as the target device.                                        */
9411
3.80k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9412
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9413
0
            if (code < 0)
9414
0
                return code;
9415
0
        }
9416
        /* UsePlanarBuffer is true in case this is CMYKspot */
9417
3.80k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9418
3.80k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9419
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9420
0
            goto no_clist_accum;
9421
0
        }
9422
        /* Do the initial fillpage into the pdf14-accum device we just created */
9423
3.80k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9424
3.80k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9425
3.80k
                                            &pconc_white,
9426
3.80k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9427
3.80k
                                            dev_profile)) < 0)
9428
0
            goto no_clist_accum;
9429
9430
3.80k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9431
3.80k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9432
3.80k
        if (code < 0)
9433
0
            goto no_clist_accum;
9434
9435
3.80k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9436
3.80k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9437
3.80k
    }
9438
1.07M
    return code;
9439
9440
0
no_clist_accum:
9441
        /* FIXME: We allocated a really small p14dev, but that won't work */
9442
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9443
1.07M
}
9444
9445
/*
9446
 * In a modest violation of good coding practice, the gs_composite_common
9447
 * fields are "known" to be simple (contain no pointers to garbage
9448
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9449
 * to be simple, so we just create a trivial structure descriptor for the
9450
 * entire gs_pdf14trans_s structure.
9451
 */
9452
#define private_st_gs_pdf14trans_t()\
9453
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9454
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9455
9456
/* GC descriptor for gs_pdf14trans_t */
9457
private_st_gs_pdf14trans_t();
9458
9459
/*
9460
 * Check for equality of two PDF 1.4 transparency compositor objects.
9461
 *
9462
 * We are currently always indicating that PDF 1.4 transparency compositors are
9463
 * equal.  Two transparency compositors may have teh same data but still
9464
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9465
 * operations in a row mean that we are creating a group inside of a group.
9466
 */
9467
static  bool
9468
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9469
0
{
9470
0
    return false;
9471
0
}
9472
9473
#ifdef DEBUG
9474
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9475
#endif
9476
9477
#define put_value(dp, value)\
9478
6.69M
    BEGIN\
9479
6.69M
        memcpy(dp, &value, sizeof(value));\
9480
6.69M
        dp += sizeof(value);\
9481
6.69M
    END
9482
9483
static inline int
9484
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9485
825k
{
9486
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9487
       because clist writer may skip this command for some bands.
9488
       For a better result we need individual CTM for each band.
9489
     */
9490
825k
    byte *pbuf = *ppbuf;
9491
825k
    int len, code;
9492
9493
825k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9494
825k
    pbuf--; /* For cmd_write_ctm. */
9495
825k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9496
825k
    if (code < 0)
9497
0
        return code;
9498
825k
    pbuf += len + 1;
9499
825k
    *ppbuf = pbuf;
9500
825k
    return 0;
9501
825k
}
9502
9503
/*
9504
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9505
 * list device. This is also where we update the pdf14_needed. When set the clist
9506
 * painting procs will update the trans_bbox state for bands that are affected.
9507
*/
9508
static  int
9509
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9510
                   gx_device_clist_writer *cdev)
9511
1.90M
{
9512
1.90M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9513
1.90M
    int need, avail = *psize;
9514
1.90M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9515
        to fit the data written below. We don't implement a dynamic check for
9516
        the buffer owerflow, assuming that the consistency is verified in the
9517
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9518
1.90M
    byte * pbuf = buf;
9519
1.90M
    int opcode = pparams->pdf14_op;
9520
1.90M
    int mask_size = 0;
9521
1.90M
    uint mask_id = 0;
9522
1.90M
    int code;
9523
1.90M
    bool found_icc;
9524
1.90M
    int64_t hashcode = 0;
9525
1.90M
    cmm_profile_t *icc_profile;
9526
1.90M
    gsicc_rendering_param_t render_cond;
9527
1.90M
    cmm_dev_profile_t *dev_profile;
9528
    /* We maintain and update working copies until we actually write the clist */
9529
1.90M
    int pdf14_needed = cdev->pdf14_needed;
9530
1.90M
    int trans_group_level = cdev->pdf14_trans_group_level;
9531
1.90M
    int smask_level = cdev->pdf14_smask_level;
9532
1.90M
    bool deep = device_is_deep((gx_device *)cdev);
9533
9534
1.90M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9535
1.90M
                                                     &dev_profile);
9536
1.90M
    if (code < 0)
9537
0
        return code;
9538
1.90M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9539
1.90M
                          &render_cond);
9540
1.90M
    *pbuf++ = opcode;     /* 1 byte */
9541
1.90M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9542
1
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9543
9544
1.90M
    switch (opcode) {
9545
0
        default:      /* Should not occur. */
9546
0
            break;
9547
20.8k
        case PDF14_PUSH_DEVICE:
9548
20.8k
            trans_group_level = 0;
9549
20.8k
            cdev->pdf14_smask_level = 0;
9550
20.8k
            cdev->page_pdf14_needed = false;
9551
20.8k
            put_value(pbuf, pparams->num_spot_colors);
9552
20.8k
            put_value(pbuf, pparams->num_spot_colors_int);
9553
20.8k
            put_value(pbuf, pparams->overprint_sim_push);
9554
20.8k
            put_value(pbuf, pparams->is_pattern);
9555
9556
            /* If we happen to be going to a color space like CIELAB then
9557
               we are going to do our blending in default RGB and convert
9558
               to CIELAB at the end.  To do this, we need to store the
9559
               default RGB profile in the clist so that we can grab it
9560
               later on during the clist read back and put image command */
9561
20.8k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9562
                /* Get the default RGB profile.  Set the device hash code
9563
                   so that we can extract it during the put_image operation. */
9564
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9565
0
                found_icc =
9566
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9567
0
                if (!found_icc) {
9568
                    /* Add it to the table */
9569
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9570
0
                                       pparams->iccprofile);
9571
0
                }
9572
0
            }
9573
20.8k
            break;
9574
20.0k
        case PDF14_POP_DEVICE:
9575
20.0k
            pdf14_needed = false;   /* reset pdf14_needed */
9576
20.0k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9577
20.0k
            smask_level = 0;
9578
20.0k
            put_value(pbuf, pparams->is_pattern);
9579
20.0k
            break;
9580
450k
        case PDF14_END_TRANS_GROUP:
9581
455k
        case PDF14_END_TRANS_TEXT_GROUP:
9582
455k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9583
455k
            if (smask_level == 0 && trans_group_level == 0)
9584
26.3k
                pdf14_needed = cdev->page_pdf14_needed;
9585
455k
            break;      /* No data */
9586
7.42k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9587
456k
        case PDF14_BEGIN_TRANS_GROUP:
9588
456k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9589
456k
            trans_group_level++;
9590
456k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9591
456k
            if (code < 0)
9592
0
                return code;
9593
456k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9594
456k
            *pbuf++ = pparams->blend_mode;
9595
456k
            *pbuf++ = pparams->group_color_type;
9596
456k
            *pbuf++ = pparams->page_group;
9597
456k
            put_value(pbuf, pparams->group_color_numcomps);
9598
456k
            put_value(pbuf, pparams->opacity);
9599
456k
            put_value(pbuf, pparams->shape);
9600
456k
            put_value(pbuf, pparams->bbox);
9601
456k
            put_value(pbuf, pparams->shade_group);
9602
456k
            put_value(pbuf, pparams->text_group);
9603
456k
            mask_id = pparams->mask_id;
9604
456k
            put_value(pbuf, mask_id);
9605
            /* Color space information maybe ICC based
9606
               in this case we need to store the ICC
9607
               profile or the ID if it is cached already */
9608
456k
            if (pparams->group_color_type == ICC) {
9609
                /* Check if it is already in the ICC clist table */
9610
11.6k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9611
11.6k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9612
11.6k
                if (!found_icc) {
9613
                    /* Add it to the table */
9614
3.94k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9615
3.94k
                    put_value(pbuf, hashcode);
9616
7.73k
                } else {
9617
                    /* It will be in the clist. Just write out the hashcode */
9618
7.73k
                    put_value(pbuf, hashcode);
9619
7.73k
                }
9620
444k
            } else {
9621
444k
                put_value(pbuf, hashcode);
9622
444k
            }
9623
456k
            break;
9624
369k
        case PDF14_BEGIN_TRANS_MASK:
9625
369k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9626
315k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9627
315k
                smask_level++;
9628
315k
            }
9629
369k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9630
369k
            if (code < 0)
9631
0
                return code;
9632
369k
            put_value(pbuf, pparams->subtype);
9633
369k
            *pbuf++ = pparams->group_color_type;
9634
369k
            put_value(pbuf, pparams->group_color_numcomps);
9635
369k
            *pbuf++ = pparams->replacing;
9636
369k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9637
369k
            *pbuf++ = pparams->Background_components;
9638
369k
            *pbuf++ = pparams->Matte_components;
9639
369k
            put_value(pbuf, pparams->bbox);
9640
369k
            mask_id = pparams->mask_id;
9641
369k
            put_value(pbuf, mask_id);
9642
369k
            if (pparams->Background_components) {
9643
1.11k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9644
9645
1.11k
                memcpy(pbuf, pparams->Background, l);
9646
1.11k
                pbuf += l;
9647
1.11k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9648
1.11k
                pbuf += sizeof(pparams->GrayBackground);
9649
1.11k
            }
9650
369k
            if (pparams->Matte_components) {
9651
56
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9652
9653
56
                memcpy(pbuf, pparams->Matte, m);
9654
56
                pbuf += m;
9655
56
            }
9656
369k
            if (!pparams->function_is_identity)
9657
1.31k
                mask_size = (256+deep)<<deep;
9658
            /* Color space information may be ICC based
9659
               in this case we need to store the ICC
9660
               profile or the ID if it is cached already */
9661
369k
            if (pparams->group_color_type == ICC) {
9662
                /* Check if it is already in the ICC clist table */
9663
315k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9664
315k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9665
315k
                if (!found_icc) {
9666
                    /* Add it to the table */
9667
2.43k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9668
2.43k
                    put_value(pbuf, hashcode);
9669
312k
                } else {
9670
                    /* It will be in the clist. Just write out the hashcode */
9671
312k
                    put_value(pbuf, hashcode);
9672
312k
                }
9673
315k
            } else {
9674
54.4k
                put_value(pbuf, hashcode);
9675
54.4k
            }
9676
369k
            break;
9677
315k
        case PDF14_END_TRANS_MASK:
9678
315k
            smask_level--;
9679
315k
            if (smask_level == 0 && trans_group_level == 0)
9680
7.17k
                pdf14_needed = cdev->page_pdf14_needed;
9681
315k
            break;
9682
218k
        case PDF14_SET_BLEND_PARAMS:
9683
218k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9684
0
                pparams->shape != 1.0)
9685
218k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9686
0
            else if (smask_level == 0 && trans_group_level == 0)
9687
0
                pdf14_needed = false;   /* At page level, set back to false */
9688
218k
            if (smask_level == 0 && trans_group_level == 0)
9689
78.6k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9690
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9691
218k
            put_value(pbuf, pparams->changed);
9692
218k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9693
39.4k
                *pbuf++ = pparams->blend_mode;
9694
218k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9695
19.3k
                *pbuf++ = pparams->text_knockout;
9696
218k
            if (pparams->changed & PDF14_SET_AIS)
9697
218k
                put_value(pbuf, pparams->ais);
9698
218k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9699
218k
                put_value(pbuf, pparams->overprint);
9700
218k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9701
218k
                put_value(pbuf, pparams->stroke_overprint);
9702
218k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9703
218k
                put_value(pbuf, pparams->fillconstantalpha);
9704
218k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9705
218k
                put_value(pbuf, pparams->strokeconstantalpha);
9706
218k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9707
218k
                put_value(pbuf, pparams->op_fs_state);
9708
218k
            break;
9709
0
        case PDF14_PUSH_TRANS_STATE:
9710
0
            break;
9711
45.6k
        case PDF14_POP_TRANS_STATE:
9712
45.6k
            break;
9713
0
        case PDF14_PUSH_SMASK_COLOR:
9714
0
            return 0;   /* We really should never be here */
9715
0
            break;
9716
0
        case PDF14_POP_SMASK_COLOR:
9717
0
            return 0;   /* We really should never be here */
9718
0
            break;
9719
1.90M
    }
9720
9721
    /* check for fit */
9722
1.90M
    need = (pbuf - buf) + mask_size;
9723
1.90M
    *psize = need;
9724
1.90M
    if (need > avail) {
9725
284k
        if (avail)
9726
0
            return_error(gs_error_rangecheck);
9727
284k
        else
9728
284k
            return gs_error_rangecheck;
9729
284k
    }
9730
9731
    /* If we are writing more than the maximum ever expected,
9732
     * return a rangecheck error. Second check is for Coverity
9733
     */
9734
1.61M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9735
1.61M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9736
0
        return_error(gs_error_rangecheck);
9737
9738
    /* Copy our serialized data into the output buffer */
9739
1.61M
    memcpy(data, buf, need - mask_size);
9740
1.61M
    if (mask_size)  /* Include the transfer mask data if present */
9741
1.00k
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9742
1.61M
    if_debug3m('v', cdev->memory,
9743
1.61M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9744
1.61M
               pdf14_opcode_names[opcode], mask_id, need);
9745
1.61M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9746
1.61M
    cdev->pdf14_trans_group_level = trans_group_level;
9747
1.61M
    cdev->pdf14_smask_level = smask_level;
9748
1.61M
    return 0;
9749
1.61M
}
9750
9751
#undef put_value
9752
9753
/* Function prototypes */
9754
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9755
                const gs_pdf14trans_params_t * pparams,
9756
                gs_memory_t * mem );
9757
9758
#define read_value(dp, value)\
9759
122M
    BEGIN\
9760
122M
        memcpy(&value, dp, sizeof(value));\
9761
122M
        dp += sizeof(value);\
9762
122M
    END
9763
9764
/*
9765
 * Convert the string representation of the PDF 1.4 transparency parameter
9766
 * into the full compositor.
9767
 */
9768
static  int
9769
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9770
                                uint size, gs_memory_t * mem )
9771
37.1M
{
9772
37.1M
    gs_pdf14trans_params_t params = {0};
9773
37.1M
    const byte * start = data;
9774
37.1M
    int used, code = 0;
9775
37.1M
    bool deep;
9776
9777
37.1M
    if (size < 1)
9778
0
        return_error(gs_error_rangecheck);
9779
9780
    /* Read PDF 1.4 compositor data from the clist */
9781
37.1M
    params.pdf14_op = *data++;
9782
37.1M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9783
37.1M
               pdf14_opcode_names[params.pdf14_op], size);
9784
37.1M
    memset(&params.ctm, 0, sizeof(params.ctm));
9785
37.1M
    switch (params.pdf14_op) {
9786
0
        default:      /* Should not occur. */
9787
0
            break;
9788
1.68M
        case PDF14_PUSH_DEVICE:
9789
1.68M
            read_value(data, params.num_spot_colors);
9790
1.68M
            read_value(data, params.num_spot_colors_int);
9791
1.68M
            read_value(data, params.overprint_sim_push);
9792
1.68M
            read_value(data, params.is_pattern);
9793
1.68M
            break;
9794
0
        case PDF14_ABORT_DEVICE:
9795
0
            break;
9796
1.68M
        case PDF14_POP_DEVICE:
9797
1.68M
            read_value(data, params.is_pattern);
9798
1.68M
            break;
9799
2.07M
        case PDF14_END_TRANS_GROUP:
9800
2.57M
        case PDF14_END_TRANS_TEXT_GROUP:
9801
#ifdef DEBUG
9802
            code += 0; /* A good place for a breakpoint. */
9803
#endif
9804
2.57M
            break;      /* No data */
9805
0
        case PDF14_PUSH_TRANS_STATE:
9806
0
            break;
9807
3.26M
        case PDF14_POP_TRANS_STATE:
9808
3.26M
            break;
9809
660k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9810
2.58M
        case PDF14_BEGIN_TRANS_GROUP:
9811
            /*
9812
             * We are currently not using the bbox or the colorspace so they were
9813
             * not placed in the clist
9814
             */
9815
2.58M
            data = cmd_read_matrix(&params.ctm, data);
9816
2.58M
            params.Isolated = (*data) & 1;
9817
2.58M
            params.Knockout = (*data++ >> 1) & 1;
9818
2.58M
            params.blend_mode = *data++;
9819
2.58M
            params.group_color_type = *data++;  /* Trans group color */
9820
2.58M
            params.page_group = *data++;
9821
2.58M
            read_value(data,params.group_color_numcomps);  /* color group size */
9822
2.58M
            read_value(data, params.opacity);
9823
2.58M
            read_value(data, params.shape);
9824
2.58M
            read_value(data, params.bbox);
9825
2.58M
            read_value(data, params.shade_group);
9826
2.58M
            read_value(data, params.text_group);
9827
2.58M
            read_value(data, params.mask_id);
9828
2.58M
            read_value(data, params.icc_hash);
9829
2.58M
            break;
9830
4.87M
        case PDF14_BEGIN_TRANS_MASK:
9831
                /* This is the largest transparency parameter at this time (potentially
9832
                 * 1531 bytes in size if Background_components =
9833
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9834
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9835
                 *
9836
                 * NOTE:
9837
                 * The clist reader must be able to handle this sized device.
9838
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9839
                 * may also need to be changed correspondingly (defined in gstparam.h)
9840
                 * Also... if another compositor param should exceed this size, this
9841
                 * same condition applies.
9842
                 */
9843
4.87M
            data = cmd_read_matrix(&params.ctm, data);
9844
4.87M
            read_value(data, params.subtype);
9845
4.87M
            params.group_color_type = *data++;
9846
4.87M
            read_value(data, params.group_color_numcomps);
9847
4.87M
            params.replacing = *data++;
9848
4.87M
            params.function_is_identity = *data & 1;
9849
4.87M
            deep = (*data++)>>1;
9850
4.87M
            params.Background_components = *data++;
9851
4.87M
            params.Matte_components = *data++;
9852
4.87M
            read_value(data, params.bbox);
9853
4.87M
            read_value(data, params.mask_id);
9854
4.87M
            if (params.Background_components) {
9855
87.1k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9856
9857
87.1k
                memcpy(params.Background, data, l);
9858
87.1k
                data += l;
9859
87.1k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9860
87.1k
                data += sizeof(params.GrayBackground);
9861
87.1k
            }
9862
4.87M
            if (params.Matte_components) {
9863
4.23k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9864
9865
4.23k
                memcpy(params.Matte, data, m);
9866
4.23k
                data += m;
9867
4.23k
            }
9868
4.87M
            read_value(data, params.icc_hash);
9869
4.87M
            if (params.function_is_identity) {
9870
4.84M
                int i;
9871
9872
4.84M
                if (deep) {
9873
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9874
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9875
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9876
4.84M
                } else {
9877
1.24G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9878
1.23G
                        params.transfer_fn[i] = (byte)floor(i *
9879
1.23G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9880
1.23G
                    }
9881
4.84M
                }
9882
4.84M
            } else {
9883
34.1k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9884
34.1k
                data += (256+deep)<<deep;
9885
34.1k
            }
9886
4.87M
            break;
9887
465k
        case PDF14_END_TRANS_MASK:
9888
465k
            break;
9889
0
        case PDF14_PUSH_SMASK_COLOR:
9890
0
            return 0;
9891
0
            break;
9892
0
        case PDF14_POP_SMASK_COLOR:
9893
0
            return 0;
9894
0
            break;
9895
19.9M
        case PDF14_SET_BLEND_PARAMS:
9896
19.9M
            read_value(data, params.changed);
9897
19.9M
            if (params.changed & PDF14_SET_BLEND_MODE)
9898
3.65M
                params.blend_mode = *data++;
9899
19.9M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9900
1.63M
                params.text_knockout = *data++;
9901
19.9M
            if (params.changed & PDF14_SET_AIS)
9902
19.9M
                read_value(data, params.ais);
9903
19.9M
            if (params.changed & PDF14_SET_OVERPRINT)
9904
19.9M
                read_value(data, params.overprint);
9905
19.9M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9906
19.9M
                read_value(data, params.stroke_overprint);
9907
19.9M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9908
19.9M
                read_value(data, params.fillconstantalpha);
9909
19.9M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9910
19.9M
                read_value(data, params.strokeconstantalpha);
9911
19.9M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9912
19.9M
                read_value(data, params.op_fs_state);
9913
19.9M
            break;
9914
37.1M
    }
9915
37.1M
    code = gs_create_pdf14trans(ppct, &params, mem);
9916
37.1M
    if (code < 0)
9917
0
        return code;
9918
37.1M
    used = data - start;
9919
37.1M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9920
9921
    /* If we read more than the maximum expected, return a rangecheck error */
9922
37.1M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9923
0
        return_error(gs_error_rangecheck);
9924
37.1M
    else
9925
37.1M
        return used;
9926
37.1M
}
9927
9928
/*
9929
 * Adjust the compositor's CTM.
9930
 */
9931
static int
9932
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9933
22.5M
{
9934
22.5M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9935
22.5M
    gs_matrix mat = pct->params.ctm;
9936
9937
22.5M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9938
22.5M
               mat.xx, mat.xy, mat.yx, mat.yy,
9939
22.5M
               mat.tx, mat.ty);
9940
22.5M
    mat.tx -= x0;
9941
22.5M
    mat.ty -= y0;
9942
22.5M
    gs_gstate_setmatrix(pgs, &mat);
9943
22.5M
    return 0;
9944
22.5M
}
9945
9946
/*
9947
 * Create a PDF 1.4 transparency compositor.
9948
 *
9949
 * Note that this routine will be called only if the device is not already
9950
 * a PDF 1.4 transparency compositor.
9951
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9952
 */
9953
static  int
9954
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9955
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9956
    gs_memory_t * mem)
9957
1.09M
{
9958
1.09M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9959
1.09M
    int code = 0;
9960
9961
    /*
9962
     * We only handle the push operation.  All other operations are ignored.
9963
     * The other operations will be handled by the composite routine
9964
     * for the PDF 1.4 compositing device.
9965
     */
9966
1.09M
    switch (pdf14pct->params.pdf14_op) {
9967
1.07M
        case PDF14_PUSH_DEVICE:
9968
1.07M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9969
            /* Change (non-error) code to 1 to indicate that we created
9970
             * a device. */
9971
1.07M
            if (code >= 0)
9972
1.07M
                code = 1;
9973
1.07M
            break;
9974
21.5k
        default:
9975
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9976
21.5k
            *pp14dev = NULL;
9977
21.5k
            return_error(gs_error_unregistered);
9978
1.09M
    }
9979
1.07M
    return code;
9980
1.09M
}
9981
9982
/*
9983
 * Find an opening compositor op.
9984
 */
9985
static gs_compositor_closing_state
9986
find_opening_op(int opening_op, gs_composite_t **ppcte,
9987
                gs_compositor_closing_state return_code)
9988
2.23M
{
9989
    /* Assuming a right *BEGIN* - *END* operation balance. */
9990
2.23M
    gs_composite_t *pcte = *ppcte;
9991
9992
5.06M
    for (;;) {
9993
5.06M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9994
4.70M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9995
4.70M
            int op = pct->params.pdf14_op;
9996
9997
4.70M
            *ppcte = pcte;
9998
4.70M
            if (op == opening_op)
9999
1.36M
                return return_code;
10000
3.33M
            if (op != PDF14_SET_BLEND_PARAMS) {
10001
1.90M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
10002
575
                    return COMP_ENQUEUE;
10003
1.90M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10004
252k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10005
234k
                        return COMP_ENQUEUE;
10006
252k
                }
10007
1.66M
                if (opening_op == PDF14_PUSH_DEVICE) {
10008
1.64M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10009
1.61M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10010
282k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10011
126k
                        return COMP_ENQUEUE;
10012
1.64M
                }
10013
1.66M
            }
10014
3.33M
        } else
10015
362k
            return COMP_ENQUEUE;
10016
2.97M
        pcte = pcte->prev;
10017
2.97M
        if (pcte == NULL)
10018
143k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10019
2.97M
    }
10020
2.23M
}
10021
10022
/*
10023
 * Find an opening compositor op.
10024
 */
10025
static gs_compositor_closing_state
10026
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10027
16.2M
{
10028
16.2M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10029
16.2M
    gs_composite_t *pct = *ppcte;
10030
10031
16.2M
    for (;;) {
10032
16.2M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10033
13.4M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10034
10035
13.4M
            *ppcte = pct;
10036
13.4M
            if (pct_pdf14->params.pdf14_op != my_op)
10037
4.05M
                return COMP_ENQUEUE;
10038
9.40M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10039
                /* If the new parameters completely replace the old ones
10040
                   then remove the old one from the queu */
10041
9.40M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10042
9.40M
                    pct_pdf14->params.changed) {
10043
8.61M
                    return COMP_REPLACE_CURR;
10044
8.61M
                } else {
10045
787k
                    return COMP_ENQUEUE;
10046
787k
                }
10047
9.40M
            }
10048
9.40M
        } else
10049
2.83M
            return COMP_ENQUEUE;
10050
0
        pct = pct->prev;
10051
0
        if (pct == NULL)
10052
0
            return COMP_ENQUEUE; /* Not in queue. */
10053
0
    }
10054
16.2M
}
10055
10056
/*
10057
 * Check for closing compositor.
10058
 */
10059
static gs_compositor_closing_state
10060
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10061
                        gx_device *dev)
10062
31.1M
{
10063
31.1M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10064
31.1M
    int op0 = pct0->params.pdf14_op;
10065
10066
31.1M
    switch (op0) {
10067
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10068
1.17M
        case PDF14_PUSH_DEVICE:
10069
1.17M
            return COMP_ENQUEUE;
10070
0
        case PDF14_ABORT_DEVICE:
10071
0
            return COMP_ENQUEUE;
10072
1.17M
        case PDF14_POP_DEVICE:
10073
1.17M
            if (*ppcte == NULL)
10074
795k
                return COMP_ENQUEUE;
10075
382k
            else {
10076
382k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10077
10078
382k
                if (state == COMP_EXEC_IDLE)
10079
98.6k
                    return COMP_DROP_QUEUE;
10080
283k
                return state;
10081
382k
            }
10082
479k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10083
2.16M
        case PDF14_BEGIN_TRANS_GROUP:
10084
2.16M
            return COMP_ENQUEUE;
10085
1.70M
        case PDF14_END_TRANS_GROUP:
10086
2.16M
        case PDF14_END_TRANS_TEXT_GROUP:
10087
2.16M
            if (*ppcte == NULL)
10088
451k
                return COMP_EXEC_QUEUE;
10089
1.71M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10090
4.03M
        case PDF14_BEGIN_TRANS_MASK:
10091
4.03M
            return COMP_ENQUEUE;
10092
0
        case PDF14_PUSH_TRANS_STATE:
10093
0
            return COMP_ENQUEUE;
10094
2.72M
        case PDF14_POP_TRANS_STATE:
10095
2.72M
            return COMP_ENQUEUE;
10096
0
        case PDF14_PUSH_SMASK_COLOR:
10097
0
            return COMP_ENQUEUE;
10098
0
            break;
10099
0
        case PDF14_POP_SMASK_COLOR:
10100
0
            return COMP_ENQUEUE;
10101
0
            break;
10102
400k
        case PDF14_END_TRANS_MASK:
10103
400k
            if (*ppcte == NULL)
10104
264k
                return COMP_EXEC_QUEUE;
10105
135k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10106
17.2M
        case PDF14_SET_BLEND_PARAMS:
10107
17.2M
            if (*ppcte == NULL)
10108
992k
                return COMP_ENQUEUE;
10109
            /* hack : ignore csel - here it is always zero : */
10110
16.2M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10111
31.1M
    }
10112
31.1M
}
10113
10114
/*
10115
 * Check whether a next operation is friendly to the compositor.
10116
 */
10117
static bool
10118
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10119
3.68M
{
10120
3.68M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10121
3.68M
    int op0 = pct0->params.pdf14_op;
10122
10123
3.68M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10124
2.40M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10125
        /* Halftone commands are always passed to the target printer device,
10126
           because transparency buffers are always contone.
10127
           So we're safe to execute them before queued transparency compositors. */
10128
1.29M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10129
374k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10130
605k
            return true;
10131
688k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10132
683k
            return true;
10133
688k
    }
10134
2.39M
    return false;
10135
3.68M
}
10136
10137
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10138
static composite_equal_proc(c_pdf14trans_equal);
10139
static composite_write_proc(c_pdf14trans_write);
10140
static composite_read_proc(c_pdf14trans_read);
10141
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10142
static composite_is_closing_proc(c_pdf14trans_is_closing);
10143
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10144
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10145
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10146
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10147
10148
/*
10149
 * Methods for the PDF 1.4 transparency compositor
10150
 *
10151
 * Note:  We have two set of methods.  They are the same except for the
10152
 * composite_clist_write_update method.  Once the clist write device is created,
10153
 * we use the second set of procedures.  This prevents the creation of multiple
10154
 * PDF 1.4 clist write compositor devices being chained together.
10155
 */
10156
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10157
    GX_COMPOSITOR_PDF14_TRANS,
10158
    {
10159
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10160
        c_pdf14trans_equal,                      /* procs.equal */
10161
        c_pdf14trans_write,                      /* procs.write */
10162
        c_pdf14trans_read,                       /* procs.read */
10163
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10164
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10165
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10166
                /* Create a PDF 1.4 clist write device */
10167
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10168
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10169
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10170
    }                                            /* procs */
10171
};
10172
10173
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10174
    GX_COMPOSITOR_PDF14_TRANS,
10175
    {
10176
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10177
        c_pdf14trans_equal,                      /* procs.equal */
10178
        c_pdf14trans_write,                      /* procs.write */
10179
        c_pdf14trans_read,                       /* procs.read */
10180
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10181
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10182
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10183
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10184
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10185
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10186
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10187
    }                                            /* procs */
10188
};
10189
10190
/*
10191
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10192
 */
10193
int
10194
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10195
265M
{
10196
265M
    return (pct->type == &gs_composite_pdf14trans_type
10197
205M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10198
265M
}
10199
10200
/*
10201
 * Create a PDF 1.4 transparency compositor data structure.
10202
 */
10203
static int
10204
gs_create_pdf14trans(
10205
    gs_composite_t **               ppct,
10206
    const gs_pdf14trans_params_t *  pparams,
10207
    gs_memory_t *                   mem )
10208
38.4M
{
10209
38.4M
    gs_pdf14trans_t *                pct;
10210
10211
38.4M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10212
38.4M
                             "gs_create_pdf14trans");
10213
38.4M
    if (pct == NULL)
10214
0
        return_error(gs_error_VMerror);
10215
38.4M
    pct->type = &gs_composite_pdf14trans_type;
10216
38.4M
    pct->id = gs_next_ids(mem, 1);
10217
38.4M
    pct->params = *pparams;
10218
38.4M
    pct->idle = false;
10219
38.4M
    *ppct = (gs_composite_t *)pct;
10220
38.4M
    return 0;
10221
38.4M
}
10222
10223
/*
10224
 * Send a PDF 1.4 transparency compositor action to the specified device.
10225
 */
10226
int
10227
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10228
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10229
1.21M
{
10230
1.21M
    gs_composite_t * pct = NULL;
10231
1.21M
    int code;
10232
10233
1.21M
    pparams->ctm = ctm_only(pgs);
10234
1.21M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10235
1.21M
    if (code < 0)
10236
0
        return code;
10237
1.21M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10238
1.21M
    if (code == gs_error_handled)
10239
0
        code = 0;
10240
10241
1.21M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10242
10243
1.21M
    return code;
10244
1.21M
}
10245
10246
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10247
10248
/*
10249
 * The PDF 1.4 transparency compositor device may have a different process
10250
 * color model than the output device.  If we are banding then we need to
10251
 * create two compositor devices.  The output side (clist reader) needs a
10252
 * compositor to actually composite the output.  We also need a compositor
10253
 * device before the clist writer.  This is needed to provide a process color
10254
 * model which matches the PDF 1.4 blending space.
10255
 *
10256
 * This section provides support for this device.
10257
 */
10258
10259
/*
10260
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10261
 * We actually use the same structure for both the clist writer and reader
10262
 * devices.  However we use separate names to identify the routines for each
10263
 * device.
10264
 */
10265
10266
static  dev_proc_composite(pdf14_clist_composite);
10267
static  dev_proc_composite(pdf14_clist_forward_composite);
10268
static  dev_proc_fill_path(pdf14_clist_fill_path);
10269
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10270
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10271
static  dev_proc_text_begin(pdf14_clist_text_begin);
10272
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10273
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10274
10275
static void
10276
pdf14_clist_init_procs(gx_device *dev,
10277
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10278
                       dev_proc_get_color_comp_index(get_color_comp_index))
10279
10.4k
{
10280
10.4k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10281
10.4k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10282
10.4k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10283
10.4k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10284
10.4k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10285
10.4k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10286
10.4k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10287
10.4k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10288
10.4k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10289
10.4k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10290
10.4k
    set_dev_proc(dev, put_params, pdf14_put_params);
10291
10.4k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10292
10.4k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10293
10.4k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10294
10.4k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10295
10.4k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10296
10.4k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10297
10.4k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10298
10.4k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10299
10.4k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10300
10.4k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10301
10.4k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10302
10.4k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10303
10.4k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10304
10.4k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10305
10.4k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10306
10.4k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10307
10.4k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10308
10.4k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10309
10.4k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10310
10.4k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10311
10.4k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10312
10.4k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10313
10.4k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10314
10.4k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10315
10.4k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10316
10.4k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10317
10.4k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10318
10.4k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10319
10.4k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10320
10.4k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10321
10.4k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10322
10.4k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10323
10.4k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10324
10.4k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10325
10.4k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10326
10.4k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10327
10.4k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10328
10.4k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10329
10.4k
}
10330
10331
static void
10332
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10333
2.99k
{
10334
2.99k
    pdf14_clist_init_procs(dev,
10335
2.99k
                           gx_default_DevGray_get_color_mapping_procs,
10336
2.99k
                           gx_default_DevGray_get_color_comp_index);
10337
2.99k
}
10338
10339
static void
10340
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10341
6.13k
{
10342
6.13k
    pdf14_clist_init_procs(dev,
10343
6.13k
                           gx_default_DevRGB_get_color_mapping_procs,
10344
6.13k
                           gx_default_DevRGB_get_color_comp_index);
10345
6.13k
}
10346
10347
static void
10348
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10349
13
{
10350
13
    pdf14_clist_init_procs(dev,
10351
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10352
13
                           gx_default_DevCMYK_get_color_comp_index);
10353
13
}
10354
10355
static void
10356
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10357
1.28k
{
10358
1.28k
    pdf14_clist_init_procs(dev,
10359
1.28k
                           pdf14_cmykspot_get_color_mapping_procs,
10360
1.28k
                           pdf14_cmykspot_get_color_comp_index);
10361
1.28k
}
10362
10363
static void
10364
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10365
0
{
10366
0
    pdf14_clist_init_procs(dev,
10367
0
                           pdf14_rgbspot_get_color_mapping_procs,
10368
0
                           pdf14_rgbspot_get_color_comp_index);
10369
0
}
10370
10371
#if 0 /* NOT USED */
10372
static int
10373
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10374
{
10375
    pdf14_clist_init_procs(dev,
10376
                           pdf14_grayspot_get_color_mapping_procs,
10377
                           pdf14_grayspot_get_color_comp_index);
10378
}
10379
#endif  /* NOT USED */
10380
10381
const pdf14_clist_device pdf14_clist_Gray_device = {
10382
    std_device_color_stype_body(pdf14_clist_device,
10383
                                pdf14_clist_Gray_initialize_device_procs,
10384
                                "pdf14clistgray",
10385
                                &st_pdf14_device,
10386
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10387
    { 0 },      /* Procs */
10388
    NULL,     /* target */
10389
    { 0 },      /* devn_params - not used */
10390
    &gray_pdf14_procs,
10391
    &gray_blending_procs
10392
};
10393
10394
const pdf14_clist_device pdf14_clist_RGB_device = {
10395
    std_device_color_stype_body(pdf14_clist_device,
10396
                                pdf14_clist_RGB_initialize_device_procs,
10397
                                "pdf14clistRGB",
10398
                                &st_pdf14_device,
10399
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10400
    { 0 },      /* Procs */
10401
    NULL,     /* target */
10402
    { 0 },      /* devn_params - not used */
10403
    &rgb_pdf14_procs,
10404
    &rgb_blending_procs
10405
};
10406
10407
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10408
    std_device_part1_(pdf14_device,
10409
                      pdf14_clist_RGBspot_initialize_device_procs,
10410
                      "pdf14clistrgbspot",
10411
                      &st_pdf14_device,
10412
                      open_init_closed),
10413
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10414
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10415
    offset_margin_values(0, 0, 0, 0, 0, 0),
10416
    std_device_part3_(),
10417
    { 0 },      /* Procs */
10418
    NULL,     /* target */
10419
    /* DeviceN parameters */
10420
    { 8,      /* Not used - Bits per color */
10421
      DeviceRGBComponents,  /* Names of color model colorants */
10422
      3,      /* Number colorants for CMYK */
10423
      0,      /* MaxSeparations has not been specified */
10424
      -1,     /* PageSpotColors has not been specified */
10425
      {0},      /* SeparationNames */
10426
      0,      /* SeparationOrder names */
10427
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10428
    },
10429
    &rgbspot_pdf14_procs,
10430
    &rgb_blending_procs
10431
};
10432
10433
const pdf14_clist_device pdf14_clist_CMYK_device = {
10434
    std_device_std_color_full_body_type(pdf14_clist_device,
10435
                                        pdf14_clist_CMYK_initialize_device_procs,
10436
                                        "pdf14clistcmyk",
10437
                                        &st_pdf14_device,
10438
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10439
                                        0, 0, 0, 0, 0, 0),
10440
    { 0 },      /* Procs */
10441
    NULL,     /* target */
10442
    { 0 },      /* devn_params - not used */
10443
    &cmyk_pdf14_procs,
10444
    &cmyk_blending_procs
10445
};
10446
10447
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10448
    std_device_part1_(pdf14_device,
10449
                      pdf14_clist_CMYKspot_initialize_device_procs,
10450
                      "pdf14clistcmykspot",
10451
                      &st_pdf14_device,
10452
                      open_init_closed),
10453
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10454
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10455
    offset_margin_values(0, 0, 0, 0, 0, 0),
10456
    std_device_part3_(),
10457
    { 0 },      /* Procs */
10458
    NULL,     /* target */
10459
    /* DeviceN parameters */
10460
    { 8,      /* Not used - Bits per color */
10461
      DeviceCMYKComponents, /* Names of color model colorants */
10462
      4,      /* Number colorants for CMYK */
10463
      0,      /* MaxSeparations has not been specified */
10464
      -1,     /* PageSpotColors has not been specified */
10465
      {0},      /* SeparationNames */
10466
      0,      /* SeparationOrder names */
10467
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10468
    },
10469
    &cmykspot_pdf14_procs,
10470
    &cmyk_blending_procs
10471
};
10472
10473
const pdf14_clist_device pdf14_clist_custom_device = {
10474
    std_device_part1_(pdf14_device,
10475
                      pdf14_clist_CMYKspot_initialize_device_procs,
10476
                      "pdf14clistcustom",
10477
                      &st_pdf14_device,
10478
                      open_init_closed),
10479
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10480
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10481
    offset_margin_values(0, 0, 0, 0, 0, 0),
10482
    std_device_part3_(),
10483
    { 0 },      /* Procs */
10484
    NULL,     /* target */
10485
    /* DeviceN parameters */
10486
    { 8,      /* Not used - Bits per color */
10487
      DeviceCMYKComponents, /* Names of color model colorants */
10488
      4,      /* Number colorants for CMYK */
10489
      0,      /* MaxSeparations has not been specified */
10490
      -1,     /* PageSpotColors has not been specified */
10491
      {0},      /* SeparationNames */
10492
      0,      /* SeparationOrder names */
10493
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10494
    },
10495
    &custom_pdf14_procs,
10496
    &custom_blending_procs
10497
};
10498
10499
/*
10500
 * the PDF 1.4 transparency spec says that color space for blending
10501
 * operations can be based upon either a color space specified in the
10502
 * group or a default value based upon the output device.  We are
10503
 * currently only using a color space based upon the device.
10504
 */
10505
static  int
10506
get_pdf14_clist_device_proto(gx_device          *dev,
10507
                             pdf14_clist_device *pdevproto,
10508
                             gs_gstate          *pgs,
10509
                       const gs_pdf14trans_t    *pdf14pct,
10510
                             bool                use_pdf14_accum)
10511
10.4k
{
10512
10.4k
    pdf14_blend_cs_t blend_cs_state;
10513
10.4k
    pdf14_default_colorspace_t dev_cs =
10514
10.4k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10515
10.4k
                                                 &blend_cs_state);
10516
10.4k
    bool deep = device_is_deep(dev);
10517
10.4k
    int num_spots = pdf14pct->params.num_spot_colors;
10518
10519
    /* overprint overide */
10520
10.4k
    if (pdf14pct->params.overprint_sim_push &&
10521
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10522
10523
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10524
0
            dev_cs = PDF14_DeviceCMYKspot;
10525
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10526
0
        } else
10527
0
            dev_cs = PDF14_DeviceCMYK;
10528
0
    }
10529
10530
10.4k
    switch (dev_cs) {
10531
2.99k
        case PDF14_DeviceGray:
10532
           /* We want gray to be single channel.  Low level
10533
               initialization of gray device prototype is
10534
               peculiar in that in dci_std_color_num_components
10535
               the comment is
10536
              "A device is monochrome only if it is bi-level"
10537
              Here we want monochrome anytime we have a gray device.
10538
              To avoid breaking things elsewhere, we will overide
10539
              the prototype intialization here */
10540
2.99k
            *pdevproto = pdf14_clist_Gray_device;
10541
2.99k
            pdevproto->color_info.max_components = 1;
10542
2.99k
            pdevproto->color_info.num_components =
10543
2.99k
                                    pdevproto->color_info.max_components;
10544
2.99k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10545
2.99k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10546
2.99k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10547
2.99k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10548
2.99k
            pdevproto->color_info.depth = deep ? 16 : 8;
10549
2.99k
            pdevproto->sep_device = false;
10550
2.99k
            break;
10551
6.13k
        case PDF14_DeviceRGB:
10552
6.13k
            *pdevproto = pdf14_clist_RGB_device;
10553
6.13k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10554
6.13k
            pdevproto->sep_device = false;
10555
6.13k
            if (deep) {
10556
0
                pdevproto->color_info.depth = 3*16;
10557
0
                pdevproto->color_info.max_color = 65535;
10558
0
                pdevproto->color_info.max_gray = 65535;
10559
0
                pdevproto->color_info.dither_colors = 65536;
10560
0
                pdevproto->color_info.dither_grays = 65536;
10561
0
            }
10562
6.13k
            break;
10563
13
        case PDF14_DeviceCMYK:
10564
13
            *pdevproto = pdf14_clist_CMYK_device;
10565
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10566
13
            pdevproto->sep_device = false;
10567
13
            if (deep) {
10568
0
                pdevproto->color_info.depth = 4*16;
10569
0
                pdevproto->color_info.max_color = 65535;
10570
0
                pdevproto->color_info.max_gray = 65535;
10571
0
                pdevproto->color_info.dither_colors = 65536;
10572
0
                pdevproto->color_info.dither_grays = 65536;
10573
0
            }
10574
13
            break;
10575
1.28k
        case PDF14_DeviceCMYKspot:
10576
1.28k
            *pdevproto = pdf14_clist_CMYKspot_device;
10577
            /*
10578
             * The number of components for the PDF14 device is the sum
10579
             * of the process components and the number of spot colors
10580
             * for the page. If we are using an NCLR ICC profile at
10581
             * the output device, those spot colors are skipped. They
10582
             * do not appear in the transparency buffer, but appear
10583
             * during put image transform of the page group to the target
10584
             * color space.
10585
             */
10586
1.28k
            if (num_spots >= 0) {
10587
1.28k
                pdevproto->devn_params.page_spot_colors = num_spots;
10588
1.28k
                pdevproto->color_info.num_components =
10589
1.28k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10590
1.28k
                if (pdevproto->color_info.num_components >
10591
1.28k
                              pdevproto->color_info.max_components)
10592
0
                    pdevproto->color_info.num_components =
10593
0
                              pdevproto->color_info.max_components;
10594
1.28k
                pdevproto->color_info.depth =
10595
1.28k
                              pdevproto->color_info.num_components * (8<<deep);
10596
1.28k
            }
10597
1.28k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10598
1.28k
            pdevproto->sep_device = true;
10599
1.28k
            break;
10600
0
        case PDF14_DeviceRGBspot:
10601
0
            *pdevproto = pdf14_clist_RGBspot_device;
10602
            /*
10603
             * The number of components for the PDF14 device is the sum
10604
             * of the process components and the number of spot colors
10605
             * for the page. If we are using an NCLR ICC profile at
10606
             * the output device, those spot colors are skipped. They
10607
             * do not appear in the transparency buffer, but appear
10608
             * during put image transform of the page group to the target
10609
             * color space.
10610
             */
10611
0
            if (num_spots >= 0) {
10612
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10613
0
                pdevproto->color_info.num_components =
10614
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10615
0
                if (pdevproto->color_info.num_components >
10616
0
                    pdevproto->color_info.max_components)
10617
0
                    pdevproto->color_info.num_components =
10618
0
                        pdevproto->color_info.max_components;
10619
0
                pdevproto->color_info.depth =
10620
0
                    pdevproto->color_info.num_components * (8 << deep);
10621
0
            }
10622
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10623
0
            pdevproto->sep_device = true;
10624
0
            break;
10625
0
        case PDF14_DeviceCustom:
10626
            /*
10627
             * We are using the output device's process color model.  The
10628
             * color_info for the PDF 1.4 compositing device needs to match
10629
             * the output device.
10630
             */
10631
0
            *pdevproto = pdf14_clist_custom_device;
10632
0
            pdevproto->color_info = dev->color_info;
10633
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10634
0
            pdevproto->color_info.depth =
10635
0
                pdevproto->color_info.num_components * (8<<deep);
10636
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10637
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10638
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10639
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10640
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10641
0
            break;
10642
0
        default:      /* Should not occur */
10643
0
            return_error(gs_error_rangecheck);
10644
10.4k
    }
10645
10.4k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10646
10.4k
    pdevproto->blend_cs_state = blend_cs_state;
10647
10.4k
    return 0;
10648
10.4k
}
10649
10650
static  int
10651
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10652
                                gx_device ** ppdev, gx_device * target,
10653
                                const gs_pdf14trans_t * pdf14pct)
10654
10.4k
{
10655
10.4k
    pdf14_clist_device dev_proto;
10656
10.4k
    pdf14_clist_device * pdev;
10657
10.4k
    int code;
10658
10.4k
    bool has_tags = device_encodes_tags(target);
10659
10.4k
    cmm_profile_t *target_profile;
10660
10.4k
    gsicc_rendering_param_t render_cond;
10661
10.4k
    cmm_dev_profile_t *dev_profile;
10662
10.4k
    uchar k;
10663
10.4k
    bool deep = device_is_deep(target);
10664
10.4k
    cmm_profile_t *icc_profile;
10665
10.4k
    int nc;
10666
10667
10.4k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10668
10.4k
    if (code < 0)
10669
0
        return code;
10670
10.4k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10671
10.4k
                          &render_cond);
10672
10.4k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10673
    /* Prototypes never include tags. We add those in later. */
10674
10.4k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10675
10.4k
                                        pgs, pdf14pct, false);
10676
10.4k
    if (code < 0)
10677
0
        return code;
10678
10.4k
    code = gs_copydevice((gx_device **) &pdev,
10679
10.4k
                         (const gx_device *) &dev_proto, mem);
10680
10.4k
    if (code < 0)
10681
0
        return code;
10682
10683
10.4k
    nc = pdev->color_info.num_components;
10684
    /* If we are not using a blending color space, the number of color planes
10685
       should not exceed that of the target */
10686
10.4k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10687
10.4k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10688
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10689
10.4k
        if (pdev->color_info.max_components > target->color_info.max_components)
10690
1.36k
            pdev->color_info.max_components = target->color_info.max_components;
10691
10.4k
    }
10692
10.4k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10693
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10694
10695
10.4k
    pdev->color_info.num_components = nc;
10696
10.4k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10697
10.4k
    pdev->pad = target->pad;
10698
10.4k
    pdev->log2_align_mod = target->log2_align_mod;
10699
10700
10.4k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10701
10702
10.4k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10703
10704
10.4k
    if (deep) {
10705
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10706
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10707
0
    }
10708
    /* If we have a tag device then go ahead and do a special encoder decoder
10709
       for the pdf14 device to make sure we maintain this information in the
10710
       encoded color information.  We could use the target device's methods but
10711
       the PDF14 device has to maintain 8 bit color always and we could run
10712
       into other issues if the number of colorants became large.  If we need to
10713
       do compressed color with tags that will be a special project at that time */
10714
10.4k
    if (has_tags) {
10715
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10716
0
    }
10717
10.4k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10718
10.4k
    gx_device_fill_in_procs((gx_device *)pdev);
10719
    /* Copying the params adds the tags to the color_info if required. */
10720
10.4k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10721
10.4k
    if (target->num_planar_planes > 0)
10722
1.41k
        pdev->num_planar_planes = pdev->color_info.num_components;
10723
10.4k
    gx_device_set_target((gx_device_forward *)pdev, target);
10724
10725
    /* Components shift, etc have to be based upon 8 bit */
10726
37.1k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10727
26.6k
        pdev->color_info.comp_bits[k] = 8<<deep;
10728
26.6k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10729
26.6k
    }
10730
10.4k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10731
10.4k
    if (code < 0)
10732
0
        return code;
10733
10.4k
    pdev->pclist_device = target;
10734
10735
10.4k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10736
10.4k
    if (code < 0)
10737
0
        return code;
10738
10.4k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10739
10.4k
        &render_cond);
10740
10.4k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10741
10742
    /* Simulated overprint case.  We have to use CMYK-based profile
10743
       Also if the target profile is NCLR, we are going to use a pdf14
10744
       device that is CMYK based and do the mapping to the NCLR profile
10745
       when the put_image occurs */
10746
10.4k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10747
10.4k
         icc_profile->data_cs == gsNCHANNEL) {
10748
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10749
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10750
0
            -1, "pdf14_create_clist_device");
10751
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10752
10.4k
    } else {
10753
        /* If the target profile was CIELAB, then overide with default RGB for
10754
           proper blending.  During put_image we will convert from RGB to
10755
           CIELAB */
10756
10.4k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10757
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10758
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10759
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10760
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10761
0
        }
10762
10.4k
    }
10763
10764
10.4k
    if (pdf14pct->params.overprint_sim_push &&
10765
0
        pdf14pct->params.num_spot_colors_int > 0) {
10766
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10767
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10768
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10769
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10770
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10771
0
    }
10772
    /* if the device has separations already defined (by SeparationOrderNames) */
10773
    /* we need to copy them (allocating new names) so the colorants are in the */
10774
    /* same order as the target device.                                        */
10775
10.4k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10776
1.41k
        code = devn_copy_params(target, (gx_device *)pdev);
10777
1.41k
        if (code < 0)
10778
0
            return code;
10779
1.41k
    }
10780
10.4k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10781
10.4k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10782
10.4k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10783
10.4k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10784
10.4k
    pdev->color_info.separable_and_linear =
10785
10.4k
        target->color_info.separable_and_linear;
10786
10.4k
    *ppdev = (gx_device *) pdev;
10787
10.4k
    return code;
10788
10.4k
}
10789
10790
/*
10791
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10792
 * compositor device is never removed.  (We do not have a remove compositor
10793
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10794
 * routine implements that action.
10795
 */
10796
static  int
10797
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10798
                                gx_device * dev)
10799
10.0k
{
10800
10.0k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10801
10.0k
    gx_device * target = pdev->target;
10802
10803
10.0k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10804
10805
    /*
10806
     * To disable the action of this device, we forward all device
10807
     * procedures to the target except the composite and copy
10808
     * the target's color_info.
10809
     */
10810
10.0k
    dev->color_info = target->color_info;
10811
10.0k
    pdf14_forward_device_procs(dev);
10812
10.0k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10813
10.0k
    return 0;
10814
10.0k
}
10815
10816
/*
10817
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10818
 * compositor device is never removed.  (We do not have a remove compositor
10819
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10820
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10821
 * again.
10822
 */
10823
static  int
10824
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10825
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10826
0
{
10827
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10828
0
    gx_device * target = pdev->target;
10829
0
    pdf14_clist_device dev_proto;
10830
0
    int code;
10831
10832
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10833
    /*
10834
     * We will not use the entire prototype device but we will set the
10835
     * color related info to match the prototype.
10836
     */
10837
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10838
0
                                        pgs, pdf14pct, false);
10839
0
    if (code < 0)
10840
0
        return code;
10841
0
    pdev->color_info = dev_proto.color_info;
10842
10843
0
    if (dev_proto.initialize_device_procs != NULL)
10844
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10845
10846
0
    pdev->procs = dev_proto.procs;
10847
0
    pdev->pad = target->pad;
10848
0
    pdev->log2_align_mod = target->log2_align_mod;
10849
10850
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10851
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10852
0
    else
10853
0
        pdev->num_planar_planes = target->num_planar_planes;
10854
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10855
10856
0
    copy_tag_setup(dev, target);
10857
10858
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10859
0
    gx_device_fill_in_procs((gx_device *)pdev);
10860
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10861
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10862
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10863
0
    check_device_separable((gx_device *)pdev);
10864
0
    return code;
10865
0
}
10866
10867
/*
10868
 * devicen params
10869
 */
10870
gs_devn_params *
10871
pdf14_ret_devn_params(gx_device *pdev)
10872
2.22M
{
10873
2.22M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10874
10875
2.22M
    return &(p14dev->devn_params);
10876
2.22M
}
10877
10878
/*
10879
 * devicen params
10880
 */
10881
gs_devn_params *
10882
pdf14_accum_ret_devn_params(gx_device *pdev)
10883
0
{
10884
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10885
10886
0
    return &(p14dev->devn_params);
10887
0
}
10888
10889
static int
10890
pdf14_accum_get_color_comp_index(gx_device * dev,
10891
    const char * pname, int name_size, int component_type)
10892
0
{
10893
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10894
0
    gx_device *target = p14dev->target;
10895
0
    int colorant_number = devn_get_color_comp_index(dev,
10896
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10897
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10898
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10899
10900
0
    if (target != NULL)
10901
        /* colorant_number returned here _should_ be the same as from above */
10902
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10903
0
                              (target, (const char *)pname, name_size, component_type);
10904
0
    return colorant_number;
10905
0
}
10906
10907
/*
10908
 * The following procedures are used to map the standard color spaces into
10909
 * the separation color components for the pdf14_accum device.
10910
 */
10911
static void
10912
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10913
0
{
10914
0
    int * map =
10915
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10916
10917
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10918
0
}
10919
10920
static void
10921
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10922
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10923
0
{
10924
0
    int * map =
10925
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10926
10927
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10928
0
}
10929
10930
static void
10931
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10932
    frac c, frac m, frac y, frac k, frac out[])
10933
0
{
10934
0
    const int * map =
10935
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10936
10937
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10938
0
}
10939
10940
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10941
    pdf14_accum_gray_cs_to_cmyk_cm,
10942
    pdf14_accum_rgb_cs_to_cmyk_cm,
10943
    pdf14_accum_cmyk_cs_to_cmyk_cm
10944
};
10945
10946
static const gx_cm_color_map_procs *
10947
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10948
0
{
10949
0
    *map_dev = dev;
10950
0
    return &pdf14_accum_cm_procs;
10951
0
}
10952
10953
/*
10954
 *  Device proc for updating the equivalent CMYK color for spot colors.
10955
 */
10956
static int
10957
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10958
0
{
10959
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10960
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10961
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10962
0
                                              &pdev->equiv_cmyk_colors);
10963
10964
0
    if (code >= 0 && tdev != NULL)
10965
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10966
0
    return code;
10967
0
}
10968
10969
/* Used when doing overprint simulation and have spot colors */
10970
static int
10971
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10972
0
{
10973
0
    pdf14_device *pdev = (pdf14_device *)dev;
10974
0
    int code;
10975
10976
    /* Make sure we are not All or None */
10977
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10978
0
        pcs->params.separation.sep_type != SEP_OTHER)
10979
0
            return 0;
10980
10981
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10982
0
        &pdev->op_pequiv_cmyk_colors);
10983
0
    return code;
10984
0
}
10985
10986
/*
10987
 * Retrieve a list of spot color names for the PDF14 device.
10988
 */
10989
int
10990
put_param_pdf14_spot_names(gx_device * pdev,
10991
                gs_separations * pseparations, gs_param_list * plist)
10992
108k
{
10993
108k
    int code, num_spot_colors, i;
10994
108k
    gs_param_string str;
10995
10996
    /* Check if the given keyname is present. */
10997
108k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10998
108k
                                                &num_spot_colors);
10999
108k
    switch (code) {
11000
0
        default:
11001
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
11002
0
            break;
11003
108k
        case 1:
11004
108k
            return 0;
11005
0
        case 0:
11006
0
            if (num_spot_colors < 1 ||
11007
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11008
0
                return_error(gs_error_rangecheck);
11009
0
            for (i = 0; i < num_spot_colors; i++) {
11010
0
                char buff[20];
11011
0
                byte * sep_name;
11012
11013
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11014
0
                code = param_read_string(plist, buff, &str);
11015
0
                switch (code) {
11016
0
                    default:
11017
0
                        param_signal_error(plist, buff, code);
11018
0
                        break;
11019
0
                    case 0:
11020
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11021
0
                                str.size, "put_param_pdf14_spot_names");
11022
0
                        if (sep_name == NULL)
11023
0
                            return_error(gs_error_VMerror);
11024
11025
0
                        memcpy(sep_name, str.data, str.size);
11026
0
                        pseparations->names[i].size = str.size;
11027
0
                        pseparations->names[i].data = sep_name;
11028
0
                }
11029
0
            }
11030
0
            pseparations->num_separations = num_spot_colors;
11031
0
            break;
11032
108k
    }
11033
0
    return 0;;
11034
0
}
11035
11036
/*
11037
 * This procedure will have information from the PDF 1.4 clist writing
11038
 * clist compositior device.  This is information output the compressed
11039
 * color list info which is needed for the support of spot colors in
11040
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11041
 * clist reading compositor.  However this device is not created until
11042
 * the clist is read.  To get this info to that device, we have to
11043
 * temporarily store that info in the output device.  This routine saves
11044
 * that info in the output device.
11045
 */
11046
int
11047
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11048
                                        gs_param_list * plist)
11049
108k
{
11050
108k
    int code;
11051
108k
    code = put_param_pdf14_spot_names(pdev,
11052
108k
                       &pdevn_params->pdf14_separations, plist);
11053
108k
    return code;
11054
108k
}
11055
11056
/*
11057
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11058
 * when we are creating the clist.  The second is for imaging the data from
11059
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11060
 * This routine is only called once the PDF 1.4 clist write compositor already
11061
 * exists.
11062
 */
11063
static  int
11064
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11065
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11066
    gx_device *cdev)
11067
1.66M
{
11068
1.66M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11069
1.66M
    int code, is_pdf14_compositor;
11070
1.66M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11071
1.66M
    bool deep = device_is_deep(dev);
11072
11073
    /* We only handle a few PDF 1.4 transparency operations */
11074
1.66M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11075
968k
        switch (pdf14pct->params.pdf14_op) {
11076
0
            case PDF14_PUSH_DEVICE:
11077
                /* Re-activate the PDF 1.4 compositor */
11078
/*
11079
                We previously did:
11080
11081
                pdev->saved_target_color_info = pdev->target->color_info;
11082
11083
                Here, but since we already saved and modified the the color_info
11084
                of the target clist device in gs_pdf14_clist_device_push() this is
11085
                overwriting saved_target_color_info that we already saved with the
11086
                group color_info, meaning when we set it back again, it's incorrect.
11087
*/
11088
0
                pdev->target->color_info = pdev->color_info;
11089
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11090
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11091
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11092
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11093
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11094
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11095
0
                pdev->saved_target_get_color_mapping_procs =
11096
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11097
0
                pdev->saved_target_get_color_comp_index =
11098
0
                                        dev_proc(pdev->target, get_color_comp_index);
11099
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11100
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11101
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11102
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11103
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11104
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11105
0
                gx_set_cmap_procs(pgs, dev);
11106
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11107
0
                pdev->blend_mode = pdev->text_knockout = 0;
11108
0
                pdev->opacity = pdev->shape = 0.0;
11109
0
                if (code < 0)
11110
0
                    return code;
11111
                /*
11112
                 * This routine is part of the PDF 1.4 clist write device.
11113
                 * Change the compositor procs to not create another since we
11114
                 * do not need to create a chain of identical devices.
11115
                 */
11116
0
                {
11117
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11118
11119
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11120
0
                    code = dev_proc(pdev->target, composite)
11121
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11122
                    /* We should never have created a new device here. */
11123
0
                    assert(code != 1);
11124
0
                    return code;
11125
0
                }
11126
10.0k
            case PDF14_POP_DEVICE:
11127
10.0k
            {
11128
10.0k
                gx_device *clistdev = pdev->target;
11129
11130
                /* Find the clist device */
11131
10.0k
                while (1) {
11132
10.0k
                    gxdso_device_child_request req;
11133
                    /* Ignore any errors here, that's expected as non-clist
11134
                     * devices don't implement it. */
11135
10.0k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11136
10.0k
                    if (code == 1)
11137
10.0k
                        break;
11138
0
                    req.n = 0;
11139
0
                    req.target = clistdev;
11140
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11141
0
                    if (code < 0)
11142
0
                        return code;
11143
0
                    clistdev = req.target;
11144
0
                }
11145
11146
                /* If we have overprint simulation spot color information, store
11147
                   it in a pseudo-band of the clist */
11148
10.0k
                if (pdev->overprint_sim &&
11149
0
                    pdev->devn_params.page_spot_colors > 0) {
11150
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11151
0
                        &pdev->op_pequiv_cmyk_colors);
11152
0
                    if (code < 0)
11153
0
                        return code;
11154
0
                }
11155
11156
                /* If we hit an error during an SMask, we need to undo the color
11157
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11158
                 * for itself if it needs to take action.
11159
                 */
11160
10.0k
                pdf14_decrement_smask_color(pgs, dev);
11161
                /* Restore the color_info for the clist device */
11162
10.0k
                clistdev->color_info = pdev->saved_target_color_info;
11163
10.0k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11164
10.0k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11165
10.0k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11166
10.0k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11167
10.0k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11168
10.0k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11169
10.0k
                gx_set_cmap_procs(pgs, clistdev);
11170
10.0k
                gx_device_decache_colors(clistdev);
11171
                /* Disable the PDF 1.4 compositor */
11172
10.0k
                pdf14_disable_clist_device(mem, pgs, dev);
11173
                /*
11174
                 * Make sure that the transfer funtions, etc. are current.
11175
                 */
11176
10.0k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11177
10.0k
                if (code < 0)
11178
0
                    return code;
11179
10.0k
                break;
11180
10.0k
            }
11181
10.0k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11182
38.9k
            case PDF14_BEGIN_TRANS_GROUP:
11183
38.9k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11184
18.0k
                    pdev->depth_within_smask++;
11185
38.9k
                pdev->smask_constructed = 0;
11186
                /*
11187
                 * Keep track of any changes made in the blending parameters.
11188
                   These need to be written out in the same bands as the group
11189
                   information is written.  Hence the passing of the dimensions
11190
                   for the group. */
11191
38.9k
                code = pdf14_clist_update_params(pdev, pgs, true,
11192
38.9k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11193
38.9k
                if (code < 0)
11194
0
                    return code;
11195
38.9k
                if (pdf14pct->params.Background_components != 0 &&
11196
0
                    pdf14pct->params.Background_components !=
11197
0
                    pdev->color_info.num_components)
11198
0
                    return_error(gs_error_rangecheck);
11199
11200
                /* We need to update the clist writer device procs based upon the
11201
                   the group color space. This ensures the proper color data is
11202
                   written out to the device. For simplicity, the list item is
11203
                   created even if the color space did not change */
11204
38.9k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11205
38.9k
                if (code < 0)
11206
0
                    return code;
11207
11208
38.9k
                break;
11209
40.9k
            case PDF14_BEGIN_TRANS_MASK:
11210
                /* We need to update the clist writer device procs based upon the
11211
                   the group color space.  For simplicity, the list item is created
11212
                   even if the color space did not change */
11213
                /* First store the current ones */
11214
40.9k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11215
22.7k
                    break;
11216
11217
                /* Update the color settings of the clist writer.  Store information in stack */
11218
18.1k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11219
18.1k
                if (code < 0)
11220
0
                    return code;
11221
11222
                /* Also, if the BC is a value that may end up as something other
11223
                  than transparent. We must use the parent colors bounding box in
11224
                  determining the range of bands in which this mask can affect.
11225
                  So, if needed change the masks bounding box at this time */
11226
18.1k
                pdev->in_smask_construction++;
11227
18.1k
                break;
11228
383k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11229
383k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11230
21
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11231
21
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11232
21
                } else
11233
383k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11234
383k
                *pcdev = dev;
11235
383k
                return 0; /* Never put into clist. Only used during writing */
11236
386k
            case PDF14_END_TRANS_TEXT_GROUP:
11237
386k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11238
384k
                    *pcdev = dev;
11239
384k
                    return 0; /* Avoids spurious ET calls in interpreter */
11240
384k
                }
11241
2.67k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11242
2.67k
                code = pdf14_clist_pop_color_model(dev, pgs);
11243
2.67k
                if (code < 0)
11244
0
                    return code;
11245
2.67k
                break;
11246
18.1k
            case PDF14_END_TRANS_MASK:
11247
18.1k
                pdev->in_smask_construction--;
11248
18.1k
                if (pdev->in_smask_construction < 0)
11249
0
                    pdev->in_smask_construction = 0;
11250
18.1k
                if (pdev->in_smask_construction == 0)
11251
18.1k
                    pdev->smask_constructed = 1;
11252
                /* fallthrough */
11253
54.4k
            case PDF14_END_TRANS_GROUP:
11254
                /* We need to update the clist writer device procs based upon the
11255
                   the group color space. */
11256
54.4k
                code = pdf14_clist_pop_color_model(dev, pgs);
11257
54.4k
                if (pdev->depth_within_smask)
11258
18.0k
                    pdev->depth_within_smask--;
11259
54.4k
                if (code < 0)
11260
0
                    return code;
11261
54.4k
                break;
11262
54.4k
            case PDF14_PUSH_TRANS_STATE:
11263
0
                break;
11264
17.6k
            case PDF14_POP_TRANS_STATE:
11265
17.6k
                break;
11266
18.1k
            case PDF14_PUSH_SMASK_COLOR:
11267
18.1k
                code = pdf14_increment_smask_color(pgs,dev);
11268
18.1k
                *pcdev = dev;
11269
18.1k
                return code;  /* Note, this are NOT put in the clist */
11270
0
                break;
11271
18.1k
            case PDF14_POP_SMASK_COLOR:
11272
18.1k
                code = pdf14_decrement_smask_color(pgs,dev);
11273
18.1k
                *pcdev = dev;
11274
18.1k
                return code;  /* Note, this are NOT put in the clist */
11275
0
                break;
11276
0
            case PDF14_SET_BLEND_PARAMS:
11277
                /* If there is a change we go ahead and apply it to the target */
11278
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11279
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11280
0
                *pcdev = dev;
11281
0
                return code;
11282
0
                break;
11283
0
            case PDF14_ABORT_DEVICE:
11284
0
                code = gx_abort_trans_device(pgs, dev);
11285
0
                if (pdev->free_devicen) {
11286
0
                    devn_free_params(dev);
11287
0
                }
11288
0
                pdf14_disable_device(dev);
11289
0
                pdf14_close(dev);
11290
0
                *pcdev = dev;
11291
0
                return code;
11292
0
                break;
11293
0
            default:
11294
0
                break;   /* Pass remaining ops to target */
11295
968k
        }
11296
968k
    }
11297
857k
    code = dev_proc(pdev->target, composite)
11298
857k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11299
    /* If we were accumulating into a pdf14-clist-accum device, */
11300
    /* we now have to render the page into it's target device */
11301
857k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11302
10.0k
        pdev->target->stype == &st_gx_devn_accum_device) {
11303
11304
3.80k
        int i, y, rows_used;
11305
3.80k
        byte *linebuf;
11306
3.80k
        byte *actual_data;
11307
3.80k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11308
        /* get the target device we want to send the image to */
11309
3.80k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11310
3.80k
        gs_image1_t image;
11311
3.80k
        gs_color_space *pcs;
11312
3.80k
        gx_image_enum_common_t *info = NULL;
11313
3.80k
        gx_image_plane_t planes;
11314
3.80k
        gsicc_rendering_param_t render_cond;
11315
3.80k
        cmm_dev_profile_t *dev_profile;
11316
3.80k
        bool save_planar = pdev->num_planar_planes;
11317
3.80k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11318
3.80k
        int save_num_separations;
11319
3.80k
        gs_int_rect rect;
11320
11321
3.80k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11322
3.80k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11323
3.80k
        pdev->num_planar_planes = save_planar;
11324
11325
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11326
         * colors do require devn support
11327
         */
11328
3.80k
        if (tdev->color_info.num_components <= 4 ||
11329
3.80k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11330
            /*
11331
             * Set color space in preparation for sending an image.
11332
             */
11333
3.80k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11334
3.80k
            if (code < 0)
11335
0
                goto put_accum_error;
11336
11337
            /* Need to set this to avoid color management during the
11338
               image color render operation.  Exception is for the special case
11339
               when the destination was CIELAB.  Then we need to convert from
11340
               default RGB to CIELAB in the put image operation.  That will happen
11341
               here as we should have set the profile for the pdf14 device to RGB
11342
               and the target will be CIELAB */
11343
3.80k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11344
3.80k
            if (code < 0)
11345
0
                goto put_accum_error;
11346
3.80k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11347
3.80k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11348
            /* pcs takes a reference to the profile data it just retrieved. */
11349
3.80k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11350
3.80k
            if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS) {
11351
0
                code = gs_note_error(gs_error_rangecheck);
11352
0
                goto put_accum_error;
11353
0
            }
11354
3.80k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11355
3.80k
        } else {
11356
             /* DeviceN case -- need to handle spot colors */
11357
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11358
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11359
0
            if (code < 0)
11360
0
                goto put_accum_error;
11361
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11362
0
            pcs->params.device_n.use_alt_cspace = false;
11363
11364
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11365
0
                goto put_accum_error;
11366
0
            }
11367
            /* One last thing -- we need to fudge the pgs->color_component_map */
11368
0
            for (i=0; i < tdev->color_info.num_components; i++)
11369
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11370
            /* copy devn_params that were accumulated into the target device's devn_params */
11371
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11372
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11373
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11374
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11375
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11376
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11377
0
            target_devn_params->separations = tdev->devn_params.separations;
11378
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11379
0
                   sizeof(gs_separation_map));
11380
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11381
0
        }
11382
3.80k
        if (linebuf == NULL) {
11383
0
            code = gs_error_VMerror;
11384
0
            goto put_accum_error;
11385
0
        }
11386
3.80k
        gs_image_t_init_adjust(&image, pcs, false);
11387
3.80k
        image.ImageMatrix.xx = (float)pdev->width;
11388
3.80k
        image.ImageMatrix.yy = (float)pdev->height;
11389
3.80k
        image.Width = pdev->width;
11390
3.80k
        image.Height = pdev->height;
11391
3.80k
        image.BitsPerComponent = 8<<deep;
11392
3.80k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11393
3.80k
        ctm_only_writable(pgs).xy = 0;
11394
3.80k
        ctm_only_writable(pgs).yx = 0;
11395
3.80k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11396
3.80k
        ctm_only_writable(pgs).tx = 0.0;
11397
3.80k
        ctm_only_writable(pgs).ty = 0.0;
11398
3.80k
        code = dev_proc(target, begin_typed_image) (target,
11399
3.80k
                                                    pgs, NULL,
11400
3.80k
                                                    (gs_image_common_t *)&image,
11401
3.80k
                                                    NULL, NULL, NULL,
11402
3.80k
                                                    pgs->memory, &info);
11403
3.80k
        if (code < 0)
11404
0
            goto put_accum_error;
11405
3.80k
        rect.p.x = 0;
11406
3.80k
        rect.q.x = tdev->width;
11407
8.16M
        for (y=0; y < tdev->height; y++) {
11408
8.16M
            gs_get_bits_params_t params;
11409
11410
8.16M
            params.options = (GB_ALIGN_ANY |
11411
8.16M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11412
8.16M
                              GB_OFFSET_0 |
11413
8.16M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11414
8.16M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11415
8.16M
            params.x_offset = 0;
11416
8.16M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11417
8.16M
            params.data[0] = linebuf;
11418
8.16M
            rect.p.y = y;
11419
8.16M
            rect.q.y = y+1;
11420
8.16M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11421
8.16M
                                                      &rect, &params);
11422
8.16M
            if (code < 0)
11423
7
                goto put_accum_error;
11424
8.16M
            actual_data = params.data[0];
11425
8.16M
            planes.data = actual_data;
11426
8.16M
            planes.data_x = 0;
11427
8.16M
            planes.raster = tdev->width * tdev->color_info.num_components;
11428
8.16M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11429
0
                goto put_accum_error;
11430
8.16M
        }
11431
11432
3.80k
put_accum_error:
11433
3.80k
        if (info != NULL) {
11434
3.80k
            if (code < 0)
11435
7
                (void)info->procs->end_image(info, true);
11436
3.79k
            else
11437
3.79k
                code = info->procs->end_image(info, true);
11438
3.80k
        }
11439
11440
3.80k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11441
        /* This will also decrement the device profile */
11442
3.80k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11443
3.80k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11444
        /* Now unhook the clist device and hook to the original so we can clean up */
11445
3.80k
        gx_device_set_target((gx_device_forward *)pdev,
11446
3.80k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11447
3.80k
        pdev->pclist_device = pdev->target;
11448
3.80k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11449
3.80k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11450
3.80k
        if (target_devn_params != NULL) {
11451
            /* prevent devn_free_params from freeing names still in use by target device */
11452
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11453
0
            tdev->devn_params.separations.num_separations = 0;
11454
0
        }
11455
3.80k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11456
3.80k
        if (target_devn_params != NULL) {
11457
0
            target_devn_params->separations.num_separations = save_num_separations;
11458
0
        }
11459
3.80k
        return code;    /* DON'T perform set_target */
11460
3.80k
    }
11461
853k
    if (code == 1) {
11462
        /* We just wrapped pdev->target, so we need to update that.*/
11463
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11464
0
        code = 0; /* We did not wrap dev. */
11465
0
    }
11466
853k
    *pcdev = dev;
11467
853k
    return code;
11468
857k
}
11469
11470
/*
11471
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11472
 * compositor' method.  However the compositor is disabled when we are not
11473
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11474
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11475
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11476
 * to the targer.
11477
 */
11478
static  int
11479
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11480
        const gs_composite_t * pct, gs_gstate * pgs,
11481
        gs_memory_t * mem, gx_device *cdev)
11482
0
{
11483
0
    pdf14_device *pdev = (pdf14_device *)dev;
11484
0
    gx_device * tdev = pdev->target;
11485
0
    gx_device * ndev;
11486
0
    int code;
11487
11488
0
    *pcdev = dev;
11489
0
    if (gs_is_pdf14trans_compositor(pct)) {
11490
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11491
11492
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11493
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11494
0
        return 0;
11495
0
    }
11496
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11497
0
    if (code == 1) {
11498
        /* We just wrapped tdev, so update our target. */
11499
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11500
0
        code = 0; /* We did not wrap dev. */
11501
0
    }
11502
0
    return code;
11503
0
}
11504
11505
/*
11506
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11507
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11508
 */
11509
static  int
11510
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11511
                          bool crop_blend_params,
11512
                          gs_pdf14trans_params_t *group_params)
11513
3.76M
{
11514
3.76M
    gs_pdf14trans_params_t params = { 0 };
11515
3.76M
    gx_device * pcdev;
11516
3.76M
    int changed = 0;
11517
3.76M
    int code = 0;
11518
3.76M
    gs_composite_t *pct_new = NULL;
11519
11520
3.76M
    params.crop_blend_params = crop_blend_params;
11521
11522
3.76M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11523
3.76M
    if (pgs->blend_mode != pdev->blend_mode) {
11524
19.7k
        changed |= PDF14_SET_BLEND_MODE;
11525
19.7k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11526
19.7k
    }
11527
3.76M
    if (pgs->text_knockout != pdev->text_knockout) {
11528
9.66k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11529
9.66k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11530
9.66k
    }
11531
3.76M
    if (pgs->alphaisshape != pdev->ais) {
11532
1.51k
        changed |= PDF14_SET_AIS;
11533
1.51k
        params.ais = pdev->ais = pgs->alphaisshape;
11534
1.51k
    }
11535
3.76M
    if (pgs->overprint != pdev->overprint) {
11536
15.3k
        changed |= PDF14_SET_OVERPRINT;
11537
15.3k
        params.overprint = pdev->overprint = pgs->overprint;
11538
15.3k
    }
11539
3.76M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11540
15.3k
        changed |= PDF14_SET_STROKEOVERPRINT;
11541
15.3k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11542
15.3k
    }
11543
3.76M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11544
23.4k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11545
23.4k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11546
23.4k
    }
11547
3.76M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11548
15.8k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11549
15.8k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11550
15.8k
    }
11551
3.76M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11552
27.0k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11553
27.0k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11554
27.0k
        if_debug0m('v', pgs->memory,
11555
27.0k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11556
27.0k
    }
11557
3.76M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11558
28.1k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11559
28.1k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11560
28.1k
        if_debug0m('v', pgs->memory,
11561
28.1k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11562
28.1k
    }
11563
3.76M
    if (crop_blend_params) {
11564
38.9k
        params.ctm = group_params->ctm;
11565
38.9k
        params.bbox = group_params->bbox;
11566
38.9k
    }
11567
3.76M
    params.changed = changed;
11568
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11569
       now to the target.  Otherwise we send the compositor action
11570
       to the pdf14 device at this time.  This is due to the fact that we
11571
       need to often perform this operation when we are already starting to
11572
       do a compositor action */
11573
3.76M
    if (changed != 0) {
11574
109k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11575
109k
        if (code < 0)
11576
0
            return code;
11577
109k
        code = dev_proc(pdev->target, composite)
11578
109k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11579
109k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11580
109k
    }
11581
3.76M
    return code;
11582
3.76M
}
11583
11584
/*
11585
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11586
 * writing the clist.
11587
 */
11588
static  int
11589
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11590
                           gx_path *ppath, const gx_fill_params *params,
11591
                           const gx_drawing_color *pdcolor,
11592
                           const gx_clip_path *pcpath)
11593
1.08M
{
11594
1.08M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11595
1.08M
    gs_gstate new_pgs = *pgs;
11596
1.08M
    int code;
11597
1.08M
    gs_pattern2_instance_t *pinst = NULL;
11598
1.08M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11599
1.08M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11600
1.08M
    gsicc_rendering_param_t render_cond;
11601
1.08M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11602
1.08M
    int push_group = 0;
11603
11604
1.08M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11605
1.08M
    if (code < 0)
11606
0
        return code;
11607
1.08M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11608
1.08M
    if (code < 0)
11609
0
        return code;
11610
11611
1.08M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11612
908
        check_device_separable(dev);
11613
11614
1.08M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11615
1.08M
                          &render_cond);
11616
1.08M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11617
1.08M
                          &render_cond);
11618
11619
    /*
11620
     * Ensure that that the PDF 1.4 reading compositor will have the current
11621
     * blending parameters.  This is needed since the fill_rectangle routines
11622
     * do not have access to the gs_gstate.  Thus we have to pass any
11623
     * changes explictly.
11624
     */
11625
1.08M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11626
1.08M
    if (code < 0)
11627
0
        return code;
11628
    /* If we are doing a shading fill and we are in a transparency group of a
11629
       different color space, then we do not want to do the shading in the
11630
       device color space. It must occur in the source space.  To handle it in
11631
       the device space would require knowing all the nested transparency group
11632
       color space as well as the transparency.  Some of the shading code ignores
11633
       this, so we have to pass on the clist_writer device to enable proper
11634
       mapping to the transparency group color space. */
11635
11636
1.08M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11637
        /* Non-idempotent blends require a transparency
11638
         * group to be pushed because shadings might
11639
         * paint several pixels twice. */
11640
7.91k
        push_group = pgs->fillconstantalpha != 1.0 ||
11641
7.67k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11642
7.91k
        pinst =
11643
7.91k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11644
7.91k
           pinst->saved->has_transparency = true;
11645
           /* The transparency color space operations are driven by the pdf14
11646
              clist writer device.  */
11647
7.91k
           pinst->saved->trans_device = dev;
11648
7.91k
    }
11649
1.08M
    if (push_group) {
11650
234
        gs_fixed_rect box;
11651
234
        gs_fixed_rect dev_bbox;
11652
11653
234
        if (pcpath) {
11654
234
            gx_cpath_outer_box(pcpath, &box);
11655
234
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11656
234
            rect_intersect(box, dev_bbox);
11657
234
        } else
11658
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11659
11660
234
        if (ppath) {
11661
15
            gs_fixed_rect path_box;
11662
11663
15
            gx_path_bbox(ppath, &path_box);
11664
15
            if (box.p.x < path_box.p.x)
11665
15
                box.p.x = path_box.p.x;
11666
15
            if (box.p.y < path_box.p.y)
11667
15
                box.p.y = path_box.p.y;
11668
15
            if (box.q.x > path_box.q.x)
11669
15
                box.q.x = path_box.q.x;
11670
15
            if (box.q.y > path_box.q.y)
11671
15
                box.q.y = path_box.q.y;
11672
15
        }
11673
11674
234
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11675
            /* No need to do anything */
11676
52
            if (pinst != NULL) {
11677
52
                pinst->saved->trans_device = NULL;
11678
52
            }
11679
52
            return 0;
11680
52
        }
11681
11682
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11683
182
        code = push_shfill_group(pdev, &new_pgs, &box);
11684
182
    } else
11685
1.08M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11686
1.08M
    if (code >= 0) {
11687
1.08M
        new_pgs.trans_device = dev;
11688
1.08M
        new_pgs.has_transparency = true;
11689
1.08M
        if (gx_dc_is_pattern2_color(pdcolor))
11690
7.85k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11691
1.07M
        else
11692
1.07M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11693
1.08M
        new_pgs.trans_device = NULL;
11694
1.08M
        new_pgs.has_transparency = false;
11695
1.08M
    }
11696
1.08M
    if (code >= 0 && push_group) {
11697
180
        code = pop_shfill_group(&new_pgs);
11698
180
        if (code >= 0)
11699
180
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11700
180
    }
11701
1.08M
    if (pinst != NULL){
11702
7.85k
        pinst->saved->trans_device = NULL;
11703
7.85k
    }
11704
1.08M
    return code;
11705
1.08M
}
11706
11707
/*
11708
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11709
 * writing the clist.
11710
 */
11711
static  int
11712
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11713
                             gx_path *ppath, const gx_stroke_params *params,
11714
                             const gx_drawing_color *pdcolor,
11715
                             const gx_clip_path *pcpath)
11716
358k
{
11717
358k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11718
358k
    gs_gstate new_pgs = *pgs;
11719
358k
    int code = 0;
11720
358k
    gs_pattern2_instance_t *pinst = NULL;
11721
358k
    int push_group = 0;
11722
11723
    /*
11724
     * Ensure that that the PDF 1.4 reading compositor will have the current
11725
     * blending parameters.  This is needed since the fill_rectangle routines
11726
     * do not have access to the gs_gstate.  Thus we have to pass any
11727
     * changes explictly.
11728
     */
11729
358k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11730
358k
    if (code < 0)
11731
0
        return code;
11732
    /* If we are doing a shading stroke and we are in a transparency group of a
11733
       different color space, then we need to get the proper device information
11734
       passed along so that we use the correct color procs and colorinfo about
11735
       the transparency device and not the final target device */
11736
358k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11737
        /* Non-idempotent blends require a transparency
11738
         * group to be pushed because shadings might
11739
         * paint several pixels twice. */
11740
48
        push_group = pgs->strokeconstantalpha != 1.0 ||
11741
48
               !blend_is_idempotent(gs_currentblendmode(pgs));
11742
48
        if (pdev->color_model_stack != NULL) {
11743
48
            pinst =
11744
48
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11745
48
            pinst->saved->has_transparency = true;
11746
            /* The transparency color space operations are driven
11747
              by the pdf14 clist writer device.  */
11748
48
            pinst->saved->trans_device = dev;
11749
48
        }
11750
48
    }
11751
358k
    if (push_group) {
11752
0
        gs_fixed_rect box;
11753
0
        if (pcpath)
11754
0
            gx_cpath_outer_box(pcpath, &box);
11755
0
        else
11756
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11757
0
        if (ppath) {
11758
0
            gs_fixed_rect path_box;
11759
0
            gs_fixed_point expansion;
11760
11761
0
            gx_path_bbox(ppath, &path_box);
11762
            /* Expand the path bounding box by the scaled line width. */
11763
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11764
                /* The expansion is so large it caused a limitcheck. */
11765
0
                path_box.p.x = path_box.p.y = min_fixed;
11766
0
                path_box.q.x = path_box.q.y = max_fixed;
11767
0
            } else {
11768
0
                expansion.x += pgs->fill_adjust.x;
11769
0
                expansion.y += pgs->fill_adjust.y;
11770
                /*
11771
                 * It's theoretically possible for the following computations to
11772
                 * overflow, so we need to check for this.
11773
                 */
11774
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11775
0
                                path_box.p.x - expansion.x);
11776
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11777
0
                                path_box.p.y - expansion.y);
11778
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11779
0
                                path_box.q.x + expansion.x);
11780
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11781
0
                                path_box.q.y + expansion.y);
11782
0
            }
11783
0
            if (box.p.x < path_box.p.x)
11784
0
                box.p.x = path_box.p.x;
11785
0
            if (box.p.y < path_box.p.y)
11786
0
                box.p.y = path_box.p.y;
11787
0
            if (box.q.x > path_box.q.x)
11788
0
                box.q.x = path_box.q.x;
11789
0
            if (box.q.y > path_box.q.y)
11790
0
                box.q.y = path_box.q.y;
11791
0
        }
11792
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11793
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11794
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11795
0
    } else
11796
358k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11797
11798
358k
    if (code >= 0) {
11799
358k
        new_pgs.trans_device = dev;
11800
358k
        new_pgs.has_transparency = true;
11801
358k
        if (gx_dc_is_pattern2_color(pdcolor))
11802
48
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11803
358k
        else
11804
358k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11805
358k
        new_pgs.trans_device = NULL;
11806
358k
        new_pgs.has_transparency = false;
11807
358k
    }
11808
358k
    if (code >= 0 && push_group) {
11809
0
        code = pop_shfill_group(&new_pgs);
11810
0
        if (code >= 0)
11811
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11812
0
    }
11813
358k
    if (pinst != NULL)
11814
48
        pinst->saved->trans_device = NULL;
11815
358k
    return code;
11816
358k
}
11817
11818
/* Set up work for doing shading patterns in fill stroke through
11819
   the clist.  We have to do all the dirty work now since we are
11820
   going through the default fill and stroke operations individually */
11821
static int
11822
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11823
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11824
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11825
    const gx_clip_path* pcpath)
11826
0
{
11827
0
    union {
11828
0
        const gs_gstate *cpgs;
11829
0
        gs_gstate *pgs;
11830
0
    } const_breaker;
11831
0
    gs_gstate *pgs;
11832
0
    int code, code2;
11833
0
    gs_transparency_group_params_t params = { 0 };
11834
0
    gs_fixed_rect clip_bbox;
11835
0
    gs_rect bbox, group_stroke_box;
11836
0
    float fill_alpha;
11837
0
    float stroke_alpha;
11838
0
    gs_blend_mode_t blend_mode;
11839
0
    gs_fixed_rect path_bbox;
11840
0
    int expansion_code;
11841
0
    gs_fixed_point expansion;
11842
11843
    /* Break const just once, neatly */
11844
0
    const_breaker.cpgs = cpgs;
11845
0
    pgs = const_breaker.pgs;
11846
11847
0
    fill_alpha = pgs->fillconstantalpha;
11848
0
    stroke_alpha = pgs->strokeconstantalpha;
11849
0
    blend_mode = pgs->blend_mode;
11850
11851
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11852
0
    if (code < 0 && code != gs_error_unknownerror)
11853
0
        return code;
11854
0
    if (code == gs_error_unknownerror) {
11855
        /* didn't get clip box from gx_curr_fixed_bbox */
11856
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11857
0
        clip_bbox.q.x = int2fixed(dev->width);
11858
0
        clip_bbox.q.y = int2fixed(dev->height);
11859
0
    }
11860
0
    if (pcpath)
11861
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11862
11863
    /* expand the ppath using stroke expansion rule, then intersect it */
11864
0
    code = gx_path_bbox(ppath, &path_bbox);
11865
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11866
0
        return 0;   /* ignore empty path */
11867
0
    if (code < 0)
11868
0
        return code;
11869
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11870
0
    if (expansion_code >= 0) {
11871
0
        path_bbox.p.x -= expansion.x;
11872
0
        path_bbox.p.y -= expansion.y;
11873
0
        path_bbox.q.x += expansion.x;
11874
0
        path_bbox.q.y += expansion.y;
11875
0
    }
11876
0
    rect_intersect(path_bbox, clip_bbox);
11877
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11878
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11879
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11880
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11881
11882
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11883
0
    if (code < 0)
11884
0
        return code;
11885
11886
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11887
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11888
0
        pgs->overprint && pgs->stroke_overprint &&
11889
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11890
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11891
11892
0
        params.Isolated = false;
11893
0
        params.group_color_type = UNKNOWN;
11894
0
        params.Knockout = false;
11895
0
        params.page_group = false;
11896
0
        params.group_opacity = fill_alpha;
11897
0
        params.group_shape = 1.0;
11898
11899
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11900
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11901
0
        if (code < 0)
11902
0
            return code;
11903
11904
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11905
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11906
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11907
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11908
11909
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11910
0
        if (code < 0)
11911
0
            goto cleanup;
11912
11913
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11914
0
        if (code < 0)
11915
0
            goto cleanup;
11916
11917
0
    } else {
11918
        /* Push a non-isolated knockout group. Do not change the alpha or
11919
           blend modes */
11920
0
        params.Isolated = false;
11921
0
        params.group_color_type = UNKNOWN;
11922
0
        params.Knockout = true;
11923
0
        params.page_group = false;
11924
0
        params.group_opacity = 1.0;
11925
0
        params.group_shape = 1.0;
11926
11927
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11928
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11929
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11930
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11931
11932
        /* restore blend mode for actual drawing in the group */
11933
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11934
11935
0
        if (fill_alpha > 0.0) {
11936
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11937
11938
            /* If we are in an overprint situation, set the blend mode to compatible
11939
               overprint */
11940
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11941
0
                pgs->overprint &&
11942
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11943
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11944
11945
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11946
0
            if (code < 0)
11947
0
                goto cleanup;
11948
11949
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11950
0
                pgs->overprint &&
11951
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11952
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11953
0
        }
11954
11955
0
        if (stroke_alpha > 0.0) {
11956
            /* Note that the stroke can end up looking like a fill here */
11957
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11958
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11959
11960
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11961
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11962
11963
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11964
0
            if (code < 0)
11965
0
                goto cleanup;
11966
11967
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11968
0
                pgs->overprint &&
11969
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11970
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11971
0
        }
11972
0
    }
11973
11974
0
cleanup:
11975
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11976
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11977
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11978
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11979
11980
    /* Restore where we were. If an error occured while in the group push
11981
       return that error code but try to do the cleanup */
11982
0
    code2 = gs_end_transparency_group(pgs);
11983
0
    if (code2 < 0) {
11984
        /* At this point things have gone very wrong. We should just shut down */
11985
0
        code = gs_abort_pdf14trans_device(pgs);
11986
0
        return code2;
11987
0
    }
11988
11989
    /* Restore if there were any changes */
11990
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11991
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11992
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11993
11994
0
    return code;
11995
0
}
11996
11997
/*
11998
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11999
 * writing the clist.
12000
 */
12001
static  int
12002
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
12003
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
12004
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
12005
                             const gx_clip_path *pcpath)
12006
7.96k
{
12007
7.96k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12008
7.96k
    gs_gstate new_pgs = *pgs;
12009
7.96k
    int code;
12010
12011
7.96k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12012
7.88k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12013
90
        return 0;
12014
12015
    /*
12016
     * Ensure that that the PDF 1.4 reading compositor will have the current
12017
     * blending parameters.  This is needed since the fill_rectangle routines
12018
     * do not have access to the gs_gstate.  Thus we have to pass any
12019
     * changes explictly.
12020
     */
12021
7.87k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12022
7.87k
    if (code < 0)
12023
0
        return code;
12024
    /* If we are doing a shading fill or stroke, the clist can't
12025
       deal with this and end up in the pdf_fill_stroke operation.
12026
       We will need to break up the fill stroke now and do
12027
       the appropriate group pushes and set up. */
12028
12029
7.87k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12030
7.87k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12031
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12032
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12033
0
    }
12034
7.87k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12035
7.87k
    new_pgs.trans_device = dev;
12036
7.87k
    new_pgs.has_transparency = true;
12037
7.87k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12038
7.87k
                                       params_stroke, pdevc_stroke, pcpath);
12039
7.87k
    new_pgs.trans_device = NULL;
12040
7.87k
    new_pgs.has_transparency = false;
12041
7.87k
    return code;
12042
7.87k
}
12043
12044
/*
12045
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12046
 * writing the clist.
12047
 */
12048
static  int
12049
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12050
                 const gs_text_params_t * text, gs_font * font,
12051
                 const gx_clip_path * pcpath,
12052
                 gs_text_enum_t ** ppenum)
12053
2.23M
{
12054
2.23M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12055
2.23M
    gs_text_enum_t *penum;
12056
2.23M
    int code;
12057
2.23M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12058
2.23M
    float opacity = pgs->fillconstantalpha;
12059
2.23M
    float shape = 1.0;
12060
2.23M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12061
2.23M
    bool draw = !(text->operation & TEXT_DO_NONE);
12062
2.23M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12063
2.23M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12064
2.23M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12065
12066
2.23M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12067
    /*
12068
     * Ensure that that the PDF 1.4 reading compositor will have the current
12069
     * blending parameters.  This is needed since the fill_rectangle routines
12070
     * do not have access to the gs_gstate.  Thus we have to pass any
12071
     * changes explictly.
12072
     */
12073
2.23M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12074
2.23M
    if (code < 0)
12075
0
        return code;
12076
    /* Pass text_begin to the target */
12077
2.23M
    code = gx_forward_text_begin(dev, pgs, text, font,
12078
2.23M
                                 pcpath, &penum);
12079
2.23M
    if (code < 0)
12080
737
        return code;
12081
12082
   /* Catch case where we already pushed a group and are trying to push another one.
12083
   In that case, we will pop the current one first, as we don't want to be left
12084
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12085
   will not be caught until we do the put_image and notice that the stack is not
12086
   empty. */
12087
2.22M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12088
3
        code = gs_end_transparency_group(pgs);
12089
3
        if (code < 0)
12090
0
            return code;
12091
3
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12092
3
    }
12093
12094
    /* We may need to push a non-isolated transparency group if the following
12095
    is true.
12096
    1) We are not currently in one that we pushed for text.  This is
12097
    is determined by looking at the pdf14 device.
12098
    2) The blend mode is not Normal or the opacity is not 1.0
12099
    3) Text knockout is set to true
12100
    4) And we are actually drawing text
12101
    */
12102
12103
2.22M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12104
2.22M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12105
2.21M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12106
12.0k
        text_mode != 3 && /* don't bother with invisible text */
12107
11.9k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12108
2.71k
        if (draw) {
12109
2.71k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12110
2.71k
            if (code == 0)
12111
2.71k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12112
2.71k
        }
12113
2.71k
    }
12114
2.22M
    *ppenum = (gs_text_enum_t *)penum;
12115
2.22M
    return code;
12116
2.22M
}
12117
12118
static  int
12119
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12120
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12121
                           const gs_int_rect * prect,
12122
                           const gx_drawing_color * pdcolor,
12123
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12124
                           gx_image_enum_common_t ** pinfo)
12125
41.6k
{
12126
41.6k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12127
41.6k
    int code;
12128
41.6k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12129
41.6k
    const gs_image_t *pim = (const gs_image_t *)pic;
12130
41.6k
    gx_image_enum *penum;
12131
41.6k
    gx_color_tile *ptile;
12132
41.6k
    gs_rect bbox_in, bbox_out;
12133
41.6k
    gs_transparency_group_params_t tgp;
12134
    /*
12135
     * Ensure that that the PDF 1.4 reading compositor will have the current
12136
     * blending parameters.  This is needed since the fill_rectangle routines
12137
     * do not have access to the gs_gstate.  Thus we have to pass any
12138
     * changes explictly.
12139
     */
12140
41.6k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12141
41.6k
    if (code < 0)
12142
0
        return code;
12143
    /* Pass image to the target */
12144
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12145
       case the clist writer cannot handle this image itself.  In such a case,
12146
       we want to make sure we dont use the target device.  I don't necc. like
12147
       doing it this way.  Probably need to go back and do something a bit
12148
       more elegant. */
12149
41.6k
    pgs_noconst->has_transparency = true;
12150
41.6k
    pgs_noconst->trans_device = dev;
12151
12152
    /* If we are filling an image mask with a pattern that has a transparency
12153
       then we need to do some special handling */
12154
41.6k
    if (pim->ImageMask) {
12155
104
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12156
28
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12157
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12158
0
                    ptile = pdcolor->colors.pattern.p_tile;
12159
                    /* Set up things in the ptile so that we get the proper
12160
                       blending etc */
12161
                    /* Set the blending procs and the is_additive setting based
12162
                       upon the number of channels */
12163
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12164
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12165
0
                        ptile->ttrans->is_additive = true;
12166
0
                    } else {
12167
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12168
0
                        ptile->ttrans->is_additive = false;
12169
0
                    }
12170
                    /* Set the blending mode in the ptile based upon the current
12171
                       setting in the gs_gstate */
12172
0
                    ptile->blending_mode = pgs->blend_mode;
12173
                    /* Set the procs so that we use the proper filling method. */
12174
                    /* Let the imaging stuff get set up */
12175
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12176
0
                                                        prect, pdcolor,
12177
0
                                                        pcpath, mem, pinfo);
12178
0
                    if (code < 0)
12179
0
                        return code;
12180
12181
0
                    penum = (gx_image_enum *) *pinfo;
12182
                    /* Apply inverse of the image matrix to our
12183
                       image size to get our bounding box. */
12184
0
                    bbox_in.p.x = 0;
12185
0
                    bbox_in.p.y = 0;
12186
0
                    bbox_in.q.x = pim->Width;
12187
0
                    bbox_in.q.y = pim->Height;
12188
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12189
0
                                                     &bbox_out);
12190
0
                    if (code < 0)
12191
0
                        return code;
12192
                    /* Set up a compositor action for pushing the group */
12193
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12194
0
                    tgp.Isolated = true;
12195
0
                    tgp.Knockout = false;
12196
0
                    tgp.page_group = false;
12197
0
                    tgp.mask_id = 0;
12198
0
                    tgp.image_with_SMask = false;
12199
0
                    tgp.idle = false;
12200
0
                    tgp.iccprofile = NULL;
12201
0
                    tgp.icc_hashcode = 0;
12202
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12203
0
                    tgp.ColorSpace = NULL;
12204
0
                    tgp.text_group = 0;
12205
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12206
0
                    tgp.group_shape = 1.0;
12207
                    /* This will handle the compositor command */
12208
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12209
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12210
0
                    ptile->ttrans->image_render = penum->render;
12211
0
                    penum->render = &pdf14_pattern_trans_render;
12212
0
                    ptile->trans_group_popped = false;
12213
0
                    pgs_noconst->has_transparency = false;
12214
0
                    pgs_noconst->trans_device = NULL;
12215
0
                    return code;
12216
0
                }
12217
0
            }
12218
28
        }
12219
104
    }
12220
    /* This basically tries high level images for clist. If that fails
12221
       then we do the default */
12222
41.6k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12223
41.6k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12224
41.6k
    if (code < 0){
12225
10.2k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12226
10.2k
                                        pdcolor, pcpath, mem, pinfo);
12227
10.2k
        pgs_noconst->has_transparency = false;
12228
10.2k
        pgs_noconst->trans_device = NULL;
12229
10.2k
        return code;
12230
31.4k
    } else {
12231
31.4k
        pgs_noconst->has_transparency = false;
12232
31.4k
        pgs_noconst->trans_device = NULL;
12233
31.4k
        return code;
12234
31.4k
    }
12235
41.6k
}
12236
12237
static int
12238
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12239
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12240
2.45k
{
12241
2.45k
    int code;
12242
12243
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12244
2.45k
                                  x, y, w, h, plane_height);
12245
2.45k
    return code;
12246
2.45k
}
12247
12248
static int
12249
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12250
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12251
10.4k
{
12252
10.4k
    int code;
12253
10.4k
    pdf14_clist_device *p14dev;
12254
10.4k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12255
12256
10.4k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12257
10.4k
    if (code < 0)
12258
0
        return code;
12259
    /*
12260
     * Set the color_info of the clist device to match the compositing
12261
     * device.  We will restore it when the compositor is popped.
12262
     * See pdf14_clist_composite for the restore.  Do the
12263
     * same with the gs_gstate's get_cmap_procs.  We do not want
12264
     * the gs_gstate to use transfer functions on our color values.
12265
     * The transfer functions will be applied at the end after we
12266
     * have done our PDF 1.4 blend operations.
12267
     */
12268
10.4k
    p14dev = (pdf14_clist_device *)(*pcdev);
12269
10.4k
    p14dev->saved_target_color_info = dev->color_info;
12270
10.4k
    dev->color_info = (*pcdev)->color_info;
12271
    /* Make sure that we keep the anti-alias information though */
12272
10.4k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12273
10.4k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12274
12275
    /* adjust the clist_color_info now */
12276
10.4k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12277
10.4k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12278
10.4k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12279
10.4k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12280
10.4k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12281
12282
10.4k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12283
10.4k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12284
10.4k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12285
10.4k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12286
10.4k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12287
10.4k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12288
10.4k
    p14dev->saved_target_get_color_mapping_procs =
12289
10.4k
                              dev_proc(dev, get_color_mapping_procs);
12290
10.4k
    p14dev->saved_target_get_color_comp_index =
12291
10.4k
                              dev_proc(dev, get_color_comp_index);
12292
10.4k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12293
10.4k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12294
10.4k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12295
10.4k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12296
10.4k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12297
10.4k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12298
10.4k
    gx_set_cmap_procs(pgs, dev);
12299
10.4k
    return code;
12300
10.4k
}
12301
/*
12302
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12303
 * to create a compositing device for clist writing.  The primary purpose of
12304
 * this device is to provide support for the process color model in which
12305
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12306
 * model of the output device.)  The actual work of compositing the image is
12307
 * done on the output (reader) side of the clist.
12308
 */
12309
static  int
12310
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12311
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12312
284k
{
12313
284k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12314
284k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12315
284k
    int code = 0;
12316
12317
    /* We only handle the push/pop operations */
12318
284k
    switch (pdf14pct->params.pdf14_op) {
12319
10.4k
        case PDF14_PUSH_DEVICE:
12320
10.4k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12321
            /* Change (non-error) code to 1 to indicate that we created
12322
             * a device. */
12323
10.4k
            if (code >= 0)
12324
10.4k
                code = 1;
12325
10.4k
            return code;
12326
12327
10.0k
        case PDF14_POP_DEVICE:
12328
10.0k
            code = clist_writer_check_empty_cropping_stack(cdev);
12329
10.0k
            break;
12330
12331
3.71k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12332
38.9k
        case PDF14_BEGIN_TRANS_GROUP:
12333
38.9k
            { /* HACK: store mask_id into our params for subsequent
12334
                   calls of c_pdf14trans_write. To do this we must
12335
                   break const. */
12336
38.9k
                gs_pdf14trans_t * pdf14pct_noconst;
12337
12338
38.9k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12339
                /* What ever the current mask ID is, that is the
12340
                   softmask group through which this transparency
12341
                   group must be rendered. Store it now. */
12342
38.9k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12343
38.9k
                if_debug1m('v', pgs->memory,
12344
38.9k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12345
38.9k
                           cdev->mask_id);
12346
38.9k
            }
12347
38.9k
            break;
12348
36.2k
        case PDF14_END_TRANS_GROUP:
12349
38.9k
        case PDF14_END_TRANS_TEXT_GROUP:
12350
38.9k
            code = 0; /* A place for breakpoint. */
12351
38.9k
            break;
12352
40.9k
        case PDF14_BEGIN_TRANS_MASK:
12353
            /* A new mask has been started */
12354
40.9k
            cdev->mask_id = ++cdev->mask_id_count;
12355
            /* replacing is set everytime that we
12356
               have a zpushtransparencymaskgroup */
12357
40.9k
            { /* HACK: store mask_id into our params for subsequent
12358
                   calls of c_pdf14trans_write. To do this we must
12359
                   break const. */
12360
40.9k
                gs_pdf14trans_t * pdf14pct_noconst;
12361
12362
40.9k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12363
40.9k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12364
40.9k
                if_debug1m('v', pgs->memory,
12365
40.9k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12366
40.9k
                           cdev->mask_id);
12367
40.9k
            }
12368
40.9k
            break;
12369
18.1k
        case PDF14_END_TRANS_MASK:
12370
18.1k
            code = 0; /* A place for breakpoint. */
12371
18.1k
            break;
12372
0
        case PDF14_PUSH_TRANS_STATE:
12373
0
            code = 0; /* A place for breakpoint. */
12374
0
            break;
12375
17.6k
        case PDF14_POP_TRANS_STATE:
12376
17.6k
            code = 0; /* A place for breakpoint. */
12377
17.6k
            break;
12378
0
        case PDF14_ABORT_DEVICE:
12379
0
            code = 0;
12380
0
            break;
12381
0
        case PDF14_PUSH_SMASK_COLOR:
12382
0
            *pcdev = dev;
12383
0
            return 0;
12384
0
            break;
12385
0
        case PDF14_POP_SMASK_COLOR:
12386
0
            *pcdev = dev;
12387
0
            return 0;
12388
0
            break;
12389
109k
        default:
12390
109k
            break;   /* do nothing for remaining ops */
12391
284k
    }
12392
273k
    *pcdev = dev;
12393
273k
    if (code < 0)
12394
0
        return code;
12395
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12396
       apply_composite. */
12397
273k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12398
    /* Wrote an extra ctm. */
12399
273k
    cmd_clear_known(cdev, ctm_known);
12400
12401
273k
    return code;
12402
273k
}
12403
12404
/*
12405
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12406
 * device color_info data match the compositing device.  We need to do this
12407
 * since the PDF 1.4 transparency compositing device may use a different
12408
 * process color model than the output device.  We do not need to modify the
12409
 * color related device procs since the compositing device has its own.  We
12410
 * restore the color_info data when the transparency device is popped.
12411
 */
12412
static  int
12413
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12414
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12415
21.9M
{
12416
21.9M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12417
21.9M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12418
21.9M
    gs_devn_params * pclist_devn_params;
12419
21.9M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12420
21.9M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12421
21.9M
    gsicc_rendering_param_t render_cond;
12422
21.9M
    cmm_dev_profile_t *dev_profile;
12423
12424
21.9M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12425
21.9M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12426
21.9M
                          &render_cond);
12427
12428
    /* If we are using the blending color space, then be sure to use that. */
12429
21.9M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12430
0
        dev_profile->blend_profile != NULL)
12431
0
        cl_icc_profile = dev_profile->blend_profile;
12432
21.9M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12433
0
        dev_profile->oi_profile != NULL)
12434
0
        cl_icc_profile = dev_profile->oi_profile;
12435
12436
21.9M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12437
21.9M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12438
21.9M
                          &render_cond);
12439
    /*
12440
     * We only handle the push/pop operations. Save and restore the color_info
12441
     * field for the clist device.  This is needed since the process color
12442
     * model of the clist device needs to match the PDF 1.4 compositing
12443
     * device.
12444
     */
12445
21.9M
    switch (pdf14pct->params.pdf14_op) {
12446
1.07M
    case PDF14_PUSH_DEVICE:
12447
        /* Overprint simulation sets the profile at prototype creation, as does
12448
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12449
1.07M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12450
1.07M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12451
1.07M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12452
1.07M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12453
1.07M
                -1, "c_pdf14trans_clist_read_update");
12454
1.07M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12455
1.07M
        }
12456
            /*
12457
             * If we are blending using spot colors (i.e. the output device
12458
             * supports spot colors) then we need to transfer
12459
             * color info from the clist PDF 1.4 compositing reader device
12460
             * to the clist writer PDF 1.4 compositing device.
12461
             * This info was transfered from that device to the output
12462
             * device as a set of device parameters.  However the clist
12463
             * reader PDF 1.4 compositing device did not exist when the
12464
             * device parameters were read from the clist.  So that info
12465
             * was buffered into the output device.
12466
             */
12467
1.07M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12468
1.07M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12469
848
                int num_comp = p14dev->color_info.num_components;
12470
848
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12471
                /*
12472
                 * The number of components for the PDF14 device is the sum
12473
                 * of the process components and the number of spot colors
12474
                 * for the page.  If the color capabilities of the parent
12475
                 * device (which coming into this are the same as the p14dev)
12476
                 * are smaller than the number of page spot colors then
12477
                 * use that for the number of components. Otherwise use
12478
                 * the page_spot_colors.  The exception is, if we had used
12479
                 * the sICCOutputColors setting, then just use that, which
12480
                 * should be already baked into num_comp. With clist patterns,
12481
                 * cdev->icc_struct may be null.
12482
                 */
12483
12484
848
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12485
848
                    p14dev->devn_params.page_spot_colors =
12486
848
                        pclist_devn_params->page_spot_colors;
12487
848
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12488
0
                        if (p14dev->num_planar_planes > 0)
12489
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12490
0
                        p14dev->color_info.num_components = num_comp;
12491
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12492
848
                    } else {
12493
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12494
848
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12495
848
                            int n = p14dev->num_std_colorants +
12496
848
                                    p14dev->devn_params.page_spot_colors + has_tags;
12497
848
                            if (p14dev->num_planar_planes > 0)
12498
848
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12499
848
                            p14dev->color_info.num_components = n;
12500
848
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12501
848
                        }
12502
848
                    }
12503
848
                }
12504
                /* limit the num_components to the max. */
12505
848
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12506
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12507
                /* Transfer the data for the spot color names
12508
                   But we have to free what may be there before we do this */
12509
848
                devn_free_params((gx_device*) p14dev);
12510
848
                p14dev->devn_params.separations =
12511
848
                    pclist_devn_params->pdf14_separations;
12512
848
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12513
848
                if (num_comp != p14dev->color_info.num_components) {
12514
                    /* Historically, there has been a comment here:
12515
                       "When the pdf14 device is opened it creates a context and some
12516
                       soft mask related objects.  The push device compositor action
12517
                       will have already created these but they are the wrong size.
12518
                       We must destroy them though before reopening the device."
12519
                       I can't see why this is the case, and testing in the cluster
12520
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12521
                       shows that this freeing/NULLing the ctx here causes problems
12522
                       when the freed ctx is reinserted at the end of clist pattern
12523
                       files. Accordingly, I'm removing the freeing/NULLing for now
12524
                       at least. */
12525
0
                    int code = dev_proc(tdev, open_device) (tdev);
12526
0
                    if (code < 0)
12527
0
                        return code;
12528
0
                }
12529
848
            }
12530
            /* Check if we need to swap out the ICC profile for the pdf14
12531
               device.  This will occur if our source profile for our device
12532
               happens to be something like CIELAB.  Then we will blend in
12533
               RGB (unless a trans group is specified) */
12534
1.07M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12535
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12536
0
                                        -1, "c_pdf14trans_clist_read_update");
12537
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12538
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12539
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12540
                /* Keep a pointer to the clist device */
12541
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12542
0
            }
12543
1.07M
            break;
12544
12545
1.07M
        case PDF14_POP_DEVICE:
12546
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12547
                    the clist playback. This code is not executed while clist
12548
                    writing. */
12549
            cdev->color_info = p14dev->saved_target_color_info;
12550
#     endif
12551
1.07M
           break;
12552
12553
19.7M
        default:
12554
19.7M
            break;   /* do nothing for remaining ops */
12555
21.9M
    }
12556
12557
21.9M
    return 0;
12558
21.9M
}
12559
12560
/*
12561
 * Get cropping for the compositor command.
12562
 */
12563
static  int
12564
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12565
                          int cropping_min, int cropping_max)
12566
284k
{
12567
284k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12568
284k
    switch (pdf14pct->params.pdf14_op) {
12569
10.4k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12570
10.0k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12571
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12572
3.71k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12573
38.9k
        case PDF14_BEGIN_TRANS_GROUP:
12574
38.9k
            { gs_int_rect rect;
12575
12576
                /* Text group always uses parents size*/
12577
38.9k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12578
2.71k
                    *ry = cropping_min;
12579
2.71k
                    *rheight = cropping_max - *ry;
12580
36.2k
                } else {
12581
36.2k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12582
36.2k
                        &pdf14pct->params.bbox, &rect);
12583
                    /* We have to crop this by the parent object.   */
12584
36.2k
                    *ry = max(rect.p.y, cropping_min);
12585
36.2k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12586
36.2k
                }
12587
38.9k
                return PUSHCROP; /* Push cropping. */
12588
3.71k
            }
12589
40.9k
        case PDF14_BEGIN_TRANS_MASK:
12590
40.9k
            { gs_int_rect rect;
12591
12592
40.9k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12593
40.9k
                                                    &pdf14pct->params.bbox, &rect);
12594
                /* We have to crop this by the parent object and worry about the BC outside
12595
                   the range, except for image SMask which don't affect areas outside the image.
12596
                   The presence of a transfer function opens the possibility of issues with this */
12597
40.9k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12598
17.0k
                      pdf14pct->params.function_is_identity)) {
12599
                    /* In this case there will not be a background effect to
12600
                       worry about.  The mask will not have any effect outside
12601
                       the bounding box.  This is NOT the default or common case. */
12602
17.0k
                    *ry = max(rect.p.y, cropping_min);
12603
17.0k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12604
17.0k
                    return PUSHCROP; /* Push cropping. */
12605
23.8k
                }  else {
12606
                    /* We need to make the soft mask range as large as the parent
12607
                       due to the fact that the background color can have an impact
12608
                       OUTSIDE the bounding box of the soft mask */
12609
23.8k
                    *ry = cropping_min;
12610
23.8k
                    *rheight = cropping_max - cropping_min;
12611
23.8k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12612
22.7k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12613
1.11k
                    else
12614
1.11k
                        return PUSHCROP; /* Push cropping. */
12615
23.8k
                }
12616
40.9k
            }
12617
36.2k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12618
2.67k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12619
18.1k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12620
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12621
17.6k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12622
109k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12623
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12624
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12625
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12626
284k
    }
12627
0
    return ALLBANDS;
12628
284k
}
12629
12630
/*
12631
 * This routine will check to see if the color component name matches those
12632
 * that are available amoung the current device's color components.  If the
12633
 * color name is known to the output device then we add it to the list of
12634
 * colorants for the PDF 1.4 transparency compositor.
12635
 *
12636
 * Notes:  There are currently three different versions of The PDF 1.4
12637
 * transparency compositor device.  The choice of which one is being used
12638
 * depends upon the process color model of the output device.  This procedure
12639
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12640
 * plus spot color process color model.
12641
 *
12642
 * Parameters:
12643
 *   dev - pointer to device data structure.
12644
 *   pname - pointer to name (zero termination not required)
12645
 *   nlength - length of the name
12646
 *   number of process colorants (either 1, 3, or 4)
12647
 *
12648
 * This routine returns a positive value (0 to n) which is the device colorant
12649
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12650
 * the colorant is not being used due to a SeparationOrder device parameter.
12651
 * It returns a negative value if not found.
12652
 */
12653
static int
12654
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12655
    int name_size, int component_type, int num_process_colors, int cmyk)
12656
7.84k
{
12657
7.84k
    pdf14_device *pdev = (pdf14_device *)dev;
12658
7.84k
    gx_device *tdev = pdev->target;
12659
7.84k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12660
7.84k
    gs_separations *pseparations;
12661
7.84k
    int comp_index;
12662
7.84k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12663
7.84k
    int offset;
12664
12665
7.84k
    while (tdev->child) {
12666
0
        tdev = tdev->child;
12667
0
    }
12668
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12669
    /* get the devn_params from the target to avoid accessing using the wrong  */
12670
    /* pointer. Bug 696372.                                                    */
12671
7.84k
    if (tdev == (gx_device *)pdev)
12672
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12673
7.84k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12674
7.84k
    pseparations = &pdevn_params->separations;
12675
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12676
     * where we are in a blend color space that is RGB or Gray based and we
12677
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12678
     * Yellow or Black, then we should use the alternate tint transform */
12679
7.84k
    if (num_process_colors < 4) {
12680
638
        int k;
12681
3.19k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12682
2.55k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12683
0
                return -1;
12684
2.55k
        }
12685
638
    }
12686
12687
7.84k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12688
12689
    /* The pdf14_clist_composite may have set the color procs.
12690
       We need the real target procs. */
12691
7.84k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12692
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12693
7.84k
        target_get_color_comp_index =
12694
7.84k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12695
    /*
12696
    * If this is not a separation name then simply forward it to the target
12697
    * device or return -1 if we are doing overprint simulation.
12698
    * The halftone setup expects this.
12699
    */
12700
7.84k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12701
7.84k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12702
6.91k
            if (target_get_color_comp_index != NULL)
12703
6.91k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12704
0
            else
12705
0
                return -1;
12706
6.91k
    }
12707
936
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12708
0
        return -1;
12709
0
    }
12710
12711
    /*
12712
    * Check if the component is in either the process color model list
12713
    * or in the SeparationNames list.
12714
    */
12715
936
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12716
936
        name_size, component_type);
12717
12718
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12719
     * This is a decision we take here to avoid problems with PDFI not
12720
     * counting such colorants as spots. */
12721
936
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12722
38
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12723
0
            return -1;
12724
38
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12725
0
            return -1;
12726
38
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12727
0
            return -1;
12728
38
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12729
0
            return -1;
12730
38
    }
12731
    /* A psdrgb device, with simulate overprint will have become a cmyk
12732
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12733
     * either, but we need to return real numbers for them as the underlying
12734
     * routine won't know about these. */
12735
936
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12736
2
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12737
0
            return 3;
12738
2
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12739
0
            return 0;
12740
2
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12741
0
            return 1;
12742
2
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12743
0
            return 2;
12744
2
    }
12745
12746
    /*
12747
    * Return the colorant number if we know this name.  Note adjustment for
12748
    * compensating of blend color space.
12749
    */
12750
936
    if (comp_index >= 0)
12751
896
        return comp_index - offset;
12752
12753
    /* Only worry about the target if we are not doing an overprint simulation */
12754
40
    if (!pdev->overprint_sim) {
12755
        /*
12756
        * If we do not know this color, check if the output (target) device does.
12757
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12758
        * the colorant so we will only get < 0 returned when we hit the max. for
12759
        * the target device.
12760
        */
12761
40
        if (target_get_color_comp_index != NULL)
12762
40
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12763
0
        else
12764
0
            return -1;
12765
        /*
12766
        * Ignore color if unknown to the output device or if color is not being
12767
        * imaged due to the SeparationOrder device parameter.
12768
        */
12769
40
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12770
0
            return comp_index - offset;
12771
40
    }
12772
12773
    /*
12774
    * This is a new colorant.  Add it to our list of colorants.
12775
    * The limit accounts for the number of process colors (at least 4).
12776
    */
12777
40
    if ((pseparations->num_separations + 1) <
12778
40
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12779
40
        int sep_num = pseparations->num_separations++;
12780
40
        int color_component_number;
12781
40
        byte * sep_name;
12782
12783
40
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12784
40
            name_size, "pdf14_spot_get_color_comp_index");
12785
40
        if (sep_name == NULL) {
12786
0
            pseparations->num_separations--;  /* we didn't add it */
12787
0
            return -1;
12788
0
        }
12789
40
        memcpy(sep_name, pname, name_size);
12790
40
        pseparations->names[sep_num].size = name_size;
12791
40
        pseparations->names[sep_num].data = sep_name;
12792
40
        color_component_number = sep_num + num_process_colors;
12793
40
        if (color_component_number >= dev->color_info.max_components)
12794
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12795
40
        else
12796
40
            pdevn_params->separation_order_map[color_component_number] =
12797
40
            color_component_number;
12798
12799
        /* Indicate that we need to find equivalent CMYK color. */
12800
40
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12801
40
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12802
12803
        /* If we're doing an overprint simulation, then the target device
12804
         * (for instance) might not know about this colorant. This is annoying
12805
         * as the target can't then output the correct names. Call the target
12806
         * get_color_comp_index routine and ignore the result to give it a
12807
         * chance to stash it. */
12808
40
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12809
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12810
12811
40
        return color_component_number;
12812
40
    }
12813
12814
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12815
40
}
12816
12817
12818
/* CMYK process + spots */
12819
static int
12820
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12821
    int name_size, int component_type)
12822
7.21k
{
12823
7.21k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12824
7.21k
}
12825
12826
/* RGB process + spots */
12827
static int
12828
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12829
    int name_size, int component_type)
12830
638
{
12831
638
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12832
638
}
12833
12834
/* Gray process + spots */
12835
static int
12836
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12837
    int name_size, int component_type)
12838
0
{
12839
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12840
0
}
12841
12842
/* These functions keep track of when we are dealing with soft masks.
12843
   In such a case, we set the default color profiles to ones that ensure
12844
   proper soft mask rendering. */
12845
static int
12846
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12847
22.5k
{
12848
22.5k
    pdf14_device * pdev = (pdf14_device *) dev;
12849
22.5k
    pdf14_smaskcolor_t *result;
12850
22.5k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12851
22.5k
    int k;
12852
12853
    /* See if we have profiles already in place.   Note we also have to
12854
       worry about a corner case where this device does not have a
12855
       smaskcolor stucture to store the profiles AND the profiles were
12856
       already swapped out in the icc_manager.  This can occur when we
12857
       pushed a transparency mask and then inside the mask we have a pattern
12858
       which also has a transparency mask.   The state of the icc_manager
12859
       is that it already has done the swap and there is no need to fool
12860
       with any of this while dealing with the soft mask within the pattern */
12861
22.5k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12862
22.5k
        pgs->icc_manager->smask_profiles->swapped) {
12863
0
            return 0;
12864
0
    }
12865
22.5k
    if (pdev->smaskcolor != NULL) {
12866
19
        pdev->smaskcolor->ref_count++;
12867
19
        if_debug1m(gs_debug_flag_icc, dev->memory,
12868
19
                   "[icc] Increment smask color now %d\n",
12869
19
                   pdev->smaskcolor->ref_count);
12870
22.5k
    } else {
12871
        /* Allocate and swap out the current profiles.  The softmask
12872
           profiles should already be in place */
12873
22.5k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12874
22.5k
                                &st_pdf14_smaskcolor,
12875
22.5k
                                "pdf14_increment_smask_color");
12876
22.5k
        if (result == NULL)
12877
0
            return gs_error_VMerror;
12878
12879
22.5k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12880
22.5k
        if (result->profiles == NULL)
12881
0
            return gs_error_VMerror;
12882
12883
22.5k
        pdev->smaskcolor = result;
12884
12885
22.5k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12886
22.5k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12887
22.5k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12888
22.5k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12889
22.5k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12890
22.5k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12891
22.5k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12892
22.5k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12893
22.5k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12894
22.5k
        pgs->icc_manager->smask_profiles->swapped = true;
12895
22.5k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12896
22.5k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12897
22.5k
        pdev->smaskcolor->ref_count = 1;
12898
        /* We also need to update the profile that is currently in the
12899
           color spaces of the graphic state.  Otherwise this can be
12900
           referenced, which will result in a mismatch.  What we want to do
12901
           is see if it was the original default and only swap in that case. */
12902
67.5k
        for (k = 0; k < 2; k++) {
12903
45.0k
            gs_color_space *pcs     = pgs->color[k].color_space;
12904
45.0k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12905
45.0k
            if (profile != NULL) {
12906
43.5k
                switch(profile->data_cs) {
12907
24.8k
                    case gsGRAY:
12908
24.8k
                        if (profile->hashcode ==
12909
24.8k
                            result->profiles->smask_gray->hashcode) {
12910
23.1k
                                profile = pgs->icc_manager->default_gray;
12911
23.1k
                        }
12912
24.8k
                        break;
12913
18.5k
                    case gsRGB:
12914
18.5k
                        if (profile->hashcode ==
12915
18.5k
                            result->profiles->smask_rgb->hashcode) {
12916
11.1k
                                profile = pgs->icc_manager->default_rgb;
12917
11.1k
                        }
12918
18.5k
                        break;
12919
184
                    case gsCMYK:
12920
184
                        if (profile->hashcode ==
12921
184
                            result->profiles->smask_cmyk->hashcode) {
12922
184
                                profile = pgs->icc_manager->default_cmyk;
12923
184
                        }
12924
184
                        break;
12925
0
                    default:
12926
12927
0
                        break;
12928
43.5k
                }
12929
43.5k
                if (pcs->cmm_icc_profile_data != profile) {
12930
34.4k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12931
34.4k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12932
34.4k
                    pcs->cmm_icc_profile_data = profile;
12933
34.4k
                }
12934
43.5k
            }
12935
45.0k
        }
12936
22.5k
    }
12937
22.5k
    return 0;
12938
22.5k
}
12939
12940
static int
12941
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12942
32.5k
{
12943
32.5k
    pdf14_device * pdev = (pdf14_device *) dev;
12944
32.5k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12945
32.5k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12946
32.5k
    int k;
12947
12948
    /* See comment in pdf14_increment_smask_color to understand this one */
12949
32.5k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12950
4.19k
        pgs->icc_manager->smask_profiles->swapped) {
12951
0
            return 0;
12952
0
    }
12953
32.5k
    if (smaskcolor != NULL) {
12954
22.5k
        smaskcolor->ref_count--;
12955
22.5k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12956
22.5k
                   "[icc] Decrement smask color.  Now %d\n",
12957
22.5k
                   smaskcolor->ref_count);
12958
22.5k
        if (smaskcolor->ref_count == 0) {
12959
22.5k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12960
            /* Lets return the profiles and clean up */
12961
            /* First see if we need to "reset" the profiles that are in
12962
               the graphic state */
12963
22.5k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12964
67.5k
            for (k = 0; k < 2; k++) {
12965
45.0k
                gs_color_space *pcs = pgs->color[k].color_space;
12966
45.0k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12967
45.0k
                if (profile != NULL) {
12968
43.5k
                    switch(profile->data_cs) {
12969
24.8k
                        case gsGRAY:
12970
24.8k
                            if (profile->hashcode ==
12971
24.8k
                                pgs->icc_manager->default_gray->hashcode) {
12972
23.1k
                                    profile =
12973
23.1k
                                        smaskcolor->profiles->smask_gray;
12974
23.1k
                            }
12975
24.8k
                            break;
12976
18.5k
                        case gsRGB:
12977
18.5k
                            if (profile->hashcode ==
12978
18.5k
                                pgs->icc_manager->default_rgb->hashcode) {
12979
11.1k
                                    profile =
12980
11.1k
                                        smaskcolor->profiles->smask_rgb;
12981
11.1k
                            }
12982
18.5k
                            break;
12983
184
                        case gsCMYK:
12984
184
                            if (profile->hashcode ==
12985
184
                                pgs->icc_manager->default_cmyk->hashcode) {
12986
184
                                    profile =
12987
184
                                        smaskcolor->profiles->smask_cmyk;
12988
184
                            }
12989
184
                            break;
12990
0
                        default:
12991
12992
0
                            break;
12993
43.5k
                    }
12994
43.5k
                    if (pcs->cmm_icc_profile_data != profile) {
12995
34.4k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12996
34.4k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12997
34.4k
                        pcs->cmm_icc_profile_data = profile;
12998
34.4k
                    }
12999
43.5k
                }
13000
45.0k
            }
13001
13002
22.5k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
13003
22.5k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
13004
22.5k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
13005
22.5k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
13006
22.5k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13007
22.5k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13008
22.5k
            icc_manager->smask_profiles->swapped = false;
13009
            /* We didn't increment the reference count when we assigned these
13010
             * so NULL them to avoid decrementing when smaskcolor is freed
13011
             */
13012
22.5k
            smaskcolor->profiles->smask_gray =
13013
22.5k
              smaskcolor->profiles->smask_rgb =
13014
22.5k
              smaskcolor->profiles->smask_cmyk = NULL;
13015
13016
22.5k
            pdf14_free_smask_color(pdev);
13017
22.5k
        }
13018
22.5k
    }
13019
32.5k
    return 0;
13020
32.5k
}
13021
13022
static void
13023
pdf14_free_smask_color(pdf14_device * pdev)
13024
22.5k
{
13025
22.5k
    if (pdev->smaskcolor != NULL) {
13026
22.5k
        if ( pdev->smaskcolor->profiles != NULL) {
13027
            /* Do not decrement the profiles - the references were moved
13028
               here and moved back again, so the ref counts don't change
13029
             */
13030
22.5k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13031
22.5k
                        "pdf14_free_smask_color");
13032
22.5k
        }
13033
22.5k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13034
22.5k
        pdev->smaskcolor = NULL;
13035
22.5k
    }
13036
22.5k
}
13037
13038
static void
13039
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13040
1.08M
{
13041
1.08M
    gx_device * const dev = (gx_device *)vptr;
13042
1.08M
    pdf14_device * pdev = (pdf14_device *)dev;
13043
1.08M
    int k;
13044
13045
1.08M
    pdf14_cleanup_group_color_profiles (pdev);
13046
13047
1.08M
    if (pdev->ctx) {
13048
32
        pdf14_ctx_free(pdev->ctx);
13049
32
        pdev->ctx = NULL;
13050
32
    }
13051
13052
1.08M
    while (pdev->color_model_stack) {
13053
35
        pdf14_pop_group_color(dev, NULL);
13054
35
    }
13055
13056
1.08M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13057
40
        if (pdev->devn_params.separations.names[k].data) {
13058
40
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13059
40
            pdev->devn_params.separations.names[k].data = NULL;
13060
40
        }
13061
40
    }
13062
13063
1.08M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13064
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13065
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13066
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13067
0
        }
13068
0
    }
13069
13070
1.08M
    gx_device_finalize(cmem, vptr);
13071
1.08M
}
13072
13073
#if DUMP_MASK_STACK
13074
13075
static void
13076
dump_mask_stack(pdf14_mask_t *mask_stack)
13077
{
13078
    pdf14_mask_t *curr_mask = mask_stack;
13079
    int level = 0;
13080
13081
    while (curr_mask != NULL) {
13082
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13083
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13084
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13085
        level++;
13086
        curr_mask = curr_mask->previous;
13087
    }
13088
}
13089
13090
/* A function to display the current state of the mask stack */
13091
static void
13092
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13093
{
13094
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13095
    if (ctx->mask_stack != NULL) {
13096
        dump_mask_stack(ctx->mask_stack);
13097
    }
13098
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13099
    if (ctx->stack != NULL) {
13100
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13101
        if (ctx->stack->mask_stack != NULL) {
13102
            dump_mask_stack(ctx->stack->mask_stack);
13103
        }
13104
    }
13105
}
13106
13107
#else
13108
13109
#ifdef DEBUG
13110
static void
13111
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13112
{
13113
    return;
13114
}
13115
#endif
13116
13117
#endif /* DUMP_MASK_STACK */