Coverage Report

Created: 2025-12-31 07:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.c
Line
Count
Source
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* 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
static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory);
136
#ifdef DEBUG
137
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
138
#endif
139
140
/* A structure used by the pdf14 device so that
141
   we can do the proper dance when the alphabuf
142
   device is being used */
143
typedef struct pdf14_abuf_state_s {
144
    bool op_ca_eq_CA;
145
    bool path_empty;
146
    float stroke_alpha;
147
    float fill_alpha;
148
    gs_gstate* pgs;
149
    gs_blend_mode_t blend_mode;
150
    bool group_needed;
151
    OP_FS_STATE orig_state;
152
} pdf14_abuf_state_t;
153
154
/* Buffer stack data structure */
155
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
156
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
157
                    saved, data, backdrop, transfer_fn, mask_stack,
158
                    matte, group_color_info);
159
160
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
161
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
162
                    stack, mask_stack, base_color);
163
164
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
165
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
166
167
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
168
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
169
                    rc_mask, previous);
170
171
gs_private_st_ptrs1(st_pdf14_rcmask, pdf14_rcmask_t, "pdf_rcmask",
172
                    pdf14_rcmask_enum_ptrs, pdf14_rcmask_reloc_ptrs,
173
                    mask_buf);
174
175
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
176
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
177
                    profiles);
178
179
/* ------ The device descriptors ------ */
180
181
/*
182
 * Default X and Y resolution.
183
 */
184
#define X_DPI 72
185
#define Y_DPI 72
186
187
static int pdf14_initialize_device(gx_device *dev);
188
189
static  int pdf14_open(gx_device * pdev);
190
static  dev_proc_close_device(pdf14_close);
191
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
192
static  dev_proc_put_params(pdf14_put_params);
193
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
194
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
195
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
196
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
197
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
198
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
199
dev_proc_encode_color(pdf14_encode_color);
200
dev_proc_encode_color(pdf14_encode_color_tag);
201
dev_proc_decode_color(pdf14_decode_color);
202
dev_proc_encode_color(pdf14_encode_color16);
203
dev_proc_encode_color(pdf14_encode_color16_tag);
204
dev_proc_decode_color(pdf14_decode_color16);
205
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
206
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
207
static  dev_proc_fill_path(pdf14_fill_path);
208
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
209
static  dev_proc_copy_mono(pdf14_copy_mono);
210
static  dev_proc_fill_mask(pdf14_fill_mask);
211
static  dev_proc_stroke_path(pdf14_stroke_path);
212
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
213
static  dev_proc_text_begin(pdf14_text_begin);
214
static  dev_proc_composite(pdf14_composite);
215
static  dev_proc_composite(pdf14_forward_composite);
216
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
217
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
218
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
219
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
220
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
221
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
222
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
223
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
224
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
225
static  dev_proc_copy_alpha(pdf14_copy_alpha);
226
static  dev_proc_copy_planes(pdf14_copy_planes);
227
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
228
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
229
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
230
static  const gx_color_map_procs *
231
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
232
233
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
234
#define YSIZE (int)(11 * Y_DPI)
235
236
/* 24-bit color. */
237
238
static void
239
pdf14_procs_initialize(gx_device *dev,
240
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
241
                       dev_proc_get_color_comp_index(get_color_comp_index),
242
                       dev_proc_encode_color(encode_color),
243
                       dev_proc_decode_color(decode_color))
244
10.2M
{
245
10.2M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
246
10.2M
    set_dev_proc(dev, open_device, pdf14_open);
247
10.2M
    set_dev_proc(dev, output_page, pdf14_output_page);
248
10.2M
    set_dev_proc(dev, close_device, pdf14_close);
249
10.2M
    set_dev_proc(dev, map_rgb_color, encode_color);
250
10.2M
    set_dev_proc(dev, map_color_rgb, decode_color);
251
10.2M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
252
10.2M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
253
10.2M
    set_dev_proc(dev, get_params, gx_forward_get_params);
254
10.2M
    set_dev_proc(dev, put_params, pdf14_put_params);
255
10.2M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
256
10.2M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
257
10.2M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
258
10.2M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
259
10.2M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
260
10.2M
    set_dev_proc(dev, composite, pdf14_composite);
261
10.2M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
262
10.2M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
263
10.2M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
264
10.2M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
265
10.2M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
266
10.2M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
267
10.2M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
268
10.2M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
269
10.2M
    set_dev_proc(dev, encode_color, encode_color);
270
10.2M
    set_dev_proc(dev, decode_color, decode_color);
271
10.2M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
272
10.2M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
273
10.2M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
274
10.2M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
275
10.2M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
276
10.2M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
277
10.2M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
278
10.2M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
279
10.2M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
280
10.2M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
281
10.2M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
282
10.2M
}
283
284
static void
285
pdf14_Gray_initialize_device_procs(gx_device *dev)
286
2.70M
{
287
2.70M
    pdf14_procs_initialize(dev,
288
2.70M
                           gx_default_DevGray_get_color_mapping_procs,
289
2.70M
                           gx_default_DevGray_get_color_comp_index,
290
2.70M
                           pdf14_encode_color,
291
2.70M
                           pdf14_decode_color);
292
2.70M
}
293
294
static void
295
pdf14_RGB_initialize_device_procs(gx_device *dev)
296
5.62M
{
297
5.62M
    pdf14_procs_initialize(dev,
298
5.62M
                           gx_default_DevRGB_get_color_mapping_procs,
299
5.62M
                           gx_default_DevRGB_get_color_comp_index,
300
5.62M
                           pdf14_encode_color,
301
5.62M
                           pdf14_decode_color);
302
5.62M
}
303
304
static void
305
pdf14_CMYK_initialize_device_procs(gx_device *dev)
306
1.35M
{
307
1.35M
    pdf14_procs_initialize(dev,
308
1.35M
                           gx_default_DevCMYK_get_color_mapping_procs,
309
1.35M
                           gx_default_DevCMYK_get_color_comp_index,
310
1.35M
                           pdf14_encode_color,
311
1.35M
                           pdf14_decode_color);
312
1.35M
}
313
314
static void
315
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
316
433k
{
317
433k
    pdf14_procs_initialize(dev,
318
433k
                           pdf14_cmykspot_get_color_mapping_procs,
319
433k
                           pdf14_cmykspot_get_color_comp_index,
320
433k
                           pdf14_encode_color,
321
433k
                           pdf14_decode_color);
322
433k
}
323
324
static void
325
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
326
122k
{
327
122k
    pdf14_procs_initialize(dev,
328
122k
                           pdf14_rgbspot_get_color_mapping_procs,
329
122k
                           pdf14_rgbspot_get_color_comp_index,
330
122k
                           pdf14_encode_color,
331
122k
                           pdf14_decode_color);
332
122k
}
333
334
static void
335
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
336
29
{
337
29
    pdf14_procs_initialize(dev,
338
29
                           pdf14_grayspot_get_color_mapping_procs,
339
29
                           pdf14_grayspot_get_color_comp_index,
340
29
                           pdf14_encode_color,
341
29
                           pdf14_decode_color);
342
29
}
343
344
static void
345
pdf14_custom_initialize_device_procs(gx_device *dev)
346
0
{
347
0
    pdf14_procs_initialize(dev,
348
0
                           gx_forward_get_color_mapping_procs,
349
0
                           gx_forward_get_color_comp_index,
350
0
                           gx_forward_encode_color,
351
0
                           gx_forward_decode_color);
352
0
}
353
354
static struct_proc_finalize(pdf14_device_finalize);
355
356
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
357
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
358
                          pdf14_device_finalize);
359
360
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
361
                                                        gx_device * target);
362
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
363
                                                        gx_device * target);
364
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
365
                                                        gx_device * target);
366
367
/* Alter pdf14 device color model based upon group or softmask. This occurs
368
   post clist or in immediate rendering case. Data stored with buffer */
369
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
370
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
371
                              cmm_profile_t *iccprofile, bool is_mask);
372
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
373
374
/* Alter clist writer device color model based upon group or softmask. Data
375
   stored in the device color model stack */
376
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
377
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
378
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
379
380
/* Used for cleaning up the stack if things go wrong */
381
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
382
383
static const pdf14_procs_t gray_pdf14_procs = {
384
    pdf14_unpack_additive,
385
    pdf14_put_image,
386
    pdf14_unpack16_additive
387
};
388
389
static const pdf14_procs_t rgb_pdf14_procs = {
390
    pdf14_unpack_additive,
391
    pdf14_put_image,
392
    pdf14_unpack16_additive
393
};
394
395
static const pdf14_procs_t cmyk_pdf14_procs = {
396
    pdf14_unpack_subtractive,
397
    pdf14_put_image,
398
    pdf14_unpack16_subtractive
399
};
400
401
static const pdf14_procs_t cmykspot_pdf14_procs = {
402
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
403
    pdf14_cmykspot_put_image,
404
    pdf14_unpack16_custom /* should never be used since we will use devn values */
405
};
406
407
static const pdf14_procs_t rgbspot_pdf14_procs = {
408
    pdf14_unpack_rgb_mix,
409
    pdf14_cmykspot_put_image,
410
    pdf14_unpack16_rgb_mix
411
};
412
413
static const pdf14_procs_t grayspot_pdf14_procs = {
414
    pdf14_unpack_gray_mix,
415
    pdf14_cmykspot_put_image,
416
    pdf14_unpack16_gray_mix
417
};
418
419
static const pdf14_procs_t custom_pdf14_procs = {
420
    pdf14_unpack_custom,
421
    pdf14_custom_put_image,
422
    pdf14_unpack16_custom
423
};
424
425
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
426
    art_blend_luminosity_custom_8,
427
    art_blend_saturation_custom_8,
428
    art_blend_luminosity_custom_16,
429
    art_blend_saturation_custom_16
430
};
431
432
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
433
    art_blend_luminosity_rgb_8,
434
    art_blend_saturation_rgb_8,
435
    art_blend_luminosity_rgb_16,
436
    art_blend_saturation_rgb_16
437
};
438
439
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
440
    art_blend_luminosity_cmyk_8,
441
    art_blend_saturation_cmyk_8,
442
    art_blend_luminosity_cmyk_16,
443
    art_blend_saturation_cmyk_16
444
};
445
446
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
447
    art_blend_luminosity_rgb_8,
448
    art_blend_saturation_rgb_8,
449
    art_blend_luminosity_rgb_16,
450
    art_blend_saturation_rgb_16
451
};
452
453
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
454
    art_blend_luminosity_custom_8,
455
    art_blend_saturation_custom_8,
456
    art_blend_luminosity_custom_16,
457
    art_blend_saturation_custom_16
458
};
459
460
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
461
    art_blend_luminosity_custom_8,
462
    art_blend_saturation_custom_8,
463
    art_blend_luminosity_custom_16,
464
    art_blend_saturation_custom_16
465
};
466
467
const pdf14_device gs_pdf14_Gray_device = {
468
    std_device_std_color_full_body_type(pdf14_device,
469
                                        pdf14_Gray_initialize_device_procs,
470
                                        "pdf14gray",
471
                                        &st_pdf14_device,
472
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
473
                                        0, 0, 0, 0, 0, 0),
474
    { 0 },      /* Procs */
475
    NULL,     /* target */
476
    { 0 },      /* devn_params - not used */
477
    &gray_pdf14_procs,
478
    &gray_blending_procs,
479
    1
480
};
481
482
const pdf14_device gs_pdf14_RGB_device = {
483
    std_device_color_stype_body(pdf14_device,
484
                                pdf14_RGB_initialize_device_procs,
485
                                "pdf14RGB",
486
                                &st_pdf14_device,
487
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
488
    { 0 },      /* Procs */
489
    NULL,     /* target */
490
    { 0 },      /* devn_params - not used */
491
    &rgb_pdf14_procs,
492
    &rgb_blending_procs,
493
    3
494
};
495
496
const pdf14_device gs_pdf14_CMYK_device = {
497
    std_device_std_color_full_body_type(pdf14_device,
498
                                        pdf14_CMYK_initialize_device_procs,
499
                                        "pdf14cmyk",
500
                                        &st_pdf14_device,
501
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
502
                                        0, 0, 0, 0, 0, 0),
503
    { 0 },      /* Procs */
504
    NULL,     /* target */
505
    { 0 },      /* devn_params - not used */
506
    &cmyk_pdf14_procs,
507
    &cmyk_blending_procs,
508
    4
509
};
510
511
const pdf14_device gs_pdf14_CMYKspot_device = {
512
    std_device_part1_(pdf14_device,
513
                      pdf14_CMYKspot_initialize_device_procs,
514
                      "pdf14cmykspot",
515
                      &st_pdf14_device,
516
                      open_init_closed),
517
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
518
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
519
    offset_margin_values(0, 0, 0, 0, 0, 0),
520
    std_device_part3_(),
521
    { 0 },      /* Procs */
522
    NULL,     /* target */
523
    /* DeviceN parameters */
524
    { 8,      /* Not used - Bits per color */
525
      DeviceCMYKComponents, /* Names of color model colorants */
526
      4,      /* Number colorants for CMYK */
527
      0,      /* MaxSeparations has not been specified */
528
      -1,     /* PageSpotColors has not been specified */
529
      {0},      /* SeparationNames */
530
      0,      /* SeparationOrder names */
531
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
532
    },
533
    &cmykspot_pdf14_procs,
534
    &cmyk_blending_procs,
535
    4
536
};
537
538
const pdf14_device gs_pdf14_RGBspot_device = {
539
    std_device_part1_(pdf14_device,
540
                      pdf14_RGBspot_initialize_device_procs,
541
                      "pdf14rgbspot",
542
                      &st_pdf14_device,
543
                      open_init_closed),
544
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
545
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
546
    offset_margin_values(0, 0, 0, 0, 0, 0),
547
    std_device_part3_(),
548
    { 0 },      /* Procs */
549
    NULL,     /* target */
550
                    /* DeviceN parameters */
551
    { 8,      /* Not used - Bits per color */
552
    0,              /* Names of color model colorants */
553
    3,          /* Number colorants for RGB */
554
    0,          /* MaxSeparations has not been specified */
555
    -1,         /* PageSpotColors has not been specified */
556
    { 0 },      /* SeparationNames */
557
    0,          /* SeparationOrder names */
558
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
559
    },
560
    &rgbspot_pdf14_procs,
561
    &rgbspot_blending_procs,
562
    3
563
};
564
565
const pdf14_device gs_pdf14_Grayspot_device = {
566
    std_device_part1_(pdf14_device,
567
                      pdf14_Grayspot_initialize_device_procs,
568
                      "pdf14grayspot",
569
                      &st_pdf14_device,
570
                      open_init_closed),
571
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
572
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
573
    offset_margin_values(0, 0, 0, 0, 0, 0),
574
    std_device_part3_(),
575
    { 0 },      /* Procs */
576
    NULL,     /* target */
577
                    /* DeviceN parameters */
578
    { 8,      /* Not used - Bits per color */
579
    0,              /* Names of color model colorants */
580
    3,          /* Number colorants for RGB */
581
    0,          /* MaxSeparations has not been specified */
582
    -1,         /* PageSpotColors has not been specified */
583
    { 0 },      /* SeparationNames */
584
    0,          /* SeparationOrder names */
585
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
586
    },
587
    &grayspot_pdf14_procs,
588
    &grayspot_blending_procs,
589
    1
590
};
591
592
/*
593
 * The 'custom' PDF 1.4 compositor device is for working with those devices
594
 * which support spot colors but do not have a CMYK process color model.
595
 *
596
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
597
 * blending modes.  These blending modes are 'non separable' and depend upon
598
 * knowing the details of the blending color space.  However we use the
599
 * process color model of the output device for our blending color space.
600
 * With an unknown process color model, we have to fall back to some 'guesses'
601
 * about how to treat these blending modes.
602
 */
603
const pdf14_device gs_pdf14_custom_device = {
604
    std_device_part1_(pdf14_device,
605
                      pdf14_custom_initialize_device_procs,
606
                      "pdf14custom",
607
                      &st_pdf14_device,
608
                      open_init_closed),
609
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
610
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
611
    offset_margin_values(0, 0, 0, 0, 0, 0),
612
    std_device_part3_(),
613
    { 0 },      /* Procs */
614
    NULL,     /* target */
615
    /* DeviceN parameters */
616
    { 8,      /* Not used - Bits per color */
617
      DeviceCMYKComponents, /* Names of color model colorants */
618
      4,      /* Number colorants for CMYK */
619
      0,      /* MaxSeparations has not been specified */
620
      -1,     /* PageSpotColors has not been specified */
621
      {0},      /* SeparationNames */
622
      0,      /* SeparationOrder names */
623
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
624
    },
625
    &custom_pdf14_procs,
626
    &custom_blending_procs,
627
    4
628
};
629
630
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
631
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
632
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
633
634
static dev_proc_print_page(no_print_page);
635
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
636
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
637
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
638
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
639
640
static int
641
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
642
0
{
643
0
    return_error(gs_error_unknownerror);
644
0
}
645
646
struct gx_device_pdf14_accum_s {
647
    gx_devn_prn_device_common;
648
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
649
};
650
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
651
652
int
653
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
654
26.4M
{
655
26.4M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
656
657
26.4M
    if (dev_spec_op == gxdso_device_child) {
658
4.75k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
659
4.75k
        if (size < sizeof(*req))
660
0
            return gs_error_unknownerror;
661
4.75k
        req->target = adev->save_p14dev;
662
4.75k
        req->n = 0;
663
4.75k
        return 0;
664
4.75k
    }
665
666
26.4M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
667
26.4M
}
668
669
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
670
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
671
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
672
673
static void
674
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
675
1.39k
{
676
1.39k
    gdev_prn_initialize_device_procs_gray8(dev);
677
678
1.39k
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
679
1.39k
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
680
1.39k
}
681
682
const gx_device_pdf14_accum pdf14_accum_Gray = {
683
    prn_device_stype_body(gx_device_pdf14_accum,
684
                          pdf14_accum_Gray_initialize_device_procs,
685
                          "pdf14-accum-Gray",
686
                          &st_gx_devn_accum_device,
687
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
688
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
689
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
690
                          256/*dither_grays*/, 0/*dither_colors*/,
691
                          no_print_page),
692
    { 0 },      /* devn_params - not used */
693
    { 0 },      /* equivalent_cmyk_color_params - not used */
694
    0/*save_p14dev*/
695
};
696
697
static void
698
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
699
5.61k
{
700
5.61k
    gdev_prn_initialize_device_procs_rgb(dev);
701
5.61k
}
702
703
const gx_device_pdf14_accum pdf14_accum_RGB = {
704
    prn_device_stype_body(gx_device_pdf14_accum,
705
                          pdf14_accum_RGB_initialize_device_procs,
706
                          "pdf14-accum-RGB",
707
                          &st_gx_devn_accum_device,
708
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
709
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
710
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
711
                          1/*dither_grays*/, 256/*dither_colors*/,
712
                          no_print_page),
713
    { 0 },      /* devn_params - not used */
714
    { 0 },      /* equivalent_cmyk_color_params - not used */
715
    0/*save_p14dev*/
716
};
717
718
static void
719
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
720
0
{
721
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
722
723
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
724
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
725
0
}
726
727
const gx_device_pdf14_accum pdf14_accum_CMYK = {
728
    prn_device_stype_body(gx_device_pdf14_accum,
729
                          pdf14_accum_CMYK_initialize_device_procs,
730
                          "pdf14-accum-CMYK",
731
                          &st_gx_devn_accum_device,
732
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
733
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
734
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
735
                          256/*dither_grays*/, 256/*dither_colors*/,
736
                          no_print_page),
737
    { 0 },      /* devn_params - not used */
738
    { 0 },      /* equivalent_cmyk_color_params - not used */
739
    0/*save_p14dev*/
740
};
741
742
static void
743
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
744
0
{
745
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
746
747
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
748
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
749
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
750
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
751
0
}
752
753
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
754
    prn_device_stype_body(gx_device_pdf14_accum,
755
                          pdf14_accum_initialize_device_procs_cmykspot,
756
                          "pdf14-accum-CMYKspot",
757
                          &st_gx_devn_accum_device,
758
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
759
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
760
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
761
                          256/*dither_grays*/, 256/*dither_colors*/,
762
                          no_print_page),
763
    /* DeviceN parameters */
764
    { 8,      /* Not used - Bits per color */
765
      DeviceCMYKComponents, /* Names of color model colorants */
766
      4,      /* Number colorants for CMYK */
767
      0,      /* MaxSeparations has not been specified */
768
      -1,     /* PageSpotColors has not been specified */
769
      { 0 },      /* SeparationNames */
770
      0,      /* SeparationOrder names */
771
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
772
    },
773
    { true },     /* equivalent_cmyk_color_params */
774
    0/*save_p14dev*/
775
};
776
777
/* GC procedures */
778
static
779
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
780
0
{
781
0
    index -= 5;
782
0
    if (index < pdev->devn_params.separations.num_separations)
783
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
784
0
    index -= pdev->devn_params.separations.num_separations;
785
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
786
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
787
0
    return 0;
788
0
}
789
0
case 0: return ENUM_OBJ(pdev->ctx);
790
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
791
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
792
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
793
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
794
0
ENUM_PTRS_END
795
796
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
797
0
{
798
0
    {
799
0
        int i;
800
801
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
802
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
803
0
        }
804
0
    }
805
0
    RELOC_VAR(pdev->ctx);
806
0
    RELOC_VAR(pdev->smaskcolor);
807
0
    RELOC_VAR(pdev->color_model_stack);
808
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
809
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
810
0
}
811
0
RELOC_PTRS_END
812
813
/* ------ Private definitions ------ */
814
815
static void
816
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
817
              int width, int height, cmm_profile_t *src_profile, int deep)
818
1.84k
{
819
1.84k
    if (deep) {
820
0
        int x, y, i;
821
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
822
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
823
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
824
825
0
        src_planestride >>= 1;
826
0
        src_rowstride >>= 1;
827
828
0
        for (y = 0; y < height; y++) {
829
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
830
0
            uint16_t *src_curr_ptr = src_row_ptr;
831
0
            for (x = 0; x < width; x++) {
832
0
                uint16_t idx = *mask_curr_ptr;
833
0
                byte     top = idx>>8;
834
0
                uint16_t a   = mask_tr_fn[top];
835
0
                int      b   = mask_tr_fn[top+1]-a;
836
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
837
838
                /* matte's happen rarely enough that we allow ourselves to
839
                 * resort to 64bit here. */
840
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
841
0
                    for (i = 0; i < src_profile->num_comps; i++) {
842
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
843
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
844
845
                        /* clip */
846
0
                        if (temp > 0xffff)
847
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
848
0
                        else if (temp < 0)
849
0
                            src_curr_ptr[i * src_planestride] = 0;
850
0
                        else
851
0
                            src_curr_ptr[i * src_planestride] = temp;
852
0
                    }
853
0
                }
854
0
                mask_curr_ptr++;
855
0
                src_curr_ptr++;
856
0
            }
857
0
            src_row_ptr += src_rowstride;
858
0
            mask_row_ptr += (maskbuf->rowstride>>1);
859
0
        }
860
1.84k
    } else {
861
1.84k
        int x, y, i;
862
1.84k
        byte *mask_row_ptr  = maskbuf->data;
863
1.84k
        byte *src_row_ptr   = src_data;
864
1.84k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
865
866
23.7k
        for (y = 0; y < height; y++) {
867
21.8k
            byte *mask_curr_ptr = mask_row_ptr;
868
21.8k
            byte *src_curr_ptr = src_row_ptr;
869
27.6M
            for (x = 0; x < width; x++) {
870
27.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
871
27.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
872
17.5M
                    for (i = 0; i < src_profile->num_comps; i++) {
873
13.1M
                        byte matte = maskbuf->matte[i]>>8;
874
13.1M
                        int val = src_curr_ptr[i * src_planestride] - matte;
875
13.1M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
876
877
                        /* clip */
878
13.1M
                        if (temp > 0xff)
879
8.00M
                            src_curr_ptr[i * src_planestride] = 0xff;
880
5.18M
                        else if (temp < 0)
881
0
                            src_curr_ptr[i * src_planestride] = 0;
882
5.18M
                        else
883
5.18M
                            src_curr_ptr[i * src_planestride] = temp;
884
13.1M
                    }
885
4.39M
                }
886
27.6M
                mask_curr_ptr++;
887
27.6M
                src_curr_ptr++;
888
27.6M
            }
889
21.8k
            src_row_ptr += src_rowstride;
890
21.8k
            mask_row_ptr += maskbuf->rowstride;
891
21.8k
        }
892
1.84k
    }
893
1.84k
}
894
895
/* Transform of color data and copy noncolor data.  Used in
896
   group pop and during the pdf14 put image calls when the blend color space
897
   is different than the target device color space.  The function will try do
898
   in-place conversion if possible.  If not, it will do an allocation.  The
899
   put_image call needs to know if an allocation was made so that it can adjust
900
   for the fact that we likely don't have a full page any longer and we don't
901
   need to do the offset to our data in the buffer. Bug 700686: If we are in
902
   a softmask that includes a matte entry, then we need to undo the matte
903
   entry here at this time in the image's native color space not the parent
904
   color space.   The endian_swap term here is only set to true if the data
905
   has been baked as BE during the put_image blending operation and we are
906
   on a LE machine.  */
907
static forceinline pdf14_buf*
908
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
909
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
910
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
911
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
912
34.3k
{
913
34.3k
    gsicc_rendering_param_t rendering_params;
914
34.3k
    gsicc_link_t *icc_link;
915
34.3k
    gsicc_bufferdesc_t src_buff_desc;
916
34.3k
    gsicc_bufferdesc_t des_buff_desc;
917
34.3k
    intptr_t src_planestride = src_buf->planestride;
918
34.3k
    intptr_t src_rowstride = src_buf->rowstride;
919
34.3k
    int src_n_planes = src_buf->n_planes;
920
34.3k
    int src_n_chan = src_buf->n_chan;
921
34.3k
    intptr_t des_planestride = src_planestride;
922
34.3k
    intptr_t des_rowstride = src_rowstride;
923
34.3k
    int des_n_planes = src_n_planes;
924
34.3k
    int des_n_chan = src_n_chan;
925
34.3k
    int diff;
926
34.3k
    int k, j;
927
34.3k
    byte *des_data = NULL;
928
34.3k
    pdf14_buf *output = src_buf;
929
34.3k
    pdf14_mask_t *mask_stack;
930
34.3k
    pdf14_buf *maskbuf;
931
34.3k
    int code;
932
933
34.3k
    *did_alloc = false;
934
935
    /* Same profile */
936
34.3k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
937
0
        return src_buf;
938
939
    /* Define the rendering intent get the link */
940
34.3k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
941
34.3k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
942
34.3k
    rendering_params.override_icc = false;
943
34.3k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
944
34.3k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
945
34.3k
    rendering_params.cmm = gsCMM_DEFAULT;
946
34.3k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
947
34.3k
        &rendering_params, pgs->memory, false);
948
34.3k
    if (icc_link == NULL)
949
0
        return NULL;
950
951
    /* If different data sizes, we have to do an allocation */
952
34.3k
    diff = des_profile->num_comps - src_profile->num_comps;
953
34.3k
    if (diff != 0) {
954
33.9k
        byte *src_ptr;
955
33.9k
        byte *des_ptr;
956
957
33.9k
        *did_alloc = true;
958
33.9k
        des_rowstride = ((width + 3) & -4)<<deep;
959
33.9k
        des_planestride = height * des_rowstride;
960
33.9k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
961
33.9k
        des_n_chan = src_n_chan + diff;
962
33.9k
        des_data = gs_alloc_bytes(ctx->memory,
963
33.9k
                                  des_planestride * des_n_planes + CAL_SLOP,
964
33.9k
                                  "pdf14_transform_color_buffer");
965
33.9k
        if (des_data == NULL)
966
0
            return NULL;
967
968
        /* Copy over the noncolor planes. May only be a dirty part, so have
969
           to copy row by row */
970
33.9k
        src_ptr = src_data;
971
33.9k
        des_ptr = des_data;
972
372k
        for (j = 0; j < height; j++) {
973
692k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
974
354k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
975
354k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
976
354k
                       width<<deep);
977
354k
            }
978
338k
            src_ptr += src_rowstride;
979
338k
            des_ptr += des_rowstride;
980
338k
        }
981
33.9k
    } else
982
441
        des_data = src_data;
983
984
    /* Set up the buffer descriptors. */
985
34.3k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
986
34.3k
                      false, true, src_planestride, src_rowstride, height, width);
987
34.3k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
988
34.3k
                      false, true, des_planestride, des_rowstride, height, width);
989
990
34.3k
    src_buff_desc.endian_swap = endian_swap;
991
34.3k
    des_buff_desc.endian_swap = endian_swap;
992
993
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
994
       context to ensure that this is not done again during the group
995
       composition */
996
34.3k
    if (has_matte &&
997
        /* Should always happen, but check for safety */
998
2.41k
        ((mask_stack = ctx->mask_stack) != NULL) &&
999
2.41k
        ((maskbuf = mask_stack->rc_mask->mask_buf) != NULL) &&
1000
2.41k
         (maskbuf->data != NULL))
1001
1.84k
    {
1002
1.84k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
1003
1.84k
    }
1004
1005
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1006
       Gray buffers, this transform does not need to worry about the cmap procs
1007
       of the target device. */
1008
34.3k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1009
34.3k
        src_data, des_data);
1010
34.3k
    gsicc_release_link(icc_link);
1011
34.3k
    if (code < 0)
1012
0
        return NULL;
1013
1014
34.3k
    output->planestride = des_planestride;
1015
34.3k
    output->rowstride = des_rowstride;
1016
34.3k
    output->n_planes = des_n_planes;
1017
34.3k
    output->n_chan = des_n_chan;
1018
    /* If not in-place conversion, then release. */
1019
34.3k
    if (des_data != src_data) {
1020
33.9k
        gs_free_object(ctx->memory, output->data,
1021
33.9k
            "pdf14_transform_color_buffer");
1022
33.9k
        output->data = des_data;
1023
        /* Note, this is needed for case where we did a put image, as the
1024
           resulting transformed buffer may not be a full page. */
1025
33.9k
        output->rect.p.x = x0;
1026
33.9k
        output->rect.p.y = y0;
1027
33.9k
        output->rect.q.x = x0 + width;
1028
33.9k
        output->rect.q.y = y0 + height;
1029
33.9k
    }
1030
34.3k
    return output;
1031
34.3k
}
1032
1033
/* This is a routine to do memset's but with 16 bit values.
1034
 * Note, that we still take bytes, NOT "num values to set".
1035
 * We assume dest is 16 bit aligned. We assume that bytes is
1036
 * a multiple of 2. */
1037
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1038
0
{
1039
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1040
0
    uint32_t v;
1041
0
    if (bytes < 0)
1042
0
        return;
1043
0
    if (((intptr_t)dest) & 2) {
1044
0
        *dest++ = value;
1045
0
        bytes--;
1046
0
        if (bytes == 0)
1047
0
            return;
1048
0
    }
1049
0
    v = value | (value<<16);
1050
0
    bytes -= 2;
1051
0
    while (bytes > 0) {
1052
0
        *(uint32_t *)dest = v;
1053
0
        dest += 2;
1054
0
        bytes -= 4;
1055
0
    }
1056
0
    bytes += 2;
1057
0
    if (bytes & 2) {
1058
0
        *dest = value;
1059
0
    }
1060
0
}
1061
1062
static pdf14_buf*
1063
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1064
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1065
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1066
    bool deep, bool endian_swap, int num_channels_to_lose)
1067
31.9k
{
1068
31.9k
    if (deep)
1069
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1070
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1071
31.9k
    else
1072
31.9k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1073
31.9k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1074
31.9k
}
1075
1076
static pdf14_buf*
1077
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1078
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1079
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1080
    bool deep, bool endian_swap)
1081
2.41k
{
1082
2.41k
    if (deep)
1083
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1084
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1085
2.41k
    else
1086
2.41k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1087
2.41k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1088
2.41k
}
1089
1090
/**
1091
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1092
 * @n_chan: Number of pixel channels including alpha, but not including
1093
 * shape, group alpha, or tags.
1094
 *
1095
 * Return value: Newly allocated buffer, or NULL on failure.
1096
 **/
1097
static  pdf14_buf *
1098
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1099
              bool has_shape, bool idle, int n_chan, int num_spots,
1100
              gs_memory_t *memory, bool deep)
1101
7.14M
{
1102
1103
    /* Note that alpha_g is the alpha for the GROUP */
1104
    /* This is distinct from the alpha that may also exist */
1105
    /* for the objects within the group.  Hence it can introduce */
1106
    /* yet another plane */
1107
1108
7.14M
    pdf14_buf *result;
1109
7.14M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1110
7.14M
    int64_t height = (rect->q.y - rect->p.y);
1111
7.14M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1112
7.14M
                   (has_tags ? 1 : 0);
1113
7.14M
    size_t planestride;
1114
#if ARCH_SIZEOF_SIZE_T <= 4
1115
    int64_t dsize = rowstride * height * n_planes;
1116
1117
    if (dsize > max_size_t)
1118
        return NULL;
1119
#endif
1120
1121
7.14M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1122
7.14M
                             "pdf14_buf_new");
1123
7.14M
    if (result == NULL)
1124
0
        return result;
1125
1126
7.14M
    result->memory = memory;
1127
7.14M
    result->backdrop = NULL;
1128
7.14M
    result->saved = NULL;
1129
7.14M
    result->isolated = false;
1130
7.14M
    result->knockout = false;
1131
7.14M
    result->has_alpha_g = has_alpha_g;
1132
7.14M
    result->has_shape = has_shape;
1133
7.14M
    result->has_tags = has_tags;
1134
7.14M
    result->rect = *rect;
1135
7.14M
    result->n_chan = n_chan;
1136
7.14M
    result->n_planes = n_planes;
1137
7.14M
    result->rowstride = rowstride;
1138
7.14M
    result->transfer_fn = NULL;
1139
7.14M
    result->is_ident = true;
1140
7.14M
    result->matte_num_comps = 0;
1141
7.14M
    result->matte = NULL;
1142
7.14M
    result->mask_stack = NULL;
1143
7.14M
    result->idle = idle;
1144
7.14M
    result->mask_id = 0;
1145
7.14M
    result->num_spots = num_spots;
1146
7.14M
    result->deep = deep;
1147
7.14M
    result->page_group = false;
1148
7.14M
    result->group_color_info = NULL;
1149
7.14M
    result->group_popped = false;
1150
1151
7.14M
    if (idle || height <= 0) {
1152
        /* Empty clipping - will skip all drawings. */
1153
3.81M
        result->planestride = 0;
1154
3.81M
        result->data = 0;
1155
3.81M
    } else {
1156
3.33M
        planestride = rowstride * height;
1157
3.33M
        result->planestride = planestride;
1158
3.33M
        result->data = gs_alloc_bytes(memory,
1159
3.33M
                                      planestride * n_planes + CAL_SLOP,
1160
3.33M
                                      "pdf14_buf_new");
1161
3.33M
        if (result->data == NULL) {
1162
0
            gs_free_object(memory, result, "pdf14_buf_new");
1163
0
            return NULL;
1164
0
        }
1165
3.33M
        if (has_alpha_g) {
1166
546k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
546k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1169
546k
        }
1170
3.33M
        if (has_tags) {
1171
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1172
            /* Memsetting by 0, so this copes with the deep case too */
1173
0
            memset (result->data + tags_plane * planestride,
1174
0
                    GS_UNTOUCHED_TAG, planestride);
1175
0
        }
1176
3.33M
    }
1177
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1178
     * Any future drawing will make it valid again, so we won't blend back
1179
     * more than we need. */
1180
7.14M
    result->dirty.p.x = rect->q.x;
1181
7.14M
    result->dirty.p.y = rect->q.y;
1182
7.14M
    result->dirty.q.x = rect->p.x;
1183
7.14M
    result->dirty.q.y = rect->p.y;
1184
7.14M
    return result;
1185
7.14M
}
1186
1187
static  void
1188
pdf14_buf_free(pdf14_buf *buf)
1189
7.14M
{
1190
7.14M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1191
7.14M
    gs_memory_t *memory = buf->memory;
1192
1193
7.14M
    if (buf->mask_stack && buf->mask_stack->rc_mask)
1194
7.14M
        rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free");
1195
1196
7.14M
    gs_free_object(memory, buf->mask_stack, "pdf14_buf_free");
1197
7.14M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1198
7.14M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1199
7.14M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1200
1201
14.2M
    while (group_color_info) {
1202
7.14M
       if (group_color_info->icc_profile != NULL) {
1203
7.14M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1204
7.14M
       }
1205
7.14M
       buf->group_color_info = group_color_info->previous;
1206
7.14M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1207
7.14M
       group_color_info = buf->group_color_info;
1208
7.14M
    }
1209
1210
7.14M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1211
7.14M
    gs_free_object(memory, buf, "pdf14_buf_free");
1212
7.14M
}
1213
1214
static void
1215
rc_pdf14_maskbuf_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1216
3.00M
{
1217
    /* Ending the mask buffer. */
1218
3.00M
    pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in;
1219
    /* free the pdf14 buffer. */
1220
3.00M
    if ( rcmask->mask_buf != NULL ){
1221
351k
        pdf14_buf_free(rcmask->mask_buf);
1222
351k
    }
1223
3.00M
    gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free");
1224
3.00M
}
1225
1226
static  pdf14_rcmask_t *
1227
pdf14_rcmask_new(gs_memory_t *memory)
1228
3.00M
{
1229
3.00M
    pdf14_rcmask_t *result;
1230
1231
3.00M
    result = gs_alloc_struct(memory, pdf14_rcmask_t, &st_pdf14_rcmask,
1232
3.00M
                             "pdf14_maskbuf_new");
1233
3.00M
    if (result == NULL)
1234
0
        return NULL;
1235
3.00M
    rc_init_free(result, memory, 1, rc_pdf14_maskbuf_free);
1236
3.00M
    result->mask_buf = NULL;
1237
3.00M
    result->memory = memory;
1238
3.00M
    return result;
1239
3.00M
}
1240
1241
static  pdf14_ctx *
1242
pdf14_ctx_new(gx_device *dev, bool deep)
1243
1.98M
{
1244
1.98M
    pdf14_ctx *result;
1245
1.98M
    gs_memory_t *memory = dev->memory->stable_memory;
1246
1247
1.98M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1248
1.98M
    if (result == NULL)
1249
0
        return result;
1250
1.98M
    result->stack = NULL;
1251
1.98M
    result->mask_stack = pdf14_mask_element_new(memory);
1252
1.98M
    result->mask_stack->rc_mask = pdf14_rcmask_new(memory);
1253
1.98M
    result->memory = memory;
1254
1.98M
    result->smask_depth = 0;
1255
1.98M
    result->smask_blend = false;
1256
1.98M
    result->deep = deep;
1257
1.98M
    result->base_color = NULL;
1258
1.98M
    return result;
1259
1.98M
}
1260
1261
static  void
1262
pdf14_ctx_free(pdf14_ctx *ctx)
1263
1.98M
{
1264
1.98M
    pdf14_buf *buf, *next;
1265
1266
1.98M
    if (ctx->base_color) {
1267
1.16M
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1268
1.16M
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1269
1.16M
    }
1270
1.98M
    if (ctx->mask_stack) {
1271
        /* A mask was created but was not used in this band. */
1272
797k
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_ctx_free");
1273
797k
        gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_ctx_free");
1274
797k
    }
1275
3.76M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1276
1.77M
        next = buf->saved;
1277
1.77M
        pdf14_buf_free(buf);
1278
1.77M
    }
1279
1.98M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1280
1.98M
}
1281
1282
/**
1283
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1284
 *
1285
 * Return value: Backdrop buffer for current group operation, or NULL
1286
 * if backdrop is fully transparent.
1287
 **/
1288
static  pdf14_buf *
1289
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1290
1.90M
{
1291
    /* Our new buffer is buf */
1292
1.90M
    pdf14_buf *buf = ctx->stack;
1293
1294
1.90M
    *is_backdrop = false;
1295
1296
1.90M
    if (buf != NULL) {
1297
        /* If the new buffer is isolated there is no backdrop */
1298
1.90M
        if (buf->isolated) return NULL;
1299
1300
        /* If the previous buffer is a knockout group
1301
           then we need to use its backdrop as the backdrop. If
1302
           it was isolated then that back drop was NULL */
1303
546k
        if (buf->saved != NULL && buf->saved->knockout) {
1304
            /* Per the spec, if we have a non-isolated group
1305
               in a knockout group the non-isolated group
1306
               uses the backdrop of its parent group (the knockout group)
1307
               as its own backdrop.  The non-isolated group must
1308
               go through the standard re-composition operation
1309
               to avoid the double application of the backdrop */
1310
28
            *is_backdrop = true;
1311
28
            return buf->saved;
1312
28
        }
1313
        /* This should be the non-isolated case where its parent is
1314
           not a knockout */
1315
546k
        if (buf->saved != NULL) {
1316
546k
            return buf->saved;
1317
546k
        }
1318
546k
    }
1319
0
    return NULL;
1320
1.90M
}
1321
1322
static pdf14_group_color_t*
1323
pdf14_make_base_group_color(gx_device* dev)
1324
1.16M
{
1325
1.16M
    pdf14_device* pdev = (pdf14_device*)dev;
1326
1.16M
    pdf14_group_color_t* group_color;
1327
1.16M
    bool deep = pdev->ctx->deep;
1328
1.16M
    bool has_tags = device_encodes_tags(dev);
1329
1330
1.16M
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1331
1332
1.16M
    group_color = gs_alloc_struct(pdev->ctx->memory,
1333
1.16M
        pdf14_group_color_t, &st_pdf14_clr,
1334
1.16M
        "pdf14_make_base_group_color");
1335
1336
1.16M
    if (group_color == NULL)
1337
0
        return NULL;
1338
1.16M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1339
1340
1.16M
    group_color->num_std_colorants = pdev->num_std_colorants;
1341
1.16M
    group_color->blend_procs = pdev->blend_procs;
1342
1.16M
    group_color->polarity = pdev->color_info.polarity;
1343
1.16M
    group_color->num_components = pdev->color_info.num_components - has_tags;
1344
1.16M
    group_color->isadditive = pdev->ctx->additive;
1345
1.16M
    group_color->unpack_procs = pdev->pdf14_procs;
1346
1.16M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1347
1.16M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1348
1.16M
    group_color->depth = pdev->color_info.depth;
1349
1.16M
    group_color->decode = dev_proc(pdev, decode_color);
1350
1.16M
    group_color->encode = dev_proc(pdev, encode_color);
1351
1.16M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1352
1.16M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1353
1.16M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1354
1.16M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1355
1.16M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1356
1.16M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1357
1.16M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1358
1.16M
    group_color->icc_profile =
1359
1.16M
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1360
1.16M
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1361
1362
1.16M
    return group_color;
1363
1.16M
}
1364
1365
/* This wil create the first buffer when we have
1366
   either the first drawing operation or transparency
1367
   group push.  At that time, the color space in which
1368
   we are going to be doing the alpha blend will be known. */
1369
static int
1370
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1371
1.04G
{
1372
1.04G
    pdf14_device *pdev = (pdf14_device *)dev;
1373
1.04G
    bool has_tags = device_encodes_tags(dev);
1374
1.04G
    int n_chan = pdev->color_info.num_components - has_tags;
1375
1.04G
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1376
1.04G
    int num_spots = pdev->ctx->num_spots;
1377
1.04G
    pdf14_buf* buf;
1378
1.04G
    gs_memory_t* memory = dev->memory->stable_memory;
1379
1380
    /* Check for a blank idle group as a base group */
1381
1.04G
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1382
1.71k
        pdev->ctx->stack->idle) {
1383
0
        pdf14_buf_free(pdev->ctx->stack);
1384
0
        pdev->ctx->stack = NULL;
1385
0
    }
1386
1387
1.04G
    if (pdev->ctx->stack != NULL)
1388
1.04G
        return 0;
1389
1390
1.04G
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1391
869k
        dev->width, dev->height);
1392
1393
869k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1394
869k
        num_spots, memory, pdev->ctx->deep);
1395
869k
    if (buf == NULL) {
1396
0
        return gs_error_VMerror;
1397
0
    }
1398
869k
    if_debug5m('v', memory,
1399
869k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1400
869k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1401
1402
869k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1403
869k
    buf->saved = NULL;
1404
869k
    pdev->ctx->stack = buf;
1405
869k
    pdev->ctx->additive = additive;
1406
1407
    /* Every buffer needs group color information including the base
1408
       one that is created for when we have no group */
1409
869k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1410
869k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1411
869k
    if (buf->group_color_info == NULL)
1412
0
        return gs_error_VMerror;
1413
1414
869k
    if (pgs != NULL)
1415
460k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1416
408k
    else
1417
408k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1418
1419
869k
    buf->group_color_info->group_color_mapping_procs =
1420
869k
        dev_proc(pdev, get_color_mapping_procs);
1421
869k
    buf->group_color_info->group_color_comp_index =
1422
869k
        dev_proc(pdev, get_color_comp_index);
1423
869k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1424
869k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1425
869k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1426
869k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1427
869k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1428
869k
    buf->group_color_info->depth = pdev->color_info.depth;
1429
869k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1430
869k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1431
869k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1432
869k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1433
869k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1434
869k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1435
869k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1436
869k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1437
869k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1438
869k
    buf->group_color_info->icc_profile =
1439
869k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1440
869k
    if (buf->group_color_info->icc_profile != NULL)
1441
869k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1442
1443
869k
    return 0;
1444
869k
}
1445
1446
static pdf14_group_color_t*
1447
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1448
50.1k
{
1449
50.1k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1450
50.1k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1451
50.1k
    if (des == NULL)
1452
0
        return NULL;
1453
1454
50.1k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1455
50.1k
    if (des->icc_profile != NULL)
1456
50.1k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1457
50.1k
    des->previous = NULL;  /* used during clist writing for state stack */
1458
1459
50.1k
    return des;
1460
50.1k
}
1461
1462
static  int
1463
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1464
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1465
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1466
                              int numcomps, bool cm_back_drop, bool shade_group,
1467
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1468
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1469
                              gx_device *dev)
1470
5.24M
{
1471
5.24M
    pdf14_buf *tos = ctx->stack;
1472
5.24M
    pdf14_buf *buf, * pdf14_backdrop;
1473
5.24M
    bool has_shape = false;
1474
5.24M
    bool is_backdrop;
1475
5.24M
    int num_spots;
1476
1477
5.24M
    if_debug1m('v', ctx->memory,
1478
5.24M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1479
1480
5.24M
    if (tos != NULL)
1481
4.34M
        has_shape = tos->has_shape || tos->knockout;
1482
1483
5.24M
    if (ctx->smask_depth > 0)
1484
6.00k
        num_spots = 0;
1485
5.24M
    else
1486
5.24M
        num_spots = ctx->num_spots;
1487
1488
1489
5.24M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1490
5.24M
                        num_spots, ctx->memory, ctx->deep);
1491
5.24M
    if (buf == NULL)
1492
0
        return_error(gs_error_VMerror);
1493
1494
5.24M
    if_debug4m('v', ctx->memory,
1495
5.24M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1496
5.24M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1497
5.24M
    buf->isolated = isolated;
1498
5.24M
    buf->knockout = knockout;
1499
5.24M
    buf->alpha = alpha;
1500
5.24M
    buf->shape = shape;
1501
5.24M
    buf->opacity = opacity;
1502
5.24M
    buf->blend_mode = blend_mode;
1503
5.24M
    buf->mask_id = mask_id;
1504
5.24M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1505
                                          set up another (nested) mask. */
1506
5.24M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1507
                            See pdf14_pop_transparency_group how to handle it. */
1508
5.24M
    buf->saved = tos;
1509
5.24M
    buf->group_color_info = group_color;
1510
1511
5.24M
    if (tos == NULL)
1512
906k
        buf->page_group = true;
1513
1514
5.24M
    ctx->stack = buf;
1515
5.24M
    if (buf->data == NULL)
1516
3.34M
        return 0;
1517
1.90M
    if (idle)
1518
0
        return 0;
1519
1.90M
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1520
1521
    /* Initializes buf->data with the backdrop or as opaque */
1522
1.90M
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1523
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1524
        /* Memsetting by 0, so this copes with the deep case too */
1525
1.35M
        memset(buf->data, 0, buf->planestride *
1526
1.35M
                                          (buf->n_chan +
1527
1.35M
                                           (buf->has_shape ? 1 : 0) +
1528
1.35M
                                           (buf->has_alpha_g ? 1 : 0)));
1529
1.35M
    } else {
1530
546k
        if (!cm_back_drop) {
1531
546k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1532
#if RAW_DUMP
1533
                                    , ctx->memory
1534
#endif
1535
546k
                                    );
1536
546k
        } else {
1537
            /* We must have an non-isolated group with a mismatch in color spaces.
1538
                In this case, we can't just copy the buffer but must CM it */
1539
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1540
0
                                        ctx->memory, pgs, dev, is_backdrop);
1541
0
        }
1542
546k
    }
1543
1544
    /* If our new group is a non-isolated knockout group, we have to maintain
1545
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1546
       knockout group. They have to always blend with the groups backdrop
1547
       not what is currently drawn in the group. Selection of the backdrop
1548
       depends upon the properties of the parent group. For example, if
1549
       the parent itself is a knockout group we actually
1550
       need to blend with its backdrop. This could be NULL if the parent was
1551
       an isolated knockout group. */
1552
1.90M
    if (buf->knockout && pdf14_backdrop != NULL) {
1553
65.4k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1554
65.4k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1555
65.4k
                                       "pdf14_push_transparency_group");
1556
65.4k
        if (buf->backdrop == NULL) {
1557
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1558
0
        }
1559
1560
65.4k
        memcpy(buf->backdrop, buf->data,
1561
65.4k
               buf->planestride * buf->n_planes);
1562
1563
#if RAW_DUMP
1564
        /* Dump the current buffer to see what we have. */
1565
        dump_raw_buffer(ctx->memory,
1566
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1567
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1568
            ctx->stack->planestride, ctx->stack->rowstride,
1569
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1570
        global_index++;
1571
#endif
1572
65.4k
    }
1573
#if RAW_DUMP
1574
    /* Dump the current buffer to see what we have. */
1575
    dump_raw_buffer(ctx->memory,
1576
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1577
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1578
                    ctx->stack->planestride, ctx->stack->rowstride,
1579
                    "TransGroupPush", ctx->stack->data, buf->deep);
1580
    global_index++;
1581
#endif
1582
1.90M
    return 0;
1583
1.90M
}
1584
1585
static  int
1586
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1587
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1588
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1589
5.24M
{
1590
5.24M
    pdf14_buf *tos = ctx->stack;
1591
5.24M
    pdf14_buf *nos = tos->saved;
1592
5.24M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1593
5.24M
    pdf14_buf *maskbuf;
1594
5.24M
    int x0, x1, y0, y1;
1595
5.24M
    int nos_num_color_comp;
1596
5.24M
    bool no_icc_match;
1597
5.24M
    pdf14_device *pdev = (pdf14_device *)dev;
1598
5.24M
    bool overprint = pdev->overprint;
1599
5.24M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1600
5.24M
    bool has_matte = false;
1601
5.24M
    int code = 0;
1602
1603
#ifdef DEBUG
1604
    pdf14_debug_mask_stack_state(ctx);
1605
#endif
1606
5.24M
    if (mask_stack == NULL) {
1607
2.96M
        maskbuf = NULL;
1608
2.96M
    }
1609
2.28M
    else {
1610
2.28M
        maskbuf = mask_stack->rc_mask->mask_buf;
1611
2.28M
    }
1612
1613
5.24M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1614
8.32k
        has_matte = true;
1615
1616
    /* Check if this is our last buffer, if yes, there is nothing to
1617
       compose to.  Keep this buffer until we have the put image.
1618
       If we have another group push, this group must be destroyed.
1619
       This only occurs sometimes when at clist creation time
1620
       push_shfill_group occured and nothing was drawn in this group.
1621
       There is also the complication if we have a softmask.  There
1622
       are two approaches to this problem.  Apply the softmask during
1623
       the put image or handle it now.  I choose the later as the
1624
       put_image code is already way to complicated. */
1625
5.24M
    if (nos == NULL && maskbuf == NULL) {
1626
905k
        tos->group_popped = true;
1627
905k
        return 0;
1628
905k
    }
1629
1630
    /* Here is the case with the soft mask.  Go ahead and create a new
1631
       target buffer (nos) with the same color information etc, but blank
1632
       and go ahead and do the blend with the softmask so that it gets applied. */
1633
4.33M
    if (nos == NULL && maskbuf != NULL) {
1634
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1635
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1636
0
        if (nos == NULL) {
1637
0
            code = gs_error_VMerror;
1638
0
            goto exit;
1639
0
        }
1640
1641
0
        if_debug4m('v', ctx->memory,
1642
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1643
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1644
1645
0
        nos->dirty = tos->dirty;
1646
0
        nos->isolated = tos->isolated;
1647
0
        nos->knockout = tos->knockout;
1648
0
        nos->alpha = 65535;
1649
0
        nos->shape = 65535;
1650
0
        nos->opacity = 65535;
1651
0
        nos->blend_mode = tos->blend_mode;
1652
0
        nos->mask_id = tos->mask_id;
1653
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1654
1655
0
        if (nos->data != NULL)
1656
0
            memset(nos->data, 0,
1657
0
                   nos->planestride * (nos->n_chan +
1658
0
                                       (nos->has_shape ? 1 : 0) +
1659
0
                                       (nos->has_alpha_g ? 1 : 0)));
1660
0
    }
1661
1662
    /* Before we get started, lets see if we have somehow gotten into
1663
       what should be an impossible situation where the group color
1664
       information does not match the buffer color information. This
1665
       can occur is there were memory issues that have perhaps blown
1666
       away information, or in the example of Bug 705197 the PDF interpreter
1667
       reuses a pattern during a circular reference causing an aliasing
1668
       of two nested patterns, one of which has a softmask. The change in
1669
       the buffer size of the inner one blows away the buffer of the
1670
       outer one leading to a mismatch of color spaces. Here
1671
       we can at least catch the case when the color space sizes have
1672
       changed and avoid buffer over-runs that would occur when we try
1673
       to do the group composition */
1674
4.33M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1675
4.33M
        tos->n_chan - 1 != tos_num_color_comp)
1676
0
        return_error(gs_error_Fatal);
1677
1678
4.33M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1679
4.33M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1680
1681
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1682
     * have made them overly large. */
1683
4.33M
    rect_intersect(tos->dirty, tos->rect);
1684
4.33M
    rect_intersect(nos->dirty, nos->rect);
1685
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1686
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1687
4.33M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1688
4.33M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1689
4.33M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1690
4.33M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1691
4.33M
    if (ctx->mask_stack) {
1692
        /* This can occur when we have a situation where we are ending out of
1693
           a group that has internal to it a soft mask and another group.
1694
           The soft mask left over from the previous trans group pop is put
1695
           into ctx->masbuf, since it is still active if another trans group
1696
           push occurs to use it.  If one does not occur, but instead we find
1697
           ourselves popping from a parent group, then this softmask is no
1698
           longer needed.  We will rc_decrement and set it to NULL. */
1699
66
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_pop_transparency_group");
1700
66
        if (ctx->mask_stack->rc_mask == NULL ){
1701
66
            gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_pop_transparency_group");
1702
66
        }
1703
66
        ctx->mask_stack = NULL;
1704
66
    }
1705
4.33M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1706
4.33M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1707
4.33M
    if (tos->idle)
1708
3.29M
        goto exit;
1709
1.04M
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1710
0
        goto exit;
1711
1712
#if RAW_DUMP
1713
    /* Dump the current buffer to see what we have. */
1714
    dump_raw_buffer(ctx->memory,
1715
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1716
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1717
                    ctx->stack->planestride, ctx->stack->rowstride,
1718
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1719
    global_index++;
1720
#endif
1721
/* Note currently if a pattern space has transparency, the ICC profile is not used
1722
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1723
   This is partially due to the fact that pdf14_pop_transparency_group and
1724
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1725
   operations called in the tile transparency code.  Instead we may want to
1726
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1727
   is where all the ICC information is handled.  We will return to look at that later */
1728
1.04M
    if (nos->group_color_info->icc_profile != NULL) {
1729
1.04M
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1730
1.04M
    } else {
1731
        /* Let the other tests make the decision if we need to transform */
1732
0
        no_icc_match = false;
1733
0
    }
1734
    /* If the color spaces are different and we actually did do a swap of
1735
       the procs for color */
1736
1.04M
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1737
1.04M
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1738
12.1k
        if (x0 < x1 && y0 < y1) {
1739
10.1k
            pdf14_buf *result;
1740
10.1k
            bool did_alloc; /* We don't care here */
1741
1742
10.1k
            if (has_matte) {
1743
2.41k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1744
2.41k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1745
2.41k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1746
2.41k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1747
2.41k
                has_matte = false;
1748
7.76k
            } else {
1749
7.76k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1750
7.76k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1751
7.76k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1752
7.76k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1753
7.76k
            }
1754
10.1k
            if (result == NULL) {
1755
                /* Clean up and return error code */
1756
0
                code = gs_error_unknownerror;
1757
0
                goto exit;
1758
0
            }
1759
1760
#if RAW_DUMP
1761
            /* Dump the current buffer to see what we have. */
1762
            dump_raw_buffer(ctx->memory,
1763
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1764
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1765
                            ctx->stack->planestride, ctx->stack->rowstride,
1766
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1767
                            ctx->stack->deep);
1768
#endif
1769
             /* compose. never do overprint in this case */
1770
10.1k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1771
10.1k
                 nos->group_color_info->isadditive,
1772
10.1k
                 nos->group_color_info->blend_procs,
1773
10.1k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1774
10.1k
        }
1775
1.02M
    } else {
1776
        /* Group color spaces are the same.  No color conversions needed */
1777
1.02M
        if (x0 < x1 && y0 < y1)
1778
666k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1779
666k
                                ctx->additive, pblend_procs, has_matte, overprint,
1780
666k
                                drawn_comps, ctx->memory, dev);
1781
1.02M
    }
1782
4.33M
exit:
1783
4.33M
    ctx->stack = nos;
1784
    /* We want to detect the cases where we have luminosity soft masks embedded
1785
       within one another.  The "alpha" channel really needs to be merged into
1786
       the luminosity channel in this case.  This will occur during the mask pop */
1787
4.33M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1788
        /* Set the trigger so that we will blend if not alpha. Since
1789
           we have softmasks embedded in softmasks */
1790
1.45k
        ctx->smask_blend = true;
1791
1.45k
    }
1792
4.33M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1793
4.33M
    pdf14_buf_free(tos);
1794
4.33M
    if (code < 0)
1795
0
        return_error(code);
1796
4.33M
    return 0;
1797
4.33M
}
1798
1799
/*
1800
 * Create a transparency mask that will be used as the mask for
1801
 * the next transparency group that is created afterwards.
1802
 * The sequence of calls is:
1803
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1804
 */
1805
static  int
1806
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1807
                             byte *transfer_fn, bool is_ident, bool idle,
1808
                             bool replacing, uint mask_id,
1809
                             gs_transparency_mask_subtype_t subtype,
1810
                             int numcomps, int Background_components,
1811
                             const float Background[], int Matte_components,
1812
                             const float Matte[], const float GrayBackground,
1813
                             pdf14_group_color_t* group_color)
1814
1.03M
{
1815
1.03M
    pdf14_buf *buf;
1816
1.03M
    int i;
1817
1818
1.03M
    if_debug2m('v', ctx->memory,
1819
1.03M
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1820
1.03M
               idle, replacing);
1821
1.03M
    ctx->smask_depth += 1;
1822
1823
1.03M
    if (ctx->stack == NULL) {
1824
0
        return_error(gs_error_VMerror);
1825
0
    }
1826
1827
    /* An optimization to consider is that if the SubType is Alpha
1828
       then we really should only be allocating the alpha band and
1829
       only draw with that channel.  Current architecture makes that
1830
       a bit tricky.  We need to create this based upon the size of
1831
       the color space + an alpha channel. NOT the device size
1832
       or the previous ctx size */
1833
    /* A mask doesn't worry about tags */
1834
1.03M
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1835
1.03M
                        ctx->memory, ctx->deep);
1836
1.03M
    if (buf == NULL)
1837
0
        return_error(gs_error_VMerror);
1838
1.03M
    buf->alpha = bg_alpha;
1839
1.03M
    buf->is_ident = is_ident;
1840
    /* fill in, but these values aren't really used */
1841
1.03M
    buf->isolated = true;
1842
1.03M
    buf->knockout = false;
1843
1.03M
    buf->shape = 0xffff;
1844
1.03M
    buf->blend_mode = BLEND_MODE_Normal;
1845
1.03M
    buf->transfer_fn = transfer_fn;
1846
1.03M
    buf->matte_num_comps = Matte_components;
1847
1.03M
    buf->group_color_info = group_color;
1848
1849
1.03M
    if (Matte_components) {
1850
8.32k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1851
8.32k
                                                "pdf14_push_transparency_mask");
1852
8.32k
        if (buf->matte == NULL)
1853
0
            return_error(gs_error_VMerror);
1854
33.3k
        for (i = 0; i < Matte_components; i++) {
1855
24.9k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1856
24.9k
        }
1857
8.32k
    }
1858
1.03M
    buf->mask_id = mask_id;
1859
    /* If replacing=false, we start the mask for an image with SMask.
1860
       In this case the image's SMask temporary replaces the
1861
       mask of the containing group. Save the containing droup's mask
1862
       in buf->mask_stack */
1863
1.03M
    buf->mask_stack = ctx->mask_stack;
1864
1.03M
    if (buf->mask_stack){
1865
257k
        rc_increment(buf->mask_stack->rc_mask);
1866
257k
    }
1867
#if RAW_DUMP
1868
    /* Dump the current buffer to see what we have. */
1869
    if (ctx->stack->planestride > 0 ){
1870
        dump_raw_buffer(ctx->memory,
1871
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1872
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1873
                        ctx->stack->planestride, ctx->stack->rowstride,
1874
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1875
        global_index++;
1876
    }
1877
#endif
1878
1.03M
    buf->saved = ctx->stack;
1879
1.03M
    ctx->stack = buf;
1880
    /* Soft Mask related information so we know how to
1881
       compute luminosity when we pop the soft mask */
1882
1.03M
    buf->SMask_SubType = subtype;
1883
1.03M
    if (buf->data != NULL) {
1884
        /* We need to initialize it to the BC if it existed */
1885
        /* According to the spec, the CS has to be the same */
1886
        /* If the back ground component is black, then don't bother
1887
           with this.  Since we are forcing the rendering to gray
1888
           earlier now, go ahead and just use the GrayBackGround color
1889
           directly. */
1890
565k
        if ( Background_components && GrayBackground != 0.0 ) {
1891
214
            if (buf->deep) {
1892
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1893
0
                gs_memset16(buf->data, gray, buf->planestride);
1894
                /* If we have a background component that was not black, then we
1895
                   need to set the alpha for this mask as if we had drawn in the
1896
                   entire soft mask buffer */
1897
0
                gs_memset16(buf->data + buf->planestride, 65535,
1898
0
                            buf->planestride *(buf->n_chan - 1));
1899
214
            } else {
1900
214
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1901
214
                memset(buf->data, gray, buf->planestride);
1902
                /* If we have a background component that was not black, then we
1903
                   need to set the alpha for this mask as if we had drawn in the
1904
                   entire soft mask buffer */
1905
214
                memset(buf->data + buf->planestride, 255,
1906
214
                       buf->planestride * (buf->n_chan - 1));
1907
214
            }
1908
565k
        } else {
1909
            /* Compose mask with opaque background */
1910
565k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1911
565k
        }
1912
565k
    }
1913
1.03M
    return 0;
1914
1.03M
}
1915
1916
static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory)
1917
257k
{
1918
257k
    pdf14_mask_t *mask_stack = ctx->mask_stack;
1919
1920
257k
    if (mask_stack->rc_mask != NULL) {
1921
1.33k
        pdf14_mask_t *curr_mask = mask_stack;
1922
1.33k
        pdf14_mask_t *old_mask;
1923
2.67k
        while (curr_mask != NULL) {
1924
            /* Force to decrement until free */
1925
3.04k
            while (curr_mask->rc_mask != NULL)
1926
1.70k
                rc_decrement(curr_mask->rc_mask, "pdf14_free_mask_stack");
1927
1.33k
            old_mask = curr_mask;
1928
1.33k
            curr_mask = curr_mask->previous;
1929
1.33k
            gs_free_object(old_mask->memory, old_mask, "pdf14_free_mask_stack");
1930
1.33k
        }
1931
256k
    } else {
1932
256k
        gs_free_object(memory, mask_stack, "pdf14_free_mask_stack");
1933
256k
    }
1934
257k
    ctx->mask_stack = NULL;
1935
257k
}
1936
1937
static  int
1938
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1939
1.03M
{
1940
1.03M
    pdf14_buf* tos = ctx->stack;
1941
1.03M
    pdf14_buf* nos = tos->saved;
1942
1.03M
    byte *new_data_buf;
1943
1.03M
    int icc_match;
1944
1.03M
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1945
1.03M
    cmm_profile_t *src_profile;
1946
1.03M
    gsicc_rendering_param_t rendering_params;
1947
1.03M
    gsicc_link_t *icc_link;
1948
1.03M
    gsicc_rendering_param_t render_cond;
1949
1.03M
    cmm_dev_profile_t *dev_profile;
1950
1.03M
    int code = 0;
1951
1952
1.03M
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1953
1.03M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1954
1.03M
                          &render_cond);
1955
1.03M
    ctx->smask_depth -= 1;
1956
    /* icc_match == -1 means old non-icc code.
1957
       icc_match == 0 means use icc code
1958
       icc_match == 1 mean no conversion needed */
1959
1.03M
    if (des_profile != NULL && src_profile != NULL ) {
1960
1.03M
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1961
1.03M
    } else {
1962
0
        icc_match = -1;
1963
0
    }
1964
1.03M
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1965
1.03M
               tos->idle);
1966
1.03M
    ctx->stack = tos->saved;
1967
1.03M
    tos->saved = NULL;  /* To avoid issues with GC */
1968
1.03M
    if (tos->mask_stack) {
1969
        /* During the soft mask push, the mask_stack was copied (not moved) from
1970
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1971
           just set to NULL.  However, before we do that we must perform
1972
           rc decrement to match the increment that occured was made.  Also,
1973
           if this is the last ref count of the rc_mask, we should free the
1974
           buffer now since no other groups need it. */
1975
256k
        rc_decrement(tos->mask_stack->rc_mask,
1976
256k
                     "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1977
256k
        if (tos->mask_stack->rc_mask) {
1978
256k
            if (tos->mask_stack->rc_mask->rc.ref_count == 1){
1979
256k
                rc_decrement(tos->mask_stack->rc_mask,
1980
256k
                            "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1981
256k
            }
1982
256k
        }
1983
256k
        tos->mask_stack = NULL;
1984
256k
    }
1985
1.03M
    if (tos->data == NULL ) {
1986
        /* This can occur in clist rendering if the soft mask does
1987
           not intersect the current band.  It would be nice to
1988
           catch this earlier and just avoid creating the structure
1989
           to begin with.  For now we need to delete the structure
1990
           that was created.  Only delete if the alpha value is 65535 */
1991
465k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1992
465k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1993
8.16k
            pdf14_buf_free(tos);
1994
8.16k
            if (ctx->mask_stack != NULL) {
1995
3.43k
                pdf14_free_mask_stack(ctx, ctx->memory);
1996
3.43k
            }
1997
457k
        } else {
1998
            /* Assign as mask buffer */
1999
457k
            if (ctx->mask_stack != NULL) {
2000
140k
                pdf14_free_mask_stack(ctx, ctx->memory);
2001
140k
            }
2002
457k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2003
457k
            ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2004
457k
            ctx->mask_stack->rc_mask->mask_buf = tos;
2005
457k
        }
2006
465k
        ctx->smask_blend = false;  /* just in case */
2007
565k
    } else {
2008
        /* If we are already in the source space then there is no reason
2009
           to do the transformation */
2010
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
2011
        /* This will reduce our memory.  We won't reuse the existing one, due */
2012
        /* Due to the fact that on certain systems we may have issues recovering */
2013
        /* the data after a resize */
2014
565k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
2015
565k
                                        "pdf14_pop_transparency_mask");
2016
565k
        if (new_data_buf == NULL)
2017
0
            return_error(gs_error_VMerror);
2018
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
2019
           we won't be filling everything during the remap if it had not been
2020
           written into by the PDF14 fill rect */
2021
565k
        memset(new_data_buf, 0, tos->planestride);
2022
        /* If the subtype was alpha, then just grab the alpha channel now
2023
           and we are all done */
2024
565k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
2025
40.7k
            ctx->smask_blend = false;  /* not used in this case */
2026
40.7k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
2027
40.7k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2028
40.7k
                       tos->rowstride,
2029
40.7k
                       (tos->data)+tos->planestride, new_data_buf);
2030
#if RAW_DUMP
2031
            /* Dump the current buffer to see what we have. */
2032
            dump_raw_buffer(ctx->memory,
2033
                            tos->rect.q.y-tos->rect.p.y,
2034
                            tos->rowstride>>tos->deep, 1,
2035
                            tos->planestride, tos->rowstride,
2036
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
2037
                            tos->deep);
2038
            global_index++;
2039
#endif
2040
524k
        } else {
2041
524k
            if (icc_match == 1 || tos->n_chan == 2) {
2042
#if RAW_DUMP
2043
                /* Dump the current buffer to see what we have. */
2044
                dump_raw_buffer(ctx->memory,
2045
                                tos->rect.q.y-tos->rect.p.y,
2046
                                tos->rowstride>>tos->deep, tos->n_planes,
2047
                                tos->planestride, tos->rowstride,
2048
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
2049
                                tos->deep);
2050
                global_index++;
2051
#endif
2052
                /* There is no need to color convert.  Data is already gray scale.
2053
                   We just need to copy the gray plane.  However it is
2054
                   possible that the soft mask could have a soft mask which
2055
                   would end us up with some alpha blending information
2056
                   (Bug691803). In fact, according to the spec, the alpha
2057
                   blending has to occur.  See FTS test fts_26_2601.pdf
2058
                   for an example of this.  Softmask buffer is intialized
2059
                   with BG values.  It would be nice to keep track if buffer
2060
                   ever has a alpha value not 1 so that we could detect and
2061
                   avoid this blend if not needed. */
2062
524k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
2063
524k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
2064
524k
                            tos->planestride, tos->deep);
2065
#if RAW_DUMP
2066
                /* Dump the current buffer to see what we have. */
2067
                dump_raw_buffer(ctx->memory,
2068
                                tos->rect.q.y-tos->rect.p.y,
2069
                                tos->rowstride>>tos->deep, 1,
2070
                                tos->planestride, tos->rowstride,
2071
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2072
                                tos->deep);
2073
                global_index++;
2074
#endif
2075
524k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2076
524k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2077
524k
                           tos->rowstride, tos->data, new_data_buf);
2078
524k
            } else {
2079
0
                if ( icc_match == -1 ) {
2080
                    /* The slow old fashioned way */
2081
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2082
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2083
0
                        tos->rowstride, tos->planestride,
2084
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2085
0
                        tos->deep
2086
#if RAW_DUMP
2087
                        , ctx->memory
2088
#endif
2089
0
                        );
2090
0
                } else {
2091
                    /* ICC case where we use the CMM */
2092
                    /* Request the ICC link for the transform that we will need to use */
2093
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2094
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2095
0
                    rendering_params.override_icc = false;
2096
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2097
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2098
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2099
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2100
0
                        src_profile, &rendering_params, pgs->memory, false);
2101
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2102
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2103
0
                              tos->rowstride, tos->planestride,
2104
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2105
                    /* Release the link */
2106
0
                    gsicc_release_link(icc_link);
2107
0
                }
2108
0
            }
2109
524k
        }
2110
        /* Free the old object, NULL test was above */
2111
565k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2112
565k
        tos->data = new_data_buf;
2113
        /* Data is single channel now */
2114
565k
        tos->n_chan = 1;
2115
565k
        tos->n_planes = 1;
2116
        /* Assign as reference counted mask buffer */
2117
565k
        if (ctx->mask_stack != NULL) {
2118
            /* In this case, the source file is wacky as it already had a
2119
               softmask and now is getting a replacement. We need to clean
2120
               up the softmask stack before doing this free and creating
2121
               a new stack. Bug 693312 */
2122
113k
            pdf14_free_mask_stack(ctx, ctx->memory);
2123
113k
        }
2124
565k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2125
565k
        if (ctx->mask_stack == NULL)
2126
0
            return gs_note_error(gs_error_VMerror);
2127
565k
        ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2128
565k
        if (ctx->mask_stack->rc_mask == NULL)
2129
0
            return gs_note_error(gs_error_VMerror);
2130
565k
        ctx->mask_stack->rc_mask->mask_buf = tos;
2131
565k
    }
2132
1.03M
    return code;
2133
1.03M
}
2134
2135
static pdf14_mask_t *
2136
pdf14_mask_element_new(gs_memory_t *memory)
2137
3.00M
{
2138
3.00M
    pdf14_mask_t *result;
2139
2140
3.00M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2141
3.00M
                             "pdf14_mask_element_new");
2142
3.00M
    if (result == NULL)
2143
0
        return NULL;
2144
    /* Get the reference counted mask */
2145
3.00M
    result->rc_mask = NULL;
2146
3.00M
    result->previous = NULL;
2147
3.00M
    result->memory = memory;
2148
3.00M
    return result;
2149
3.00M
}
2150
2151
static int
2152
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2153
0
{
2154
    /* We need to push the current soft mask.  We need to
2155
       be able to recover it if we draw a new one and
2156
       then obtain a Q operation ( a pop ) */
2157
2158
0
    pdf14_device *pdev = (pdf14_device *)dev;
2159
0
    pdf14_ctx *ctx = pdev->ctx;
2160
0
    pdf14_mask_t *new_mask;
2161
2162
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2163
    /* We need to push the current mask buffer   */
2164
    /* Allocate a new element for the stack.
2165
       Don't do anything if there is no mask present.*/
2166
0
    if (ctx->mask_stack != NULL) {
2167
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2168
        /* Duplicate and make the link */
2169
0
        new_mask->rc_mask = ctx->mask_stack->rc_mask;
2170
0
        rc_increment(new_mask->rc_mask);
2171
0
        new_mask->previous = ctx->mask_stack;
2172
0
        ctx->mask_stack = new_mask;
2173
0
    }
2174
#ifdef DEBUG
2175
    pdf14_debug_mask_stack_state(pdev->ctx);
2176
#endif
2177
0
    return 0;
2178
0
}
2179
2180
static int
2181
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2182
5.78M
{
2183
    /* Pop the soft mask.  It is no longer needed. Likely due to
2184
       a Q that has occurred. */
2185
5.78M
    pdf14_device *pdev = (pdf14_device *)dev;
2186
5.78M
    pdf14_ctx *ctx = pdev->ctx;
2187
5.78M
    pdf14_mask_t *old_mask;
2188
2189
5.78M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2190
    /* rc decrement the current link after we break it from
2191
       the list, then free the stack element.  Don't do
2192
       anything if there is no mask present. */
2193
5.78M
    if (ctx->mask_stack != NULL) {
2194
1.04M
        old_mask = ctx->mask_stack;
2195
1.04M
        ctx->mask_stack = ctx->mask_stack->previous;
2196
1.04M
        if (old_mask->rc_mask) {
2197
1.04M
            rc_decrement(old_mask->rc_mask, "pdf14_pop_transparency_state");
2198
1.04M
        }
2199
1.04M
        gs_free_object(old_mask->memory, old_mask, "pdf14_pop_transparency_state");
2200
        /* We need to have some special handling here for when we have nested
2201
           soft masks.  There may be a copy in the stack that we may need to
2202
           adjust. */
2203
1.04M
        if (ctx->smask_depth > 0) {
2204
1.30k
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2205
1.10k
                ctx->stack->mask_stack = ctx->mask_stack;
2206
1.10k
            }
2207
1.30k
        }
2208
1.04M
    }
2209
#ifdef DEBUG
2210
    pdf14_debug_mask_stack_state(pdev->ctx);
2211
#endif
2212
5.78M
    return 0;
2213
5.78M
}
2214
2215
static  int
2216
pdf14_open(gx_device *dev)
2217
1.98M
{
2218
1.98M
    pdf14_device *pdev = (pdf14_device *)dev;
2219
2220
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2221
1.98M
    if (pdev->ctx == NULL) {
2222
1.98M
        bool has_tags = device_encodes_tags(dev);
2223
1.98M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2224
1.98M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2225
1.98M
        if (pdev->ctx == NULL)
2226
0
            return_error(gs_error_VMerror);
2227
2228
1.98M
        pdev->ctx->rect.p.x = 0;
2229
1.98M
        pdev->ctx->rect.p.y = 0;
2230
1.98M
        pdev->ctx->rect.q.x = dev->width;
2231
1.98M
        pdev->ctx->rect.q.y = dev->height;
2232
1.98M
        pdev->ctx->has_tags = has_tags;
2233
1.98M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2234
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2235
         * is. I am not sure how to fix that. */
2236
1.98M
        if (pdev->ctx->num_spots < 0)
2237
0
            pdev->ctx->num_spots = 0;
2238
1.98M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2239
1.98M
    }
2240
1.98M
    pdev->free_devicen = true;
2241
1.98M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2242
1.98M
    return 0;
2243
1.98M
}
2244
2245
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2246
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2247
};
2248
2249
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2250
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2251
};
2252
2253
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2254
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2255
};
2256
2257
static const gx_cm_color_map_procs *
2258
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2259
9.64M
{
2260
9.64M
    *tdev = dev;
2261
9.64M
    return &pdf14_DeviceCMYKspot_procs;
2262
9.64M
}
2263
2264
static const gx_cm_color_map_procs *
2265
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2266
16.0M
{
2267
16.0M
    *tdev = dev;
2268
16.0M
    return &pdf14_DeviceRGBspot_procs;
2269
16.0M
}
2270
2271
static const gx_cm_color_map_procs *
2272
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2273
87
{
2274
87
    *tdev = dev;
2275
87
    return &pdf14_DeviceGrayspot_procs;
2276
87
}
2277
2278
static void
2279
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2280
0
{
2281
0
    for (; n != 0; n--) {
2282
0
        uint16_t in = *src++;
2283
0
        ((byte *)dst)[0] = in>>8;
2284
0
        ((byte *)dst)[1] = in;
2285
0
        dst++;
2286
0
    }
2287
0
}
2288
2289
/* Used to pass along information about the buffer created by the
2290
   pdf14 device.  This is used by the pattern accumulator when the
2291
   pattern contains transparency.  Note that if free_device is true then
2292
   we need to go ahead and get the buffer data copied and free up the
2293
   device.  This only occurs at the end of a pattern accumulation operation */
2294
int
2295
pdf14_get_buffer_information(const gx_device * dev,
2296
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2297
                             bool free_device)
2298
69.2k
{
2299
69.2k
    const pdf14_device * pdev = (pdf14_device *)dev;
2300
69.2k
    pdf14_buf *buf;
2301
69.2k
    gs_int_rect rect;
2302
69.2k
    int x1,y1,width,height;
2303
2304
69.2k
    if ( pdev->ctx == NULL){
2305
0
        return 0;  /* this can occur if the pattern is a clist */
2306
0
    }
2307
#ifdef DEBUG
2308
    pdf14_debug_mask_stack_state(pdev->ctx);
2309
#endif
2310
69.2k
    buf = pdev->ctx->stack;
2311
69.2k
    rect = buf->rect;
2312
69.2k
    transbuff->buf = (free_device ? NULL : buf);
2313
69.2k
    x1 = min(pdev->width, rect.q.x);
2314
69.2k
    y1 = min(pdev->height, rect.q.y);
2315
69.2k
    width = x1 - rect.p.x;
2316
69.2k
    height = y1 - rect.p.y;
2317
2318
69.2k
    transbuff->n_chan    = buf->n_chan;
2319
69.2k
    transbuff->has_tags  = buf->has_tags;
2320
69.2k
    transbuff->has_shape = buf->has_shape;
2321
69.2k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2322
69.2k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2323
69.2k
    transbuff->deep      = buf->deep;
2324
2325
69.2k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2326
15.1k
        transbuff->planestride = 0;
2327
15.1k
        transbuff->rowstride = 0;
2328
15.1k
        return 0;
2329
15.1k
    }
2330
2331
54.0k
    if (free_device) {
2332
19.0k
        transbuff->pdev14 = NULL;
2333
19.0k
        transbuff->rect = rect;
2334
19.0k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2335
            /* If the bbox is smaller than the whole buffer than go ahead and
2336
               create a new one to use.  This can occur if we drew in a smaller
2337
               area than was specified by the transparency group rect. */
2338
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2339
0
            intptr_t planestride = rowstride * height;
2340
0
            int k, j;
2341
0
            byte *buff_ptr_src, *buff_ptr_des;
2342
2343
0
            transbuff->planestride = planestride;
2344
0
            transbuff->rowstride = rowstride;
2345
0
            transbuff->transbytes =
2346
0
                         gs_alloc_bytes(mem,
2347
0
                                        planestride *
2348
0
                                                (buf->n_chan +
2349
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2350
0
                                        "pdf14_get_buffer_information");
2351
0
            if (transbuff->transbytes == NULL)
2352
0
                return gs_error_VMerror;
2353
2354
0
            transbuff->mem = mem;
2355
0
            if (transbuff->deep) {
2356
0
                for (j = 0; j < transbuff->n_chan; j++) {
2357
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2358
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2359
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2360
0
                    for (k = 0; k < height; k++) {
2361
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2362
0
                        buff_ptr_des += rowstride;
2363
0
                        buff_ptr_src += buf->rowstride;
2364
0
                    }
2365
0
                }
2366
0
            } else {
2367
0
                for (j = 0; j < transbuff->n_chan; j++) {
2368
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2369
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2370
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2371
0
                    for (k = 0; k < height; k++) {
2372
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2373
0
                        buff_ptr_des += rowstride;
2374
0
                        buff_ptr_src += buf->rowstride;
2375
0
                    }
2376
0
                }
2377
0
            }
2378
2379
19.0k
        } else {
2380
            /* The entire buffer is used.  Go ahead and grab the pointer and
2381
               clear the pointer in the pdf14 device data buffer so it is not
2382
               freed when we close the device */
2383
19.0k
            transbuff->planestride = buf->planestride;
2384
19.0k
            transbuff->rowstride = buf->rowstride;
2385
19.0k
            transbuff->transbytes = buf->data;
2386
19.0k
            transbuff->mem = buf->memory;
2387
19.0k
            buf->data = NULL;  /* So that the buffer is not freed */
2388
19.0k
            if (transbuff->deep) {
2389
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2390
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2391
0
                uint16_t *buff_ptr;
2392
0
                int j, k, z;
2393
0
                intptr_t rowstride = transbuff->rowstride>>1;
2394
0
                intptr_t planestride = transbuff->planestride;
2395
0
                for (j = 0; j < transbuff->n_chan; j++) {
2396
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2397
0
                    for (k = 0; k < height; k++) {
2398
0
                        for (z = 0; z < width; z++) {
2399
0
                            uint16_t in = buff_ptr[z];
2400
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2401
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2402
0
                        }
2403
0
                        buff_ptr += rowstride;
2404
0
                    }
2405
0
                }
2406
0
            }
2407
19.0k
        }
2408
#if RAW_DUMP
2409
        /* Dump the buffer that should be going into the pattern */;
2410
        dump_raw_buffer_be(buf->memory,
2411
                           height, width, transbuff->n_chan,
2412
                           transbuff->planestride, transbuff->rowstride,
2413
                           "pdf14_pattern_buff", transbuff->transbytes,
2414
                           transbuff->deep);
2415
        global_index++;
2416
#endif
2417
        /* Go ahead and free up the pdf14 device */
2418
19.0k
        dev_proc(dev, close_device)((gx_device *)dev);
2419
35.0k
    } else {
2420
        /* Here we are coming from one of the fill image / pattern / mask
2421
           operations */
2422
35.0k
        transbuff->pdev14 = dev;
2423
35.0k
        transbuff->planestride = buf->planestride;
2424
35.0k
        transbuff->rowstride = buf->rowstride;
2425
35.0k
        transbuff->transbytes = buf->data;
2426
35.0k
        transbuff->mem = buf->memory;
2427
35.0k
        transbuff->rect = rect;
2428
#if RAW_DUMP
2429
    /* Dump the buffer that should be going into the pattern */;
2430
        dump_raw_buffer(buf->memory,
2431
                        height, width, buf->n_chan,
2432
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2433
                        "pdf14_pattern_buff",
2434
                        buf->data,
2435
                        transbuff->deep);
2436
        global_index++;
2437
#endif
2438
35.0k
    }
2439
54.0k
    return 0;
2440
54.0k
}
2441
2442
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2443
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2444
2445
2446
static int
2447
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2448
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2449
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2450
24.1k
{
2451
24.1k
    pdf14_buf* cm_result = NULL;
2452
24.1k
    cmm_profile_t* des_profile;
2453
24.1k
    gsicc_rendering_param_t render_cond;
2454
24.1k
    bool did_alloc;
2455
24.1k
    bool endian_swap;
2456
2457
24.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2458
24.1k
        &render_cond);
2459
2460
#if RAW_DUMP
2461
#if !ARCH_IS_BIG_ENDIAN
2462
    if (was_blended && (*buf)->deep)
2463
      dump_raw_buffer_be(dev->ctx->memory,
2464
          height, width, (*buf)->n_planes, (*buf)->planestride,
2465
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2466
    else
2467
#endif
2468
      dump_raw_buffer(dev->ctx->memory,
2469
          height, width, (*buf)->n_planes, (*buf)->planestride,
2470
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2471
    global_index++;
2472
#endif
2473
2474
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2475
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2476
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2477
       will need to know if it is dealing with native or BE data. */
2478
24.1k
    if (was_blended && (*buf)->deep) {
2479
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2480
           color conversion */
2481
#if ARCH_IS_BIG_ENDIAN
2482
        endian_swap = false;
2483
#else
2484
0
        endian_swap = true;
2485
0
#endif
2486
24.1k
    } else {
2487
        /* Data is in native format. No swap needed for CMM */
2488
24.1k
        endian_swap = false;
2489
24.1k
    }
2490
2491
24.1k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2492
24.1k
        *buf_ptr, src_profile, des_profile, x, y, width,
2493
24.1k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2494
2495
24.1k
    if (cm_result == NULL)
2496
0
        return_error(gs_error_VMerror);
2497
2498
    /* Update */
2499
24.1k
    *buf = cm_result;
2500
2501
    /* Make sure our buf_ptr is pointing to the proper location */
2502
24.1k
    if (did_alloc)
2503
24.1k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2504
2505
#if RAW_DUMP
2506
    dump_raw_buffer(dev->ctx->memory,
2507
        height, width, (*buf)->n_planes, (*buf)->planestride,
2508
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2509
    global_index++;
2510
#endif
2511
24.1k
    return 0;
2512
24.1k
}
2513
2514
/**
2515
 * pdf14_put_image: Put rendered image to target device.
2516
 * @pdev: The PDF 1.4 rendering device.
2517
 * @pgs: State for image draw operation.
2518
 * @target: The target device.
2519
 *
2520
 * Puts the rendered image in @pdev's buffer to @target. This is called
2521
 * as part of the sequence of popping the PDF 1.4 device filter.
2522
 *
2523
 * Return code: negative on error.
2524
 **/
2525
static  int
2526
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2527
1.80M
{
2528
1.80M
    const pdf14_device * pdev = (pdf14_device *)dev;
2529
1.80M
    int code;
2530
1.80M
    gs_image1_t image;
2531
1.80M
    gx_image_enum_common_t *info;
2532
1.80M
    pdf14_buf *buf = pdev->ctx->stack;
2533
1.80M
    gs_int_rect rect;
2534
1.80M
    int y;
2535
1.80M
    int num_comp;
2536
1.80M
    byte *linebuf, *linebuf_unaligned;
2537
1.80M
    gs_color_space *pcs;
2538
1.80M
    int x1, y1, width, height;
2539
1.80M
    byte *buf_ptr;
2540
1.80M
    int num_rows_left;
2541
1.80M
    cmm_profile_t* src_profile = NULL;
2542
1.80M
    cmm_profile_t* des_profile = NULL;
2543
1.80M
    cmm_dev_profile_t *pdf14dev_profile;
2544
1.80M
    cmm_dev_profile_t *dev_target_profile;
2545
1.80M
    uint16_t bg;
2546
1.80M
    bool has_tags = device_encodes_tags(dev);
2547
1.80M
    bool deep = pdev->ctx->deep;
2548
1.80M
    intptr_t planestride;
2549
1.80M
    intptr_t rowstride;
2550
1.80M
    blend_image_row_proc_t *blend_row;
2551
1.80M
    bool color_mismatch = false;
2552
1.80M
    bool supports_alpha = false;
2553
1.80M
    int i;
2554
1.80M
    int alpha_offset, tag_offset;
2555
1.80M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2556
1.80M
    int rendering_intent_saved;
2557
1.80M
    int additive;
2558
2559
    /* Nothing was ever drawn. */
2560
1.80M
    if (buf == NULL)
2561
160k
        return 0;
2562
2563
1.64M
    additive = buf->group_color_info->isadditive;
2564
2565
1.64M
    src_profile = buf->group_color_info->icc_profile;
2566
2567
1.64M
    num_comp = buf->n_chan - 1;
2568
1.64M
    rect = buf->rect;
2569
1.64M
    planestride = buf->planestride;
2570
1.64M
    rowstride = buf->rowstride;
2571
2572
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2573
       potential problem. Bug 694190 */
2574
1.64M
    if (buf->saved != NULL) {
2575
125
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2576
125
    }
2577
1.64M
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2578
1.64M
    rect_intersect(rect, buf->dirty);
2579
1.64M
    x1 = min(pdev->width, rect.q.x);
2580
1.64M
    y1 = min(pdev->height, rect.q.y);
2581
1.64M
    width = x1 - rect.p.x;
2582
1.64M
    height = y1 - rect.p.y;
2583
#ifdef DUMP_TO_PNG
2584
    dump_planar_rgba(pdev->memory, buf);
2585
#endif
2586
1.64M
    if (width <= 0 || height <= 0 || buf->data == NULL)
2587
318k
        return 0;
2588
1.32M
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2589
2590
    /* Check that target is OK.  From fuzzing results the target could have been
2591
       destroyed, for e.g if it were a pattern accumulator that was closed
2592
       prematurely (Bug 694154).  We should always be able to to get an ICC
2593
       profile from the target. */
2594
1.32M
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2595
1.32M
    if (code < 0)
2596
0
        return code;
2597
1.32M
    if (dev_target_profile == NULL)
2598
0
        return gs_throw_code(gs_error_Fatal);
2599
2600
1.32M
    if (src_profile == NULL) {
2601
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2602
0
        if (code < 0) {
2603
0
            return code;
2604
0
        }
2605
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2606
0
    }
2607
2608
    /* Check if we have a color conversion issue */
2609
1.32M
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2610
1.32M
    if (!gsicc_profiles_equal(des_profile, src_profile))
2611
220k
        color_mismatch = true;
2612
2613
    /* Check if target supports alpha */
2614
1.32M
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2615
1.32M
    code = 0;
2616
2617
#if RAW_DUMP
2618
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2619
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2620
        "pre_final_blend", buf_ptr, deep);
2621
#endif
2622
2623
    /* Note. The logic below will need a little rework if we ever
2624
       have a device that has tags and alpha support */
2625
1.32M
    if (supports_alpha) {
2626
0
        if (!color_mismatch) {
2627
0
            alpha_offset = num_comp;
2628
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2629
2630
0
            for (i = 0; i < buf->n_planes; i++)
2631
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2632
0
            for (; i < target->color_info.num_components; i++)
2633
0
                buf_ptrs[i] = 0;
2634
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2635
0
                rect.p.x, rect.p.y, width, height,
2636
0
                rowstride, alpha_offset,
2637
0
                tag_offset);
2638
            /* Right now code has number of rows written */
2639
0
        } else {
2640
            /* In this case, just color convert and maintain alpha.  This is a case
2641
               where we either either blend in the right color space and have no
2642
               alpha for the output device or hand back the wrong color space with
2643
               alpha data.  We choose the later. */
2644
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2645
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2646
0
                width, height, false);
2647
0
            if (code < 0)
2648
0
                return code;
2649
2650
            /* reset */
2651
0
            rowstride = buf->rowstride;
2652
0
            planestride = buf->planestride;
2653
0
            num_comp = buf->n_chan - 1;
2654
0
            alpha_offset = num_comp;
2655
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2656
2657
            /* And then out */
2658
0
            for (i = 0; i < buf->n_planes; i++)
2659
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2660
0
            for (; i < target->color_info.num_components; i++)
2661
0
                buf_ptrs[i] = 0;
2662
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2663
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2664
0
                tag_offset);
2665
            /* Right now code has number of rows written */
2666
0
        }
2667
1.32M
    } else if (has_tags) {
2668
        /* We are going out to a device that supports tags */
2669
0
        if (deep) {
2670
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2671
0
                buf->planestride, num_comp, additive, false);
2672
0
        } else {
2673
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2674
0
                buf->planestride, num_comp, additive);
2675
0
        }
2676
2677
#if RAW_DUMP
2678
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2679
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2680
            "post_final_blend", buf_ptr, deep);
2681
#endif
2682
2683
        /* Take care of color issues */
2684
0
        if (color_mismatch) {
2685
            /* In this case, just color convert and maintain alpha.  This is a case
2686
               where we either either blend in the right color space and have no
2687
               alpha for the output device or hand back the wrong color space with
2688
               alpha data.  We choose the later. */
2689
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2690
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2691
0
            if (code < 0)
2692
0
                return code;
2693
2694
#if RAW_DUMP
2695
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2696
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2697
                "final_color_manage", buf_ptr, deep);
2698
            global_index++;
2699
#endif
2700
0
        }
2701
2702
        /* reset */
2703
0
        rowstride = buf->rowstride;
2704
0
        planestride = buf->planestride;
2705
0
        num_comp = buf->n_chan - 1;
2706
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2707
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2708
2709
        /* And then out */
2710
0
        for (i = 0; i < buf->n_planes; i++)
2711
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2712
0
        for (; i < target->color_info.num_components; i++)
2713
0
            buf_ptrs[i] = 0;
2714
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2715
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2716
0
            tag_offset);
2717
        /* Right now code has number of rows written */
2718
2719
0
    }
2720
2721
    /* If code > 0 then put image worked.  Let it finish and then exit */
2722
1.32M
    if (code > 0) {
2723
        /* We processed some or all of the rows.  Continue until we are done */
2724
0
        num_rows_left = height - code;
2725
0
        while (num_rows_left > 0) {
2726
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2727
0
                                                rect.p.x, rect.p.y + code, width,
2728
0
                                                num_rows_left, rowstride,
2729
0
                                                alpha_offset, tag_offset);
2730
0
            num_rows_left = num_rows_left - code;
2731
0
        }
2732
0
        return 0;
2733
0
    }
2734
2735
    /* Target device did not support alpha or tags.
2736
     * Set color space in preparation for sending an image.
2737
     * color conversion will occur after blending with through
2738
     * the begin typed image work flow.
2739
     */
2740
2741
1.32M
    planestride = buf->planestride;
2742
1.32M
    rowstride = buf->rowstride;
2743
1.32M
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2744
1.32M
    if (code < 0)
2745
0
        return code;
2746
    /* Need to set this to avoid color management during the image color render
2747
       operation.  Exception is for the special case when the destination was
2748
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2749
       image operation.  That will happen here as we should have set the profile
2750
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2751
       the case when we have a blend color space that is different than the
2752
       target device color space */
2753
1.32M
    pcs->cmm_icc_profile_data = src_profile;
2754
2755
    /* pcs takes a reference to the profile data it just retrieved. */
2756
1.32M
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2757
1.32M
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2758
1.32M
    gs_image_t_init_adjust(&image, pcs, false);
2759
1.32M
    image.ImageMatrix.xx = (float)width;
2760
1.32M
    image.ImageMatrix.yy = (float)height;
2761
1.32M
    image.Width = width;
2762
1.32M
    image.Height = height;
2763
1.32M
    image.BitsPerComponent = deep ? 16 : 8;
2764
1.32M
    image.ColorSpace = pcs;
2765
1.32M
    ctm_only_writable(pgs).xx = (float)width;
2766
1.32M
    ctm_only_writable(pgs).xy = 0;
2767
1.32M
    ctm_only_writable(pgs).yx = 0;
2768
1.32M
    ctm_only_writable(pgs).yy = (float)height;
2769
1.32M
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2770
1.32M
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2771
    /* Make sure that the relative colorimetric rendering intent is
2772
       used for this image. */
2773
1.32M
    rendering_intent_saved = pgs->renderingintent;
2774
1.32M
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2775
1.32M
    code = dev_proc(target, begin_typed_image) (target,
2776
1.32M
                                                pgs, NULL,
2777
1.32M
                                                (gs_image_common_t *)&image,
2778
1.32M
                                                NULL, NULL, NULL,
2779
1.32M
                                                pgs->memory, &info);
2780
1.32M
    pgs->renderingintent = rendering_intent_saved;
2781
1.32M
    if (code < 0) {
2782
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2783
0
        return code;
2784
0
    }
2785
#if RAW_DUMP
2786
    /* Dump the current buffer to see what we have. */
2787
    dump_raw_buffer(pdev->ctx->memory,
2788
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2789
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2790
                    pdev->ctx->stack->n_planes,
2791
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2792
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2793
    dump_raw_buffer(pdev->ctx->memory,
2794
                    height, width, buf->n_planes,
2795
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2796
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2797
    global_index++;
2798
    clist_band_count++;
2799
#endif
2800
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2801
    /* 28 byte overflow for AVX CMYK case. */
2802
1.32M
#define SSE_ALIGN 32
2803
1.32M
#define SSE_OVERFLOW 28
2804
1.32M
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2805
1.32M
    if (linebuf_unaligned == NULL)
2806
0
        return gs_error_VMerror;
2807
1.32M
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2808
2809
1.32M
    blend_row = deep ? gx_build_blended_image_row16 :
2810
1.32M
                       gx_build_blended_image_row;
2811
#ifdef WITH_CAL
2812
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2813
                                  blend_row, num_comp, deep);
2814
#endif
2815
2816
1.32M
    bg = additive ? (deep ? 65535 : 255) : 0;
2817
14.7M
    for (y = 0; y < height; y++) {
2818
13.4M
        gx_image_plane_t planes;
2819
13.4M
        int rows_used;
2820
2821
13.4M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2822
13.4M
        planes.data = linebuf;
2823
13.4M
        planes.data_x = 0;
2824
13.4M
        planes.raster = width * num_comp;
2825
13.4M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2826
        /* todo: check return value */
2827
13.4M
        buf_ptr += buf->rowstride;
2828
13.4M
    }
2829
1.32M
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2830
1.32M
    info->procs->end_image(info, true);
2831
    /* This will also decrement the device profile */
2832
1.32M
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2833
1.32M
    return code;
2834
1.32M
}
2835
2836
/* Overprint simulation with spots.  Collapse to CMYK */
2837
static void
2838
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2839
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2840
    cmyk_composite_map *map, bool keep_alpha)
2841
0
{
2842
0
    int comp_num;
2843
0
    uint cyan, magenta, yellow, black;
2844
0
    cmyk_composite_map *cmyk_map_entry;
2845
0
    int x, y;
2846
0
    intptr_t position;
2847
0
    byte comp, a;
2848
2849
0
    for (y = 0; y < height; y++) {
2850
0
        position = y * rowstride;
2851
0
        for (x = 0; x < width; x++) {
2852
0
            a = buf_ptr[position + planestride * num_comp];
2853
0
            if (a != 0) {
2854
0
                cyan = buf_ptr[position] * frac_1;
2855
0
                magenta = buf_ptr[position + planestride] * frac_1;
2856
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2857
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2858
0
                cmyk_map_entry = &(map[4]);
2859
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2860
0
                    comp = buf_ptr[position + planestride * comp_num];
2861
0
                    cyan += cmyk_map_entry->c * comp;
2862
0
                    magenta += cmyk_map_entry->m * comp;
2863
0
                    yellow += cmyk_map_entry->y * comp;
2864
0
                    black += cmyk_map_entry->k * comp;
2865
0
                    cmyk_map_entry++;
2866
0
                }
2867
0
                cyan /= frac_1;
2868
0
                magenta /= frac_1;
2869
0
                yellow /= frac_1;
2870
0
                black /= frac_1;
2871
2872
0
                if (cyan > 255)
2873
0
                    cyan = 255;
2874
0
                if (magenta > 255)
2875
0
                    magenta = 255;
2876
0
                if (yellow > 255)
2877
0
                    yellow = 255;
2878
0
                if (black > 255)
2879
0
                    black = 255;
2880
2881
0
                buf_ptr[position] = cyan;
2882
0
                buf_ptr[position + planestride] = magenta;
2883
0
                buf_ptr[position + planestride * 2] = yellow;
2884
0
                buf_ptr[position + planestride * 3] = black;
2885
0
            }
2886
0
            if (keep_alpha) {
2887
                /* Move the alpha and tag data */
2888
0
                buf_ptr[position + planestride * 4] = a;
2889
0
                if (tag_offset > 0) {
2890
0
                    buf_ptr[position + planestride * 5] =
2891
0
                        buf_ptr[position + planestride * tag_offset];
2892
0
                }
2893
0
            } else {
2894
                /* Remove alpha but keep tags */
2895
0
                if (tag_offset > 0) {
2896
0
                    buf_ptr[position + planestride * 4] =
2897
0
                        buf_ptr[position + planestride * tag_offset];
2898
0
                }
2899
2900
0
            }
2901
0
            position += 1;
2902
0
        }
2903
0
    }
2904
0
}
2905
2906
static void
2907
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2908
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2909
    cmyk_composite_map *map, bool keep_alpha)
2910
0
{
2911
0
    int comp_num;
2912
0
    ulong cyan, magenta, yellow, black;
2913
0
    cmyk_composite_map *cmyk_map_entry;
2914
0
    int x, y;
2915
0
    intptr_t position;
2916
0
    ulong comp, a;
2917
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2918
2919
    /* planestride and rowstride are in bytes, and we want them in shorts */
2920
0
    planestride >>= 1;
2921
0
    rowstride >>= 1;
2922
2923
0
    for (y = 0; y < height; y++) {
2924
0
        position = y * rowstride;
2925
0
        for (x = 0; x < width; x++) {
2926
0
            a = buf_ptr[position + planestride * num_comp];
2927
0
            if (a != 0) {
2928
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2929
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2930
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2931
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2932
0
                cmyk_map_entry = &(map[4]);
2933
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2934
0
                    comp = buf_ptr[position + planestride * comp_num];
2935
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2936
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2937
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2938
0
                    black += (ulong)cmyk_map_entry->k * comp;
2939
0
                    cmyk_map_entry++;
2940
0
                }
2941
0
                cyan /= frac_1_long;
2942
0
                magenta /= frac_1_long;
2943
0
                yellow /= frac_1_long;
2944
0
                black /= frac_1_long;
2945
2946
0
                if (cyan > 65535)
2947
0
                    cyan = 65535;
2948
0
                if (magenta > 65535)
2949
0
                    magenta = 65535;
2950
0
                if (yellow > 65535)
2951
0
                    yellow = 65535;
2952
0
                if (black > 65535)
2953
0
                    black = 65535;
2954
2955
#if ARCH_IS_BIG_ENDIAN
2956
                buf_ptr[position] = cyan;
2957
                buf_ptr[position + planestride] = magenta;
2958
                buf_ptr[position + planestride * 2] = yellow;
2959
                buf_ptr[position + planestride * 3] = black;
2960
#else
2961
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2962
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2963
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2964
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2965
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2966
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2967
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2968
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2969
0
#endif
2970
0
            }
2971
            /* Move the alpha and tag data */
2972
#if ARCH_IS_BIG_ENDIAN
2973
            if (keep_alpha) {
2974
                buf_ptr[position + planestride * 4] = a;
2975
                if (tag_offset > 0) {
2976
                    buf_ptr[position + planestride * 5] =
2977
                        buf_ptr[position + planestride * tag_offset];
2978
                }
2979
            } else {
2980
                if (tag_offset > 0) {
2981
                    buf_ptr[position + planestride * 4] =
2982
                        buf_ptr[position + planestride * tag_offset];
2983
                }
2984
            }
2985
#else
2986
0
            if (keep_alpha) {
2987
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2988
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2989
0
                if (tag_offset > 0) {
2990
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2991
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2992
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2993
0
                        buf_ptr[position + planestride * tag_offset];
2994
0
                }
2995
0
            } else {
2996
0
                if (tag_offset > 0) {
2997
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2998
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2999
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
3000
0
                        buf_ptr[position + planestride * tag_offset];
3001
0
                }
3002
0
            }
3003
0
#endif
3004
0
            position += 1;
3005
0
        }
3006
0
    }
3007
0
}
3008
3009
static void
3010
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
3011
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
3012
    cmyk_composite_map *map, bool keep_alpha, bool deep)
3013
0
{
3014
0
    if (deep) {
3015
0
        if (keep_alpha) {
3016
0
            if (tag_offset > 0) {
3017
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3018
0
                    planestride, num_comp, spot_start, tag_offset,
3019
0
                    map, true);
3020
0
            } else {
3021
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3022
0
                    planestride, num_comp, spot_start, 0,
3023
0
                    map, true);
3024
0
            }
3025
0
        } else {
3026
0
            if (tag_offset > 0) {
3027
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3028
0
                    planestride, num_comp, spot_start, tag_offset,
3029
0
                    map, false);
3030
0
            } else {
3031
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3032
0
                    planestride, num_comp, spot_start, 0,
3033
0
                    map, false);
3034
0
            }
3035
0
        }
3036
0
    } else {
3037
0
        if (keep_alpha) {
3038
0
            if (tag_offset > 0) {
3039
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3040
0
                    planestride, num_comp, spot_start, tag_offset,
3041
0
                    map, true);
3042
0
            } else {
3043
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3044
0
                    planestride, num_comp, spot_start, 0,
3045
0
                    map, true);
3046
0
            }
3047
0
        } else {
3048
0
            if (tag_offset > 0) {
3049
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3050
0
                    planestride, num_comp, spot_start, tag_offset,
3051
0
                    map, false);
3052
0
            } else {
3053
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3054
0
                    planestride, num_comp, spot_start, 0,
3055
0
                    map, false);
3056
0
            }
3057
0
        }
3058
0
    }
3059
0
}
3060
3061
/* This is for the case where we have mixture of spots and additive color.
3062
   For example, RGB + spots or Gray + spots */
3063
static void
3064
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3065
    intptr_t planestride, int num_comp, int spot_start)
3066
24.1k
{
3067
24.1k
    int x, y;
3068
24.1k
    intptr_t position;
3069
24.1k
    byte comp, a;
3070
24.1k
    int tmp, comp_num;
3071
3072
255k
    for (y = 0; y < height; y++) {
3073
230k
        position = y * rowstride;
3074
231M
        for (x = 0; x < width; x++) {
3075
231M
            a = buf_ptr[position + planestride * num_comp];
3076
231M
            if ((a + 1) & 0xfe) {
3077
10.0M
                a ^= 0xff;
3078
40.1M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3079
30.1M
                    comp = buf_ptr[position + planestride * comp_num];
3080
30.1M
                    tmp = ((0xff - comp) * a) + 0x80;
3081
30.1M
                    comp += (tmp + (tmp >> 8)) >> 8;
3082
30.1M
                    buf_ptr[position + planestride * comp_num] = comp;
3083
30.1M
                }
3084
10.0M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3085
0
                    comp = buf_ptr[position + planestride * comp_num];
3086
0
                    tmp = ((-comp) * a) + 0x80;
3087
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3088
0
                    buf_ptr[position + planestride * comp_num] = comp;
3089
0
                }
3090
221M
            } else if (a == 0) {
3091
175M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3092
131M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3093
131M
                }
3094
51.9M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3095
8.15M
                    buf_ptr[position + planestride * comp_num] = 0;
3096
8.15M
                }
3097
43.8M
            }
3098
231M
            position += 1;
3099
231M
        }
3100
230k
    }
3101
24.1k
}
3102
3103
static void
3104
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3105
    intptr_t planestride, int num_comp, int spot_start)
3106
0
{
3107
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3108
0
    int x, y;
3109
0
    intptr_t position;
3110
0
    int comp, a;
3111
0
    int tmp, comp_num;
3112
3113
    /* planestride and rowstride are in bytes, and we want them in shorts */
3114
0
    planestride >>= 1;
3115
0
    rowstride >>= 1;
3116
3117
    /* Note that the input here is native endian, and the output must be in big endian! */
3118
0
    for (y = 0; y < height; y++) {
3119
0
        position = y * rowstride;
3120
0
        for (x = 0; x < width; x++) {
3121
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3122
0
            a = buf_ptr[position + planestride * num_comp];
3123
0
            if (a == 0) {
3124
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3125
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3126
0
                }
3127
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3128
0
                    buf_ptr[position + planestride * comp_num] = 0;
3129
0
                }
3130
0
            } else if (a == 0xffff) {
3131
#if ARCH_IS_BIG_ENDIAN
3132
#else
3133
                /* Convert from native -> big endian */
3134
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3135
0
                    comp = buf_ptr[position + planestride * comp_num];
3136
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3137
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3138
0
                }
3139
0
#endif
3140
0
            } else {
3141
0
                a ^= 0xffff;
3142
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3143
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3144
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3145
0
                    comp = buf_ptr[position + planestride * comp_num];
3146
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3147
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3148
                    /* Store as big endian */
3149
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3150
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3151
0
                }
3152
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3153
0
                    comp = buf_ptr[position + planestride * comp_num];
3154
0
                    tmp = ((0 - comp) * a) + 0x4000;
3155
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3156
                    /* Store as big endian */
3157
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3158
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3159
0
                }
3160
0
            }
3161
0
            position += 1;
3162
0
        }
3163
0
    }
3164
0
}
3165
3166
static int
3167
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3168
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3169
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3170
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3171
    gs_separations* pseparations, bool deep)
3172
73.0k
{
3173
73.0k
    pdf14_device* pdev = (pdf14_device*)dev;
3174
73.0k
    int code = 0;
3175
73.0k
    int y;
3176
73.0k
    int num_rows_left;
3177
73.0k
    int i;
3178
73.0k
    gs_int_rect rect = rect_in;
3179
73.0k
    intptr_t planestride = planestride_in;
3180
73.0k
    intptr_t rowstride = rowstride_in;
3181
73.0k
    byte* buf_ptr = NULL;
3182
73.0k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3183
73.0k
    cmm_profile_t* des_profile = NULL;
3184
73.0k
    cmm_dev_profile_t* dev_target_profile;
3185
73.0k
    cmm_dev_profile_t* pdf14dev_profile;
3186
73.0k
    bool color_mismatch = false;
3187
73.0k
    bool supports_alpha = false;
3188
73.0k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3189
73.0k
    int alpha_offset = num_comp;
3190
73.0k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3191
73.0k
    gs_color_space *pcs;
3192
73.0k
    gs_image1_t image;
3193
73.0k
    gx_image_enum_common_t *info;
3194
73.0k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3195
73.0k
    pdf14_buf *cm_result = NULL;
3196
73.0k
    bool did_alloc;
3197
73.0k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3198
73.0k
    bool has_spots = pdev->ctx->num_spots > 0;
3199
73.0k
    bool blend_spots = !target_sep_device && has_spots;
3200
73.0k
    bool lose_channels = false;
3201
3202
    /* Check if group color space is CMYK based */
3203
73.0k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3204
73.0k
    if (code < 0)
3205
0
        return code;
3206
73.0k
    if (dev_target_profile == NULL)
3207
0
        return gs_throw_code(gs_error_Fatal);
3208
3209
73.0k
    if (src_profile == NULL) {
3210
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3211
0
        if (code < 0) {
3212
0
            return code;
3213
0
        }
3214
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3215
0
    }
3216
3217
    /* If the target device does not support spot colors and we have spot colors
3218
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3219
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3220
73.0k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3221
3222
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3223
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3224
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3225
0
        if (cm_result == NULL)
3226
0
            return_error(gs_error_VMerror);
3227
3228
        /* Update */
3229
0
        buf = cm_result;
3230
0
        src_profile = pgs->icc_manager->default_cmyk;
3231
0
        num_comp = buf->n_chan - 1;
3232
0
        additive = 0;
3233
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3234
0
        alpha_offset = num_comp;
3235
3236
#if RAW_DUMP
3237
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3238
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3239
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3240
        global_index++;
3241
#endif
3242
0
    }
3243
3244
    /* Fix order map if needed */
3245
343k
    for (i = 0; i < num_comp; i++) {
3246
270k
        pdev->devn_params.separation_order_map[i] = i;
3247
270k
    }
3248
3249
    /* Check if we have a color conversion issue */
3250
73.0k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3251
73.0k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3252
24.1k
        color_mismatch = true;
3253
73.0k
    if (des_profile->data_cs == gsNCHANNEL)
3254
0
        lose_channels = true;
3255
3256
    /* Check if target supports alpha */
3257
73.0k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3258
73.0k
    code = 0;
3259
3260
73.0k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3261
3262
    /* Note. The logic below will need a little rework if we ever
3263
       have a device that has tags and alpha support */
3264
73.0k
    if (supports_alpha) {
3265
3266
        /* If doing simulated overprint, Bring the spot color channels into
3267
           CMYK. Data is planar and 16 bit data in native format. */
3268
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3269
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3270
3271
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3272
0
            if (pdev->pclist_device != NULL) {
3273
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3274
3275
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3276
0
                if (code < 0)
3277
0
                    return code;
3278
0
            }
3279
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3280
3281
            /* Now we go to big endian */
3282
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3283
0
                planestride, num_comp, src_profile->num_comps,
3284
0
                tag_offset, cmyk_map, true, deep);
3285
3286
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3287
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3288
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3289
0
            buf->num_spots = 0;
3290
0
            num_comp = buf->n_chan - 1;
3291
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3292
0
        }
3293
3294
0
        if (!color_mismatch) {
3295
0
            for (i = 0; i < buf->n_planes; i++)
3296
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3297
0
            for (; i < target->color_info.num_components; i++)
3298
0
                buf_ptrs[i] = 0;
3299
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3300
0
                rect.p.x, rect.p.y, width, height,
3301
0
                rowstride, alpha_offset, tag_offset);
3302
            /* Right now code has number of rows written */
3303
0
        } else {
3304
            /* In this case, just color convert and maintain alpha.
3305
               This is a case where we either either blend in the
3306
               right color space and have no alpha for the output
3307
               device or hand back the wrong color space with
3308
               alpha data.  We choose the later. */
3309
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3310
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3311
0
                        rect.p.y, width, height, false);
3312
0
            if (code < 0)
3313
0
                return code;
3314
3315
            /* reset */
3316
0
            rowstride = buf->rowstride;
3317
0
            planestride = buf->planestride;
3318
0
            num_comp = buf->n_chan - 1;
3319
0
            alpha_offset = num_comp;
3320
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3321
3322
            /* And then out */
3323
0
            for (i = 0; i < buf->n_planes; i++)
3324
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3325
0
            for (; i < target->color_info.num_components; i++)
3326
0
                buf_ptrs[i] = 0;
3327
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3328
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3329
0
                tag_offset);
3330
            /* Right now code has number of rows written.  Writing continues below */
3331
0
        }
3332
73.0k
    } else {
3333
        /* Device could not handle the alpha data (we actually don't have
3334
           a device that does spot colorants and has an alpha channel so
3335
           the above code is untested.  Go ahead and preblend now and then
3336
           color convert if needed */
3337
#if RAW_DUMP
3338
           /* Dump before and after the blend to make sure we are doing that ok */
3339
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3340
            "pre_put_image_blend_image", buf_ptr, deep);
3341
        global_index++;
3342
#endif
3343
3344
73.0k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3345
24.1k
            if (deep) {
3346
            /* In this case, we are NOT going to bring the spots into the CMYK
3347
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3348
               16 bit data will be converted now from native endian to big endian during
3349
               the blending process */
3350
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3351
0
                    planestride, num_comp, src_profile->num_comps);
3352
24.1k
            } else {
3353
24.1k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3354
24.1k
                    planestride, num_comp, src_profile->num_comps);
3355
24.1k
            }
3356
48.8k
        } else {
3357
48.8k
            if (deep) {
3358
            /* In this case, if blend_spots == true, we will shortly be bringing
3359
               the spot colors to CMYK equivalent colors. It is at that time that
3360
               we will convert from native endian to big endian. In all other
3361
               cases this blending will due to conversion from native to BE */
3362
0
                bool keep_native = (blend_spots == true);
3363
3364
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3365
0
                    planestride, num_comp, additive, keep_native);
3366
48.8k
            } else {
3367
48.8k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3368
48.8k
                    planestride, num_comp, additive);
3369
48.8k
            }
3370
48.8k
        }
3371
3372
73.0k
        if (deep && has_tags)
3373
0
        {
3374
            /* We still need to convert the tags from Native to BE */
3375
#if ARCH_IS_BIG_ENDIAN
3376
#else
3377
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3378
0
            int i, j;
3379
0
            for (j = 0; j < height; j++)
3380
0
            {
3381
0
                for (i = 0; i < width; i++)
3382
0
                {
3383
0
                    uint16_t tag = *tags++;
3384
0
                    ((byte *)tags)[-2] = tag >> 8;
3385
0
                    ((byte *)tags)[-1] = tag;
3386
0
                }
3387
0
                tags += (buf->rowstride>>1) - width;
3388
0
            }
3389
0
#endif
3390
0
        }
3391
3392
#if RAW_DUMP
3393
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3394
            "post_put_image_blend_image", buf_ptr, deep);
3395
        global_index++;
3396
#endif
3397
3398
        /* If doing simulated overprint and we are not going to a sep device and
3399
           we have spot colors, then bring the spot color channels into CMYK
3400
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3401
           At this point, data is planar and 16 bit data is still in native format. It is
3402
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3403
           above during the alpha blend operation. */
3404
73.0k
        if (blend_spots) {
3405
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3406
3407
            /* In the clist case, we need to get equiv spots out of the
3408
               pseudo-band. */
3409
0
            if (pdev->pclist_device != NULL) {
3410
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3411
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3412
0
                if (code < 0)
3413
0
                    return code;
3414
0
            }
3415
3416
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3417
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3418
0
                planestride, num_comp, src_profile->num_comps,
3419
0
                tag_offset, cmyk_map, false, deep);
3420
3421
            /* Reset buffer information. We have CMYK and maybe tags */
3422
0
            num_comp = 4;
3423
0
            alpha_offset = 0;
3424
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3425
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3426
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3427
0
            buf->num_spots = 0;
3428
3429
#if RAW_DUMP
3430
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3431
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3432
            global_index++;
3433
#endif
3434
0
        }
3435
3436
        /* Map to the destination color space */
3437
73.0k
        if (color_mismatch) {
3438
            /* We started out with the original process colorants, and spots. If we have an
3439
             * nchannel output profile, this can mean that the first few spots might come from
3440
             * that and the rest from the document itself. e.g:
3441
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3442
             * Then we might have a blend space that changes the process colorants:
3443
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3444
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3445
             * If we're not careful, we'll end up with:
3446
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3447
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3448
             */
3449
24.1k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3450
24.1k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3451
24.1k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3452
24.1k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3453
24.1k
            if (code < 0)
3454
0
                return code;
3455
3456
            /* reset */
3457
24.1k
            rowstride = buf->rowstride;
3458
24.1k
            planestride = buf->planestride;
3459
24.1k
            num_comp = buf->n_chan;
3460
24.1k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3461
24.1k
        }
3462
3463
#if RAW_DUMP
3464
        /* Dump after the CS transform */
3465
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3466
            "post_put_image_color_convert", buf_ptr, deep);
3467
        global_index++;
3468
        /* clist_band_count++; */
3469
#endif
3470
3471
        /* Try put_image again. This can occur if the
3472
           target, like psdcmyk and tiffsep, support put_image */
3473
73.0k
        alpha_offset = 0;
3474
440k
        for (i = 0; i < buf->n_planes; i++)
3475
367k
            buf_ptrs[i] = buf_ptr + i * planestride;
3476
73.0k
        for (; i < target->color_info.num_components; i++)
3477
0
            buf_ptrs[i] = 0;
3478
73.0k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3479
73.0k
            rect.p.x, rect.p.y, width, height,
3480
73.0k
            rowstride, alpha_offset, tag_offset);
3481
73.0k
    }
3482
3483
    /* Put image was succesful.  We processed some or all of the rows.
3484
       Continue until we are done */
3485
73.0k
    if (code > 0) {
3486
149
        num_rows_left = height - code;
3487
149
        while (num_rows_left > 0) {
3488
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3489
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3490
0
                alpha_offset, tag_offset);
3491
0
            if (code < 0) {
3492
0
                return code;
3493
0
            }
3494
0
            num_rows_left = num_rows_left - code;
3495
0
        }
3496
149
        return 0;
3497
149
    }
3498
3499
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3500
       as well as those devices that support alpha (pngalpha,
3501
       png16malpha). If we are here, then we are doing an
3502
       overprint simulation on some other device. Image data
3503
       is aleady blended and in device color space. */
3504
72.8k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3505
72.8k
    if (code < 0)
3506
0
        return code;
3507
3508
    /* Already in destination CS */
3509
72.8k
    pcs->cmm_icc_profile_data = des_profile;
3510
3511
    /* pcs takes a reference to the profile data it just retrieved. */
3512
72.8k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3513
72.8k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3514
3515
    /* If we have more components to write out than are in the des_profile,
3516
     * then just using a PCS based on des_profile, will result in us dropping
3517
     * the spot colors.
3518
     * So, if our target supports devn colors, we instead construct a
3519
     * DevN device space with colors names taken from the devn_params, and
3520
     * use that instead. */
3521
72.8k
    if (des_profile->num_comps != target->color_info.num_components &&
3522
2.47k
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3523
2.47k
    {
3524
2.47k
        int num_std;
3525
2.47k
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3526
2.47k
        gs_color_space *pcs2 = pcs;
3527
2.47k
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3528
2.47k
                                     pcs2, pgs->memory->non_gc_memory);
3529
2.47k
        if (code < 0)
3530
0
            return code;
3531
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3532
2.47k
        pcs->params.device_n.use_alt_cspace = false;
3533
2.47k
        num_std = devn_params->num_std_colorant_names;
3534
12.3k
        for (i = 0; i < num_std; i++) {
3535
9.89k
            const char *name = devn_params->std_colorant_names[i];
3536
9.89k
            size_t len = strlen(name);
3537
9.89k
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3538
9.89k
            if (pcs->params.device_n.names[i] == NULL) {
3539
0
                int j = 0;
3540
0
                for (j = 0;j < i; j++) {
3541
0
                    if (pcs->params.device_n.names[j] != NULL)
3542
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3543
0
                    pcs->params.device_n.names[j] = NULL;
3544
0
                }
3545
0
                return_error(gs_error_VMerror);
3546
0
            }
3547
9.89k
            strcpy(pcs->params.device_n.names[i], name);
3548
9.89k
        }
3549
2.47k
        for (; i < devn_params->separations.num_separations; i++) {
3550
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3551
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");
3552
0
            if (pcs->params.device_n.names[i] == NULL) {
3553
0
                int j = 0;
3554
0
                for (j = 0;j < i; j++) {
3555
0
                    if (pcs->params.device_n.names[j] != NULL)
3556
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3557
0
                    pcs->params.device_n.names[j] = NULL;
3558
0
                }
3559
0
                return_error(gs_error_VMerror);
3560
0
            }
3561
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3562
0
            pcs->params.device_n.names[i][name->size] = 0;
3563
0
        }
3564
2.47k
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3565
0
            return code;
3566
0
        }
3567
        /* One last thing -- we need to fudge the pgs->color_component_map */
3568
14.8k
        for (i=0; i < dev->color_info.num_components; i++)
3569
12.3k
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3570
2.47k
    }
3571
3572
72.8k
    gs_image_t_init_adjust(&image, pcs, false);
3573
72.8k
    image.ImageMatrix.xx = (float)width;
3574
72.8k
    image.ImageMatrix.yy = (float)height;
3575
72.8k
    image.Width = width;
3576
72.8k
    image.Height = height;
3577
72.8k
    image.BitsPerComponent = deep ? 16 : 8;
3578
72.8k
    image.ColorSpace = pcs;
3579
72.8k
    image.format = gs_image_format_component_planar;
3580
3581
72.8k
    ctm_only_writable(pgs).xx = (float)width;
3582
72.8k
    ctm_only_writable(pgs).xy = 0;
3583
72.8k
    ctm_only_writable(pgs).yx = 0;
3584
72.8k
    ctm_only_writable(pgs).yy = (float)height;
3585
72.8k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3586
72.8k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3587
72.8k
    code = dev_proc(target, begin_typed_image) (target,
3588
72.8k
        pgs, NULL, (gs_image_common_t *)&image,
3589
72.8k
        NULL, NULL, NULL, pgs->memory, &info);
3590
72.8k
    if (code < 0) {
3591
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3592
0
        return code;
3593
0
    }
3594
#if RAW_DUMP
3595
    /* Dump the current buffer to see what we have. */
3596
    dump_raw_buffer(pdev->ctx->memory,
3597
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3598
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3599
        pdev->ctx->stack->n_planes,
3600
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3601
        "put_image_final_big", pdev->ctx->stack->data, deep);
3602
    dump_raw_buffer(pdev->ctx->memory,
3603
        height, width, buf->n_planes,
3604
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3605
        "put_image_final_small", buf_ptr, deep);
3606
    global_index++;
3607
    clist_band_count++;
3608
#endif
3609
3610
390k
    for (i = 0; i < num_comp; i++) {
3611
317k
        planes[i].data = buf_ptr + i * planestride;
3612
317k
        planes[i].data_x = 0;
3613
317k
        planes[i].raster = buf->rowstride;
3614
317k
    }
3615
3616
808k
    for (y = 0; y < height; y++) {
3617
735k
        int rows_used;
3618
3619
735k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3620
3621
3.92M
        for (i = 0; i < num_comp; i++) {
3622
3.18M
            planes[i].data += buf->rowstride;
3623
3.18M
        }
3624
735k
    }
3625
72.8k
    info->procs->end_image(info, true);
3626
3627
    /* This will also decrement the profile */
3628
72.8k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3629
72.8k
    return code;
3630
72.8k
}
3631
3632
/**
3633
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3634
 * @pdev: The PDF 1.4 rendering device.
3635
 * @pgs: State for image draw operation.
3636
 * @target: The target device.
3637
 *
3638
 * Puts the rendered image in @pdev's buffer to @target. This is called
3639
 * as part of the sequence of popping the PDF 1.4 device filter.
3640
 *
3641
 * Return code: negative on error.
3642
 **/
3643
static  int
3644
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3645
152k
{
3646
152k
    pdf14_device *pdev = (pdf14_device *)dev;
3647
152k
    pdf14_buf *buf = pdev->ctx->stack;
3648
152k
    gs_int_rect rect;
3649
152k
    int x1, y1, width, height;
3650
152k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3651
152k
    gs_separations *pseparations = &pdevn_params->separations;
3652
152k
    intptr_t planestride;
3653
152k
    intptr_t rowstride;
3654
152k
    bool deep = pdev->ctx->deep;
3655
152k
    int num_comp;
3656
3657
    /* Nothing was ever drawn. */
3658
152k
    if (buf == NULL)
3659
40.2k
        return 0;
3660
3661
112k
    num_comp = buf->n_chan - 1;
3662
112k
    rect = buf->rect;
3663
112k
    planestride = buf->planestride;
3664
112k
    rowstride = buf->rowstride;
3665
3666
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3667
       potential problem. Bug 694190 */
3668
112k
    if (buf->saved != NULL) {
3669
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3670
1
    }
3671
112k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3672
112k
    rect_intersect(rect, buf->dirty);
3673
112k
    x1 = min(pdev->width, rect.q.x);
3674
112k
    y1 = min(pdev->height, rect.q.y);
3675
112k
    width = x1 - rect.p.x;
3676
112k
    height = y1 - rect.p.y;
3677
112k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3678
39.4k
        return 0;
3679
3680
#if RAW_DUMP
3681
    /* Dump the current buffer to see what we have. */
3682
    dump_raw_buffer(pdev->ctx->memory,
3683
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3684
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3685
                    pdev->ctx->stack->n_planes,
3686
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3687
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3688
                    pdev->ctx->stack->deep);
3689
3690
    global_index++;
3691
    clist_band_count++;
3692
#endif
3693
3694
73.0k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3695
73.0k
                      buf, planestride, rowstride,
3696
73.0k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3697
73.0k
                      buf->has_tags, rect, pseparations, deep);
3698
112k
}
3699
3700
/**
3701
 * pdf14_custom_put_image: Put rendered image to target device.
3702
 * @pdev: The PDF 1.4 rendering device.
3703
 * @pgs: State for image draw operation.
3704
 * @target: The target device.
3705
 *
3706
 * Puts the rendered image in @pdev's buffer to @target. This is called
3707
 * as part of the sequence of popping the PDF 1.4 device filter.
3708
 *
3709
 * Return code: negative on error.
3710
 **/
3711
static  int
3712
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3713
0
{
3714
0
    pdf14_device * pdev = (pdf14_device *)dev;
3715
0
    pdf14_buf *buf = pdev->ctx->stack;
3716
0
    bool deep = pdev->ctx->deep;
3717
0
    gs_int_rect rect;
3718
0
    int x0, y0;
3719
0
    intptr_t planestride;
3720
0
    intptr_t rowstride;
3721
0
    int num_comp;
3722
0
    uint16_t bg;
3723
0
    int x1, y1, width, height;
3724
0
    byte *buf_ptr;
3725
3726
    /* Nothing was ever drawn. */
3727
0
    if (buf == NULL)
3728
0
        return 0;
3729
3730
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3731
0
    num_comp = buf->n_chan - 1;
3732
0
    rect = buf->rect;
3733
0
    x0 = rect.p.x;
3734
0
    y0 = rect.p.y;
3735
0
    planestride = buf->planestride;
3736
0
    rowstride = buf->rowstride;
3737
3738
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3739
       potential problem. Bug 694190 */
3740
0
    if (buf->saved != NULL) {
3741
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3742
0
    }
3743
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3744
0
    rect_intersect(rect, buf->dirty);
3745
0
    x1 = min(pdev->width, rect.q.x);
3746
0
    y1 = min(pdev->height, rect.q.y);
3747
0
    width = x1 - rect.p.x;
3748
0
    height = y1 - rect.p.y;
3749
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3750
0
        return 0;
3751
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3752
3753
0
    return gx_put_blended_image_custom(target, buf_ptr,
3754
0
                      planestride, rowstride,
3755
0
                      x0, y0, width, height, num_comp, bg, deep);
3756
0
}
3757
3758
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3759
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3760
 * putting everything back how it was, and cleaning up the reference counts.
3761
 */
3762
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3763
4.00M
{
3764
4.00M
    if (pdev->ctx && pdev->ctx->stack) {
3765
1.77M
        pdf14_buf *buf, *next;
3766
3767
1.77M
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3768
126
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3769
126
            next = buf->saved;
3770
252
            while (group_color_info) {
3771
126
               if (group_color_info->icc_profile != NULL) {
3772
126
                   cmm_profile_t *group_profile;
3773
126
                   gsicc_rendering_param_t render_cond;
3774
126
                   cmm_dev_profile_t *dev_profile;
3775
126
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3776
3777
126
                   if (code >= 0) {
3778
126
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3779
126
                                             &render_cond);
3780
3781
126
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3782
126
                                               -1, "pdf14_end_transparency_group");
3783
126
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3784
126
                           group_color_info->icc_profile;
3785
126
                       group_color_info->icc_profile = NULL;
3786
126
                   }
3787
126
               }
3788
3789
126
               group_color_info = group_color_info->previous;
3790
126
            }
3791
126
        }
3792
1.77M
    }
3793
4.00M
}
3794
3795
static  int
3796
pdf14_close(gx_device *dev)
3797
2.00M
{
3798
2.00M
    pdf14_device *pdev = (pdf14_device *)dev;
3799
3800
2.00M
    pdf14_cleanup_group_color_profiles(pdev);
3801
3802
2.00M
    if (pdev->ctx) {
3803
1.98M
        pdf14_ctx_free(pdev->ctx);
3804
1.98M
        pdev->ctx = NULL;
3805
1.98M
    }
3806
2.00M
    return 0;
3807
2.00M
}
3808
3809
/* This is called when something has gone wrong and the interpreter received a
3810
   stop while in the middle of doing something with the PDF14 device.  We need
3811
   to clean up and end this in a graceful manner */
3812
static int
3813
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3814
0
{
3815
0
    pdf14_device *pdev = (pdf14_device *)dev;
3816
    /* The things that need to be cleaned up */
3817
0
    pdf14_ctx *ctx = pdev->ctx;
3818
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3819
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3820
3821
    /* Free up the smask color */
3822
0
    if (smaskcolor != NULL) {
3823
0
        smaskcolor->ref_count = 1;
3824
0
        pdf14_decrement_smask_color(pgs, dev);
3825
0
        pdev->smaskcolor = NULL;
3826
0
    }
3827
3828
    /* Free up the nested color procs and decrement the profiles */
3829
0
    if (group_color != NULL) {
3830
0
        while (group_color->previous != NULL)
3831
0
            pdf14_pop_group_color(dev, pgs);
3832
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3833
0
        pdev->color_model_stack = NULL;
3834
0
    }
3835
3836
    /* Start the context clean up */
3837
0
    if (ctx != NULL) {
3838
0
        pdf14_buf *buf, *next;
3839
0
        pdf14_group_color_t *procs, *prev_procs;
3840
3841
0
        if (ctx->mask_stack != NULL) {
3842
0
            pdf14_free_mask_stack(ctx, ctx->memory);
3843
0
        }
3844
3845
        /* Now the stack of buffers */
3846
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3847
0
            next = buf->saved;
3848
3849
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3850
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3851
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3852
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3853
            /* During the soft mask push, the mask_stack was copied (not moved) from
3854
               the ctx to the tos mask_stack. We are done with this now so it is safe
3855
               to free this one object */
3856
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3857
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3858
0
                prev_procs = procs->previous;
3859
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3860
0
            }
3861
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3862
0
        }
3863
        /* Finally the context itself */
3864
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3865
0
        pdev->ctx = NULL;
3866
0
    }
3867
0
    return 0;
3868
0
}
3869
3870
static  int
3871
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3872
0
{
3873
0
    pdf14_device * pdev = (pdf14_device *)dev;
3874
3875
0
    if (pdev->target != NULL)
3876
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3877
0
    return 0;
3878
0
}
3879
3880
16.0M
#define COPY_PARAM(p) dev->p = target->p
3881
10.0M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3882
3883
static void
3884
copy_tag_setup(gx_device *dev, const gx_device *target)
3885
2.00M
{
3886
2.00M
    bool deep = device_is_deep(target);
3887
2.00M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3888
2.00M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3889
2.00M
    COPY_PARAM(graphics_type_tag);
3890
2.00M
    if (had_tags && !has_tags)
3891
0
    {
3892
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3893
0
        dev->color_info.num_components--;
3894
0
        dev->color_info.depth -= deep ? 16 : 8;
3895
0
    }
3896
2.00M
    else if (!had_tags && has_tags)
3897
0
    {
3898
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3899
0
        dev->color_info.num_components++;
3900
0
        dev->color_info.depth += deep ? 16 : 8;
3901
0
    }
3902
2.00M
}
3903
3904
/*
3905
 * Copy device parameters back from a target.  This copies all standard
3906
 * parameters related to page size and resolution, but not any of the
3907
 * color-related parameters, as the pdf14 device retains its own color
3908
 * handling. This routine is parallel to gx_device_copy_params().
3909
 * Note that it DOES copy the devn_params since these are required to
3910
 * keep agreement with colorant name->number mapping, and don't change
3911
 * with the pdf14 color handling.
3912
 */
3913
static  int
3914
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3915
2.00M
{
3916
2.00M
    cmm_dev_profile_t *profile_targ;
3917
2.00M
    cmm_dev_profile_t *profile_dev14;
3918
2.00M
    pdf14_device *pdev = (pdf14_device*) dev;
3919
2.00M
    cmm_profile_t *blend_profile = NULL;
3920
2.00M
    int k;
3921
3922
2.00M
    COPY_PARAM(width);
3923
2.00M
    COPY_PARAM(height);
3924
2.00M
    COPY_ARRAY_PARAM(MediaSize);
3925
2.00M
    COPY_ARRAY_PARAM(ImagingBBox);
3926
2.00M
    COPY_PARAM(ImagingBBox_set);
3927
2.00M
    COPY_ARRAY_PARAM(HWResolution);
3928
2.00M
    COPY_ARRAY_PARAM(Margins);
3929
2.00M
    COPY_ARRAY_PARAM(HWMargins);
3930
2.00M
    COPY_PARAM(PageCount);
3931
2.00M
    COPY_PARAM(MaxPatternBitmap);
3932
3933
3934
    /* Supposedly this function isn't supposed to change the color setup of dev.
3935
     * BUT... if we change the tags value, we have to change the color setup to
3936
     * keep it valid. This is because num_components and depth include tags. */
3937
2.00M
    copy_tag_setup(dev, target);
3938
2.00M
    COPY_PARAM(interpolate_control);
3939
2.00M
    COPY_PARAM(non_strict_bounds);
3940
2.00M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3941
3942
2.00M
    if (dev->icc_struct == NULL) {
3943
2.00M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3944
2.00M
        if (dev->icc_struct == NULL)
3945
0
            return_error(gs_error_VMerror);
3946
2.00M
        profile_dev14 = dev->icc_struct;
3947
2.00M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3948
2.00M
                                          &(profile_targ));
3949
3950
10.0M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3951
8.03M
            if (profile_targ->device_profile[k] != NULL) {
3952
2.00M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3953
2.00M
            }
3954
8.03M
            if (profile_dev14->device_profile[k] != NULL) {
3955
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3956
0
            }
3957
8.03M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3958
8.03M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3959
8.03M
        }
3960
3961
2.00M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3962
2.00M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3963
2.00M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3964
2.00M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3965
2.00M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3966
2.00M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3967
2.00M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3968
2.00M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3969
2.00M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3970
3971
2.00M
        switch (pdev->blend_cs_state) {
3972
2.00M
            case PDF14_BLEND_CS_UNSPECIFIED:
3973
2.00M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3974
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3975
                   during the device push, when we have
3976
                   access to the pgs */
3977
2.00M
                break;
3978
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3979
0
                blend_profile = profile_targ->oi_profile;
3980
0
                break;
3981
0
            case PDF14_BLEND_CS_SPECIFIED:
3982
0
                blend_profile = profile_targ->blend_profile;
3983
0
                break;
3984
0
            default:
3985
0
                break;
3986
2.00M
        }
3987
3988
2.00M
        if (blend_profile != NULL) {
3989
            /* Set the device profile to the blend profile. Note only default profile is set */
3990
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3991
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3992
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3993
0
        }
3994
3995
2.00M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3996
2.00M
    }
3997
2.00M
#undef COPY_ARRAY_PARAM
3998
2.00M
#undef COPY_PARAM
3999
2.00M
    return 0;
4000
2.00M
}
4001
4002
/*
4003
 * This is a forwarding version of the put_params device proc.  It is only
4004
 * used when the PDF 1.4 compositor devices are closed.  The routine will
4005
 * check if the target device has closed and, if so, close itself.  The routine
4006
 * also sync the device parameters.
4007
 */
4008
static  int
4009
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
4010
0
{
4011
0
    pdf14_device * pdev = (pdf14_device *)dev;
4012
0
    gx_device * tdev = pdev->target;
4013
0
    bool was_open = tdev->is_open;
4014
0
    int code = 0;
4015
4016
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4017
0
        gx_device_decache_colors(dev);
4018
0
        if (!tdev->is_open) {
4019
0
            code = gs_closedevice(dev);
4020
0
            if (code == 0)
4021
0
                code = was_open ? 1 : 0;   /* target device closed */
4022
0
        }
4023
0
        gx_device_copy_params(dev, tdev);
4024
0
    }
4025
0
    return code;
4026
0
}
4027
4028
/* Function prototypes */
4029
int put_param_pdf14_spot_names(gx_device * pdev,
4030
                gs_separations * pseparations, gs_param_list * plist);
4031
90.5k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
4032
4033
/*
4034
 * The put_params method for the PDF 1.4 device will check if the
4035
 * target device has closed and, if so, close itself.  Note:  This routine is
4036
 * currently being used by both the pdf14_clist_device and the pdf_device.
4037
 * Please make sure that any changes are either applicable to both devices
4038
 * or clone the routine for each device.
4039
 */
4040
static  int
4041
pdf14_put_params(gx_device * dev, gs_param_list * plist)
4042
0
{
4043
0
    pdf14_device * pdev = (pdf14_device *)dev;
4044
0
    gx_device * tdev = pdev->target;
4045
0
    bool was_open = tdev->is_open;
4046
0
    int code = 0, code2 = 0;
4047
4048
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4049
0
        gx_device_decache_colors(dev);
4050
0
        if (!tdev->is_open) {
4051
0
            code = gs_closedevice(dev);
4052
0
            if (code == 0)
4053
0
                code = was_open ? 1 : 0;   /* target device closed */
4054
0
        }
4055
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4056
0
        if (code2 < 0)
4057
0
            code = code2;
4058
0
    }
4059
0
    return code;
4060
0
}
4061
4062
/*
4063
 * Copy marking related parameters into the PDF 1.4 device structure for use
4064
 * by pdf14_fill_rectangle.
4065
 */
4066
static  void
4067
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4068
69.5M
{
4069
69.5M
    pdf14_device * pdev = (pdf14_device *)dev;
4070
4071
69.5M
    if (pgs->alphaisshape) {
4072
1.56M
        pdev->opacity = 1.0;
4073
1.56M
        if (pgs->is_fill_color) {
4074
1.49M
            pdev->shape = pgs->fillconstantalpha;
4075
1.49M
        } else {
4076
65.0k
            pdev->shape = pgs->strokeconstantalpha;
4077
65.0k
        }
4078
67.9M
    } else {
4079
67.9M
        pdev->shape = 1.0;
4080
67.9M
        if (pgs->is_fill_color) {
4081
28.8M
            pdev->opacity = pgs->fillconstantalpha;
4082
39.0M
        } else {
4083
39.0M
            pdev->opacity = pgs->strokeconstantalpha;
4084
39.0M
        }
4085
67.9M
    }
4086
69.5M
    pdev->alpha = pdev->opacity * pdev->shape;
4087
69.5M
    pdev->blend_mode = pgs->blend_mode;
4088
69.5M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4089
69.5M
        pdev->overprint = pgs->overprint;
4090
69.5M
        pdev->stroke_overprint = pgs->stroke_overprint;
4091
69.5M
    } else {
4092
0
        pdev->overprint = false;
4093
0
        pdev->stroke_overprint = false;
4094
0
    }
4095
4096
69.5M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4097
69.5M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4098
4099
69.5M
    if (pgs->is_fill_color)
4100
30.3M
        pdev->op_state = PDF14_OP_STATE_FILL;
4101
39.1M
    else
4102
39.1M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4103
4104
69.5M
    if_debug6m('v', dev->memory,
4105
69.5M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4106
69.5M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4107
69.5M
               pdev->stroke_effective_op_mode);
4108
69.5M
}
4109
4110
static  void
4111
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4112
48.9M
{
4113
48.9M
    bool hastrans = false;
4114
4115
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4116
     * makes other operations much slower. We have no option however, if the
4117
     * current colour involves transparency, or if it's anything other than
4118
     * a completely solid (or transparent) operation in the normal blend mode.
4119
     */
4120
48.9M
    if (pdcolor != NULL)
4121
48.9M
    {
4122
48.9M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4123
999k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4124
19.4k
            hastrans = true;
4125
48.9M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4126
            /* FIXME: Here we assume that ALL type 2 patterns are
4127
             * transparent - this test could be better. */
4128
74.0k
            hastrans = true;
4129
74.0k
        }
4130
48.9M
    }
4131
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4132
       This appears to be the only place where this test is done so
4133
       not adding a is_idempotent method */
4134
48.9M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4135
199k
        pgs->blend_mode != BLEND_MODE_Darken &&
4136
193k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4137
48.7M
        (pgs->fillconstantalpha != 1.0) ||
4138
47.7M
        (pgs->strokeconstantalpha != 1.0) ||
4139
47.7M
        (hastrans))
4140
1.36M
    {
4141
        /*
4142
         * The blend operations are not idempotent.  Force non-idempotent
4143
         * filling and stroking operations.
4144
         */
4145
1.36M
        pgs->log_op |= lop_pdf14;
4146
1.36M
    }
4147
48.9M
}
4148
4149
static int
4150
push_shfill_group(pdf14_clist_device *pdev,
4151
                  gs_gstate *pgs,
4152
                  gs_fixed_rect *box)
4153
2.78k
{
4154
2.78k
    gs_transparency_group_params_t params = { 0 };
4155
2.78k
    int code;
4156
2.78k
    gs_rect cb;
4157
2.78k
    gs_gstate fudged_pgs = *pgs;
4158
4159
2.78k
    params.shade_group = true;
4160
4161
    /* gs_begin_transparency_group takes a bbox that it then
4162
     * transforms by ctm. Our bbox has already been transformed,
4163
     * so clear out the ctm. */
4164
2.78k
    fudged_pgs.ctm.xx = 1.0;
4165
2.78k
    fudged_pgs.ctm.xy = 0;
4166
2.78k
    fudged_pgs.ctm.yx = 0;
4167
2.78k
    fudged_pgs.ctm.yy = 1.0;
4168
2.78k
    fudged_pgs.ctm.tx = 0;
4169
2.78k
    fudged_pgs.ctm.ty = 0;
4170
2.78k
    cb.p.x = fixed2int_pixround(box->p.x);
4171
2.78k
    cb.p.y = fixed2int_pixround(box->p.y);
4172
2.78k
    cb.q.x = fixed2int_pixround(box->q.x);
4173
2.78k
    cb.q.y = fixed2int_pixround(box->q.y);
4174
4175
2.78k
    params.Isolated = false;
4176
2.78k
    params.Knockout = true;
4177
2.78k
    params.page_group = false;
4178
2.78k
    params.group_opacity = fudged_pgs.fillconstantalpha;
4179
2.78k
    params.group_shape = 1.0;
4180
2.78k
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4181
4182
    /* We have the group handle the blendmode and the opacity,
4183
     * and continue with the existing graphics state reset
4184
     * to normal, opaque operation. We could do it the other
4185
     * way around, but this way means that if we push a knockout
4186
     * group for a stroke, and then the code calls back into
4187
     * the fill operation as part of doing the stroking, we don't
4188
     * push another one. */
4189
2.78k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4190
2.78k
    gs_setfillconstantalpha(pgs, 1.0);
4191
2.78k
    gs_setstrokeconstantalpha(pgs, 1.0);
4192
2.78k
    if (pdev) {
4193
2.78k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4194
2.78k
        if (code < 0)
4195
0
            return code;
4196
2.78k
    }
4197
4198
2.78k
    return code;
4199
2.78k
}
4200
4201
static int
4202
pop_shfill_group(gs_gstate *pgs)
4203
2.78k
{
4204
2.78k
     return gs_end_transparency_group(pgs);
4205
2.78k
}
4206
4207
static int
4208
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4209
                           gx_path *ppath, const gx_fill_params *params,
4210
                           const gx_drawing_color *pdcolor,
4211
                           const gx_clip_path *pcpath)
4212
39.5M
{
4213
39.5M
    gs_gstate new_pgs = *pgs;
4214
39.5M
    int code = 0;
4215
39.5M
    gs_pattern2_instance_t *pinst = NULL;
4216
39.5M
    int push_group = 0;
4217
4218
39.5M
    code = pdf14_initialize_ctx(dev, pgs);
4219
39.5M
    if (code < 0)
4220
0
        return code;
4221
4222
39.5M
    if (pdcolor == NULL)
4223
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4224
39.5M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4225
39.5M
    if (gx_dc_is_pattern1_color(pdcolor)){
4226
1.11M
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4227
1.06M
            gx_pattern1_clist_has_trans(pdcolor) ){
4228
            /* In this case, we need to push a transparency group
4229
               and tile the pattern color, which is stored in
4230
               a pdf14 device buffer in the ctile object memember
4231
               variable ttrans */
4232
#if RAW_DUMP
4233
            /* Since we do not get a put_image to view what
4234
               we have do it now */
4235
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4236
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4237
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4238
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4239
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4240
                        ppatdev14->ctx->stack->rect.p.y *
4241
                        ppatdev14->ctx->stack->rowstride +
4242
                        ppatdev14->ctx->stack->rect.p.x;
4243
                    dump_raw_buffer(ppatdev14->ctx->memory,
4244
                                    (ppatdev14->ctx->stack->rect.q.y -
4245
                                     ppatdev14->ctx->stack->rect.p.y),
4246
                                    (ppatdev14->ctx->stack->rect.q.x -
4247
                                     ppatdev14->ctx->stack->rect.p.x),
4248
                                    ppatdev14->ctx->stack->n_planes,
4249
                                    ppatdev14->ctx->stack->planestride,
4250
                                    ppatdev14->ctx->stack->rowstride,
4251
                                    "Pattern_Fill", buf_ptr,
4252
                                    ppatdev14->ctx->stack->deep);
4253
                    global_index++;
4254
                } else {
4255
                     gx_pattern_trans_t *patt_trans =
4256
                                        pdcolor->colors.pattern.p_tile->ttrans;
4257
                     dump_raw_buffer(patt_trans->mem,
4258
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4259
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4260
                                     patt_trans->n_chan,
4261
                                     patt_trans->planestride, patt_trans->rowstride,
4262
                                     "Pattern_Fill_clist",
4263
                                     patt_trans->transbytes +
4264
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4265
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4266
                                     patt_trans->deep);
4267
                    global_index++;
4268
                }
4269
            }
4270
#endif
4271
148k
            pdf14_set_marking_params(dev, &new_pgs);
4272
148k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4273
148k
                params, pdcolor, pcpath);
4274
148k
            new_pgs.trans_device = NULL;
4275
148k
            new_pgs.has_transparency = false;
4276
148k
            return code;
4277
148k
        }
4278
1.11M
    }
4279
39.4M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4280
39.4M
        pdcolor->type == &gx_dc_devn_masked) {
4281
        /* Non-idempotent blends require a transparency
4282
         * group to be pushed because shadings might
4283
         * paint several pixels twice. */
4284
59
        push_group = pgs->fillconstantalpha != 1.0 ||
4285
59
               !blend_is_idempotent(gs_currentblendmode(pgs));
4286
59
        pinst =
4287
59
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4288
59
        pinst->saved->has_transparency = true;
4289
        /* The transparency color space operations are driven
4290
           by the pdf14 clist writer device.  */
4291
59
        pinst->saved->trans_device = dev;
4292
59
    }
4293
39.4M
    if (push_group) {
4294
0
        gs_fixed_rect box;
4295
0
        if (pcpath)
4296
0
            gx_cpath_outer_box(pcpath, &box);
4297
0
        else
4298
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4299
0
        if (ppath) {
4300
0
            gs_fixed_rect path_box;
4301
4302
0
            gx_path_bbox(ppath, &path_box);
4303
0
            if (box.p.x < path_box.p.x)
4304
0
                box.p.x = path_box.p.x;
4305
0
            if (box.p.y < path_box.p.y)
4306
0
                box.p.y = path_box.p.y;
4307
0
            if (box.q.x > path_box.q.x)
4308
0
                box.q.x = path_box.q.x;
4309
0
            if (box.q.y > path_box.q.y)
4310
0
                box.q.y = path_box.q.y;
4311
0
        }
4312
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4313
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4314
0
    } else
4315
39.4M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4316
39.4M
    pdf14_set_marking_params(dev, &new_pgs);
4317
39.4M
    if (code >= 0) {
4318
39.4M
        new_pgs.trans_device = dev;
4319
39.4M
        new_pgs.has_transparency = true;
4320
        /* ppath can permissibly be NULL here, if we want to have a
4321
         * shading or a pattern fill the clipping path. This upsets
4322
         * coverity, which is not smart enough to realise that the
4323
         * validity of a NULL ppath depends on the type of pdcolor.
4324
         * We'll mark it as a false positive. */
4325
39.4M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4326
39.4M
        new_pgs.trans_device = NULL;
4327
39.4M
        new_pgs.has_transparency = false;
4328
39.4M
    }
4329
39.4M
    if (code >= 0 && push_group) {
4330
0
        code = pop_shfill_group(&new_pgs);
4331
0
        pdf14_set_marking_params(dev, pgs);
4332
0
    }
4333
39.4M
    if (pinst != NULL){
4334
59
        pinst->saved->trans_device = NULL;
4335
59
    }
4336
39.4M
    return code;
4337
39.5M
}
4338
4339
static  int
4340
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4341
                             gx_path *ppath, const gx_stroke_params *params,
4342
                             const gx_drawing_color *pdcolor,
4343
                             const gx_clip_path *pcpath)
4344
5.72M
{
4345
5.72M
    gs_gstate new_pgs = *pgs;
4346
5.72M
    int push_group = 0;
4347
5.72M
    int code = 0;
4348
4349
5.72M
    if (pdcolor == NULL)
4350
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4351
4352
5.72M
    code = pdf14_initialize_ctx(dev, pgs);
4353
5.72M
    if (code < 0)
4354
0
        return code;
4355
4356
5.72M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4357
        /* Non-idempotent blends require a transparency
4358
         * group to be pushed because shadings might
4359
         * paint several pixels twice. */
4360
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4361
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4362
0
    }
4363
5.72M
    if (push_group) {
4364
0
        gs_fixed_rect box;
4365
0
        if (pcpath)
4366
0
            gx_cpath_outer_box(pcpath, &box);
4367
0
        else
4368
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4369
4370
        /* For fill_path, we accept ppath == NULL to mean
4371
         * fill the entire clipping region. That makes no
4372
         * sense for stroke_path, hence ppath is always non
4373
         * NULL here. */
4374
0
        {
4375
0
            gs_fixed_rect path_box;
4376
0
            gs_fixed_point expansion;
4377
4378
0
            gx_path_bbox(ppath, &path_box);
4379
            /* Expand the path bounding box by the scaled line width. */
4380
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4381
                /* The expansion is so large it caused a limitcheck. */
4382
0
                path_box.p.x = path_box.p.y = min_fixed;
4383
0
                path_box.q.x = path_box.q.y = max_fixed;
4384
0
            } else {
4385
0
                expansion.x += pgs->fill_adjust.x;
4386
0
                expansion.y += pgs->fill_adjust.y;
4387
                /*
4388
                 * It's theoretically possible for the following computations to
4389
                 * overflow, so we need to check for this.
4390
                 */
4391
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4392
0
                                path_box.p.x - expansion.x);
4393
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4394
0
                                path_box.p.y - expansion.y);
4395
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4396
0
                                path_box.q.x + expansion.x);
4397
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4398
0
                                path_box.q.y + expansion.y);
4399
0
            }
4400
0
            if (box.p.x < path_box.p.x)
4401
0
                box.p.x = path_box.p.x;
4402
0
            if (box.p.y < path_box.p.y)
4403
0
                box.p.y = path_box.p.y;
4404
0
            if (box.q.x > path_box.q.x)
4405
0
                box.q.x = path_box.q.x;
4406
0
            if (box.q.y > path_box.q.y)
4407
0
                box.q.y = path_box.q.y;
4408
0
        }
4409
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4410
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4411
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4412
0
    } else
4413
5.72M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4414
5.72M
    pdf14_set_marking_params(dev, &new_pgs);
4415
5.72M
    if (code >= 0) {
4416
5.72M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4417
4418
5.72M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4419
5.72M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4420
5.72M
        ((pdf14_device*)dev)->op_state = save_op_state;
4421
5.72M
    }
4422
5.72M
    if (code >= 0 && push_group) {
4423
0
        code = pop_shfill_group(&new_pgs);
4424
0
        pdf14_set_marking_params(dev, pgs);
4425
0
    }
4426
4427
5.72M
    return code;
4428
5.72M
}
4429
4430
/* Pull out steps of transparency updates for fill/stroke
4431
   so that they can be invoked elsewhere (e.g.
4432
   when the abuf device is handling the stroke/fill */
4433
4434
/* Set-up prior to fill operation in fill-stroke */
4435
static int
4436
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4437
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4438
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4439
92.8k
{
4440
92.8k
    int code = 0;
4441
92.8k
    gs_transparency_group_params_t params = { 0 };
4442
92.8k
    gs_fixed_rect clip_bbox;
4443
92.8k
    gs_rect bbox, group_stroke_box;
4444
92.8k
    gs_fixed_rect path_bbox;
4445
92.8k
    int expansion_code;
4446
92.8k
    gs_fixed_point expansion;
4447
92.8k
    pdf14_device* p14dev = (pdf14_device*)dev;
4448
4449
92.8k
    *path_empty = false;
4450
4451
92.8k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4452
92.8k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4453
55
        return 0;
4454
4455
    /* The clip box returned here is scaled up by path_log2scale, so we need
4456
     * to scale down by this later. */
4457
92.8k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4458
92.8k
    if (code < 0 && code != gs_error_unknownerror)
4459
0
        return code;
4460
4461
92.8k
    if (code == gs_error_unknownerror) {
4462
        /* didn't get clip box from gx_curr_fixed_bbox */
4463
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4464
         * scaling down by this in a moment. */
4465
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4466
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4467
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4468
0
    }
4469
    /* pcpath->outer_box is scaled by path_log2scale too. */
4470
92.8k
    if (pcpath)
4471
92.8k
        rect_intersect(clip_bbox, pcpath->outer_box);
4472
4473
    /* expand the ppath using stroke expansion rule, then intersect it */
4474
92.8k
    code = gx_path_bbox(ppath, &path_bbox);
4475
4476
    /* If we are coming from the abuf device, the path has been scaled
4477
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4478
       on the path_bbox so that we get the proper bounding box for our group. */
4479
92.8k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4480
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4481
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4482
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4483
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4484
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4485
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4486
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4487
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4488
0
    }
4489
4490
92.8k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4491
60.7k
        *path_empty = true;
4492
60.7k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4493
                     there are simply too many return cases that I can't account for. */
4494
60.7k
    }
4495
32.0k
    if (code < 0)
4496
0
        return code;
4497
4498
32.0k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4499
32.0k
    if (expansion_code >= 0) {
4500
29.1k
        path_bbox.p.x -= expansion.x;
4501
29.1k
        path_bbox.p.y -= expansion.y;
4502
29.1k
        path_bbox.q.x += expansion.x;
4503
29.1k
        path_bbox.q.y += expansion.y;
4504
29.1k
    }
4505
32.0k
    rect_intersect(path_bbox, clip_bbox);
4506
32.0k
    bbox.p.x = fixed2float(path_bbox.p.x);
4507
32.0k
    bbox.p.y = fixed2float(path_bbox.p.y);
4508
32.0k
    bbox.q.x = fixed2float(path_bbox.q.x);
4509
32.0k
    bbox.q.y = fixed2float(path_bbox.q.y);
4510
4511
32.0k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4512
32.0k
    if (code < 0)
4513
9
        return code;
4514
4515
32.0k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4516
0
        p14dev->overprint = pgs->overprint;
4517
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4518
0
    }
4519
4520
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4521
32.0k
    if (fill_alpha == stroke_alpha &&
4522
10.9k
        p14dev->overprint && p14dev->stroke_overprint &&
4523
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4524
4525
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4526
           compatible overprint mode.  Group will be composited with
4527
           original alpha and blend mode */
4528
0
        *op_ca_eq_CA = true;
4529
0
        params.Isolated = false;
4530
0
        params.group_color_type = UNKNOWN;
4531
0
        params.Knockout = false;
4532
0
        params.page_group = false;
4533
0
        params.group_opacity = 1.0;
4534
0
        params.group_shape = fill_alpha;
4535
4536
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4537
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4538
0
        if (code < 0)
4539
0
            return code;
4540
4541
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4542
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4543
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4544
4545
32.0k
    } else {
4546
        /* Push a non-isolated knockout group. Do not change the alpha or
4547
            blend modes. Note: we need to draw those that have alpha = 0 */
4548
32.0k
        *op_ca_eq_CA = false;
4549
32.0k
        params.Isolated = false;
4550
32.0k
        params.group_color_type = UNKNOWN;
4551
32.0k
        params.Knockout = true;
4552
32.0k
        params.page_group = false;
4553
32.0k
        params.group_shape = 1.0;
4554
32.0k
        params.group_opacity = 1.0;
4555
4556
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4557
32.0k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4558
32.0k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4559
32.0k
        if (code < 0)
4560
0
            return code;
4561
4562
        /* restore blend mode for actual drawing in the group */
4563
32.0k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4564
4565
        /* If we are in an overprint situation, set the blend mode to compatible
4566
            overprint */
4567
32.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4568
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4569
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4570
32.0k
    }
4571
32.0k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4572
32.0k
    return code;
4573
32.0k
}
4574
4575
/* Set-up prior to stroke operation in fill-stroke */
4576
static void
4577
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4578
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4579
32.1k
{
4580
32.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4581
4582
32.1k
    if (op_ca_eq_CA) {
4583
55
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4584
32.0k
    } else {
4585
32.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4586
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4587
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4588
4589
        /* Note that the stroke can end up doing fill methods */
4590
32.0k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4591
4592
32.0k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4593
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4594
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4595
32.0k
    }
4596
32.1k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4597
32.1k
}
4598
4599
/* Cleanup after the stroke in fill-stroke  */
4600
static int
4601
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4602
32.1k
{
4603
32.1k
    int code;
4604
4605
32.1k
    if (!op_ca_eq_CA) {
4606
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4607
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4608
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4609
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4610
          * We therefore need to make sure it is set according to the current fill state.
4611
          */
4612
32.0k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4613
32.0k
        code = gs_update_trans_marking_params(pgs);
4614
32.0k
        if (code < 0)
4615
0
            return code;
4616
32.0k
        pdf14_set_marking_params(dev, pgs);
4617
32.0k
    }
4618
4619
32.1k
    return 0;
4620
32.1k
}
4621
4622
/* cleanup in fill-stroke  */
4623
static int
4624
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4625
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4626
32.1k
{
4627
32.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4628
32.1k
    int code2;
4629
32.1k
    int code = 0;
4630
4631
    /* Restore the state */
4632
32.1k
    p14dev->op_state = save_op_state;
4633
32.1k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4634
32.1k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4635
32.1k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4636
4637
32.1k
    code2 = gs_end_transparency_group(pgs);
4638
32.1k
    if (code2 < 0) {
4639
        /* At this point things have gone very wrong. We should just shut down */
4640
0
        code = gs_abort_pdf14trans_device(pgs);
4641
0
        return code2;
4642
0
    }
4643
32.1k
    return code;
4644
32.1k
}
4645
4646
static int
4647
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4648
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4649
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4650
    const gx_clip_path *pcpath)
4651
362k
{
4652
362k
    bool op_ca_eq_CA;
4653
362k
    bool path_empty;
4654
362k
    int code;
4655
362k
    float stroke_alpha = cpgs->strokeconstantalpha;
4656
362k
    float fill_alpha = cpgs->fillconstantalpha;
4657
362k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4658
362k
    pdf14_device* p14dev = (pdf14_device*)dev;
4659
362k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4660
362k
    gs_log2_scale_point path_log2scale;
4661
362k
    bool group_needed = true;
4662
362k
    gx_device* curr_pgs_dev = cpgs->device;
4663
4664
362k
    union {
4665
362k
        const gs_gstate* cpgs;
4666
362k
        gs_gstate* pgs;
4667
362k
    } const_breaker;
4668
362k
    gs_gstate* pgs;
4669
4670
    /* Break const just once, neatly */
4671
362k
    const_breaker.cpgs = cpgs;
4672
362k
    pgs = const_breaker.pgs;
4673
362k
    path_log2scale.x = 0;
4674
362k
    path_log2scale.y = 0;
4675
4676
362k
    code = pdf14_initialize_ctx(dev, pgs);
4677
362k
    if (code < 0)
4678
0
        return code;
4679
4680
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4681
     * blend is normal we don't do a group push. Just do the stroke
4682
     * and the fill, even with overprint */
4683
362k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4684
270k
        group_needed = false;
4685
4686
362k
    if (group_needed) {
4687
92.8k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4688
                              can be called on the clist writer side when dealing
4689
                              with the abuf/pdf14 interaction. Those calls have to
4690
                              go through the gs_trans API not the gx_trans or pdf14
4691
                              methods.  Perhaps these methods should have a different
4692
                              suffix, but they are static methods here in the pdf14
4693
                              file. */
4694
92.8k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4695
92.8k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4696
92.8k
        pgs->device = curr_pgs_dev;
4697
92.8k
        if (code < 0)
4698
9
            goto cleanup;
4699
92.8k
        if (path_empty)
4700
60.7k
            return 0;
4701
92.8k
    }
4702
4703
302k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4704
302k
    if (code < 0)
4705
0
        goto cleanup;
4706
4707
302k
    if (group_needed)
4708
32.1k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4709
302k
    gs_swapcolors_quick(pgs);
4710
4711
4712
#if RAW_DUMP
4713
    /* Dump the current buffer to see what we have. */
4714
    dump_raw_buffer(p14dev->ctx->memory,
4715
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4716
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4717
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4718
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4719
    global_index++;
4720
#endif
4721
4722
302k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4723
302k
    gs_swapcolors_quick(pgs);
4724
302k
    if (code < 0) {
4725
0
        goto cleanup;
4726
0
    }
4727
4728
#if RAW_DUMP
4729
    /* Dump the current buffer to see what we have. */
4730
    dump_raw_buffer(p14dev->ctx->memory,
4731
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4732
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4733
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4734
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4735
    global_index++;
4736
#endif
4737
302k
    if (group_needed)
4738
32.1k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4739
4740
302k
cleanup:
4741
302k
    if (group_needed) {
4742
32.1k
        int code1;
4743
32.1k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4744
32.1k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4745
32.1k
            save_op_state);
4746
32.1k
        if (code1 < 0)
4747
0
            code = code1;
4748
32.1k
        pgs->device = curr_pgs_dev;
4749
32.1k
    }
4750
302k
    return code;
4751
302k
}
4752
4753
static int
4754
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4755
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4756
                      gx_color_index color, int depth)
4757
0
{
4758
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4759
0
                                  color, NULL, depth, false);
4760
0
}
4761
4762
static int
4763
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4764
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4765
                      const gx_drawing_color *pdcolor, int depth)
4766
0
{
4767
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4768
0
                                  0, pdcolor, depth, true);
4769
0
}
4770
4771
static int
4772
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4773
                          int aa_raster, gx_bitmap_id id, int x, int y,
4774
                          int w, int h, gx_color_index color,
4775
                          const gx_device_color *pdc, int depth, bool devn)
4776
0
{
4777
0
    const byte *aa_row;
4778
0
    pdf14_device *pdev = (pdf14_device *)dev;
4779
0
    pdf14_buf *buf = pdev->ctx->stack;
4780
0
    int i, j, k;
4781
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4782
0
    byte src[PDF14_MAX_PLANES];
4783
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4784
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4785
0
    bool additive = pdev->ctx->additive;
4786
0
    intptr_t rowstride = buf->rowstride;
4787
0
    intptr_t planestride = buf->planestride;
4788
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4789
0
    bool has_alpha_g = buf->has_alpha_g;
4790
0
    bool has_shape = buf->has_shape;
4791
0
    bool has_tags = buf->has_tags;
4792
0
    bool knockout = buf->knockout;
4793
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4794
0
        blend_mode == BLEND_MODE_Compatible ||
4795
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4796
0
    int num_chan = buf->n_chan;
4797
0
    int num_comp = num_chan - 1;
4798
0
    intptr_t shape_off = num_chan * planestride;
4799
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4800
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4801
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4802
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4803
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4804
0
    gx_color_index comps;
4805
0
    byte shape = 0; /* Quiet compiler. */
4806
0
    byte src_alpha;
4807
0
    int alpha2_aa, alpha_aa, sx;
4808
0
    int alpha_aa_act;
4809
0
    int xoff;
4810
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4811
0
    int shift = 8;
4812
0
    bool has_backdrop = buf->backdrop != NULL;
4813
4814
0
    if (buf->data == NULL)
4815
0
        return 0;
4816
0
    aa_row = data;
4817
0
    if (has_tags) {
4818
0
        if (devn)
4819
0
            curr_tag = pdc->tag;
4820
0
        else
4821
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4822
0
    }
4823
4824
0
    if (devn) {
4825
0
        if (additive) {
4826
0
            for (j = 0; j < num_comp; j++) {
4827
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4828
0
            }
4829
0
        } else {
4830
0
            for (j = 0; j < num_comp; j++) {
4831
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4832
0
            }
4833
0
        }
4834
0
    } else
4835
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4836
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4837
0
    if (has_shape)
4838
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4839
    /* Limit the area we write to the bounding rectangle for this buffer */
4840
0
    if (x < buf->rect.p.x) {
4841
0
        xoff = data_x + buf->rect.p.x - x;
4842
0
        w += x - buf->rect.p.x;
4843
0
        x = buf->rect.p.x;
4844
0
    } else {
4845
0
        xoff = data_x;
4846
0
    }
4847
0
    if (y < buf->rect.p.y) {
4848
0
      h += y - buf->rect.p.y;
4849
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4850
0
      y = buf->rect.p.y;
4851
0
    }
4852
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4853
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4854
    /* Update the dirty rectangle. */
4855
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4856
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4857
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4858
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4859
4860
    /* composite with backdrop only. */
4861
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4862
0
    if (knockout && has_backdrop)
4863
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4864
0
    else
4865
0
        bline = line;
4866
4867
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4868
0
        back_ptr = bline;
4869
0
        dst_ptr = line;
4870
0
        sx = xoff;
4871
0
        for (i = 0; i < w; ++i, ++sx) {
4872
            /* Complement the components for subtractive color spaces */
4873
0
            if (additive) {
4874
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4875
0
                    dst[k] = back_ptr[k * planestride];
4876
0
            } else { /* Complement the components for subtractive color spaces */
4877
0
                for (k = 0; k < num_comp; ++k)
4878
0
                    dst[k] = 255 - back_ptr[k * planestride];
4879
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4880
0
            }
4881
            /* Get the aa alpha from the buffer */
4882
0
            switch(depth)
4883
0
            {
4884
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4885
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4886
0
                break;
4887
0
            case 4:
4888
0
                alpha2_aa = aa_row[sx >> 1];
4889
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4890
0
                break;
4891
0
            case 8:
4892
0
                alpha_aa = aa_row[sx];
4893
0
                break;
4894
0
            default:
4895
0
                return_error(gs_error_rangecheck);
4896
0
            }
4897
0
            if (alpha_aa != 0) {  /* This does happen */
4898
0
                if (alpha_aa != 255) {
4899
                    /* We have an alpha value from aa */
4900
0
                    alpha_aa_act = alpha_aa;
4901
0
                    if (src_alpha != 255) {
4902
                        /* Need to combine it with the existing alpha */
4903
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4904
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4905
0
                    }
4906
                    /* Set our source alpha value appropriately */
4907
0
                    src[num_comp] = alpha_aa_act;
4908
0
                } else {
4909
                    /* We may have to reset this is it was changed as we
4910
                       moved across the row */
4911
0
                    src[num_comp] = src_alpha;
4912
0
                }
4913
0
                if (knockout) {
4914
0
                    if (buf->isolated) {
4915
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4916
0
                    } else {
4917
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4918
0
                            blend_mode, pdev->blend_procs, pdev);
4919
0
                    }
4920
0
                } else {
4921
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4922
0
                                                    pdev->blend_procs, pdev);
4923
0
                }
4924
                /* Complement the results for subtractive color spaces */
4925
0
                if (additive) {
4926
0
                    for (k = 0; k < num_chan; ++k)
4927
0
                        dst_ptr[k * planestride] = dst[k];
4928
0
                } else {
4929
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4930
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4931
0
                                ++k, comps >>= 1) {
4932
0
                            if ((comps & 0x1) != 0) {
4933
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4934
0
                            }
4935
0
                        }
4936
                        /* The alpha channel */
4937
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4938
0
                    } else {
4939
0
                        for (k = 0; k < num_comp; ++k)
4940
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4941
                        /* The alpha channel */
4942
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4943
0
                    }
4944
0
                }
4945
0
                if (has_alpha_g) {
4946
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4947
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4948
0
                }
4949
0
                if (has_shape) {
4950
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4951
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4952
0
                }
4953
0
                if (has_tags) {
4954
                    /* If alpha is 100% then set to curr_tag, else or */
4955
                    /* other than Normal BM, we always OR */
4956
0
                    if (src[num_comp] == 255 && tag_blend) {
4957
0
                        dst_ptr[tag_off] = curr_tag;
4958
0
                    } else {
4959
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4960
0
                    }
4961
0
                }
4962
0
            }
4963
0
            ++dst_ptr;
4964
0
            ++back_ptr;
4965
0
        }
4966
0
        line += rowstride;
4967
0
        bline += rowstride;
4968
0
    }
4969
0
    return 0;
4970
0
}
4971
4972
static int
4973
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4974
                             int aa_raster, gx_bitmap_id id, int x, int y,
4975
                             int w, int h, gx_color_index color,
4976
                             const gx_device_color *pdc, int depth, bool devn)
4977
0
{
4978
0
    const byte *aa_row;
4979
0
    pdf14_device *pdev = (pdf14_device *)dev;
4980
0
    pdf14_buf *buf = pdev->ctx->stack;
4981
0
    int i, j, k;
4982
0
    byte *bline, *line;
4983
0
    uint16_t *dst_ptr, *back_ptr;
4984
0
    uint16_t src[PDF14_MAX_PLANES];
4985
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4986
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4987
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4988
0
        blend_mode == BLEND_MODE_Compatible ||
4989
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4990
0
    bool additive = pdev->ctx->additive;
4991
0
    intptr_t rowstride = buf->rowstride;
4992
0
    int planestride = buf->planestride;
4993
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4994
0
    bool has_alpha_g = buf->has_alpha_g;
4995
0
    bool has_shape = buf->has_shape;
4996
0
    bool has_tags = buf->has_tags;
4997
0
    bool knockout = buf->knockout;
4998
0
    int num_chan = buf->n_chan;
4999
0
    int num_comp = num_chan - 1;
5000
0
    intptr_t shape_off = num_chan * planestride;
5001
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
5002
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
5003
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
5004
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
5005
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
5006
0
    gx_color_index comps;
5007
0
    uint16_t shape = 0; /* Quiet compiler. */
5008
0
    uint16_t src_alpha;
5009
0
    int alpha2_aa, alpha_aa, sx;
5010
0
    int alpha_aa_act;
5011
0
    int xoff;
5012
0
    bool has_backdrop = buf->backdrop != NULL;
5013
5014
0
    if (buf->data == NULL)
5015
0
        return 0;
5016
0
    aa_row = data;
5017
0
    if (has_tags) {
5018
0
        if (devn)
5019
0
            curr_tag = pdc->tag;
5020
0
        else
5021
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
5022
0
    }
5023
5024
0
    if (devn) {
5025
0
        if (additive) {
5026
0
            for (j = 0; j < num_comp; j++) {
5027
0
                src[j] = pdc->colors.devn.values[j];
5028
0
            }
5029
0
        } else {
5030
0
            for (j = 0; j < num_comp; j++) {
5031
0
                src[j] = 65535 - pdc->colors.devn.values[j];
5032
0
            }
5033
0
        }
5034
0
    } else
5035
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
5036
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
5037
0
    if (has_shape)
5038
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
5039
    /* Limit the area we write to the bounding rectangle for this buffer */
5040
0
    if (x < buf->rect.p.x) {
5041
0
        xoff = data_x + buf->rect.p.x - x;
5042
0
        w += x - buf->rect.p.x;
5043
0
        x = buf->rect.p.x;
5044
0
    } else {
5045
0
        xoff = data_x;
5046
0
    }
5047
0
    if (y < buf->rect.p.y) {
5048
0
      h += y - buf->rect.p.y;
5049
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5050
0
      y = buf->rect.p.y;
5051
0
    }
5052
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5053
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5054
    /* Update the dirty rectangle. */
5055
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5056
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5057
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5058
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5059
5060
    /* composite with backdrop only. */
5061
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5062
0
    if (knockout && has_backdrop)
5063
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5064
0
    else
5065
0
        bline = line;
5066
5067
0
    planestride >>= 1;
5068
0
    rowstride   >>= 1;
5069
0
    alpha_g_off >>= 1;
5070
0
    shape_off   >>= 1;
5071
0
    tag_off     >>= 1;
5072
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5073
0
        back_ptr = (uint16_t *)(void *)bline;
5074
0
        dst_ptr = (uint16_t *)(void *)line;
5075
0
        sx = xoff;
5076
0
        for (i = 0; i < w; ++i, ++sx) {
5077
            /* Complement the components for subtractive color spaces */
5078
0
            if (additive) {
5079
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5080
0
                    dst[k] = back_ptr[k * planestride];
5081
0
            } else { /* Complement the components for subtractive color spaces */
5082
0
                for (k = 0; k < num_comp; ++k)
5083
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5084
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5085
0
            }
5086
            /* Get the aa alpha from the buffer */
5087
0
            switch(depth)
5088
0
            {
5089
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5090
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5091
0
                break;
5092
0
            case 4:
5093
0
                alpha2_aa = aa_row[sx >> 1];
5094
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5095
0
                break;
5096
0
            case 8:
5097
0
                alpha_aa = aa_row[sx];
5098
0
                break;
5099
0
            default:
5100
0
                return_error(gs_error_rangecheck);
5101
0
            }
5102
0
            if (alpha_aa != 0) {  /* This does happen */
5103
0
                if (alpha_aa != 255) {
5104
                    /* We have an alpha value from aa */
5105
0
                    alpha_aa_act = alpha_aa * 0x101;
5106
0
                    if (src_alpha != 65535) {
5107
                        /* Need to combine it with the existing alpha */
5108
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5109
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5110
0
                    }
5111
                    /* Set our source alpha value appropriately */
5112
0
                    src[num_comp] = alpha_aa_act;
5113
0
                } else {
5114
                    /* We may have to reset this is it was changed as we
5115
                       moved across the row */
5116
0
                    src[num_comp] = src_alpha;
5117
0
                }
5118
0
                if (knockout) {
5119
0
                    if (buf->isolated) {
5120
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5121
0
                    } else {
5122
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5123
0
                            blend_mode, pdev->blend_procs, pdev);
5124
0
                    }
5125
0
                } else {
5126
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5127
0
                                                     pdev->blend_procs, pdev);
5128
0
                }
5129
                /* Complement the results for subtractive color spaces */
5130
0
                if (additive) {
5131
0
                    for (k = 0; k < num_chan; ++k)
5132
0
                        dst_ptr[k * planestride] = dst[k];
5133
0
                } else {
5134
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5135
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5136
0
                                ++k, comps >>= 1) {
5137
0
                            if ((comps & 0x1) != 0) {
5138
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5139
0
                            }
5140
0
                        }
5141
                        /* The alpha channel */
5142
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5143
0
                    } else {
5144
0
                        for (k = 0; k < num_comp; ++k)
5145
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5146
                        /* The alpha channel */
5147
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5148
0
                    }
5149
0
                }
5150
0
                if (has_alpha_g) {
5151
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5152
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5153
0
                }
5154
0
                if (has_shape) {
5155
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5156
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5157
0
                }
5158
0
                if (has_tags) {
5159
                    /* If alpha is 100% then set to curr_tag, else or */
5160
                    /* other than Normal BM, we always OR */
5161
0
                    if (src[num_comp] == 65535 && tag_blend) {
5162
0
                        dst_ptr[tag_off] = curr_tag;
5163
0
                    } else {
5164
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5165
0
                    }
5166
0
                }
5167
0
            }
5168
0
            ++dst_ptr;
5169
0
            ++back_ptr;
5170
0
        }
5171
0
        line += rowstride;
5172
0
        bline += rowstride;
5173
0
    }
5174
0
    return 0;
5175
0
}
5176
5177
static int
5178
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5179
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5180
                      gx_color_index color, const gx_device_color *pdc,
5181
                      int depth, bool devn)
5182
0
{
5183
0
    bool deep = device_is_deep(dev);
5184
0
    int code;
5185
5186
0
    code = pdf14_initialize_ctx(dev, NULL);
5187
0
    if (code < 0)
5188
0
        return code;
5189
5190
0
    if (deep)
5191
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5192
0
                                            id, x, y, w, h,
5193
0
                                            color, pdc, depth, devn);
5194
0
    else
5195
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5196
0
                                         id, x, y, w, h,
5197
0
                                         color, pdc, depth, devn);
5198
0
}
5199
5200
static  int
5201
pdf14_fill_mask(gx_device * orig_dev,
5202
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5203
                     int x, int y, int w, int h,
5204
                     const gx_drawing_color * pdcolor, int depth,
5205
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5206
29.7M
{
5207
29.7M
    gx_device *dev;
5208
29.7M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5209
29.7M
    gx_device_clip cdev;
5210
29.7M
    gx_color_tile *ptile = NULL;
5211
29.7M
    int code = 0;
5212
29.7M
    gs_int_rect group_rect;
5213
29.7M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5214
29.7M
    bool has_pattern_trans = false;
5215
29.7M
    cmm_dev_profile_t *dev_profile;
5216
5217
29.7M
    if (pdcolor == NULL)
5218
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5219
5220
29.7M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5221
29.7M
    if (code < 0)
5222
0
        return code;
5223
5224
    /* If we are doing a fill with a pattern that has a transparency then
5225
       go ahead and do a push and a pop of the transparency group */
5226
29.7M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5227
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5228
0
            ptile = pdcolor->colors.pattern.p_tile;
5229
            /* Set up things in the ptile so that we get the proper
5230
               blending etc */
5231
            /* Set the blending procs and the is_additive setting based
5232
               upon the number of channels */
5233
0
            if (ptile->ttrans->n_chan-1 < 4) {
5234
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5235
0
                ptile->ttrans->is_additive = true;
5236
0
            } else {
5237
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5238
0
                ptile->ttrans->is_additive = false;
5239
0
            }
5240
            /* Set the procs so that we use the proper filling method. */
5241
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5242
            /* Based upon if the tiles overlap pick the type of rect
5243
               fill that we will want to use */
5244
0
            if (ptile->has_overlap) {
5245
                /* This one does blending since there is tile overlap */
5246
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5247
0
            } else {
5248
                /* This one does no blending since there is no tile overlap */
5249
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5250
0
            }
5251
            /* Push the group */
5252
0
            group_rect.p.x = x;
5253
0
            group_rect.p.y = max(0,y);
5254
0
            group_rect.q.x = x + w;
5255
0
            group_rect.q.y = y + h;
5256
0
            if (!(w <= 0 || h <= 0)) {
5257
5258
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5259
0
                if (group_color_info == NULL)
5260
0
                    return_error(gs_error_VMerror);
5261
5262
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5263
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5264
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5265
0
                     group_color_info, NULL, NULL);
5266
0
                if (code < 0)
5267
0
                    return code;
5268
                /* Set up the output buffer information now that we have
5269
                   pushed the group */
5270
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5271
0
                if (fill_trans_buffer == NULL)
5272
0
                    return_error(gs_error_VMerror);
5273
5274
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5275
0
                                              fill_trans_buffer, NULL, false);
5276
                /* Store this in the appropriate place in pdcolor.  This
5277
                   is released later after the mask fill */
5278
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5279
0
                has_pattern_trans = true;
5280
0
            }
5281
0
        }
5282
0
    }
5283
29.7M
    if (pcpath != 0) {
5284
3.99M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5285
3.99M
        dev = (gx_device *) & cdev;
5286
3.99M
    } else
5287
25.7M
        dev = orig_dev;
5288
29.7M
    if (depth > 1) {
5289
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5290
0
        code = (*dev_proc(dev, copy_alpha))
5291
0
            (dev, data, dx, raster, id, x, y, w, h,
5292
0
             gx_dc_pure_color(pdcolor), depth);
5293
29.7M
    } else {
5294
29.7M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5295
29.7M
                                          x, y, w, h, dev, lop, false);
5296
29.7M
    }
5297
29.7M
    if (has_pattern_trans) {
5298
0
        bool has_tags = device_encodes_tags(dev);
5299
0
        if (code >= 0)
5300
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5301
0
        if (code >= 0)
5302
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5303
0
                                                p14dev->blend_procs,
5304
0
                                                p14dev->color_info.num_components - has_tags,
5305
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5306
0
                                                orig_dev);
5307
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5308
0
                       "pdf14_fill_mask");
5309
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5310
0
    }
5311
29.7M
    if (pcpath != 0)
5312
3.99M
        gx_destroy_clip_device_on_stack(&cdev);
5313
29.7M
    return code;
5314
29.7M
}
5315
5316
5317
5318
/* Used for filling rects when we are doing a fill with a pattern that
5319
   has transparency */
5320
static  int
5321
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5322
                        gx_path * ppath, const gx_fill_params * params,
5323
                        const gx_device_color * pdevc,
5324
                        const gx_clip_path * pcpath)
5325
148k
{
5326
148k
    int code;
5327
148k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5328
148k
    gs_fixed_rect clip_box;
5329
148k
    gs_fixed_rect outer_box;
5330
148k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5331
148k
    gs_int_rect rect;
5332
148k
    gx_clip_rect *curr_clip_rect;
5333
148k
    gx_color_tile *ptile = NULL;
5334
148k
    int k;
5335
148k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5336
148k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5337
148k
    int n_chan_tile;
5338
148k
    gx_clip_path cpath_intersection;
5339
148k
    gx_path path_ttrans;
5340
148k
    pdf14_group_color_t *group_color_info;
5341
148k
    bool has_tags = device_encodes_tags(pdev);
5342
5343
148k
    if (ppath == NULL)
5344
0
        return_error(gs_error_unknownerror);  /* should not happen */
5345
148k
    if (pcpath != NULL) {
5346
142k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5347
142k
    } else {
5348
5.98k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5349
5.98k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5350
5.98k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5351
5.98k
    }
5352
148k
    if (code < 0)
5353
0
        return code;
5354
148k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5355
148k
                                          params->rule, pgs_noconst, params);
5356
148k
    if (code < 0)
5357
0
        return code;
5358
    /* One (common) case worth optimising for is where we have a pattern that
5359
     * is positioned such that only one repeat of the tile is actually
5360
     * visible. In this case, we can restrict the size of the blending group
5361
     * we need to produce to be that of the actual area of the tile that is
5362
     * used. */
5363
148k
    ptile = pdevc->colors.pattern.p_tile;
5364
148k
    if (ptile->ttrans != NULL)
5365
50.1k
    {
5366
50.1k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5367
50.1k
            (cpath_intersection.outer_box.p.y < 0) ||
5368
50.1k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5369
19.3k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5370
31.3k
        {
5371
            /* More than one repeat of the tile would be visible, so we can't
5372
             * use the optimisation here. (Actually, this test isn't quite
5373
             * right - it actually tests whether more than the '0th' repeat
5374
             * of the tile is visible. A better test would test if just one
5375
             * repeat of the tile was visible, irrespective of which one.
5376
             * This is (hopefully) relatively rare, and would make the code
5377
             * below more complex too, so we're ignoring that for now. If it
5378
             * becomes evident that it's a case that matters we can revisit
5379
             * it.) */
5380
31.3k
        } else {
5381
            /* Only the 0th repeat is visible. Restrict the size further to
5382
             * just the used area of that patch. */
5383
18.8k
            gx_path_init_local(&path_ttrans, ppath->memory);
5384
18.8k
            code = gx_path_add_rectangle(&path_ttrans,
5385
18.8k
                                         int2fixed(ptile->ttrans->rect.p.x),
5386
18.8k
                                         int2fixed(ptile->ttrans->rect.p.y),
5387
18.8k
                                         int2fixed(ptile->ttrans->rect.q.x),
5388
18.8k
                                         int2fixed(ptile->ttrans->rect.q.y));
5389
18.8k
            if (code < 0)
5390
0
                return code;
5391
18.8k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5392
18.8k
                                      params->rule, pgs_noconst);
5393
18.8k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5394
18.8k
            if (code < 0)
5395
0
                return code;
5396
18.8k
        }
5397
50.1k
    }
5398
    /* Now let us push a transparency group into which we are
5399
     * going to tile the pattern.  */
5400
148k
    if (ppath != NULL) {
5401
148k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5402
5403
148k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5404
148k
        rect.p.x = fixed2int(outer_box.p.x);
5405
148k
        rect.p.y = fixed2int(outer_box.p.y);
5406
148k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5407
148k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5408
5409
        /* The color space of this group must be the same as that of the
5410
           tile.  Then when we pop the group, if there is a mismatch between
5411
           the tile color space and the current context we will do the proper
5412
           conversion.  In this way, we ensure that if the tile has any overlapping
5413
           occuring it will be blended in the proper manner i.e in the tile
5414
           underlying color space. */
5415
148k
        if (ptile->cdev == NULL) {
5416
50.1k
            if (ptile->ttrans == NULL)
5417
0
                return_error(gs_error_unknownerror);  /* should not happen */
5418
50.1k
            n_chan_tile = ptile->ttrans->n_chan;
5419
98.3k
        } else {
5420
98.3k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5421
98.3k
        }
5422
148k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5423
5424
        /* Transparency handling with patterns confuses me, so some notes...
5425
         *
5426
         * For simple, non-transparent patterns, like you'd get in PS, we've
5427
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5428
         * times. To cope with unmarked pixels, we have a "transparency" plane
5429
         * (simple on/off) that says whether a pixel is marked or not.
5430
         *
5431
         * For patterns with transparency (but not blending), we can create an
5432
         * isolated transparency group, tile all the bitmap tiles into that, and
5433
         * then blend that back with the required alpha at the end. This works
5434
         * because the alpha values of the individual objects within the tile are
5435
         * recorded in that group.
5436
         *
5437
         * We can't do that for groups that use blending though, as each object
5438
         * in the pattern might use a different blend, and we don't (can't) record
5439
         * the blending mode. An isolated group doesn't even allow us to actually
5440
         * do the blending at all. So, for such patterns (any patterns that sets (or
5441
         * just has a resource that mentions) a non-normal blend mode), we use
5442
         * a pattern clist.
5443
         */
5444
148k
        if (ptile->cdev == NULL) {
5445
50.1k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5446
50.1k
            if (group_color_info == NULL)
5447
0
                return gs_error_VMerror;
5448
5449
50.1k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5450
50.1k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5451
50.1k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5452
50.1k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5453
50.1k
            if (code < 0)
5454
0
                return code;
5455
50.1k
        }
5456
5457
        /* Set the blending procs and the is_additive setting based
5458
           upon the number of channels */
5459
148k
        if (ptile->cdev == NULL) {
5460
50.1k
            if (n_chan_tile-1 < 4) {
5461
48.0k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5462
48.0k
                ptile->ttrans->is_additive = true;
5463
48.0k
            } else {
5464
2.12k
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5465
2.12k
                ptile->ttrans->is_additive = false;
5466
2.12k
            }
5467
50.1k
        }
5468
        /* Now lets go through the rect list and fill with the pattern */
5469
        /* First get the buffer that we will be filling */
5470
148k
        if (ptile->cdev == NULL) {
5471
50.1k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5472
50.1k
            if (fill_trans_buffer == NULL) {
5473
0
                p14dev->pclist_device = NULL;
5474
0
                return_error(gs_error_VMerror);
5475
0
            }
5476
50.1k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5477
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5478
               want to use */
5479
50.1k
            if (ptile->has_overlap) {
5480
                /* This one does blending since there is tile overlap */
5481
1.31k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5482
48.8k
            } else {
5483
                /* This one does no blending since there is no tile overlap */
5484
48.8k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5485
48.8k
            }
5486
            /* fill the rectangles */
5487
50.1k
            phase.x = pdevc->phase.x;
5488
50.1k
            phase.y = pdevc->phase.y;
5489
50.1k
            if (cpath_intersection.rect_list->list.head != NULL){
5490
1.20k
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5491
20.0k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5492
18.8k
                    if_debug5m('v', pgs->memory,
5493
18.8k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5494
18.8k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5495
18.8k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5496
18.8k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5497
18.8k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5498
18.8k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5499
18.8k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5500
18.8k
                    curr_clip_rect = curr_clip_rect->next;
5501
18.8k
                }
5502
48.9k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5503
                /* The case when there is just a single rect */
5504
48.6k
                if_debug5m('v', pgs->memory,
5505
48.6k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5506
48.6k
                           cpath_intersection.rect_list->list.single.xmin,
5507
48.6k
                           cpath_intersection.rect_list->list.single.ymin,
5508
48.6k
                           cpath_intersection.rect_list->list.single.xmax-
5509
48.6k
                              cpath_intersection.rect_list->list.single.xmin,
5510
48.6k
                           cpath_intersection.rect_list->list.single.ymax-
5511
48.6k
                              cpath_intersection.rect_list->list.single.ymin,
5512
48.6k
                           (int)ptile->id);
5513
48.6k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5514
48.6k
                                                  cpath_intersection.rect_list->list.single.ymin,
5515
48.6k
                                                  cpath_intersection.rect_list->list.single.xmax,
5516
48.6k
                                                  cpath_intersection.rect_list->list.single.ymax,
5517
48.6k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5518
48.6k
            }
5519
98.3k
        } else {
5520
            /* Clist pattern with transparency.  Create a clip device from our
5521
               cpath_intersection.  The above non-clist case could probably be
5522
               done this way too, which will reduce the amount of code here.
5523
               That is for another day though due to time constraints*/
5524
98.3k
            gx_device *dev;
5525
98.3k
            gx_device_clip clipdev;
5526
5527
98.3k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5528
98.3k
            dev = (gx_device *)&clipdev;
5529
98.3k
            phase.x = pdevc->phase.x;
5530
98.3k
            phase.y = pdevc->phase.y;
5531
98.3k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5532
98.3k
                                              ptile, fill_trans_buffer, phase,
5533
98.3k
                                              dev, pdevc, 1);
5534
98.3k
            gx_destroy_clip_device_on_stack(&clipdev);
5535
98.3k
        }
5536
        /* We're done drawing with the pattern, remove the reference to the
5537
         * pattern device
5538
         */
5539
148k
        p14dev->pclist_device = NULL;
5540
148k
        if (code < 0)
5541
0
            return code;
5542
5543
        /* free our buffer object */
5544
148k
        if (fill_trans_buffer != NULL) {
5545
50.1k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5546
50.1k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5547
50.1k
        }
5548
148k
        if (ptile->cdev == NULL) {
5549
            /* pop our transparency group which will force the blending.
5550
               This was all needed for Bug 693498 */
5551
50.1k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5552
50.1k
                                                p14dev->blend_procs,
5553
50.1k
                                                p14dev->color_info.num_components - has_tags,
5554
50.1k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5555
50.1k
                                                pdev);
5556
50.1k
        }
5557
148k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5558
148k
        p14dev->pclist_device = NULL;
5559
148k
    }
5560
148k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5561
148k
    return code;
5562
148k
}
5563
5564
/* Useful function that should probably go elsewhere.
5565
 * Call this function to find the topmost pdf14 device in the device chain,
5566
 * or NULL if there is not one.
5567
 */
5568
static pdf14_device *find_pdf14_device(gx_device *dev)
5569
0
{
5570
0
    pdf14_device *pdev;
5571
5572
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5573
0
        return NULL;
5574
0
    return pdev;
5575
0
}
5576
5577
/* Imager render for pattern transparency filling.  This is just here to catch
5578
   the final flush, at which time we will pop the group and reset a few items */
5579
static  int
5580
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5581
                    uint w, int h, gx_device * dev)
5582
0
{
5583
0
    int code;
5584
0
    pdf14_device * p14dev;
5585
0
    const gs_gstate * pgs = penum->pgs;
5586
0
    gx_device_color * pdcolor = (penum->icolor1);
5587
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5588
0
    bool has_tags = device_encodes_tags(dev);
5589
5590
    /* Pass along to the original renderer */
5591
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5592
0
    if (code < 0)
5593
0
        return code;
5594
    /* On our final time through here, go ahead and pop the transparency
5595
       group and reset the procs in the device color. And free the fill
5596
       trans buffer object */
5597
0
    if (h == 0 && ptile->trans_group_popped == false) {
5598
0
        p14dev = find_pdf14_device(dev);
5599
5600
0
        if (p14dev->pclist_device == NULL) {
5601
            /* Used if we are on clist writing phase.  Would only
5602
               occur if we somehow failed in high level clist
5603
               image writing */
5604
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5605
0
        } else {
5606
            /* Used if we are on clist reading phase.  If we had high level
5607
               image in clist */
5608
0
            cmm_dev_profile_t *dev_profile;
5609
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5610
0
            if (code < 0)
5611
0
                return code;
5612
5613
0
            if_debug2m('v', p14dev->ctx->memory,
5614
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5615
0
                       ptile->uid.id, ptile->id);
5616
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5617
0
                    p14dev->color_info.num_components - has_tags,
5618
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5619
0
                    (gx_device *) p14dev);
5620
0
        }
5621
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5622
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5623
0
                       "pdf14_pattern_trans_render");
5624
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5625
0
    }
5626
0
    return code;
5627
0
}
5628
5629
/* This function is used to get things in place for filling a mask image
5630
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5631
   and pdf14_clist_begin_type_image */
5632
static int
5633
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5634
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5635
                           const gs_int_rect * prect,
5636
                           const gx_drawing_color * pdcolor,
5637
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5638
                           gx_image_enum_common_t ** pinfo)
5639
0
{
5640
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5641
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5642
0
    gx_color_tile *ptile;
5643
0
    int code;
5644
0
    gs_int_rect group_rect;
5645
0
    gx_image_enum *penum;
5646
0
    gs_rect bbox_in, bbox_out;
5647
0
    gx_pattern_trans_t *fill_trans_buffer;
5648
5649
0
    ptile = pdcolor->colors.pattern.p_tile;
5650
    /* Set up things in the ptile so that we get the proper
5651
       blending etc */
5652
    /* Set the blending procs and the is_additive setting based
5653
       upon the number of channels */
5654
0
    if (ptile->ttrans->n_chan-1 < 4) {
5655
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5656
0
        ptile->ttrans->is_additive = true;
5657
0
    } else {
5658
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5659
0
        ptile->ttrans->is_additive = false;
5660
0
    }
5661
    /* Set the blending mode in the ptile based upon the current
5662
       setting in the gs_gstate */
5663
0
    ptile->blending_mode = pgs->blend_mode;
5664
    /* Based upon if the tiles overlap pick the type of rect
5665
       fill that we will want to use */
5666
0
    if (ptile->has_overlap) {
5667
        /* This one does blending since there is tile overlap */
5668
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5669
0
    } else {
5670
        /* This one does no blending since there is no tile overlap */
5671
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5672
0
    }
5673
    /* Set the procs so that we use the proper filling method. */
5674
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5675
    /* Let the imaging stuff get set up */
5676
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5677
0
                            prect, pdcolor,pcpath, mem, pinfo);
5678
0
    if (code < 0)
5679
0
        return code;
5680
    /* Now Push the group */
5681
    /* First apply the inverse of the image matrix to our
5682
       image size to get our bounding box. */
5683
0
    bbox_in.p.x = 0;
5684
0
    bbox_in.p.y = 0;
5685
0
    bbox_in.q.x = pim->Width;
5686
0
    bbox_in.q.y = pim->Height;
5687
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5688
0
                                &bbox_out);
5689
0
    if (code < 0)
5690
0
        return code;
5691
    /* That in turn will get hit by the matrix in the gs_gstate */
5692
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5693
0
                                            &bbox_out, (gs_gstate *)pgs);
5694
0
    if (code < 0)
5695
0
        return code;
5696
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5697
0
        if_debug2m('v', p14dev->ctx->memory,
5698
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5699
0
                   ptile->uid.id, ptile->id);
5700
5701
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5702
0
                                             65535, pgs->blend_mode, 0, 0,
5703
0
                                             ptile->ttrans->n_chan-1, false, false,
5704
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5705
5706
        /* Set up the output buffer information now that we have
5707
           pushed the group */
5708
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5709
0
        if (fill_trans_buffer == NULL)
5710
0
            return_error(gs_error_VMerror);
5711
5712
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5713
5714
        /* Store this in the appropriate place in pdcolor.  This
5715
           is released later in pdf14_pattern_trans_render when
5716
           we are all done with the mask fill */
5717
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5718
5719
        /* Change the renderer to handle this case so we can catch the
5720
           end.  We will then pop the group and reset the pdcolor proc.
5721
           Keep the base renderer also. */
5722
0
        penum = (gx_image_enum *) *pinfo;
5723
0
        ptile->ttrans->image_render = penum->render;
5724
0
        penum->render = &pdf14_pattern_trans_render;
5725
0
        ptile->trans_group_popped = false;
5726
0
    }
5727
0
    return code;
5728
0
}
5729
5730
static  int
5731
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5732
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5733
                           const gs_int_rect * prect,
5734
                           const gx_drawing_color * pdcolor,
5735
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5736
                           gx_image_enum_common_t ** pinfo)
5737
832k
{
5738
832k
    const gs_image_t *pim = (const gs_image_t *)pic;
5739
832k
    int code;
5740
5741
832k
    code = pdf14_initialize_ctx(dev, pgs);
5742
832k
    if (code < 0)
5743
0
        return code;
5744
5745
    /* If we are filling an image mask with a pattern that has a transparency
5746
       then we need to do some special handling */
5747
832k
    if (pim->ImageMask) {
5748
162
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5749
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5750
                /* If we are in a final run through here for this case then
5751
                   go ahead and push the transparency group.   Also, update
5752
                   the proc for the pattern color so that we used the
5753
                   appropriate fill operation.  Note that the group
5754
                   is popped and the proc will be reset when we flush the
5755
                   image data.  This is handled in a special pdf14 image
5756
                   renderer which will end up installed for this case.
5757
                   Detect setting of begin_image to gx_no_begin_image.
5758
                   (final recursive call) */
5759
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5760
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5761
0
                                                prect, pdcolor, pcpath, mem,
5762
0
                                                pinfo);
5763
0
                    return code;
5764
0
                }
5765
0
            }
5766
0
        }
5767
162
    }
5768
832k
    pdf14_set_marking_params(dev, pgs);
5769
832k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5770
832k
                                        pcpath, mem, pinfo);
5771
832k
}
5772
5773
static  void
5774
pdf14_set_params(gs_gstate * pgs,
5775
                 gx_device * dev,
5776
                 const gs_pdf14trans_params_t * pparams)
5777
21.3M
{
5778
21.3M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5779
21.3M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5780
3.87M
        pgs->blend_mode = pparams->blend_mode;
5781
21.3M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5782
1.97M
        pgs->text_knockout = pparams->text_knockout;
5783
21.3M
    if (pparams->changed & PDF14_SET_AIS)
5784
1.05M
        pgs->alphaisshape = pparams->ais;
5785
21.3M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5786
5.99M
        pgs->overprint = pparams->overprint;
5787
21.3M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5788
5.97M
        pgs->stroke_overprint = pparams->stroke_overprint;
5789
21.3M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5790
7.20M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5791
21.3M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5792
5.68M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5793
21.3M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5794
5.92M
        gs_swapcolors_quick(pgs);
5795
5.92M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5796
2.06M
            pgs->is_fill_color = false;
5797
3.85M
        else
5798
3.85M
            pgs->is_fill_color = true;
5799
5.92M
    }
5800
21.3M
    pdf14_set_marking_params(dev, pgs);
5801
21.3M
}
5802
5803
/*
5804
 * This open_device method for the PDF 1.4 compositor devices is only used
5805
 * when these devices are disabled.  This routine is about as close to
5806
 * a pure "forwarding" open_device operation as is possible. Its only
5807
 * significant function is to ensure that the is_open field of the
5808
 * PDF 1.4 compositor devices matches that of the target device.
5809
 *
5810
 * We assume this procedure is called only if the device is not already
5811
 * open, and that gs_opendevice will take care of the is_open flag.
5812
 */
5813
static  int
5814
pdf14_forward_open_device(gx_device * dev)
5815
0
{
5816
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5817
0
    gx_device * tdev = pdev->target;
5818
0
    int code;
5819
5820
    /* The PDF 1.4 compositing devices must have a target */
5821
0
    if (tdev == 0)
5822
0
        return_error(gs_error_unknownerror);
5823
0
    if ((code = gs_opendevice(tdev)) >= 0)
5824
0
        gx_device_copy_params(dev, tdev);
5825
0
    return code;
5826
0
}
5827
5828
/*
5829
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5830
 * for setting any device procs that should not be forwarded.
5831
 */
5832
static  void
5833
pdf14_forward_device_procs(gx_device * dev)
5834
1.97M
{
5835
1.97M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5836
1.97M
    pdf14_device *p14dev = (pdf14_device*)dev;
5837
5838
    /* If doing simulated overprint with spot colors
5839
       then makes sure to reset devn setting */
5840
1.97M
    if (p14dev->overprint_sim &&
5841
0
        p14dev->color_info.num_components > 4)
5842
0
        p14dev->icc_struct->supports_devn =
5843
0
            p14dev->target_support_devn;
5844
5845
    /*
5846
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5847
     * This will ensure that any new device procs are also set.  However that
5848
     * routine only changes procs which are NULL.  Thus we start by setting all
5849
     * procs to NULL.
5850
     */
5851
1.97M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5852
1.97M
    gx_device_forward_fill_in_procs(pdev);
5853
    /*
5854
     * gx_device_forward_fill_in_procs does not forward all procs.
5855
     * Set the remainding procs to also forward.
5856
     */
5857
1.97M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5858
1.97M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5859
1.97M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5860
1.97M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5861
1.97M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5862
1.97M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5863
1.97M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5864
1.97M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5865
1.97M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5866
1.97M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5867
    /* These are forwarding devices with minor tweaks. */
5868
1.97M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5869
1.97M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5870
1.97M
}
5871
5872
/*
5873
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5874
 * compositor device is never removed.  (We do not have a remove compositor
5875
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5876
 * routine implements that action.
5877
 */
5878
int
5879
pdf14_disable_device(gx_device * dev)
5880
1.96M
{
5881
1.96M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5882
5883
1.96M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5884
1.96M
    dev->color_info = pdev->target->color_info;
5885
1.96M
    pdf14_forward_device_procs(dev);
5886
1.96M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5887
1.96M
    return 0;
5888
1.96M
}
5889
5890
/*
5891
 * The default color space for PDF 1.4 blend modes is based upon the process
5892
 * color model of the output device.
5893
 */
5894
static  pdf14_default_colorspace_t
5895
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5896
                                 pdf14_blend_cs_t *blend_cs_state)
5897
5.42M
{
5898
    /* If a blend color space was specified, then go ahead and use that to
5899
       define the default color space for the blend modes.  Only Gray, RGB
5900
       or CMYK blend color spaces are allowed.  Note we do not allow this
5901
       setting if we are dealing with a separation device. */
5902
5.42M
    cmm_dev_profile_t *dev_profile;
5903
5.42M
    cmm_profile_t *blend_profile = NULL;
5904
5.42M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5905
5.42M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5906
5.42M
    bool valid_blend_cs = false;
5907
5.42M
    int has_tags = device_encodes_tags(pdev);
5908
5909
5.42M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5910
5911
    /* Are we using a blend color space or the output intent color space? Also
5912
       is there a conflict in the settings. i.e. has someone set a blend color
5913
       space and tried to use the output intent with simulate overprint setting.
5914
    */
5915
5.42M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5916
0
        dev_profile->oi_profile != NULL &&
5917
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5918
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5919
           possible conflicting command line settings and we will err on using the blend profile
5920
           if one was specified. */
5921
0
        if (dev_profile->blend_profile != NULL &&
5922
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5923
0
            blend_profile = dev_profile->blend_profile;
5924
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5925
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5926
0
        } else {
5927
            /* All good, use the output intent profile as we have one
5928
               and are doing simulate overprint with a different device
5929
               profile set. */
5930
0
            blend_profile = dev_profile->oi_profile;
5931
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5932
0
        }
5933
5.42M
    } else if (dev_profile->blend_profile != NULL &&
5934
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5935
        /* Blend profile is different than device profile */
5936
0
        blend_profile = dev_profile->blend_profile;
5937
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5938
0
    }
5939
5940
    /* Make sure any blend color space is valid along with other cond */
5941
5.42M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5942
0
        if (!blend_profile->isdevlink &&
5943
0
            !blend_profile->islab &&
5944
0
            (blend_profile->data_cs == gsGRAY ||
5945
0
             blend_profile->data_cs == gsRGB ||
5946
0
             blend_profile->data_cs == gsCMYK)) {
5947
            /* Also, do not allow the use of the blend space when we are pushing
5948
               a pattern pdf14 device.  Those should inherit from the parent */
5949
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5950
0
                  gx_device_is_pattern_accum(pdev))) {
5951
0
                valid_blend_cs = true;
5952
0
            }
5953
0
        }
5954
0
    }
5955
5956
    /* If num components is one, just go ahead and use gray.  This avoids
5957
       issues with additive/subtractive mono color devices  */
5958
5.42M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5959
5.00M
        pdev->color_info.num_components == 1) {
5960
        /*
5961
        * Note:  We do not allow the SeparationOrder device parameter for
5962
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5963
        * and 3 colorants for DeviceRGB.
5964
        */
5965
5.00M
        if (valid_blend_cs) {
5966
0
            *blend_cs_state = temp_cs_state;
5967
0
            switch (blend_profile->num_comps) {
5968
0
            case 1:
5969
0
                return PDF14_DeviceGray;
5970
0
            case 3:
5971
0
                return PDF14_DeviceRGB;
5972
0
            case 4:
5973
0
                return PDF14_DeviceCMYK;
5974
0
            }
5975
0
        }
5976
5.00M
        if (pdev->color_info.num_components - has_tags == 1)
5977
1.55M
            return PDF14_DeviceGray;
5978
3.45M
        else if (pdev->color_info.num_components - has_tags == 3)
5979
3.45M
            return PDF14_DeviceRGB;
5980
0
        else
5981
0
            return PDF14_DeviceRGBspot;
5982
5.00M
    } else {
5983
        /*
5984
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5985
         * the CMYK plus spot colors will not support the blend color space
5986
         */
5987
424k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5988
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5989
        return PDF14_DeviceCustom;
5990
#endif
5991
        /*
5992
         * Count the number of CMYK process components supported by the output
5993
         * device.
5994
         */
5995
2.12M
        for (i = 0; i < 4; i++) {
5996
1.69M
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5997
5998
1.69M
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5999
1.69M
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
6000
1.69M
            if (output_comp_num >= 0) {
6001
1.69M
                num_cmyk++;
6002
1.69M
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
6003
1.69M
                    num_cmyk_used++;
6004
1.69M
            }
6005
1.69M
        }
6006
        /*
6007
         * Check if the device supports only CMYK.  Otherewise we assume that
6008
         * the output device supports spot colors.  Note:  This algorithm can
6009
         * be fooled if the SeparationOrder device parameter is being used by
6010
         * the output device device to only select CMYK.
6011
         */
6012
424k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
6013
400k
            && pdev->color_info.max_components == 4) {
6014
50.0k
            if (valid_blend_cs) {
6015
0
                *blend_cs_state = temp_cs_state;
6016
0
                switch (blend_profile->num_comps) {
6017
0
                case 1:
6018
0
                    return PDF14_DeviceGray;
6019
0
                case 3:
6020
0
                    return PDF14_DeviceRGB;
6021
0
                case 4:
6022
0
                    return PDF14_DeviceCMYK;
6023
0
                }
6024
0
            }
6025
50.0k
            return PDF14_DeviceCMYK;
6026
50.0k
        }
6027
        /*
6028
         * Check if we should use the 'custom' PDF 1.4 compositor device.
6029
         * This device is only needed for those devices which do not support
6030
         * a basic CMYK process color model.
6031
         */
6032
374k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
6033
374k
        if (num_cmyk != 4)
6034
0
            return PDF14_DeviceCustom;
6035
374k
#endif
6036
        /*
6037
         * Otherewise we use a CMYK plus spot colors for blending.
6038
         */
6039
374k
        if (valid_blend_cs)
6040
0
            *blend_cs_state = temp_cs_state;
6041
374k
        return PDF14_DeviceCMYKspot;
6042
374k
    }
6043
5.42M
}
6044
6045
/*
6046
 * the PDF 1.4 transparency spec says that color space for blending
6047
 * operations can be based upon either a color space specified in the
6048
 * group or a default value based upon the output device.  We are
6049
 * currently only using a color space based upon the device.
6050
 */
6051
static  int
6052
get_pdf14_device_proto(gx_device       *dev,
6053
                       pdf14_device    *pdevproto,
6054
                       gs_gstate       *pgs,
6055
                 const gs_pdf14trans_t *pdf14pct,
6056
                       bool             use_pdf14_accum)
6057
1.98M
{
6058
1.98M
    pdf14_blend_cs_t blend_cs_state;
6059
1.98M
    pdf14_default_colorspace_t dev_cs =
6060
1.98M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6061
1.98M
                                                 &blend_cs_state);
6062
1.98M
    bool deep = device_is_deep(dev);
6063
1.98M
    int num_spots = pdf14pct->params.num_spot_colors;
6064
1.98M
    bool has_tags = device_encodes_tags(dev);
6065
6066
    /* overprint overide */
6067
1.98M
    if (pdf14pct->params.overprint_sim_push &&
6068
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6069
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6070
0
            dev_cs = PDF14_DeviceCMYKspot;
6071
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6072
0
        } else
6073
0
            dev_cs = PDF14_DeviceCMYK;
6074
0
    }
6075
6076
1.98M
    switch (dev_cs) {
6077
590k
        case PDF14_DeviceGray:
6078
590k
            *pdevproto = gs_pdf14_Gray_device;
6079
590k
            pdevproto->color_info.max_components = 1 + has_tags;
6080
590k
            pdevproto->color_info.num_components =
6081
590k
                                    pdevproto->color_info.max_components + has_tags;
6082
590k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6083
590k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6084
590k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6085
590k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6086
590k
            pdevproto->sep_device = false;
6087
590k
            break;
6088
1.23M
        case PDF14_DeviceRGB:
6089
1.23M
            *pdevproto = gs_pdf14_RGB_device;
6090
1.23M
            pdevproto->color_info.max_components += has_tags;
6091
1.23M
            pdevproto->color_info.num_components += has_tags;
6092
1.23M
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6093
1.23M
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6094
1.23M
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6095
1.23M
            pdevproto->sep_device = false;
6096
1.23M
            break;
6097
2.59k
        case PDF14_DeviceCMYK:
6098
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6099
2.59k
            pdevproto->color_info.max_components += has_tags;
6100
2.59k
            pdevproto->color_info.num_components += has_tags;
6101
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6102
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6103
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6104
2.59k
            pdevproto->sep_device = false;
6105
2.59k
            break;
6106
157k
        case PDF14_DeviceCMYKspot:
6107
157k
            *pdevproto = gs_pdf14_CMYKspot_device;
6108
            /* Need to figure out how we want to handle the device profile
6109
               for this case */
6110
            /*
6111
             * The number of components for the PDF14 device is the sum
6112
             * of the process components and the number of spot colors
6113
             * for the page.
6114
             */
6115
157k
            if (num_spots >= 0) {
6116
157k
                pdevproto->color_info.num_components =
6117
157k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6118
157k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6119
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6120
157k
                pdevproto->color_info.depth =
6121
157k
                                    pdevproto->color_info.num_components * (8<<deep);
6122
157k
                pdevproto->sep_device = true;
6123
157k
            }
6124
0
            else
6125
0
            {
6126
0
                pdevproto->color_info.max_components += has_tags;
6127
0
                pdevproto->color_info.num_components += has_tags;
6128
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6129
0
            }
6130
157k
            break;
6131
0
        case PDF14_DeviceRGBspot:
6132
0
            *pdevproto = gs_pdf14_RGBspot_device;
6133
            /* Need to figure out how we want to handle the device profile
6134
               for this case */
6135
            /*
6136
             * The number of components for the PDF14 device is the sum
6137
             * of the process components and the number of spot colors
6138
             * for the page.
6139
             */
6140
0
            if (num_spots >= 0) {
6141
0
                pdevproto->color_info.num_components =
6142
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6143
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6144
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6145
0
                pdevproto->color_info.depth =
6146
0
                    pdevproto->color_info.num_components * (8 << deep);
6147
0
                pdevproto->sep_device = true;
6148
0
            }
6149
0
            else
6150
0
            {
6151
0
                pdevproto->color_info.max_components += has_tags;
6152
0
                pdevproto->color_info.num_components += has_tags;
6153
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6154
0
            }
6155
0
            break;
6156
0
        case PDF14_DeviceCustom:
6157
            /*
6158
             * We are using the output device's process color model.  The
6159
             * color_info for the PDF 1.4 compositing device needs to match
6160
             * the output device.
6161
             */
6162
0
            *pdevproto = gs_pdf14_custom_device;
6163
0
            pdevproto->color_info = dev->color_info;
6164
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6165
0
            pdevproto->color_info.depth =
6166
0
                       pdevproto->color_info.num_components * (8<<deep);
6167
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6168
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6169
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6170
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6171
0
            break;
6172
0
        default:      /* Should not occur */
6173
0
            return_error(gs_error_rangecheck);
6174
1.98M
    }
6175
1.98M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6176
1.98M
    pdevproto->blend_cs_state = blend_cs_state;
6177
1.98M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6178
1.98M
    return 0;
6179
1.98M
}
6180
6181
/* When playing back the clist, we need to know if the buffer device is compatible */
6182
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6183
/* depth are critical since these must match when reading back colors.             */
6184
bool
6185
pdf14_ok_to_optimize(gx_device *dev)
6186
3.42M
{
6187
3.42M
    pdf14_blend_cs_t blend_cs_state;
6188
3.42M
    pdf14_default_colorspace_t pdf14_cs =
6189
3.42M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6190
3.42M
    gsicc_colorbuffer_t dev_icc_cs;
6191
3.42M
    bool ok = false;
6192
3.42M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6193
3.42M
    cmm_dev_profile_t *dev_profile;
6194
3.42M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6195
3.42M
    bool deep = device_is_deep(dev);
6196
6197
3.42M
    if (code < 0)
6198
0
        return false;
6199
6200
3.42M
    check_device_compatible_encoding(dev);
6201
6202
3.42M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6203
1.25M
        return false;
6204
6205
2.17M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6206
    /* If the outputprofile is not "standard" then colors converted to device color */
6207
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6208
2.17M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6209
0
        return false;                           /* can't handle funky output profiles */
6210
6211
2.17M
    switch (pdf14_cs) {
6212
524k
        case PDF14_DeviceGray:
6213
524k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6214
524k
            break;
6215
1.43M
        case PDF14_DeviceRGB:
6216
1.43M
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6217
1.43M
            break;
6218
0
        case PDF14_DeviceCMYK:
6219
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6220
0
            break;
6221
214k
        case PDF14_DeviceCMYKspot:
6222
214k
            ok = false;     /* punt for this case */
6223
214k
            break;
6224
0
        case PDF14_DeviceRGBspot:
6225
0
            ok = false;     /* punt for this case */
6226
0
            break;
6227
0
        case PDF14_DeviceCustom:
6228
            /*
6229
             * We are using the output device's process color model.  The
6230
             * color_info for the PDF 1.4 compositing device needs to match
6231
             * the output device, but it may not have been contone.
6232
             */
6233
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6234
0
            break;
6235
0
        default:      /* Should not occur */
6236
0
            ok = false;
6237
2.17M
    }
6238
2.17M
    return ok;
6239
2.17M
}
6240
6241
/*
6242
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6243
 * compositor device is never removed.  (We do not have a remove compositor
6244
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6245
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6246
 * again.
6247
 */
6248
static  int
6249
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6250
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6251
0
{
6252
0
    pdf14_device * pdev = (pdf14_device *)dev;
6253
0
    gx_device * target = pdev->target;
6254
0
    pdf14_device dev_proto;
6255
0
    bool has_tags = device_encodes_tags(dev);
6256
0
    int code;
6257
0
    bool deep = device_is_deep(dev);
6258
6259
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6260
6261
    /*
6262
     * We will not use the entire prototype device but we will set the
6263
     * color related info and the device procs to match the prototype.
6264
     */
6265
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6266
0
                                  pdf14pct, false);
6267
0
    if (code < 0)
6268
0
        return code;
6269
0
    pdev->color_info = dev_proto.color_info;
6270
0
    pdev->pad = target->pad;
6271
0
    pdev->log2_align_mod = target->log2_align_mod;
6272
6273
    /* The prototype has the color setup without tags. If we are
6274
     * using tags, then we need to extend num_components and depth.
6275
     */
6276
0
    if (has_tags) {
6277
0
        pdev->color_info.num_components++;
6278
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6279
0
    }
6280
6281
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6282
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6283
0
    else
6284
0
        pdev->num_planar_planes = target->num_planar_planes;
6285
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6286
6287
0
    if (dev_proto.initialize_device_procs != NULL)
6288
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6289
0
    pdev->procs = dev_proto.procs;
6290
0
    if (deep) {
6291
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6292
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6293
0
    }
6294
0
    if (has_tags) {
6295
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6296
0
    }
6297
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6298
0
    gx_device_fill_in_procs((gx_device *)pdev);
6299
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6300
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6301
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6302
0
    check_device_separable(dev);
6303
0
    return dev_proc(pdev, open_device)(dev);
6304
0
}
6305
6306
/*
6307
 * Implement the various operations that can be specified via the PDF 1.4
6308
 * create compositor request.
6309
 */
6310
static  int
6311
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6312
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6313
49.6M
{
6314
49.6M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6315
49.6M
    gs_pdf14trans_params_t params = pdf14pct->params;
6316
49.6M
    int code = 0;
6317
6318
49.6M
    params.idle = pdf14pct->idle;
6319
49.6M
    switch (params.pdf14_op) {
6320
0
        default:      /* Should not occur. */
6321
0
            break;
6322
25.2k
        case PDF14_PUSH_DEVICE:
6323
25.2k
            if (!(params.is_pattern)) {
6324
0
                p14dev->blend_mode = 0;
6325
0
                p14dev->opacity = p14dev->shape = 0.0;
6326
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6327
0
            }
6328
25.2k
            break;
6329
0
        case PDF14_ABORT_DEVICE:
6330
            /* Something has gone very wrong.  Let transparency device clean up
6331
               what ever it has allocated and then we are shutting it down */
6332
0
            code = gx_abort_trans_device(pgs, pdev);
6333
0
            if (p14dev->free_devicen) {
6334
0
                devn_free_params(pdev);
6335
0
            }
6336
0
            pdf14_disable_device(pdev);
6337
0
            pdf14_close(pdev);
6338
0
            break;
6339
1.97M
        case PDF14_POP_DEVICE:
6340
1.97M
            if (!(params.is_pattern)) {
6341
1.95M
                if_debug0m('v', pdev->memory,
6342
1.95M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6343
1.95M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6344
1.95M
                gx_set_cmap_procs(pgs, p14dev->target);
6345
                /* Send image out raster data to output device */
6346
1.95M
                {
6347
                    /* Make a copy so we can change the ROP */
6348
1.95M
                    gs_gstate new_pgs = *pgs;
6349
6350
                    /* We don't use the gs_gstate log_op since this is for the */
6351
                    /* clist playback. Putting the image (band in the case of the */
6352
                    /* clist) only needs to use the default ROP to copy the data  */
6353
1.95M
                    new_pgs.log_op = rop3_default;
6354
1.95M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6355
1.95M
                }
6356
                /* Before we disable the device release any deviceN structures.
6357
                    free_devicen is set if the pdf14 device had inherited its
6358
                    deviceN parameters from the target clist device.  In this
6359
                    case they should not be freed */
6360
1.95M
                if (p14dev->free_devicen) {
6361
1.94M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6362
1.94M
                    if (devn_params) {
6363
1.94M
                        gxdso_spot_info si;
6364
1.94M
                        si.params = devn_params;
6365
1.94M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6366
1.94M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6367
1.94M
                    }
6368
1.94M
                    devn_free_params(pdev);
6369
1.94M
                }
6370
1.95M
                pdf14_disable_device(pdev);
6371
1.95M
                pdf14_close(pdev);
6372
1.95M
            }
6373
1.97M
            break;
6374
906k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6375
5.19M
        case PDF14_BEGIN_TRANS_GROUP:
6376
5.19M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6377
744k
                p14dev->depth_within_smask++;
6378
5.19M
            p14dev->smask_constructed = 0;
6379
5.19M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6380
5.19M
            break;
6381
4.41M
        case PDF14_END_TRANS_GROUP:
6382
4.41M
            code = gx_end_transparency_group(pgs, pdev);
6383
4.41M
            if (p14dev->depth_within_smask)
6384
743k
                p14dev->depth_within_smask--;
6385
4.41M
            break;
6386
401
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6387
401
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6388
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6389
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6390
0
            } else
6391
401
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6392
401
            break;
6393
785k
        case PDF14_END_TRANS_TEXT_GROUP:
6394
785k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6395
784k
                code = gx_end_transparency_group(pgs, pdev);
6396
785k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6397
785k
            break;
6398
8.96M
        case PDF14_BEGIN_TRANS_MASK:
6399
8.96M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6400
8.96M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6401
1.03M
                p14dev->in_smask_construction++;
6402
8.96M
            break;
6403
1.03M
        case PDF14_END_TRANS_MASK:
6404
1.03M
            code = gx_end_transparency_mask(pgs, pdev, &params);
6405
1.03M
            if (code >= 0) {
6406
1.03M
                p14dev->in_smask_construction--;
6407
1.03M
                if (p14dev->in_smask_construction < 0)
6408
0
                    p14dev->in_smask_construction = 0;
6409
1.03M
                if (p14dev->in_smask_construction == 0)
6410
1.02M
                    p14dev->smask_constructed = 1;
6411
1.03M
            }
6412
1.03M
            break;
6413
21.3M
        case PDF14_SET_BLEND_PARAMS:
6414
21.3M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6415
21.3M
            break;
6416
0
        case PDF14_PUSH_TRANS_STATE:
6417
0
            code = gx_push_transparency_state(pgs, pdev);
6418
0
            break;
6419
5.78M
        case PDF14_POP_TRANS_STATE:
6420
5.78M
            code = gx_pop_transparency_state(pgs, pdev);
6421
5.78M
            break;
6422
17.6k
        case PDF14_PUSH_SMASK_COLOR:
6423
17.6k
            code = pdf14_increment_smask_color(pgs, pdev);
6424
17.6k
            break;
6425
17.6k
        case PDF14_POP_SMASK_COLOR:
6426
17.6k
            code = pdf14_decrement_smask_color(pgs, pdev);
6427
17.6k
            break;
6428
49.6M
    }
6429
49.6M
    return code;
6430
49.6M
}
6431
6432
/*
6433
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6434
 * compositor' method.  However the compositor is disabled when we are not
6435
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6436
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6437
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6438
 * to the target.
6439
 */
6440
static  int
6441
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6442
        const gs_composite_t * pct, gs_gstate * pgs,
6443
        gs_memory_t * mem, gx_device *cdev)
6444
2.93k
{
6445
2.93k
    pdf14_device *pdev = (pdf14_device *)dev;
6446
2.93k
    gx_device * tdev = pdev->target;
6447
2.93k
    int code;
6448
6449
2.93k
    *pcdev = dev;
6450
2.93k
    if (gs_is_pdf14trans_compositor(pct)) {
6451
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6452
6453
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6454
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6455
0
        return 0;
6456
0
    }
6457
2.93k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6458
2.93k
    if (code == 1) {
6459
        /* We have created a new compositor that wrapped tdev. This means
6460
         * that our target should be updated to point to that. */
6461
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6462
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6463
0
    }
6464
2.93k
    return code;
6465
2.93k
}
6466
6467
/*
6468
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6469
 * and return. Since the gs_pdf14_device only supports the high-level routines
6470
 * of the interface, don't bother trying to handle any other compositor.
6471
 */
6472
static int
6473
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6474
        const gs_composite_t * pct, gs_gstate * pgs,
6475
        gs_memory_t * mem, gx_device *cdev)
6476
310M
{
6477
310M
    pdf14_device *p14dev = (pdf14_device *)dev;
6478
310M
    if (gs_is_pdf14trans_compositor(pct)) {
6479
49.6M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6480
49.6M
        *pcdev = dev;
6481
        /* cdev, may be the clist reader device which may contain information that
6482
           we will need related to the ICC color spaces that define transparency
6483
           groups.  We want this propogated through all the pdf14 functions.  Store
6484
           a pointer to it in the pdf14 device */
6485
49.6M
        p14dev->pclist_device = cdev;
6486
49.6M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6487
260M
    } else if (gs_is_overprint_compositor(pct)) {
6488
                /* If we had an overprint compositer action, then the
6489
                   color components that were drawn should be updated.
6490
                   The overprint compositor logic and its interactions
6491
                   with the clist is a little odd as it passes uninitialized
6492
                   values around a fair amount.  Hence the forced assignement here.
6493
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6494
260M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6495
260M
                gx_color_index drawn_comps;
6496
260M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6497
6498
260M
                p14dev->op_state = op_pct->params.op_state;
6499
260M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6500
130M
                    if (op_pct->params.retain_any_comps) {
6501
694k
                        drawn_comps = op_pct->params.drawn_comps;
6502
129M
                    } else {
6503
                        /* Draw everything. If this parameter was not set, clist does
6504
                           not fill it in.  */
6505
129M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6506
129M
                    }
6507
6508
130M
                    if (op_pct->params.is_fill_color) {
6509
76.2M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6510
76.2M
                        p14dev->drawn_comps_fill = drawn_comps;
6511
76.2M
                    } else {
6512
54.3M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6513
54.3M
                        p14dev->drawn_comps_stroke = drawn_comps;
6514
54.3M
                    }
6515
                    /* We restore the NONE states as that is used just to force
6516
                       overprint settings in the overprint compositor communication */
6517
130M
                    p14dev->op_state = curr_state;
6518
130M
                }
6519
260M
                *pcdev = dev;
6520
260M
                return 0;
6521
260M
    } else
6522
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6523
310M
}
6524
6525
static int
6526
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6527
                      gs_blend_mode_t blend_mode, float opacity,
6528
                      float shape, bool is_clist)
6529
4.24k
{
6530
4.24k
    int code;
6531
4.24k
    gs_transparency_group_params_t params = { 0 };
6532
4.24k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6533
4.24k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6534
4.24k
    float alpha = pgs->fillconstantalpha;
6535
6536
    /* Push a non-isolated knock-out group making sure the opacity and blend
6537
       mode are correct */
6538
4.24k
    params.Isolated = false;
6539
4.24k
    params.Knockout = true;
6540
4.24k
    params.page_group = false;
6541
4.24k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6542
4.24k
    params.group_opacity = 1.0;
6543
4.24k
    params.group_shape = 1.0;
6544
6545
4.24k
    gs_setfillconstantalpha(pgs, 1.0);
6546
4.24k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6547
6548
4.24k
    if (is_clist) {
6549
4.24k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6550
4.24k
        if (code < 0)
6551
0
            return code;
6552
4.24k
    }
6553
6554
4.24k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6555
4.24k
    gs_setfillconstantalpha(pgs, alpha);
6556
4.24k
    gs_setblendmode(pgs, blend_mode);
6557
4.24k
    if (code < 0)
6558
0
        return code;
6559
6560
4.24k
    if (is_clist) {
6561
4.24k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6562
4.24k
    }
6563
4.24k
    return code;
6564
4.24k
}
6565
6566
static  int
6567
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6568
                 const gs_text_params_t * text, gs_font * font,
6569
                 const gx_clip_path * pcpath,
6570
                 gs_text_enum_t ** ppenum)
6571
614
{
6572
614
    int code;
6573
614
    gs_text_enum_t *penum;
6574
614
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6575
614
    float opacity = pgs->fillconstantalpha;
6576
614
    float shape = 1.0;
6577
614
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6578
614
    pdf14_device *pdev = (pdf14_device*)dev;
6579
614
    bool draw = !(text->operation & TEXT_DO_NONE);
6580
614
    uint text_mode = gs_currenttextrenderingmode(pgs);
6581
614
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6582
614
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6583
6584
614
    code = pdf14_initialize_ctx(dev, pgs);
6585
614
    if (code < 0)
6586
0
        return code;
6587
6588
614
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6589
614
    pdf14_set_marking_params(dev, pgs);
6590
614
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6591
614
    if (code < 0)
6592
0
        return code;
6593
6594
    /* We may need to push a non-isolated transparency group if the following
6595
       is true.
6596
       1) We are not currently in one that we pushed for text and we are in
6597
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6598
       2) The blend mode is not Normal or the opacity is not 1.0
6599
       3) Text knockout is set to true
6600
       4) We are actually doing a text drawing
6601
6602
       Special note:  If text-knockout is set to false while we are within a
6603
       BT ET pair, we should pop the group.  I need to create a test file for
6604
       this case.  */
6605
6606
       /* Catch case where we already pushed a group and are trying to push another one.
6607
       In that case, we will pop the current one first, as we don't want to be left
6608
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6609
       will not be caught until we do the put_image and notice that the stack is not
6610
       empty. */
6611
614
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6612
0
        code = gs_end_transparency_group(pgs);
6613
0
        if (code < 0)
6614
0
            return code;
6615
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6616
0
    }
6617
6618
614
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6619
613
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6620
613
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6621
1
         text_mode != 3 && /* don't bother with invisible text */
6622
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6623
1
        if (draw) {
6624
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6625
1
                false);
6626
1
        }
6627
614
    *ppenum = (gs_text_enum_t *)penum;
6628
614
    return code;
6629
614
}
6630
6631
static  int
6632
pdf14_initialize_device(gx_device *new_dev)
6633
1.98M
{
6634
1.98M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6635
6636
1.98M
    pdev->ctx = NULL;
6637
1.98M
    pdev->color_model_stack = NULL;
6638
1.98M
    pdev->smaskcolor = NULL;
6639
6640
1.98M
    return 0;
6641
1.98M
}
6642
6643
/*
6644
 * Implement copy_mono by filling lots of small rectangles.
6645
 */
6646
static int
6647
pdf14_copy_mono(gx_device * dev,
6648
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6649
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6650
29.9M
{
6651
29.9M
    const byte *sptr;
6652
29.9M
    const byte *line;
6653
29.9M
    int sbit, first_bit;
6654
29.9M
    int code, sbyte, bit, count;
6655
29.9M
    int run_length, startx, current_bit, bit_value;
6656
29.9M
    gx_color_index current_color;
6657
6658
29.9M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6659
29.9M
    line = base + (sourcex >> 3);
6660
29.9M
    sbit = sourcex & 7;
6661
29.9M
    first_bit = 7 - sbit;
6662
6663
    /* Loop through the height of the specified area. */
6664
224M
    while (h-- > 0) {
6665
        /* Set up for the start of each line of the area. */
6666
194M
        sptr = line;
6667
194M
        sbyte = *sptr++;
6668
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6669
         * the loop below so adding 1 means that we don't fall into the bit == 0
6670
         * case and incorrectly read a new byte from the source. This weirdness is because
6671
         * the original code wouold read off the end of the buffer if the number of bits in
6672
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6673
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6674
         * of the loop to the beginning meant we would not read past the end of the buffer
6675
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6676
         * reading another byte.
6677
         */
6678
194M
        bit = first_bit + 1;
6679
194M
        count = w;
6680
194M
        run_length = 0;
6681
194M
        startx = x;
6682
194M
        current_bit = 0;
6683
194M
        current_color = zero;
6684
6685
        /* Loop across each pixel of a line. */
6686
2.64G
        do {
6687
            /* Move to the next input bit. */
6688
2.64G
            if (bit == 0) {
6689
227M
                bit = 7;
6690
227M
                sbyte = *sptr++;
6691
227M
            }
6692
2.41G
            else
6693
2.41G
                bit--;
6694
2.64G
            bit_value = (sbyte >> bit) & 1;
6695
2.64G
            if (bit_value == current_bit) {
6696
                /* The value did not change, simply increment our run length */
6697
2.16G
                run_length++;
6698
2.16G
            } else {
6699
                /* The value changed, fill the current rectangle. */
6700
479M
                if (run_length != 0) {
6701
457M
                    if (current_color != gx_no_color_index) {
6702
196M
                        code = (*dev_proc(dev, fill_rectangle))
6703
196M
                                (dev, startx, y, run_length, 1, current_color);
6704
196M
                        if (code < 0)
6705
0
                            return code;
6706
196M
                    }
6707
457M
                    startx += run_length;
6708
457M
                }
6709
479M
                run_length = 1;
6710
479M
                current_color = bit_value ? one : zero;
6711
479M
                current_bit = bit_value;
6712
479M
            }
6713
2.64G
        } while (--count > 0);
6714
        /* Fill the last rectangle in the line. */
6715
194M
        if (run_length != 0 && current_color != gx_no_color_index) {
6716
85.9M
            code = (*dev_proc(dev, fill_rectangle))
6717
85.9M
                        (dev, startx, y, run_length, 1, current_color);
6718
85.9M
            if (code < 0)
6719
0
                return code;
6720
85.9M
        }
6721
        /* Move to the next line */
6722
194M
        line += sraster;
6723
194M
        y++;
6724
194M
    }
6725
29.9M
    return 0;
6726
29.9M
}
6727
6728
/* Added to avoid having to go back and forth between fixed and int
6729
   in some of the internal methods used for dealing with tiling
6730
   and devn colors */
6731
static int
6732
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6733
    const gx_drawing_color *pdcolor)
6734
2.44k
{
6735
2.44k
    pdf14_device *pdev = (pdf14_device *)dev;
6736
2.44k
    pdf14_buf *buf;
6737
2.44k
    int code;
6738
6739
2.44k
    fit_fill_xywh(dev, x, y, w, h);
6740
2.44k
    if (w <= 0 || h <= 0)
6741
0
        return 0;
6742
6743
2.44k
    code = pdf14_initialize_ctx(dev, NULL);
6744
2.44k
    if (code < 0)
6745
0
        return code;
6746
2.44k
    buf = pdev->ctx->stack;
6747
6748
2.44k
    if (buf->knockout)
6749
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6750
0
            true);
6751
2.44k
    else
6752
2.44k
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6753
2.44k
}
6754
6755
/* Step through and do rect fills with the devn colors as
6756
   we hit each transition in the bitmap. It is possible
6757
   that one of the colors is not devn, but is pure and
6758
   is set to gx_no_color_index. This type of mix happens
6759
   for example from tile_clip_fill_rectangle_hl_color */
6760
static int
6761
pdf14_copy_mono_devn(gx_device *dev,
6762
    const byte *base, int sourcex, int sraster,
6763
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6764
    const gx_drawing_color *pdcolor1)
6765
668
{
6766
668
    const byte *sptr;
6767
668
    const byte *line;
6768
668
    int sbit, first_bit;
6769
668
    int code, sbyte, bit, count;
6770
668
    int run_length, startx, current_bit, bit_value;
6771
668
    const gx_drawing_color *current_color;
6772
6773
668
    if ((x | y) < 0) {
6774
0
        if (x < 0) {
6775
0
            w += x;
6776
0
            sourcex -= x;
6777
0
            x = 0;
6778
0
        }
6779
0
        if (y < 0) {
6780
0
            h += y;
6781
0
            base -= (int)(y * sraster);
6782
0
            y = 0;
6783
0
        }
6784
0
    }
6785
668
    if (w > (dev)->width - x)
6786
0
        w = (dev)->width - x;
6787
668
    if (h > (dev)->height - y)
6788
0
        h = (dev)->height - y;
6789
668
    if (w <= 0 || h <= 0)
6790
0
        return 0;
6791
6792
668
    line = base + (sourcex >> 3);
6793
668
    sbit = sourcex & 7;
6794
668
    first_bit = 7 - sbit;
6795
6796
    /* Loop through the height of the specified area. */
6797
2.10k
    while (h-- > 0) {
6798
        /* Set up for the start of each line of the area. */
6799
1.43k
        sptr = line;
6800
1.43k
        sbyte = *sptr++;
6801
1.43k
        bit = first_bit;
6802
1.43k
        count = w;
6803
1.43k
        run_length = 0;
6804
1.43k
        startx = x;
6805
1.43k
        current_bit = 0;
6806
1.43k
        current_color = pdcolor0;
6807
6808
        /* Loop across each pixel of a line. */
6809
15.6k
        do {
6810
15.6k
            bit_value = (sbyte >> bit) & 1;
6811
15.6k
            if (bit_value == current_bit) {
6812
                /* The value did not change, simply increment our run length */
6813
11.3k
                run_length++;
6814
11.3k
            } else {
6815
                /* The value changed, fill the current rectangle. */
6816
4.26k
                if (run_length != 0) {
6817
3.85k
                    if (current_color->type != gx_dc_type_pure &&
6818
1.82k
                        current_color->colors.pure != gx_no_color_index) {
6819
1.82k
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6820
1.82k
                            run_length, 1, current_color);
6821
1.82k
                        if (code < 0)
6822
0
                            return code;
6823
1.82k
                    }
6824
3.85k
                    startx += run_length;
6825
3.85k
                }
6826
4.26k
                run_length = 1;
6827
4.26k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6828
4.26k
                current_bit = bit_value;
6829
4.26k
            }
6830
6831
            /* Move to the next input bit. */
6832
15.6k
            if (bit == 0) {
6833
1.40k
                bit = 7;
6834
1.40k
                sbyte = *sptr++;
6835
1.40k
            } else
6836
14.2k
                bit--;
6837
15.6k
        } while (--count > 0);
6838
6839
        /* Fill the last rectangle in the line. */
6840
1.43k
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6841
619
            current_color->colors.pure != gx_no_color_index) {
6842
619
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6843
619
                run_length, 1, current_color);
6844
619
            if (code < 0)
6845
0
                return code;
6846
619
        }
6847
        /* Move to the next line */
6848
1.43k
        line += sraster;
6849
1.43k
        y++;
6850
1.43k
    }
6851
668
    return 0;
6852
668
}
6853
6854
/* Step through the tiles doing essentially copy_mono but with devn colors */
6855
static int
6856
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6857
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6858
    const gx_drawing_color *pdcolor1, int px, int py)
6859
668
{   /* Fill the rectangle in chunks. */
6860
668
    int width = tiles->size.x;
6861
668
    int height = tiles->size.y;
6862
668
    int raster = tiles->raster;
6863
668
    int rwidth = tiles->rep_width;
6864
668
    int rheight = tiles->rep_height;
6865
668
    int shift = tiles->shift;
6866
6867
668
    if (rwidth == 0 || rheight == 0)
6868
0
        return_error(gs_error_unregistered);
6869
668
    fit_fill_xy(dev, x, y, w, h);
6870
6871
668
     {
6872
668
        int xoff = (shift == 0 ? px :
6873
668
                px + (y + py) / rheight * tiles->rep_shift);
6874
668
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6875
0
            (x + xoff) & (rwidth - 1) :
6876
668
            (x + xoff) % rwidth);
6877
668
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6878
0
            (y + py) & (rheight - 1) :
6879
668
            (y + py) % rheight);
6880
668
        int icw = width - irx;
6881
668
        int ch = height - ry;
6882
668
        byte *row = tiles->data + ry * raster;
6883
668
        int code = 0;
6884
6885
668
        if (ch >= h) {      /* Shallow operation */
6886
668
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6887
668
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6888
668
                    w, h, pdcolor0, pdcolor1);
6889
668
                if (code < 0)
6890
0
                    return_error(code);
6891
668
            } else {
6892
0
                int ex = x + w;
6893
0
                int fex = ex - width;
6894
0
                int cx = x + icw;
6895
6896
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6897
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6898
0
                if (code < 0)
6899
0
                    return_error(code);
6900
6901
0
                while (cx <= fex) {
6902
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6903
0
                        width, h, pdcolor0, pdcolor1);
6904
0
                    if (code < 0)
6905
0
                        return_error(code);
6906
0
                    cx += width;
6907
0
                }
6908
0
                if (cx < ex) {
6909
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6910
0
                        ex - cx, h, pdcolor0, pdcolor1);
6911
0
                    if (code < 0)
6912
0
                        return_error(code);
6913
0
                }
6914
0
            }
6915
668
        } else if (icw >= w && shift == 0) {
6916
            /* Narrow operation, no shift */
6917
0
            int ey = y + h;
6918
0
            int fey = ey - height;
6919
0
            int cy = y + ch;
6920
6921
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6922
0
                x, y, w, ch, pdcolor0, pdcolor1);
6923
0
            if (code < 0)
6924
0
                return_error(code);
6925
0
            row = tiles->data;
6926
0
            do {
6927
0
                ch = (cy > fey ? ey - cy : height);
6928
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6929
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6930
0
                if (code < 0)
6931
0
                    return_error(code);
6932
0
            } while ((cy += ch) < ey);
6933
0
        } else {
6934
            /* Full operation.  If shift != 0, some scan lines */
6935
            /* may be narrow.  We could test shift == 0 in advance */
6936
            /* and use a slightly faster loop, but right now */
6937
            /* we don't bother. */
6938
0
            int ex = x + w, ey = y + h;
6939
0
            int fex = ex - width, fey = ey - height;
6940
0
            int cx, cy;
6941
6942
0
            for (cy = y;;) {
6943
0
                if (icw >= w) {
6944
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6945
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6946
0
                    if (code < 0)
6947
0
                        return_error(code);
6948
0
                } else {
6949
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6950
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6951
0
                    if (code < 0)
6952
0
                        return_error(code);
6953
0
                    cx = x + icw;
6954
0
                    while (cx <= fex) {
6955
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6956
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6957
0
                        if (code < 0)
6958
0
                            return_error(code);
6959
0
                        cx += width;
6960
0
                    }
6961
0
                    if (cx < ex) {
6962
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6963
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6964
0
                        if (code < 0)
6965
0
                            return_error(code);
6966
0
                    }
6967
0
                }
6968
0
                if ((cy += ch) >= ey)
6969
0
                    break;
6970
0
                ch = (cy > fey ? ey - cy : height);
6971
0
                if ((irx += shift) >= rwidth)
6972
0
                    irx -= rwidth;
6973
0
                icw = width - irx;
6974
0
                row = tiles->data;
6975
0
            }
6976
0
        }
6977
668
    }
6978
668
    return 0;
6979
668
}
6980
6981
/* pdf14 device supports devn */
6982
static int
6983
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6984
    int x, int y, int w, int h,
6985
    const gx_drawing_color *pdcolor0,
6986
    const gx_drawing_color *pdcolor1, int px, int py)
6987
668
{
6988
668
    pdf14_device *pdev = (pdf14_device *)dev;
6989
668
    pdf14_buf *buf;
6990
668
    int num_comp;
6991
668
    int k;
6992
668
    bool same = false;
6993
668
    int code;
6994
6995
668
    code = pdf14_initialize_ctx(dev, NULL);
6996
668
    if (code < 0)
6997
0
        return code;
6998
668
    buf = pdev->ctx->stack;
6999
668
    num_comp = buf->n_chan - 1;
7000
7001
    /* if color0 is identical to color1, do rect fill */
7002
668
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
7003
0
        same = true;
7004
0
        for (k = 0; k < num_comp; k++) {
7005
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
7006
0
                same = false;
7007
0
                break;
7008
0
            }
7009
0
        }
7010
0
    }
7011
7012
668
    if (same) {
7013
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
7014
668
    } else {
7015
        /* Go through the tile stepping using code stolen from
7016
           gx_default_strip_tile_rectangle and call the rect fills
7017
           using code stolen from pdf14_copy_mono but using devn
7018
           colors */
7019
668
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
7020
668
            x, y, w, h, pdcolor0, pdcolor1, px, py);
7021
668
    }
7022
668
    return code;
7023
668
}
7024
7025
/* Used in a few odd cases where the target device is planar and we have
7026
   a planar tile (pattern) and we are copying it into place here */
7027
static int
7028
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
7029
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
7030
4.62k
{
7031
4.62k
    pdf14_device *pdev = (pdf14_device *)dev;
7032
4.62k
    pdf14_ctx *ctx;
7033
4.62k
    pdf14_buf *buf;
7034
4.62k
    int xo = x;
7035
4.62k
    int yo = y;
7036
4.62k
    pdf14_buf fake_tos;
7037
4.62k
    int deep;
7038
7039
4.62k
    int code = pdf14_initialize_ctx(dev, NULL);
7040
4.62k
    if (code < 0)
7041
0
        return code;
7042
7043
4.62k
    fit_fill_xywh(dev, x, y, w, h);
7044
4.62k
    if (w <= 0 || h <= 0)
7045
0
        return 0;
7046
7047
4.62k
    ctx = pdev->ctx;
7048
4.62k
    buf = ctx->stack;
7049
4.62k
    deep = ctx->deep;
7050
7051
4.62k
    fake_tos.deep = deep;
7052
4.62k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7053
4.62k
    fake_tos.backdrop = NULL;
7054
4.62k
    fake_tos.blend_mode = pdev->blend_mode;
7055
4.62k
    fake_tos.color_space = buf->color_space;
7056
4.62k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7057
4.62k
    fake_tos.dirty.p.x = x;
7058
4.62k
    fake_tos.dirty.p.y = y;
7059
4.62k
    fake_tos.dirty.q.x = x + w;
7060
4.62k
    fake_tos.dirty.q.y = y + h;
7061
4.62k
    fake_tos.has_alpha_g = 0;
7062
4.62k
    fake_tos.has_shape = 0;
7063
4.62k
    fake_tos.has_tags = 0;
7064
4.62k
    fake_tos.idle = false;
7065
4.62k
    fake_tos.isolated = false;
7066
4.62k
    fake_tos.knockout = false;
7067
4.62k
    fake_tos.mask_id = 0;
7068
4.62k
    fake_tos.mask_stack = NULL;
7069
4.62k
    fake_tos.matte = NULL;
7070
4.62k
    fake_tos.matte_num_comps = 0;
7071
4.62k
    fake_tos.memory = dev->memory;
7072
4.62k
    fake_tos.n_chan = dev->color_info.num_components;
7073
4.62k
    fake_tos.n_planes = dev->color_info.num_components;
7074
4.62k
    fake_tos.num_spots = 0;
7075
4.62k
    fake_tos.group_color_info = NULL;
7076
4.62k
    fake_tos.planestride = raster * (size_t)plane_height;
7077
4.62k
    fake_tos.rect.p.x = x;
7078
4.62k
    fake_tos.rect.p.y = y;
7079
4.62k
    fake_tos.rect.q.x = x + w;
7080
4.62k
    fake_tos.rect.q.y = y + h;
7081
4.62k
    fake_tos.rowstride = raster;
7082
4.62k
    fake_tos.saved = NULL;
7083
4.62k
    fake_tos.shape = 0xffff;
7084
4.62k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7085
4.62k
    fake_tos.transfer_fn = NULL;
7086
4.62k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7087
4.62k
                                  pdev->ctx->memory, dev);
7088
4.62k
    return 0;
7089
4.62k
}
7090
7091
static int
7092
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7093
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7094
    const gx_clip_path *pcpath)
7095
42.6M
{
7096
42.6M
    pdf14_device *pdev = (pdf14_device *)dev;
7097
42.6M
    pdf14_buf* buf;
7098
42.6M
    int code;
7099
42.6M
    int x = fixed2int(rect->p.x);
7100
42.6M
    int y = fixed2int(rect->p.y);
7101
42.6M
    int w = fixed2int(rect->q.x) - x;
7102
42.6M
    int h = fixed2int(rect->q.y) - y;
7103
7104
42.6M
    fit_fill_xywh(dev, x, y, w, h);
7105
42.6M
    if (w <= 0 || h <= 0)
7106
1.33M
        return 0;
7107
7108
41.2M
    code = pdf14_initialize_ctx(dev, pgs);
7109
41.2M
    if (code < 0)
7110
0
        return code;
7111
41.2M
    buf = pdev->ctx->stack;
7112
7113
41.2M
    if (buf->knockout)
7114
701k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7115
701k
                                                   true);
7116
40.5M
    else
7117
40.5M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7118
41.2M
}
7119
7120
static  int
7121
pdf14_fill_rectangle(gx_device * dev,
7122
                    int x, int y, int w, int h, gx_color_index color)
7123
942M
{
7124
942M
    pdf14_device *pdev = (pdf14_device *)dev;
7125
942M
    pdf14_buf *buf;
7126
942M
    int code;
7127
7128
942M
    fit_fill_xywh(dev, x, y, w, h);
7129
942M
    if (w <= 0 || h <= 0)
7130
26.5M
        return 0;
7131
7132
915M
    code = pdf14_initialize_ctx(dev, NULL);
7133
915M
    if (code < 0)
7134
0
        return code;
7135
7136
915M
    buf = pdev->ctx->stack;
7137
7138
915M
    if (buf->knockout)
7139
5.13M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7140
5.13M
                                                   false);
7141
910M
    else
7142
910M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7143
915M
}
7144
7145
static int
7146
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7147
                                    const gs_rect *pbbox, gs_int_rect *rect)
7148
5.61M
{
7149
5.61M
    gs_rect dev_bbox;
7150
5.61M
    int code;
7151
7152
5.61M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7153
5.61M
    if (code < 0)
7154
0
        return code;
7155
5.61M
    rect->p.x = (int)floor(dev_bbox.p.x);
7156
5.61M
    rect->p.y = (int)floor(dev_bbox.p.y);
7157
5.61M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7158
5.61M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7159
    /* Sanity check rect for insane ctms */
7160
5.61M
    if (rect->p.x < 0)
7161
1.32M
        rect->p.x = 0;
7162
5.61M
    if (rect->q.x < rect->p.x)
7163
4.91k
        rect->q.x = rect->p.x;
7164
5.61M
    if (rect->p.y < 0)
7165
5.14M
        rect->p.y = 0;
7166
5.61M
    if (rect->q.y < rect->p.y)
7167
186k
        rect->q.y = rect->p.y;
7168
5.61M
    return 0;
7169
5.61M
}
7170
7171
static  int
7172
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7173
                              const gs_rect *pbbox, gs_gstate *pgs)
7174
5.44M
{
7175
5.44M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7176
7177
5.44M
    if (code < 0)
7178
0
        return code;
7179
5.44M
    rect_intersect(*rect, pdev->ctx->rect);
7180
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7181
5.44M
    if (rect->q.x < rect->p.x)
7182
19.7k
        rect->q.x = rect->p.x;
7183
5.44M
    if (rect->q.y < rect->p.y)
7184
144k
        rect->q.y = rect->p.y;
7185
5.44M
    return 0;
7186
5.44M
}
7187
7188
static  int
7189
pdf14_begin_transparency_group(gx_device* dev,
7190
    const gs_transparency_group_params_t* ptgp,
7191
    const gs_rect* pbbox,
7192
    gs_gstate* pgs, gs_memory_t* mem)
7193
5.19M
{
7194
5.19M
    pdf14_device* pdev = (pdf14_device*)dev;
7195
5.19M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7196
5.19M
    gs_int_rect rect;
7197
5.19M
    int code;
7198
5.19M
    bool isolated = ptgp->Isolated;
7199
5.19M
    gs_transparency_color_t group_color_type;
7200
5.19M
    cmm_profile_t* group_profile;
7201
5.19M
    cmm_profile_t* tos_profile;
7202
5.19M
    gsicc_rendering_param_t render_cond;
7203
5.19M
    cmm_dev_profile_t* dev_profile;
7204
5.19M
    bool cm_back_drop = false;
7205
5.19M
    bool new_icc = false;
7206
5.19M
    pdf14_group_color_t* group_color_info;
7207
5.19M
    bool has_tags = device_encodes_tags(dev);
7208
7209
5.19M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7210
5.19M
    if (code < 0)
7211
0
        return code;
7212
5.19M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7213
7214
5.19M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7215
785k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7216
785k
    }
7217
7218
5.19M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7219
785k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7220
4.41M
    else
7221
4.41M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7222
7223
5.19M
    if (code < 0)
7224
0
        return code;
7225
5.19M
    if_debug5m('v', pdev->memory,
7226
5.19M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7227
5.19M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7228
7229
    /* If the group color is unknown then use the current device profile. */
7230
5.19M
    if (ptgp->group_color_type == UNKNOWN) {
7231
4.25M
        group_color_type = ICC;
7232
4.25M
        group_profile = tos_profile;
7233
4.25M
    }
7234
942k
    else {
7235
942k
        group_color_type = ptgp->group_color_type;
7236
942k
        group_profile = ptgp->iccprofile;
7237
942k
    }
7238
7239
    /* We have to handle case where the profile is in the clist */
7240
5.19M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7241
        /* Get the serialized data from the clist. */
7242
942k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7243
942k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7244
942k
        if (group_profile == NULL)
7245
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7246
        /* Keep a pointer to the clist device */
7247
942k
        group_profile->dev = (gx_device*)pcrdev;
7248
942k
        new_icc = true;
7249
942k
    }
7250
5.19M
    if (group_profile != NULL) {
7251
        /* If we have a non-isolated group and the color space is different,
7252
            we will need to CM the backdrop. */
7253
5.19M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7254
360k
            cm_back_drop = true;
7255
360k
        }
7256
5.19M
    }
7257
7258
    /* Always create the base color group information as it is only through
7259
       groups that we can have a color space change.  This will survive
7260
       the life of the context. */
7261
5.19M
    if (pdev->ctx->base_color == NULL) {
7262
1.16M
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7263
1.16M
    }
7264
7265
    /* If this is not the page group and we don't yet have a group, we need
7266
       to create a buffer for the whole page so that we can handle stuff drawn
7267
       outside this current group (e.g. two non inclusive groups drawn independently) */
7268
5.19M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7269
88.6k
        code = pdf14_initialize_ctx(dev, NULL);
7270
88.6k
        if (code < 0)
7271
0
            return code;
7272
88.6k
        pdev->ctx->stack->isolated = true;
7273
88.6k
    }
7274
7275
5.19M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7276
5.19M
        group_profile, false);
7277
5.19M
    if (group_color_info == NULL)
7278
0
        return gs_error_VMerror;
7279
5.19M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7280
7281
5.19M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7282
5.19M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7283
5.19M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7284
5.19M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7285
5.19M
                                        pgs->blend_mode, ptgp->idle,
7286
5.19M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7287
5.19M
                                         cm_back_drop, ptgp->shade_group,
7288
5.19M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7289
5.19M
    if (new_icc)
7290
942k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7291
5.19M
    return code;
7292
5.19M
}
7293
7294
static void
7295
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7296
5.19M
{
7297
5.19M
    pdf14_device* pdev = (pdf14_device*)dev;
7298
7299
5.19M
    if (group_color != NULL &&
7300
5.19M
        !(group_color->group_color_mapping_procs == NULL &&
7301
5.19M
            group_color->group_color_comp_index == NULL)) {
7302
5.19M
        bool has_tags = device_encodes_tags(dev);
7303
5.19M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7304
5.19M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7305
5.19M
        pdev->color_info.polarity = group_color->polarity;
7306
5.19M
        if (pdev->num_planar_planes > 0)
7307
239k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7308
5.19M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7309
5.19M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7310
5.19M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7311
5.19M
        pdev->blend_procs = group_color->blend_procs;
7312
5.19M
        pdev->ctx->additive = group_color->isadditive;
7313
5.19M
        pdev->pdf14_procs = group_color->unpack_procs;
7314
5.19M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7315
5.19M
        pdev->color_info.depth = group_color->depth;
7316
5.19M
        pdev->color_info.max_color = group_color->max_color;
7317
5.19M
        pdev->color_info.max_gray = group_color->max_gray;
7318
5.19M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7319
5.19M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7320
5.19M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7321
5.19M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7322
5.19M
        if (group_color->icc_profile != NULL) {
7323
            /* make sure to decrement the device profile.  If it was allocated
7324
               with the push then it will be freed. */
7325
5.19M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7326
5.19M
                                    -1, "pdf14_pop_color_model");
7327
5.19M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7328
5.19M
                                    group_color->icc_profile;
7329
7330
5.19M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7331
5.19M
                                    1, "pdf14_pop_color_model");
7332
5.19M
        }
7333
5.19M
        pdev->num_std_colorants = group_color->num_std_colorants;
7334
5.19M
    }
7335
5.19M
}
7336
7337
static  int
7338
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7339
5.19M
{
7340
5.19M
    pdf14_device* pdev = (pdf14_device*)dev;
7341
5.19M
    int code;
7342
5.19M
    cmm_profile_t* group_profile;
7343
5.19M
    gsicc_rendering_param_t render_cond;
7344
5.19M
    cmm_dev_profile_t* dev_profile;
7345
5.19M
    int has_tags = device_encodes_tags(dev);
7346
7347
5.19M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7348
5.19M
    if (code < 0)
7349
0
        return code;
7350
7351
5.19M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7352
5.19M
        &render_cond);
7353
5.19M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7354
7355
5.19M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7356
5.19M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7357
5.19M
    if (code < 0)
7358
0
        return code;
7359
#ifdef DEBUG
7360
    pdf14_debug_mask_stack_state(pdev->ctx);
7361
#endif
7362
    /* If this group is the base group, then restore the color model
7363
       of the device at this time.  Note that during the actual device pop
7364
       we will need to use the profile of the buffer not the pdf14 device
7365
       as the source color space */
7366
5.19M
    if (pdev->ctx->stack->group_popped) {
7367
905k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7368
4.28M
    } else {
7369
4.28M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7370
4.28M
    }
7371
7372
5.19M
    return code;
7373
5.19M
}
7374
7375
static pdf14_group_color_t*
7376
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7377
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7378
                        bool is_mask)
7379
6.22M
{
7380
6.22M
    pdf14_device *pdevproto = NULL;
7381
6.22M
    pdf14_device *pdev = (pdf14_device *)dev;
7382
6.22M
    const pdf14_procs_t *new_14procs = NULL;
7383
6.22M
    pdf14_group_color_t *group_color;
7384
6.22M
    gx_color_polarity_t new_polarity;
7385
6.22M
    uchar new_num_comps;
7386
6.22M
    bool new_additive;
7387
6.22M
    gx_device_clist_reader *pcrdev;
7388
6.22M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7389
6.22M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7390
6.22M
    int k;
7391
6.22M
    bool has_tags = device_encodes_tags(dev);
7392
6.22M
    bool deep = pdev->ctx->deep;
7393
7394
6.22M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7395
7396
6.22M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7397
7398
6.22M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7399
6.22M
                               pdf14_group_color_t, &st_pdf14_clr,
7400
6.22M
                               "pdf14_push_color_model");
7401
6.22M
    if (group_color == NULL)
7402
0
        return NULL;
7403
7404
6.22M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7405
7406
6.22M
    switch (group_color_type) {
7407
0
        case GRAY_SCALE:
7408
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7409
0
            new_num_comps = 1;
7410
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7411
0
            new_additive = true;
7412
0
            new_14procs = &gray_pdf14_procs;
7413
0
            break;
7414
0
        case DEVICE_RGB:
7415
0
        case CIE_XYZ:
7416
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7417
0
            new_num_comps = 3;
7418
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7419
0
            new_additive = true;
7420
0
            new_14procs = &rgb_pdf14_procs;
7421
0
            break;
7422
0
        case DEVICE_CMYK:
7423
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7424
0
            new_num_comps = 4;
7425
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7426
0
            new_additive = false;
7427
            /* This is needed due to the mismatched compressed encode decode
7428
                between the device procs and the pdf14 procs */
7429
0
            if (dev->color_info.num_components > 4){
7430
0
                new_14procs = &cmykspot_pdf14_procs;
7431
0
            } else {
7432
0
                new_14procs = &cmyk_pdf14_procs;
7433
0
            }
7434
0
            break;
7435
6.22M
        case ICC:
7436
            /* If we are coming from the clist reader, then we need to get
7437
                the ICC data now  */
7438
6.22M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7439
                /* Get the serialized data from the clist.  Not the whole
7440
                    profile. */
7441
1.01M
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7442
1.01M
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7443
1.01M
                                                    icc_hashcode);
7444
1.01M
                if (iccprofile == NULL)
7445
0
                    return NULL;
7446
                /* Keep a pointer to the clist device */
7447
1.01M
                iccprofile->dev = (gx_device *) pcrdev;
7448
5.21M
            } else {
7449
                /* Go ahead and rc increment right now.  This way when
7450
                    we pop, we will make sure to decrement and avoid a
7451
                    leak for the above profile that we just created.  This
7452
                    goes with the assignment to the device's profile.
7453
                    Note that we still do the increment for the group_color
7454
                    assignment below. */
7455
5.21M
                if (iccprofile == NULL)
7456
0
                    return NULL;
7457
5.21M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7458
5.21M
            }
7459
6.22M
            new_num_comps = iccprofile->num_comps;
7460
6.22M
            if (new_num_comps == 4) {
7461
1.46M
                new_additive = false;
7462
1.46M
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7463
4.76M
            } else {
7464
4.76M
                new_additive = true;
7465
4.76M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7466
4.76M
            }
7467
6.22M
            switch (new_num_comps) {
7468
1.48M
                case 1:
7469
1.48M
                    if (pdev->sep_device && !is_mask) {
7470
29
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7471
29
                        new_14procs = &grayspot_pdf14_procs;
7472
1.48M
                    } else {
7473
1.48M
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7474
1.48M
                        new_14procs = &gray_pdf14_procs;
7475
1.48M
                    }
7476
1.48M
                    break;
7477
3.27M
                case 3:
7478
3.27M
                    if (pdev->sep_device) {
7479
122k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7480
122k
                        new_14procs = &rgbspot_pdf14_procs;
7481
122k
                    }
7482
3.15M
                    else {
7483
3.15M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7484
3.15M
                        new_14procs = &rgb_pdf14_procs;
7485
3.15M
                    }
7486
3.27M
                    break;
7487
1.46M
                case 4:
7488
1.46M
                    if (pdev->sep_device) {
7489
117k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7490
117k
                        new_14procs = &cmykspot_pdf14_procs;
7491
1.34M
                    } else {
7492
1.34M
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7493
1.34M
                        new_14procs = &cmyk_pdf14_procs;
7494
1.34M
                    }
7495
1.46M
                    break;
7496
0
                default:
7497
0
                    return NULL;
7498
0
                    break;
7499
6.22M
            }
7500
6.22M
            break;
7501
6.22M
        default:
7502
0
            return NULL;
7503
0
            break;
7504
6.22M
    }
7505
7506
    /* We might just have changed the colorspace of the device, which means
7507
     * the number of colorants have changed. */
7508
6.22M
    group_color->num_std_colorants = new_num_comps;
7509
6.22M
    pdev->num_std_colorants = new_num_comps;
7510
7511
6.22M
    if (has_tags)
7512
0
        new_num_comps++;
7513
7514
6.22M
    if (group_color_type == ICC && iccprofile != NULL) {
7515
6.22M
        group_color->icc_profile = iccprofile;
7516
6.22M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7517
6.22M
    }
7518
7519
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7520
       spot colorants and know how to index into them */
7521
6.22M
    if (pdev->sep_device && !is_mask) {
7522
239k
        int num_spots = dev->color_info.num_components - has_tags -
7523
239k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7524
7525
239k
        if (num_spots > 0)
7526
6.47k
            new_num_comps += num_spots;
7527
239k
    }
7528
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7529
23.4M
    for (k = 0; k < new_num_comps; k++) {
7530
17.1M
        comp_bits[k] = 8<<deep;
7531
17.1M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7532
17.1M
    }
7533
7534
    /* Set device values now and store settings in group_color.  Then they
7535
       are available when we pop the previous group */
7536
6.22M
    if_debug2m('v', pdev->memory,
7537
6.22M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7538
6.22M
                pdev->color_info.num_components,new_num_comps);
7539
6.22M
    {
7540
6.22M
        gx_device local_device;
7541
7542
6.22M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7543
6.22M
        local_device.initialize_device_procs((gx_device *)&local_device);
7544
6.22M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7545
6.22M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7546
6.22M
    }
7547
6.22M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7548
6.22M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7549
6.22M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7550
6.22M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7551
6.22M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7552
6.22M
    if (pdev->num_planar_planes > 0)
7553
304k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7554
6.22M
    group_color->num_components = new_num_comps - has_tags;
7555
6.22M
    pdev->color_info.num_components = new_num_comps;
7556
6.22M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7557
6.22M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7558
6.22M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7559
6.22M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7560
6.22M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7561
6.22M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7562
6.22M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7563
6.22M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7564
6.22M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7565
6.22M
    group_color->depth = pdev->color_info.depth;
7566
6.22M
    group_color->decode = dev_proc(pdev, decode_color);
7567
6.22M
    group_color->encode = dev_proc(pdev, encode_color);
7568
6.22M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7569
6.22M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7570
6.22M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7571
6.22M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7572
6.22M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7573
6.22M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7574
6.22M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7575
7576
    /* If the CS was ICC based, we need to update the device ICC profile
7577
        in the ICC manager, since that is the profile that is used for the
7578
        PDF14 device */
7579
6.22M
    if (group_color_type == ICC && iccprofile != NULL) {
7580
        /* iccprofile was incremented above if we had not just created it.
7581
           When we do the pop we will decrement and if we just created it, it
7582
           will be destroyed */
7583
6.22M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7584
6.22M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7585
6.22M
    }
7586
6.22M
    return group_color;
7587
6.22M
}
7588
7589
static int
7590
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7591
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7592
                             bool is_mask)
7593
125k
{
7594
125k
    pdf14_device* pdev = (pdf14_device*)dev;
7595
125k
    pdf14_group_color_t* new_group_color;
7596
125k
    gsicc_rendering_param_t render_cond;
7597
125k
    cmm_dev_profile_t* dev_profile;
7598
125k
    pdf14_device* pdevproto;
7599
125k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7600
125k
    const pdf14_procs_t* new_14procs;
7601
125k
    bool update_color_info;
7602
125k
    gx_color_polarity_t new_polarity;
7603
125k
    int new_num_comps;
7604
125k
    bool new_additive = false;
7605
125k
    byte new_depth;
7606
125k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7607
125k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7608
125k
    int k;
7609
125k
    bool has_tags = device_encodes_tags(dev);
7610
125k
    bool deep = device_is_deep(dev);
7611
125k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7612
125k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7613
125k
    cmm_profile_t *old_profile = NULL;
7614
7615
125k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7616
7617
125k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7618
125k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7619
125k
        &render_cond);
7620
125k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7621
7622
    /* Allocate a new one */
7623
125k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7624
125k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7625
7626
125k
    if (new_group_color == NULL)
7627
0
        return_error(gs_error_VMerror);
7628
7629
    /* Link to old one */
7630
125k
    new_group_color->previous = pdev->color_model_stack;
7631
7632
    /* Reassign new one to dev */
7633
125k
    pdev->color_model_stack = new_group_color;
7634
7635
    /* Initialize with values */
7636
125k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7637
125k
    new_group_color->group_color_mapping_procs =
7638
125k
        dev_proc(pdev, get_color_mapping_procs);
7639
125k
    new_group_color->group_color_comp_index =
7640
125k
        dev_proc(pdev, get_color_comp_index);
7641
125k
    new_group_color->blend_procs = pdev->blend_procs;
7642
125k
    new_group_color->polarity = pdev->color_info.polarity;
7643
125k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7644
125k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7645
125k
    new_group_color->depth = pdev->color_info.depth;
7646
125k
    new_group_color->max_color = pdev->color_info.max_color;
7647
125k
    new_group_color->max_gray = pdev->color_info.max_gray;
7648
125k
    new_group_color->decode = dev_proc(pdev, decode_color);
7649
125k
    new_group_color->encode = dev_proc(pdev, encode_color);
7650
125k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7651
125k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7652
125k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7653
125k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7654
7655
125k
    if (new_profile == NULL)
7656
77.7k
        new_group_color->icc_profile = NULL;
7657
7658
    /* isadditive is only used in ctx */
7659
125k
    if (pdev->ctx) {
7660
0
        new_group_color->isadditive = pdev->ctx->additive;
7661
0
    }
7662
7663
125k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7664
125k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7665
7666
125k
    if (group_color_type == ICC && new_profile == NULL)
7667
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7668
125k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7669
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7670
       are based upon the color space of the device.  We want to remain in the
7671
       color space defined by the color space of the soft mask or transparency
7672
       group as opposed to the device color space. Later, when we pop the softmask
7673
       we will collapse it to a single band and then compose with it to the device
7674
       color space (or the parent layer space).  In the case where we pop an
7675
       isolated transparency group, we will do the blending in the proper color
7676
       space and then transform the data when we pop the group.  Remember that only
7677
       isolated groups can have color spaces that are different than their parent. */
7678
125k
    update_color_info = false;
7679
125k
    switch (group_color_type) {
7680
0
    case GRAY_SCALE:
7681
0
        if (pdev->color_info.num_components != 1) {
7682
0
            update_color_info = true;
7683
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7684
0
            new_num_comps = 1;
7685
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7686
0
            new_additive = true;
7687
0
            new_14procs = &gray_pdf14_procs;
7688
0
            new_depth = 8 << deep;
7689
0
        }
7690
0
        break;
7691
0
    case DEVICE_RGB:
7692
0
    case CIE_XYZ:
7693
0
        if (pdev->color_info.num_components != 3) {
7694
0
            update_color_info = true;
7695
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7696
0
            new_num_comps = 3;
7697
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7698
0
            new_additive = true;
7699
0
            new_14procs = &rgb_pdf14_procs;
7700
0
            new_depth = 24 << deep;
7701
0
        }
7702
0
        break;
7703
0
    case DEVICE_CMYK:
7704
0
        if (pdev->color_info.num_components != 4) {
7705
0
            update_color_info = true;
7706
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7707
0
            new_num_comps = 4;
7708
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7709
0
            new_additive = false;
7710
            /* This is needed due to the mismatched compressed encode decode
7711
               between the device procs and the pdf14 procs */
7712
0
            if (dev->color_info.num_components > 4) {
7713
0
                new_14procs = &cmykspot_pdf14_procs;
7714
0
            }
7715
0
            else {
7716
0
                new_14procs = &cmyk_pdf14_procs;
7717
0
            }
7718
0
            new_depth = 32 << deep;
7719
0
        }
7720
0
        break;
7721
47.5k
    case ICC:
7722
        /* Check if the profile is different. */
7723
47.5k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7724
43.0k
            update_color_info = true;
7725
43.0k
            new_num_comps = new_profile->num_comps;
7726
43.0k
            new_depth = new_profile->num_comps * (8 << deep);
7727
43.0k
            switch (new_num_comps) {
7728
39.2k
            case 1:
7729
39.2k
                if (pdev->sep_device && !is_mask) {
7730
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7731
0
                    new_14procs = &grayspot_pdf14_procs;
7732
0
                }
7733
39.2k
                else {
7734
39.2k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7735
39.2k
                    new_14procs = &gray_pdf14_procs;
7736
39.2k
                }
7737
39.2k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7738
39.2k
                new_additive = true;
7739
39.2k
                break;
7740
2.66k
            case 3:
7741
2.66k
                if (pdev->sep_device) {
7742
743
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7743
743
                    new_14procs = &rgbspot_pdf14_procs;
7744
743
                }
7745
1.91k
                else {
7746
1.91k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7747
1.91k
                    new_14procs = &rgb_pdf14_procs;
7748
1.91k
                }
7749
2.66k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7750
2.66k
                new_additive = true;
7751
2.66k
                break;
7752
1.14k
            case 4:
7753
1.14k
                if (pdev->sep_device) {
7754
64
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7755
64
                    new_14procs = &cmykspot_pdf14_procs;
7756
64
                }
7757
1.08k
                else {
7758
1.08k
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7759
1.08k
                    new_14procs = &cmyk_pdf14_procs;
7760
1.08k
                }
7761
1.14k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7762
1.14k
                new_additive = false;
7763
1.14k
                break;
7764
0
            default:
7765
0
                return gs_throw(gs_error_undefinedresult,
7766
43.0k
                    "ICC Number of colorants illegal");
7767
43.0k
            }
7768
43.0k
        }
7769
47.5k
        break;
7770
77.7k
    case UNKNOWN:
7771
77.7k
        return 0;
7772
0
        break;
7773
0
    default:
7774
0
        return_error(gs_error_rangecheck);
7775
0
        break;
7776
125k
    }
7777
7778
47.5k
    if (!update_color_info) {
7779
        /* Profile not updated */
7780
4.50k
        new_group_color->icc_profile = NULL;
7781
4.50k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7782
4.50k
        return 0;
7783
4.50k
    }
7784
7785
43.0k
    if (has_tags) {
7786
0
        new_num_comps++;
7787
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7788
0
        if (pdev->num_planar_planes > 0)
7789
0
            new_depth += deep ? 16 : 8;
7790
0
        else
7791
0
            new_depth += 8;
7792
0
    }
7793
43.0k
    if (pdev->sep_device && !is_mask) {
7794
807
        int num_spots;
7795
7796
807
        if (old_profile == NULL)
7797
0
            return_error(gs_error_undefined);
7798
7799
807
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7800
7801
807
        if (num_spots > 0) {
7802
68
            new_num_comps += num_spots;
7803
68
            new_depth = (8 << deep) * new_num_comps;
7804
68
        }
7805
807
    }
7806
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7807
94.9k
    for (k = 0; k < new_num_comps; k++) {
7808
51.9k
        comp_bits[k] = 8 << deep;
7809
51.9k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7810
51.9k
    }
7811
43.0k
    if_debug2m('v', pdev->memory,
7812
43.0k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7813
43.0k
        pdev->color_info.num_components, new_num_comps);
7814
    /* Set new information in the device */
7815
43.0k
    {
7816
43.0k
        gx_device local_device;
7817
7818
43.0k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7819
43.0k
        local_device.initialize_device_procs((gx_device *)&local_device);
7820
43.0k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7821
43.0k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7822
43.0k
    }
7823
43.0k
    pdev->blend_procs = pdevproto->blend_procs;
7824
43.0k
    pdev->color_info.polarity = new_polarity;
7825
43.0k
    pdev->color_info.max_color = deep ? 65535 : 255;
7826
43.0k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7827
43.0k
    pdev->pdf14_procs = new_14procs;
7828
43.0k
    if (pdev->num_planar_planes > 0)
7829
6.39k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7830
43.0k
    pdev->color_info.num_components = new_num_comps;
7831
43.0k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7832
43.0k
    pdev->color_info.depth = new_depth;
7833
43.0k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7834
43.0k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7835
43.0k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7836
43.0k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7837
43.0k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7838
7839
    /* If we have a compressed color codec, and we are doing a soft mask
7840
       push operation then go ahead and update the color encode and
7841
       decode for the pdf14 device to not used compressed color
7842
       encoding while in the soft mask.  We will just check for gray
7843
       and compressed.  Note that we probably don't have_tags if we
7844
       are dealing with compressed color.  But is is possible so
7845
       we add it in to catch for future use. */
7846
43.0k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7847
43.0k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7848
43.0k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7849
43.0k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7850
43.0k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7851
43.0k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7852
    /* For the ICC profiles, we want to update the ICC profile for the
7853
       device.  We store the original in group_color.
7854
       That will be stored in the clist and restored during the reading phase. */
7855
43.0k
    if (group_color_type == ICC) {
7856
43.0k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7857
43.0k
        new_group_color->icc_profile =
7858
43.0k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7859
43.0k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7860
43.0k
    }
7861
43.0k
    if (pdev->ctx) {
7862
0
        pdev->ctx->additive = new_additive;
7863
0
    }
7864
43.0k
    return 1;  /* Lets us detect that we did do an update */
7865
43.0k
}
7866
7867
static int
7868
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7869
125k
{
7870
7871
125k
    pdf14_device *pdev = (pdf14_device *)dev;
7872
125k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7873
125k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7874
7875
125k
    if (group_color == NULL)
7876
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7877
7878
125k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7879
    /* The color procs are always pushed.  Simply restore them. */
7880
125k
    if (group_color->group_color_mapping_procs == NULL &&
7881
0
        group_color->group_color_comp_index == NULL) {
7882
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7883
125k
    } else {
7884
125k
        bool has_tags = device_encodes_tags(dev);
7885
125k
        if_debug2m('v', pdev->memory,
7886
125k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7887
125k
                   pdev->color_info.num_components,group_color->num_components);
7888
125k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7889
125k
        gx_set_cmap_procs(pgs, dev);
7890
125k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7891
125k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7892
125k
        pdev->color_info.polarity = group_color->polarity;
7893
125k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7894
125k
        pdev->color_info.depth = group_color->depth;
7895
125k
        if (pdev->num_planar_planes > 0)
7896
15.7k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7897
125k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7898
125k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7899
125k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7900
125k
        pdev->blend_procs = group_color->blend_procs;
7901
125k
        pdev->pdf14_procs = group_color->unpack_procs;
7902
125k
        pdev->color_info.max_color = group_color->max_color;
7903
125k
        pdev->color_info.max_gray = group_color->max_gray;
7904
125k
        set_dev_proc(pdev, encode_color, group_color->encode);
7905
125k
        set_dev_proc(pdev, decode_color, group_color->decode);
7906
125k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7907
125k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7908
125k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7909
125k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7910
7911
        /* clist writer fill rect has no access to gs_gstate */
7912
        /* and it forwards the target device.  this information */
7913
        /* is passed along to use in this case */
7914
125k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7915
125k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7916
125k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7917
125k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7918
125k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7919
125k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7920
125k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7921
125k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7922
125k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7923
125k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7924
125k
        if (pdev->ctx){
7925
0
            pdev->ctx->additive = group_color->isadditive;
7926
0
        }
7927
       /* The device profile must be restored. */
7928
125k
        if (group_color->icc_profile != NULL) {
7929
43.0k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7930
43.0k
                                    -1, "pdf14_clist_pop_color_model");
7931
43.0k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7932
43.0k
        }
7933
125k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7934
125k
    }
7935
125k
   pdf14_pop_group_color(dev, pgs);
7936
125k
    return 0;
7937
125k
}
7938
7939
/* When a transparency group is popped, the parent colorprocs must be restored.
7940
   Since the color mapping procs are all based upon the device, we must have a
7941
   nested list based upon the transparency group color space.  This nesting
7942
   must be outside the nested ctx structures to allow the nesting for the
7943
   clist writer */
7944
static void
7945
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7946
125k
{
7947
125k
    pdf14_device *pdev = (pdf14_device *)dev;
7948
125k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7949
7950
125k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7951
7952
    /* Update the link */
7953
125k
    pdev->color_model_stack = group_color->previous;
7954
7955
    /* Free the old one */
7956
125k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7957
125k
}
7958
7959
static  int
7960
pdf14_begin_transparency_mask(gx_device *dev,
7961
                              const gx_transparency_mask_params_t *ptmp,
7962
                              const gs_rect *pbbox,
7963
                              gs_gstate *pgs, gs_memory_t *mem)
7964
8.96M
{
7965
8.96M
    pdf14_device *pdev = (pdf14_device *)dev;
7966
8.96M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7967
8.96M
    byte *transfer_fn;
7968
8.96M
    gs_int_rect rect;
7969
8.96M
    int code;
7970
8.96M
    int group_color_numcomps;
7971
8.96M
    gs_transparency_color_t group_color_type;
7972
8.96M
    bool deep = device_is_deep(dev);
7973
8.96M
    pdf14_group_color_t* group_color_info;
7974
7975
8.96M
    code = pdf14_initialize_ctx(dev, pgs);
7976
8.96M
    if (code < 0)
7977
0
        return code;
7978
7979
8.96M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7980
7.93M
        pdf14_ctx *ctx = pdev->ctx;
7981
7982
        /* free up any maskbuf on the current tos */
7983
7.93M
        if (ctx->mask_stack) {
7984
1.37M
            if (ctx->mask_stack->rc_mask->mask_buf != NULL ) {
7985
671k
                pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf);
7986
671k
                ctx->mask_stack->rc_mask->mask_buf = NULL;
7987
671k
            }
7988
1.37M
        }
7989
7.93M
        return 0;
7990
7.93M
    }
7991
1.03M
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7992
1.03M
                                         "pdf14_begin_transparency_mask");
7993
1.03M
    if (transfer_fn == NULL)
7994
0
        return_error(gs_error_VMerror);
7995
1.03M
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7996
1.03M
    if (code < 0)
7997
0
        return code;
7998
    /* If we have background components the background alpha may be nonzero */
7999
1.03M
    if (ptmp->Background_components)
8000
342k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
8001
1.03M
    if_debug1m('v', dev->memory,
8002
1.03M
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
8003
1.03M
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
8004
   /* If the group color is unknown, then we must use the previous group color
8005
       space or the device process color space */
8006
1.03M
    if (ptmp->group_color_type == UNKNOWN){
8007
0
        if (pdev->ctx->stack){
8008
            /* Use previous group color space */
8009
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
8010
0
        } else {
8011
            /* Use process color space */
8012
0
            group_color_numcomps = pdev->color_info.num_components;
8013
0
        }
8014
0
        switch (group_color_numcomps) {
8015
0
            case 1:
8016
0
                group_color_type = GRAY_SCALE;
8017
0
                break;
8018
0
            case 3:
8019
0
                group_color_type = DEVICE_RGB;
8020
0
                break;
8021
0
            case 4:
8022
0
                group_color_type = DEVICE_CMYK;
8023
0
            break;
8024
0
            default:
8025
                /* We can end up here if we are in a deviceN color space and
8026
                   we have a sep output device */
8027
0
                group_color_type = DEVICEN;
8028
0
            break;
8029
0
         }
8030
1.03M
    } else {
8031
1.03M
        group_color_type = ptmp->group_color_type;
8032
1.03M
        group_color_numcomps = ptmp->group_color_numcomps;
8033
1.03M
    }
8034
8035
1.03M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
8036
1.03M
                                               ptmp->iccprofile, true);
8037
1.03M
    if (group_color_info == NULL)
8038
0
        return gs_error_VMerror;
8039
8040
    /* Note that the soft mask always follows the group color requirements even
8041
       when we have a separable device */
8042
1.03M
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
8043
1.03M
                                        transfer_fn, ptmp->function_is_identity,
8044
1.03M
                                        ptmp->idle, ptmp->replacing,
8045
1.03M
                                        ptmp->mask_id, ptmp->subtype,
8046
1.03M
                                        group_color_numcomps,
8047
1.03M
                                        ptmp->Background_components,
8048
1.03M
                                        ptmp->Background,
8049
1.03M
                                        ptmp->Matte_components,
8050
1.03M
                                        ptmp->Matte,
8051
1.03M
                                        ptmp->GrayBackground,
8052
1.03M
                                        group_color_info);
8053
1.03M
    if (code < 0)
8054
0
        return code;
8055
8056
1.03M
    return 0;
8057
1.03M
}
8058
8059
static  int
8060
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8061
1.03M
{
8062
1.03M
    pdf14_device *pdev = (pdf14_device *)dev;
8063
1.03M
    pdf14_group_color_t *group_color;
8064
1.03M
    int ok;
8065
1.03M
    bool has_tags = device_encodes_tags(dev);
8066
8067
1.03M
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8068
1.03M
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8069
#ifdef DEBUG
8070
    pdf14_debug_mask_stack_state(pdev->ctx);
8071
#endif
8072
8073
    /* May need to reset some color stuff related
8074
     * to a mismatch between the Smask color space
8075
     * and the Smask blending space */
8076
1.03M
    if (pdev->ctx->stack != NULL ) {
8077
1.03M
        group_color = pdev->ctx->stack->group_color_info;
8078
1.03M
        if (!(group_color->group_color_mapping_procs == NULL &&
8079
1.03M
            group_color->group_color_comp_index == NULL)) {
8080
1.03M
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8081
1.03M
            gx_set_cmap_procs(pgs, dev);
8082
1.03M
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8083
1.03M
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8084
1.03M
            pdev->color_info.polarity = group_color->polarity;
8085
1.03M
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8086
1.03M
            if (pdev->num_planar_planes > 0)
8087
64.6k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8088
1.03M
            pdev->color_info.num_components = group_color->num_components + has_tags;
8089
1.03M
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8090
1.03M
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8091
1.03M
            pdev->num_std_colorants = group_color->num_std_colorants;
8092
1.03M
            pdev->color_info.depth = group_color->depth;
8093
1.03M
            pdev->blend_procs = group_color->blend_procs;
8094
1.03M
            pdev->ctx->additive = group_color->isadditive;
8095
1.03M
            pdev->pdf14_procs = group_color->unpack_procs;
8096
1.03M
            pdev->color_info.max_color = group_color->max_color;
8097
1.03M
            pdev->color_info.max_gray = group_color->max_gray;
8098
1.03M
            set_dev_proc(pdev, encode_color, group_color->encode);
8099
1.03M
            set_dev_proc(pdev, decode_color, group_color->decode);
8100
1.03M
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8101
1.03M
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8102
1.03M
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8103
1.03M
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8104
            /* Take care of the ICC profile */
8105
1.03M
            if (group_color->icc_profile != NULL) {
8106
1.03M
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8107
1.03M
                                        -1, "pdf14_end_transparency_mask");
8108
1.03M
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8109
1.03M
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8110
1.03M
                                         1, "pdf14_end_transparency_mask");
8111
1.03M
            }
8112
1.03M
        }
8113
1.03M
    }
8114
1.03M
    return ok;
8115
1.03M
}
8116
8117
static  int
8118
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8119
                                 gx_color_index color,
8120
                                 const gx_device_color *pdc, bool devn)
8121
5.83M
{
8122
5.83M
    pdf14_device *pdev = (pdf14_device *)dev;
8123
5.83M
    pdf14_buf *buf = pdev->ctx->stack;
8124
5.83M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8125
5.83M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8126
242k
        blend_mode == BLEND_MODE_Compatible ||
8127
242k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8128
5.83M
    int i, j, k;
8129
5.83M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8130
5.83M
    byte src[PDF14_MAX_PLANES];
8131
5.83M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8132
5.83M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8133
5.83M
    intptr_t rowstride = buf->rowstride;
8134
5.83M
    intptr_t planestride = buf->planestride;
8135
5.83M
    int num_chan = buf->n_chan;
8136
5.83M
    int num_comp = num_chan - 1;
8137
5.83M
    intptr_t shape_off = num_chan * planestride;
8138
5.83M
    bool has_shape = buf->has_shape;
8139
5.83M
    bool has_alpha_g = buf->has_alpha_g;
8140
5.83M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8141
5.83M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8142
5.83M
                                   (has_shape ? planestride : 0);
8143
5.83M
    bool has_tags = buf->has_tags;
8144
5.83M
    bool additive = pdev->ctx->additive;
8145
5.83M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8146
5.83M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8147
5.83M
    int shift = 8;
8148
5.83M
    byte shape = 0; /* Quiet compiler. */
8149
5.83M
    byte src_alpha;
8150
5.83M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8151
5.83M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8152
5.31M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8153
5.83M
    gx_color_index comps;
8154
5.83M
    bool has_backdrop = buf->backdrop != NULL;
8155
8156
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8157
       subtractive) and we are doing overprint with drawn_comps == 0
8158
       then this is a no-operation */
8159
5.83M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8160
0
        return 0;
8161
8162
5.83M
    if (buf->data == NULL)
8163
2
        return 0;
8164
#if 0
8165
    if (sizeof(color) <= sizeof(ulong))
8166
        if_debug6m('v', dev->memory,
8167
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8168
                   x, y, w, h, (ulong)color, num_chan);
8169
    else
8170
        if_debug7m('v', dev->memory,
8171
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8172
                   x, y, w, h,
8173
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8174
                   num_chan);
8175
#endif
8176
    /*
8177
     * Unpack the gx_color_index values.  Complement the components for subtractive
8178
     * color spaces.
8179
     */
8180
5.83M
    if (devn) {
8181
701k
        if (has_tags) {
8182
0
            curr_tag = pdc->tag;
8183
0
        }
8184
701k
        if (additive) {
8185
1.81M
            for (j = 0; j < num_comp; j++) {
8186
1.36M
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8187
1.36M
            }
8188
454k
        } else {
8189
1.23M
            for (j = 0; j < num_comp; j++) {
8190
984k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8191
984k
            }
8192
246k
        }
8193
5.13M
    } else {
8194
5.13M
        if (has_tags) {
8195
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8196
0
        }
8197
5.13M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8198
5.13M
    }
8199
8200
5.83M
    if (!has_tags)
8201
5.83M
        tag_off = 0;
8202
8203
5.83M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8204
5.83M
    if (has_shape) {
8205
6.61k
        shape = (byte)floor (255 * pdev->shape + 0.5);
8206
5.82M
    } else {
8207
5.82M
        shape_off = 0;
8208
5.82M
    }
8209
8210
5.83M
    if (!has_alpha_g)
8211
0
        alpha_g_off = 0;
8212
5.83M
    src_alpha = 255 - src_alpha;
8213
5.83M
    shape = 255 - shape;
8214
8215
    /* Fit the mark into the bounds of the buffer */
8216
5.83M
    if (x < buf->rect.p.x) {
8217
0
        w += x - buf->rect.p.x;
8218
0
        x = buf->rect.p.x;
8219
0
    }
8220
5.83M
    if (y < buf->rect.p.y) {
8221
9
      h += y - buf->rect.p.y;
8222
9
      y = buf->rect.p.y;
8223
9
    }
8224
5.83M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8225
5.83M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8226
    /* Update the dirty rectangle with the mark. */
8227
5.83M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8228
5.83M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8229
5.83M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8230
5.83M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8231
8232
    /* composite with backdrop only. */
8233
5.83M
    if (has_backdrop)
8234
5.83M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8235
0
    else
8236
0
        bline = NULL;
8237
8238
5.83M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8239
8240
12.2M
    for (j = 0; j < h; ++j) {
8241
6.38M
        bg_ptr = bline;
8242
6.38M
        dst_ptr = line;
8243
264M
        for (i = 0; i < w; ++i) {
8244
            /* Complement the components for subtractive color spaces */
8245
257M
            if (has_backdrop) {
8246
257M
                if (additive) {
8247
954M
                    for (k = 0; k < num_comp; ++k)
8248
705M
                        dst[k] = bg_ptr[k * planestride];
8249
249M
                } else {
8250
40.9M
                    for (k = 0; k < num_comp; ++k)
8251
32.7M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8252
8.18M
                }
8253
257M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8254
257M
            }
8255
257M
            if (buf->isolated || !has_backdrop) {
8256
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8257
257M
            } else {
8258
257M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8259
257M
                                            blend_mode, pdev->blend_procs, pdev);
8260
257M
            }
8261
            /* Complement the results for subtractive color spaces */
8262
257M
            if (additive) {
8263
249M
                if (!overprint) {
8264
1.20G
                    for (k = 0; k < num_chan; ++k)
8265
954M
                        dst_ptr[k * planestride] = dst[k];
8266
249M
                } else {
8267
                    /* Hybrid additive with subtractive spots */
8268
                    /* We may have to do the compatible overprint blending */
8269
73.5k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8270
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8271
0
                            blend_mode, pdev->blend_procs, pdev);
8272
0
                    }
8273
294k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8274
220k
                        if ((comps & 0x1) != 0) {
8275
220k
                            dst_ptr[k * planestride] = dst[k];
8276
220k
                        } else {
8277
                            /* Compatible overprint blend result. */
8278
0
                            dst_ptr[k * planestride] = dst2[k];
8279
0
                        }
8280
220k
                    }
8281
73.5k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8282
73.5k
                }
8283
249M
            } else {
8284
8.18M
                if (overprint) {
8285
                    /* We may have to do the compatible overprint blending */
8286
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8287
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8288
0
                            blend_mode, pdev->blend_procs, pdev);
8289
0
                    }
8290
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8291
0
                        if ((comps & 0x1) != 0) {
8292
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8293
0
                        } else {
8294
                            /* Compatible overprint blend result. */
8295
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8296
0
                        }
8297
0
                    }
8298
8.18M
                } else {
8299
40.9M
                    for (k = 0; k < num_comp; ++k)
8300
32.7M
                        dst_ptr[k * planestride] = 255 - dst[k];
8301
8.18M
                }
8302
8.18M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8303
8.18M
            }
8304
257M
            if (tag_off) {
8305
                /* If src alpha is 100% then set to curr_tag, else or */
8306
                /* other than Normal BM, we always OR */
8307
0
                if (src[num_comp] == 255 && tag_blend) {
8308
0
                    dst_ptr[tag_off] = curr_tag;
8309
0
                } else {
8310
0
                    dst_ptr[tag_off] |= curr_tag;
8311
0
                }
8312
0
            }
8313
            /* Knockout group alpha and shape too */
8314
257M
            if (alpha_g_off)
8315
257M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8316
257M
            if (shape_off)
8317
6.93k
                dst_ptr[shape_off] = 255 - shape;
8318
257M
            ++dst_ptr;
8319
257M
            if (has_backdrop)
8320
257M
                ++bg_ptr;
8321
257M
        }
8322
6.38M
        bline += rowstride;
8323
6.38M
        line += rowstride;
8324
6.38M
    }
8325
#if 0
8326
/* #if RAW_DUMP */
8327
    /* Dump the current buffer to see what we have. */
8328
    dump_raw_buffer(pdev->ctx->memory,
8329
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8330
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8331
                    pdev->ctx->stack->n_planes,
8332
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8333
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8334
                    pdev->ctx->stack->deep);
8335
    global_index++;
8336
#endif
8337
5.83M
    return 0;
8338
5.83M
}
8339
8340
static  int
8341
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8342
                                   gx_color_index color,
8343
                                   const gx_device_color *pdc, bool devn)
8344
0
{
8345
0
    pdf14_device *pdev = (pdf14_device *)dev;
8346
0
    pdf14_buf *buf = pdev->ctx->stack;
8347
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8348
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8349
0
        blend_mode == BLEND_MODE_Compatible ||
8350
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8351
0
    int i, j, k;
8352
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8353
0
    uint16_t src[PDF14_MAX_PLANES];
8354
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8355
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8356
0
    intptr_t rowstride = buf->rowstride;
8357
0
    intptr_t planestride = buf->planestride;
8358
0
    int num_chan = buf->n_chan;
8359
0
    int num_comp = num_chan - 1;
8360
0
    intptr_t shape_off = num_chan * planestride;
8361
0
    bool has_shape = buf->has_shape;
8362
0
    bool has_alpha_g = buf->has_alpha_g;
8363
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8364
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8365
0
                                   (has_shape ? planestride : 0);
8366
0
    bool has_tags = buf->has_tags;
8367
0
    bool additive = pdev->ctx->additive;
8368
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8369
0
    uint16_t shape = 0; /* Quiet compiler. */
8370
0
    uint16_t src_alpha;
8371
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8372
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8373
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8374
0
    gx_color_index comps;
8375
0
    bool has_backdrop = buf->backdrop != NULL;
8376
8377
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8378
       subtractive) and we are doing overprint with drawn_comps == 0
8379
       then this is a no-operation */
8380
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8381
0
        return 0;
8382
8383
0
    if (buf->data == NULL)
8384
0
        return 0;
8385
#if 0
8386
    if (sizeof(color) <= sizeof(ulong))
8387
        if_debug6m('v', dev->memory,
8388
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8389
                   x, y, w, h, (ulong)color, num_chan);
8390
    else
8391
        if_debug7m('v', dev->memory,
8392
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8393
                   x, y, w, h,
8394
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8395
                   num_chan);
8396
#endif
8397
    /*
8398
     * Unpack the gx_color_index values.  Complement the components for subtractive
8399
     * color spaces.
8400
     */
8401
0
    if (devn) {
8402
0
        if (has_tags) {
8403
0
            curr_tag = pdc->tag;
8404
0
        }
8405
0
        if (additive) {
8406
0
            for (j = 0; j < num_comp; j++) {
8407
0
                src[j] = pdc->colors.devn.values[j];
8408
0
            }
8409
0
        } else {
8410
0
            for (j = 0; j < num_comp; j++) {
8411
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8412
0
            }
8413
0
        }
8414
0
    } else {
8415
0
        if (has_tags) {
8416
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8417
0
        }
8418
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8419
0
    }
8420
8421
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8422
0
    if (has_shape) {
8423
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8424
0
    } else {
8425
0
        shape_off = 0;
8426
0
    }
8427
8428
0
    if (!has_tags) {
8429
0
        tag_off = 0;
8430
0
    }
8431
8432
0
    if (!has_alpha_g)
8433
0
        alpha_g_off = 0;
8434
0
    src_alpha = 65535 - src_alpha;
8435
0
    shape = 65535 - shape;
8436
8437
    /* Fit the mark into the bounds of the buffer */
8438
0
    if (x < buf->rect.p.x) {
8439
0
        w += x - buf->rect.p.x;
8440
0
        x = buf->rect.p.x;
8441
0
    }
8442
0
    if (y < buf->rect.p.y) {
8443
0
      h += y - buf->rect.p.y;
8444
0
      y = buf->rect.p.y;
8445
0
    }
8446
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8447
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8448
    /* Update the dirty rectangle with the mark. */
8449
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8450
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8451
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8452
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8453
8454
8455
    /* composite with backdrop only. */
8456
0
    if (has_backdrop)
8457
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8458
0
    else
8459
0
        bline = NULL;
8460
8461
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8462
0
    planestride >>= 1;
8463
0
    rowstride >>= 1;
8464
0
    alpha_g_off >>= 1;
8465
0
    shape_off >>= 1;
8466
0
    tag_off >>= 1;
8467
8468
0
    for (j = 0; j < h; ++j) {
8469
0
        bg_ptr = bline;
8470
0
        dst_ptr = line;
8471
0
        for (i = 0; i < w; ++i) {
8472
            /* Complement the components for subtractive color spaces */
8473
0
            if (has_backdrop) {
8474
0
                if (additive) {
8475
0
                    for (k = 0; k < num_comp; ++k)
8476
0
                        dst[k] = bg_ptr[k * planestride];
8477
0
                } else {
8478
0
                    for (k = 0; k < num_comp; ++k)
8479
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8480
0
                }
8481
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8482
0
            }
8483
0
            if (buf->isolated || !has_backdrop) {
8484
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8485
0
            } else {
8486
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8487
0
                                              blend_mode, pdev->blend_procs, pdev);
8488
0
            }
8489
            /* Complement the results for subtractive color spaces */
8490
0
            if (additive) {
8491
0
                if (!overprint) {
8492
0
                    for (k = 0; k < num_chan; ++k)
8493
0
                        dst_ptr[k * planestride] = dst[k];
8494
0
                } else {
8495
                    /* Hybrid additive with subtractive spots */
8496
                    /* We may have to do the compatible overprint blending */
8497
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8498
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8499
0
                            blend_mode, pdev->blend_procs, pdev);
8500
0
                    }
8501
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8502
0
                        if ((comps & 0x1) != 0) {
8503
0
                            dst_ptr[k * planestride] = dst[k];
8504
0
                        } else {
8505
                            /* Compatible overprint blend result. */
8506
0
                            dst_ptr[k * planestride] = dst2[k];
8507
0
                        }
8508
0
                    }
8509
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8510
0
                }
8511
0
            } else {
8512
0
                if (overprint) {
8513
                    /* We may have to do the compatible overprint blending */
8514
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8515
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8516
0
                            blend_mode, pdev->blend_procs, pdev);
8517
0
                    }
8518
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8519
0
                        if ((comps & 0x1) != 0) {
8520
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8521
0
                        } else {
8522
                            /* Compatible overprint blend result. */
8523
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8524
0
                        }
8525
0
                    }
8526
0
                } else {
8527
0
                    for (k = 0; k < num_comp; ++k)
8528
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8529
0
                }
8530
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8531
0
            }
8532
0
            if (tag_off) {
8533
                /* FIXME: As we are knocking out, possibly, we should be
8534
                 * always overwriting tag values here? */
8535
                /* If src alpha is 100% then set to curr_tag, else or */
8536
                /* other than Normal BM, we always OR */
8537
0
                if (src[num_comp] == 65535 && tag_blend) {
8538
0
                    dst_ptr[tag_off] = curr_tag;
8539
0
                } else {
8540
0
                    dst_ptr[tag_off] |= curr_tag;
8541
0
                }
8542
0
            }
8543
            /* Knockout group alpha and shape too */
8544
0
            if (alpha_g_off)
8545
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8546
0
            if (shape_off)
8547
0
                dst_ptr[shape_off] = 65535 - shape;
8548
0
            ++dst_ptr;
8549
0
            if (has_backdrop)
8550
0
                ++bg_ptr;
8551
0
        }
8552
0
        bline += rowstride;
8553
0
        line += rowstride;
8554
0
    }
8555
#if 0
8556
/* #if RAW_DUMP */
8557
    /* Dump the current buffer to see what we have. */
8558
    dump_raw_buffer(pdev->ctx->memory,
8559
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8560
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8561
                    pdev->ctx->stack->n_planes,
8562
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8563
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8564
                    pdev->ctx->stack->deep);
8565
    global_index++;
8566
#endif
8567
0
    return 0;
8568
0
}
8569
8570
static  int
8571
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8572
                                    gx_color_index color,
8573
                                    const gx_device_color *pdc, bool devn)
8574
5.83M
{
8575
5.83M
    pdf14_device *pdev = (pdf14_device *)dev;
8576
5.83M
    pdf14_buf *buf = pdev->ctx->stack;
8577
8578
5.83M
    if (buf->deep)
8579
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8580
5.83M
    else
8581
5.83M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8582
5.83M
}
8583
8584
/**
8585
 * Here we have logic to override the cmap_procs with versions that
8586
 * do not apply the transfer function. These copies should track the
8587
 * versions in gxcmap.c.
8588
 **/
8589
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8590
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8591
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8592
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8593
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8594
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8595
8596
static  const gx_color_map_procs pdf14_cmap_many = {
8597
     pdf14_cmap_gray_direct,
8598
     pdf14_cmap_rgb_direct,
8599
     pdf14_cmap_cmyk_direct,
8600
     pdf14_cmap_separation_direct,
8601
     pdf14_cmap_devicen_direct,
8602
     pdf14_cmap_is_halftoned
8603
    };
8604
8605
/**
8606
 * Note: copied from gxcmap.c because it's inlined.
8607
 **/
8608
static  inline void
8609
map_components_to_colorants(const frac * pcc,
8610
                            const gs_devicen_color_map * pcolor_component_map,
8611
                            frac * plist,
8612
                            int num_additives)
8613
4.47M
{
8614
4.47M
    int i = pcolor_component_map->num_colorants - 1;
8615
4.47M
    int pos;
8616
8617
    /* Clear all output colorants first */
8618
22.3M
    for (; i >= num_additives; i--) {
8619
17.8M
        plist[i] = frac_0;
8620
17.8M
    }
8621
4.48M
    for (; i >= 0; i--) {
8622
8.71k
        plist[i] = frac_1;
8623
8.71k
    }
8624
    /* Map color components into output list */
8625
9.49M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8626
5.01M
        pos = pcolor_component_map->color_map[i];
8627
5.01M
        if (pos >= 0) {
8628
5.01M
            if (pos < num_additives)
8629
0
                plist[pos] = frac_1 - pcc[i];
8630
5.01M
            else
8631
5.01M
                plist[pos] = pcc[i];
8632
5.01M
        }
8633
5.01M
    }
8634
4.47M
}
8635
8636
/* See Section 7.6.4 of PDF 1.7 spec */
8637
static inline bool
8638
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8639
494M
{
8640
494M
    if (pgs->fillconstantalpha != 1.0 ||
8641
493M
        pgs->strokeconstantalpha != 1.0 ||
8642
493M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8643
22.3M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8644
23.5M
        return 0;
8645
8646
    /* We can only be opaque if we're not in an SMask. */
8647
470M
    return dev_proc(pdev, dev_spec_op)(pdev,
8648
470M
                                       gxdso_in_smask,
8649
470M
                                       NULL, 0) != 1;
8650
494M
}
8651
8652
static  void
8653
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8654
                       gx_device * dev, gs_color_select_t select)
8655
18.8M
{
8656
18.8M
    int i, nc, ncomps;
8657
18.8M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8658
18.8M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8659
18.8M
    gx_color_index color;
8660
18.8M
    gx_device *trans_device;
8661
18.8M
    const gx_device *map_dev;
8662
18.8M
    const gx_cm_color_map_procs *procs;
8663
8664
    /* If trans device is set, we need to use its procs. */
8665
18.8M
    if (pgs->trans_device != NULL) {
8666
4.35M
        trans_device = pgs->trans_device;
8667
14.5M
    } else {
8668
14.5M
        trans_device = dev;
8669
14.5M
    }
8670
18.8M
    ncomps = trans_device->color_info.num_components;
8671
8672
    /* map to the color model */
8673
18.8M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8674
18.8M
    procs->map_gray(map_dev, gray, cm_comps);
8675
8676
18.8M
    nc = ncomps;
8677
18.8M
    if (device_encodes_tags(trans_device))
8678
0
        nc--;
8679
18.8M
    if (pdf14_state_opaque(trans_device, pgs)) {
8680
9.82M
        for (i = 0; i < nc; i++)
8681
4.91M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8682
13.9M
    } else {
8683
27.9M
        for (i = 0; i < nc; i++)
8684
13.9M
            cv[i] = frac2cv(cm_comps[i]);
8685
13.9M
    }
8686
    /* Copy tags untransformed. */
8687
18.8M
    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 Gray + spots as devn colors */
8692
18.8M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8693
1.71M
        for (i = 0; i < ncomps; i++)
8694
858k
            pdc->colors.devn.values[i] = cv[i];
8695
54.9M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8696
54.1M
            pdc->colors.devn.values[i] = 0;
8697
858k
        pdc->type = gx_dc_type_devn;
8698
18.0M
    } else {
8699
        /* encode as a color index */
8700
18.0M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8701
        /* check if the encoding was successful; we presume failure is rare */
8702
18.0M
        if (color != gx_no_color_index)
8703
18.0M
            color_set_pure(pdc, color);
8704
18.0M
    }
8705
18.8M
}
8706
8707
static  void
8708
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8709
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8710
442M
{
8711
442M
    int i, nc, ncomps;
8712
442M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8713
442M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8714
442M
    gx_color_index color;
8715
442M
    gx_device *trans_device;
8716
442M
    const gx_device *map_dev;
8717
442M
    const gx_cm_color_map_procs *procs;
8718
8719
    /* If trans device is set, we need to use its procs. */
8720
442M
    if (pgs->trans_device != NULL){
8721
1.98M
        trans_device = pgs->trans_device;
8722
440M
    } else {
8723
440M
        trans_device = dev;
8724
440M
    }
8725
442M
    ncomps = trans_device->color_info.num_components;
8726
    /* map to the color model */
8727
442M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8728
442M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8729
8730
442M
    nc = ncomps;
8731
442M
    if (device_encodes_tags(trans_device))
8732
0
        nc--;
8733
442M
    if (pdf14_state_opaque(trans_device, pgs)) {
8734
907M
        for (i = 0; i < nc; i++)
8735
680M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8736
226M
    } else {
8737
860M
        for (i = 0; i < nc; i++)
8738
645M
            cv[i] = frac2cv(cm_comps[i]);
8739
215M
    }
8740
    /* Copy tags untransformed. */
8741
442M
    if (nc < ncomps)
8742
0
        cv[nc] = dev->graphics_type_tag;
8743
8744
    /* If output device supports devn, we need to make sure we send it the
8745
       proper color type.  We now support RGB + spots as devn colors */
8746
442M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8747
64.1M
        for (i = 0; i < ncomps; i++)
8748
48.1M
            pdc->colors.devn.values[i] = cv[i];
8749
994M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8750
978M
            pdc->colors.devn.values[i] = 0;
8751
16.0M
        pdc->type = gx_dc_type_devn;
8752
426M
    } else {
8753
        /* encode as a color index */
8754
426M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8755
        /* check if the encoding was successful; we presume failure is rare */
8756
426M
        if (color != gx_no_color_index)
8757
426M
            color_set_pure(pdc, color);
8758
426M
    }
8759
442M
}
8760
8761
static  void
8762
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8763
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8764
     const gs_color_space *pcs)
8765
33.5M
{
8766
33.5M
    int i, nc, ncomps;
8767
33.5M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8768
33.5M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8769
33.5M
    gx_color_index color;
8770
33.5M
    gx_device *trans_device;
8771
33.5M
    const gx_device *map_dev;
8772
33.5M
    const gx_cm_color_map_procs *procs;
8773
8774
8775
    /* If trans device is set, we need to use its procs. */
8776
33.5M
    if (pgs->trans_device != NULL){
8777
27.6M
        trans_device = pgs->trans_device;
8778
27.6M
    } else {
8779
5.85M
        trans_device = dev;
8780
5.85M
    }
8781
33.5M
    ncomps = trans_device->color_info.num_components;
8782
8783
    /* Map to the color model. Transfer function is only used
8784
       if we are drawing with an opaque color. */
8785
33.5M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8786
33.5M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8787
8788
33.5M
    nc = ncomps;
8789
33.5M
    if (device_encodes_tags(trans_device))
8790
0
        nc--;
8791
33.5M
    if (pdf14_state_opaque(trans_device, pgs)) {
8792
150M
        for (i = 0; i < nc; i++)
8793
120M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8794
30.1M
    } else {
8795
16.6M
        for (i = 0; i < nc; i++)
8796
13.2M
            cv[i] = frac2cv(cm_comps[i]);
8797
3.32M
    }
8798
    /* Copy tags untransformed. */
8799
33.5M
    if (nc < ncomps)
8800
0
        cv[nc] = dev->graphics_type_tag;
8801
8802
    /* if output device supports devn, we need to make sure we send it the
8803
       proper color type */
8804
33.5M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8805
48.1M
        for (i = 0; i < ncomps; i++)
8806
38.5M
            pdc->colors.devn.values[i] = cv[i];
8807
588M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8808
578M
            pdc->colors.devn.values[i] = 0;
8809
9.64M
        pdc->type = gx_dc_type_devn;
8810
23.8M
    } else {
8811
        /* encode as a color index */
8812
23.8M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8813
        /* check if the encoding was successful; we presume failure is rare */
8814
23.8M
        if (color != gx_no_color_index)
8815
23.8M
            color_set_pure(pdc, color);
8816
23.8M
    }
8817
33.5M
}
8818
8819
static int
8820
pdf14_get_num_spots(gx_device * dev)
8821
4.47M
{
8822
4.47M
    cmm_dev_profile_t *dev_profile;
8823
4.47M
    cmm_profile_t *icc_profile;
8824
4.47M
    gsicc_rendering_param_t render_cond;
8825
8826
4.47M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8827
4.47M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8828
4.47M
        &render_cond);
8829
4.47M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8830
4.47M
}
8831
8832
static  void
8833
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8834
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8835
114k
{
8836
114k
    int i, nc, ncomps = dev->color_info.num_components;
8837
114k
    int num_spots = pdf14_get_num_spots(dev);
8838
114k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8839
114k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8840
114k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8841
114k
    gx_color_index color;
8842
114k
    int n = 0;
8843
8844
114k
    nc = ncomps;
8845
114k
    if (device_encodes_tags(dev))
8846
0
        nc--;
8847
8848
114k
    n = additive ? nc - num_spots : 0;
8849
114k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8850
0
        frac comp_value = all;
8851
8852
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8853
0
            cm_comps[i] = comp_value;
8854
        /*
8855
         * Invert the photometric interpretation for additive
8856
         * color spaces because separations are always subtractive.
8857
         */
8858
0
        if (additive)
8859
0
            comp_value = frac_1 - comp_value;
8860
        /* Use the "all" value for all components */
8861
0
        for (; i >= 0; i--)
8862
0
            cm_comps[i] = comp_value;
8863
114k
    } else {
8864
114k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8865
8866
114k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8867
0
            color_set_null(pdc);
8868
0
            return;
8869
0
        }
8870
8871
        /* map to the color model */
8872
229k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8873
114k
            comp_value[i] = all;
8874
114k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8875
114k
    }
8876
8877
    /* apply the transfer function(s); convert to color values */
8878
123k
    for (i = 0; i < n; i++)
8879
114k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8880
564k
    for (; i < nc; i++)
8881
449k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8882
8883
    /* Copy tags untransformed. */
8884
114k
    if (nc < ncomps)
8885
0
        cv[nc] = dev->graphics_type_tag;
8886
8887
    /* if output device supports devn, we need to make sure we send it the
8888
       proper color type */
8889
114k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8890
573k
        for (i = 0; i < ncomps; i++)
8891
458k
            pdc->colors.devn.values[i] = cv[i];
8892
6.99M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8893
6.87M
            pdc->colors.devn.values[i] = 0;
8894
114k
        pdc->type = gx_dc_type_devn;
8895
114k
    } else {
8896
        /* encode as a color index */
8897
0
        color = dev_proc(dev, encode_color)(dev, cv);
8898
        /* check if the encoding was successful; we presume failure is rare */
8899
0
        if (color != gx_no_color_index)
8900
0
            color_set_pure(pdc, color);
8901
0
    }
8902
114k
}
8903
8904
static  void
8905
pdf14_cmap_devicen_direct(const frac * pcc,
8906
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8907
    gs_color_select_t select, const gs_color_space *pcs)
8908
4.35M
{
8909
4.35M
    int i, nc, ncomps = dev->color_info.num_components;
8910
4.35M
    int num_spots = pdf14_get_num_spots(dev);
8911
4.35M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8912
4.35M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8913
4.35M
    gx_color_index color;
8914
4.35M
    gx_device *trans_device;
8915
4.35M
    int num_add_colorants = 0;
8916
8917
     /*  We may be coming from the clist writer which often forwards us the
8918
         target device. If this occurs we actually need to get to the color
8919
         space defined by the transparency group and we use the operators
8920
         defined by the transparency device to do the job.
8921
       */
8922
4.35M
    if (pgs->trans_device != NULL){
8923
4.35M
        trans_device = pgs->trans_device;
8924
4.35M
    } else {
8925
0
        trans_device = dev;
8926
0
    }
8927
4.35M
    ncomps = trans_device->color_info.num_components;
8928
4.35M
    nc = ncomps;
8929
4.35M
    if (device_encodes_tags(trans_device))
8930
0
        nc--;
8931
8932
4.35M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8933
0
        num_add_colorants = nc - num_spots;
8934
8935
    /* map to the color model */
8936
4.35M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8937
8938
    /* apply the transfer function(s); convert to color values */
8939
    /* The additive ones (if there are any) need to be inverted. */
8940
4.35M
    for (i = 0; i < num_add_colorants; i++)
8941
4.35M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8942
21.7M
    for (; i < nc; i++)
8943
17.4M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8944
    /* Copy tags untransformed. */
8945
4.35M
    if (nc < ncomps)
8946
0
        cv[nc] = dev->graphics_type_tag;
8947
8948
    /* if output device supports devn, we need to make sure we send it the
8949
       proper color type */
8950
4.35M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8951
4.69M
        for (i = 0; i < ncomps; i++)
8952
3.75M
            pdc->colors.devn.values[i] = cv[i];
8953
57.2M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8954
56.3M
            pdc->colors.devn.values[i] = 0;
8955
938k
        pdc->type = gx_dc_type_devn;
8956
3.42M
    } else {
8957
    /* encode as a color index */
8958
3.42M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8959
        /* check if the encoding was successful; we presume failure is rare */
8960
3.42M
        if (color != gx_no_color_index)
8961
3.42M
            color_set_pure(pdc, color);
8962
3.42M
    }
8963
4.35M
}
8964
8965
static  bool
8966
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8967
468k
{
8968
468k
    return false;
8969
468k
}
8970
8971
static  const gx_color_map_procs *
8972
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8973
3.74M
{
8974
    /* The pdf14 marking device itself is always continuous tone. */
8975
3.74M
    return &pdf14_cmap_many;
8976
3.74M
}
8977
8978
static int
8979
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8980
                  void *data, int size)
8981
1.12G
{
8982
1.12G
    pdf14_device * p14dev = (pdf14_device *)pdev;
8983
8984
1.12G
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8985
2.26M
        return 1;
8986
1.12G
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8987
77.2k
        return 1;
8988
1.12G
    if (dev_spec_op == gxdso_is_pdf14_device) {
8989
1.80k
        if (data != NULL && size == sizeof(gx_device *))
8990
918
            *(gx_device **)data = pdev;
8991
1.80k
        return 1;
8992
1.80k
    }
8993
1.12G
    if (dev_spec_op == gxdso_device_child) {
8994
5.20k
        pdf14_device *dev = (pdf14_device *)pdev;
8995
5.20k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8996
5.20k
        if (d->target == pdev) {
8997
5.20k
            d->target = dev->target;
8998
5.20k
            return 1;
8999
5.20k
        }
9000
5.20k
    }
9001
1.12G
    if (dev_spec_op == gxdso_supports_devn
9002
593M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
9003
593M
        cmm_dev_profile_t *dev_profile;
9004
593M
        int code;
9005
593M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
9006
593M
        if (code == 0) {
9007
593M
            return dev_profile->supports_devn;
9008
593M
        } else {
9009
0
            return 0;
9010
0
        }
9011
593M
    }
9012
529M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
9013
674k
        pdf14_device* dev = (pdf14_device*)pdev;
9014
9015
674k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
9016
674k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
9017
218k
            return 1;
9018
455k
        return 0;
9019
674k
    }
9020
529M
    if (dev_spec_op == gxdso_is_encoding_direct)
9021
940k
        return 1;
9022
9023
    /* We don't want to pass on these spec_ops either, because the child might respond
9024
     * with an inappropriate response when the PDF14 device is active. For example; the
9025
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
9026
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
9027
     */
9028
528M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
9029
856k
        return 0;
9030
527M
    if (dev_spec_op == gxdso_copy_color_is_fast)
9031
499k
        return 0;
9032
526M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
9033
76.4k
        return 0;
9034
526M
    if(dev_spec_op == gxdso_supports_hlcolor)
9035
2.17k
        return 0;
9036
526M
    if(dev_spec_op == gxdso_pattern_can_accum)
9037
200k
        return 0;
9038
526M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
9039
3.96k
        return 0;
9040
526M
    if (dev_spec_op == gxdso_overprint_active) {
9041
8.69M
        if (p14dev->pclist_device != NULL) {
9042
8.66M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
9043
8.66M
        } else {
9044
37.6k
            return p14dev->overprint || p14dev->stroke_overprint;
9045
37.6k
        }
9046
8.69M
    }
9047
9048
    /* These should be coming only from the abuf device
9049
       during fill-stroke operation. Any other use will
9050
       result in bad things. */
9051
517M
    if (dev_spec_op == gxdso_abuf_optrans)
9052
0
    {
9053
0
        int ret = p14dev->op_state;
9054
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
9055
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
9056
0
        const gs_gstate* cpgs = state_data->pgs;
9057
0
        union {
9058
0
            const gs_gstate* cpgs;
9059
0
            gs_gstate* pgs;
9060
0
        } const_breaker;
9061
0
        gs_gstate* pgs;
9062
0
        int code = 0;
9063
0
        int code1 = 0;
9064
9065
        /* A compile time assert to check our storage types are appropriately sized. */
9066
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9067
9068
        /* I don't really like this, but there is no easy way around it. The device
9069
           in the pgs needs to be the pdf14 device to ensure that the compositor
9070
           actions occur with the gs_transparency calls. We have to call at that
9071
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9072
           operations are invoked. We could change the gs_trans calls to take a
9073
           device to avoid this dance but that changes the device procs. */
9074
0
        gx_device *curr_dev;
9075
9076
0
        const_breaker.cpgs = cpgs;
9077
0
        pgs = const_breaker.pgs;
9078
0
        curr_dev = pgs->device;
9079
0
        pgs->device = pdev;
9080
9081
0
        switch (state_data->op_trans) {
9082
9083
0
            case OP_FS_TRANS_PREFILL:
9084
0
                pdf14_abuf->orig_state = p14dev->op_state;
9085
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9086
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9087
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9088
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9089
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9090
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9091
0
                    pdf14_abuf->group_needed = false;
9092
0
                else
9093
0
                    pdf14_abuf->group_needed = true;
9094
9095
0
                if (pdf14_abuf->group_needed) {
9096
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9097
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9098
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9099
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9100
0
                        state_data->alpha_buf_path_scale);
9101
0
                    if (code < 0)
9102
0
                        goto cleanup;
9103
0
                }
9104
0
                code = gs_update_trans_marking_params(pgs);
9105
0
                break;
9106
9107
0
            case OP_FS_TRANS_PRESTROKE:
9108
0
                if (pdf14_abuf->group_needed) {
9109
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9110
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9111
0
                }
9112
0
                code = gs_update_trans_marking_params(pgs);
9113
0
                break;
9114
9115
0
            case OP_FS_TRANS_POSTSTROKE:
9116
0
                if (pdf14_abuf->group_needed) {
9117
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9118
0
                                                        pdf14_abuf->op_ca_eq_CA);
9119
0
                }
9120
0
                if (code >= 0)
9121
0
                    code = gs_update_trans_marking_params(pgs);
9122
9123
                /* fallthrough */
9124
9125
0
            case OP_FS_TRANS_CLEANUP:
9126
0
cleanup:
9127
0
                if (pdf14_abuf->group_needed) {
9128
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9129
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9130
0
                    if (code1 < 0)
9131
0
                        code = gs_note_error(gs_error_Fatal);
9132
0
                }
9133
0
                break;
9134
0
        }
9135
0
        pgs->device = curr_dev;
9136
9137
0
        return (code < 0) ? code : ret;
9138
0
    }
9139
9140
517M
    if (dev_spec_op == gxdso_in_smask_construction)
9141
8.90M
        return p14dev->in_smask_construction > 0;
9142
508M
    if (dev_spec_op == gxdso_in_smask)
9143
472M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9144
36.9M
    if (dev_spec_op == gxdso_replacecolor) {
9145
35.9M
        gx_device *tdev = p14dev->target;
9146
35.9M
        cmm_dev_profile_t *tdev_profile;
9147
35.9M
        int code;
9148
9149
         /* If in a softmask or softmask construction do not allow
9150
           replacement. */
9151
35.9M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9152
817k
            return 0;
9153
9154
        /* If the target CS is different than the pdf14 profile add this information
9155
           for the target device that will be handling the replacement. While not
9156
           perfect this at least lets you do the replacehment and have some information
9157
           about what the situation is. */
9158
35.1M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9159
35.1M
        if (code != 0)
9160
0
            return 0;
9161
9162
35.1M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9163
35.1M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9164
23.9M
            color_replace_t* replace_data = (color_replace_t*)data;
9165
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9166
               color remap operation. */
9167
23.9M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9168
23.9M
        }
9169
9170
        /* Pass on to target device */
9171
35.1M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9172
35.1M
    }
9173
946k
    if (dev_spec_op == gxdso_device_insert_child) {
9174
446
        gx_device *tdev = p14dev->target;
9175
446
        p14dev->target = (gx_device *)data;
9176
446
        rc_increment(p14dev->target);
9177
446
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9178
446
        return 0;
9179
446
    }
9180
945k
    if (dev_spec_op == gxdso_interpolate_threshold)
9181
19.7k
        return p14dev->interpolate_threshold;
9182
9183
925k
    if (dev_spec_op == gxdso_overprintsim_state) {
9184
19.7k
        unsigned char *data_uchar = (unsigned char *) data;
9185
19.7k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9186
19.7k
        if (p14dev->ctx != NULL)
9187
19
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9188
19.6k
        else
9189
19.6k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9190
19.7k
        return 1;
9191
19.7k
    }
9192
9193
906k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9194
925k
}
9195
9196
/* Needed to set color monitoring in the target device's profile */
9197
int
9198
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9199
0
{
9200
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9201
0
    gx_device *targ = p14dev->target;
9202
0
    cmm_dev_profile_t *dev_profile;
9203
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9204
9205
0
    if (code == 0)
9206
0
        dev_profile->pageneutralcolor = monitoring;
9207
0
    return code;
9208
0
}
9209
9210
static int
9211
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9212
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9213
1.98M
{
9214
1.98M
    pdf14_device dev_proto;
9215
1.98M
    pdf14_device * p14dev;
9216
1.98M
    int code;
9217
1.98M
    bool has_tags;
9218
1.98M
    cmm_profile_t *icc_profile;
9219
1.98M
    gsicc_rendering_param_t render_cond;
9220
1.98M
    cmm_dev_profile_t *dev_profile;
9221
1.98M
    uchar k;
9222
1.98M
    int max_bitmap;
9223
1.98M
    bool use_pdf14_accum = false;
9224
1.98M
    bool deep;
9225
9226
    /* Guard against later seg faults, this should not be possible */
9227
1.98M
    if (target == NULL)
9228
0
        return gs_throw_code(gs_error_Fatal);
9229
9230
1.98M
    has_tags = device_encodes_tags(target);
9231
1.98M
    deep = device_is_deep(target);
9232
1.98M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9233
1.98M
                                 target->space_params.MaxBitmap;
9234
    /* If the device is not a printer class device, it won't support saved-pages */
9235
    /* and so we may need to make a clist device in order to prevent very large  */
9236
    /* or high resolution pages from having allocation problems.                 */
9237
    /* We use MaxBitmap to decide when a clist is needed.*/
9238
1.98M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9239
10.6k
        gx_device_is_pattern_clist(target) == 0 &&
9240
10.6k
        gx_device_is_pattern_accum(target) == 0 &&
9241
7.52k
        gs_device_is_memory(target) == 0) {
9242
9243
7.52k
        uint32_t pdf14_trans_buffer_size =
9244
7.52k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9245
7.52k
                                         target->color_info.num_components,
9246
7.52k
                                         deep ? 16 : 8) >> 3);
9247
9248
7.52k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9249
7.52k
                pdf14_trans_buffer_size *= target->height;
9250
0
        else
9251
0
                max_bitmap = 0;     /* Force decision to clist */
9252
7.52k
        if (pdf14_trans_buffer_size > max_bitmap)
9253
7.00k
            use_pdf14_accum = true;
9254
7.52k
    }
9255
1.98M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9256
1.98M
    if (code < 0)
9257
0
        return code;
9258
1.98M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9259
1.98M
                          &render_cond);
9260
1.98M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9261
9262
    /* Get the proto from which to copy the device. This will always
9263
     * ignore tags! */
9264
1.98M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9265
1.98M
                                  pdf14pct, use_pdf14_accum);
9266
1.98M
    if (code < 0)
9267
0
        return code;
9268
1.98M
    code = gs_copydevice((gx_device **) &p14dev,
9269
1.98M
                         (const gx_device *) &dev_proto, mem);
9270
1.98M
    if (code < 0)
9271
0
        return code;
9272
9273
1.98M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9274
9275
    /* Copying the params across will add tags to the colorinfo as required. */
9276
1.98M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9277
1.98M
    if (code < 0)
9278
0
        return code;
9279
9280
1.98M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9281
1.98M
    p14dev->pad = target->pad;
9282
1.98M
    p14dev->log2_align_mod = target->log2_align_mod;
9283
1.98M
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0) {
9284
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9285
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9286
0
    }
9287
1.98M
    else if (pdf14pct->params.overprint_sim_push && target->num_planar_planes != 0) {
9288
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9289
0
        p14dev->color_info.num_components = p14dev->num_planar_planes;
9290
0
    }
9291
1.98M
    else
9292
1.98M
        p14dev->num_planar_planes = target->num_planar_planes;
9293
1.98M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9294
9295
1.98M
    p14dev->alpha = 1.0;
9296
1.98M
    p14dev->shape = 1.0;
9297
1.98M
    p14dev->opacity = 1.0;
9298
1.98M
    p14dev->fillconstantalpha = 1.0;
9299
1.98M
    p14dev->strokeconstantalpha = 1.0;
9300
9301
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9302
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9303
       do the mapping to the NCLR profile when the put_image occurs */
9304
1.98M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9305
1.98M
        icc_profile->data_cs == gsNCHANNEL) {
9306
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9307
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9308
0
            -1, "gs_pdf14_device_push");
9309
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9310
1.98M
    } else {
9311
        /* If the target profile was CIELAB (and we are not using a blend CS),
9312
           then overide with default RGB for proper blending.  During put_image
9313
           we will convert from RGB to CIELAB.  Need to check that we have a
9314
           default profile, which will not be the case if we are coming from the clist reader */
9315
1.98M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9316
0
            && pgs->icc_manager->default_rgb != NULL &&
9317
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9318
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9319
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9320
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9321
0
                -1, "gs_pdf14_device_push");
9322
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9323
0
        }
9324
1.98M
    }
9325
9326
1.98M
    if (pdf14pct->params.overprint_sim_push &&
9327
0
        pdf14pct->params.num_spot_colors_int > 0) {
9328
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9329
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9330
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9331
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9332
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9333
0
    }
9334
9335
    /* The number of color planes should not exceed that of the target.
9336
       Unless we are using a blend CS */
9337
1.98M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9338
1.98M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9339
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9340
1.98M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9341
157k
            p14dev->color_info.max_components = target->color_info.max_components;
9342
1.98M
    }
9343
1.98M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9344
    /* If we have a tag device then go ahead and do a special encoder
9345
       decoder for the pdf14 device to make sure we maintain this
9346
       information in the encoded color information.  We could use
9347
       the target device's methods but the PDF14 device has to maintain
9348
       8 bit color always and we could run into other issues if the number
9349
       of colorants became large.  If we need to do compressed color with
9350
       tags that will be a special project at that time */
9351
1.98M
    if (deep) {
9352
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9353
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9354
0
    }
9355
1.98M
    if (has_tags) {
9356
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9357
0
    }
9358
    /* if the device has separations already defined (by SeparationOrderNames) */
9359
    /* we need to copy them (allocating new names) so the colorants are in the */
9360
    /* same order as the target device.                                        */
9361
1.98M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9362
157k
        code = devn_copy_params(target, (gx_device *)p14dev);
9363
157k
        if (code < 0) {
9364
60
            *pdev = NULL;
9365
60
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9366
60
            rc_decrement(p14dev, "gs_pdf14_device_push");
9367
60
            return code;
9368
60
        }
9369
157k
    }
9370
    /* by definition pdf14_encode _is_ standard */
9371
1.98M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9372
1.98M
    gx_device_fill_in_procs((gx_device *)p14dev);
9373
1.98M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9374
1.98M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9375
1.98M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9376
9377
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9378
6.92M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9379
4.93M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9380
4.93M
        p14dev->color_info.comp_shift[k] =
9381
4.93M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9382
4.93M
    }
9383
1.98M
    if (use_pdf14_accum) {
9384
        /* we will disable this device later, but we don't want to allocate large buffers */
9385
7.00k
        p14dev->width = 1;
9386
7.00k
        p14dev->height = 1;
9387
7.00k
    }
9388
9389
1.98M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9390
1.98M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9391
1.98M
    *pdev = (gx_device *) p14dev;
9392
1.98M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9393
1.98M
    p14dev->color_model_stack = NULL;
9394
9395
    /* In case we have alphabits set */
9396
1.98M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9397
9398
1.98M
    if (pdf14pct->params.is_pattern) {
9399
22.2k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9400
22.2k
        if (code < 0) {
9401
0
            *pdev = NULL;
9402
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9403
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9404
0
            return code;
9405
0
        }
9406
22.2k
    }
9407
9408
    /* We should never go into this when using a blend color space */
9409
1.98M
    if (use_pdf14_accum) {
9410
7.00k
        const gx_device_pdf14_accum *accum_proto = NULL;
9411
7.00k
        gx_device *new_target = NULL;
9412
7.00k
        gx_device_color pdcolor;
9413
7.00k
        frac pconc_white = frac_1;
9414
7.00k
        bool UsePlanarBuffer = false;
9415
9416
7.00k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9417
9418
        /* get the prototype for the accumulator device based on colorspace */
9419
7.00k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9420
1.39k
            case 1:
9421
1.39k
                accum_proto = &pdf14_accum_Gray;
9422
1.39k
                break;
9423
5.61k
            case 3:
9424
5.61k
                accum_proto = &pdf14_accum_RGB;
9425
5.61k
                break;
9426
0
            case 4:
9427
0
                accum_proto = &pdf14_accum_CMYK;
9428
0
                break;
9429
0
            default:
9430
0
                accum_proto = &pdf14_accum_CMYKspot;
9431
0
                UsePlanarBuffer = true;
9432
7.00k
        }
9433
7.00k
        if (accum_proto == NULL ||
9434
7.00k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9435
0
            goto no_clist_accum;
9436
9437
7.00k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9438
        /* Fill in values from the target device before opening */
9439
7.00k
        new_target->color_info = p14dev->color_info;
9440
7.00k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9441
7.00k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9442
7.00k
        set_linear_color_bits_mask_shift(new_target);
9443
7.00k
        gs_pdf14_device_copy_params(new_target, target);
9444
7.00k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9445
7.00k
        gx_device_fill_in_procs(new_target);
9446
9447
7.00k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9448
7.00k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9449
7.00k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9450
9451
        /* This is used to mark the various internal subclass devices as having already
9452
         * been pushed, so that opening the device won't result in us trying to push
9453
         * them again, which leads to trouble.
9454
         */
9455
7.00k
        code = mark_internal_subclass_devices(new_target);
9456
7.00k
        if (code < 0)
9457
0
            return code;
9458
9459
        /* if the device has separations already defined (by SeparationOrderNames) */
9460
        /* we need to copy them (allocating new names) so the colorants are in the */
9461
        /* same order as the target device.                                        */
9462
7.00k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9463
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9464
0
            if (code < 0)
9465
0
                return code;
9466
0
        }
9467
        /* UsePlanarBuffer is true in case this is CMYKspot */
9468
7.00k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9469
7.00k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9470
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9471
0
            goto no_clist_accum;
9472
0
        }
9473
        /* Do the initial fillpage into the pdf14-accum device we just created */
9474
7.00k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9475
7.00k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9476
7.00k
                                            &pconc_white,
9477
7.00k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9478
7.00k
                                            dev_profile)) < 0)
9479
0
            goto no_clist_accum;
9480
9481
7.00k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9482
7.00k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9483
7.00k
        if (code < 0)
9484
0
            goto no_clist_accum;
9485
9486
7.00k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9487
7.00k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9488
7.00k
    }
9489
1.98M
    return code;
9490
9491
0
no_clist_accum:
9492
        /* FIXME: We allocated a really small p14dev, but that won't work */
9493
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9494
1.98M
}
9495
9496
/*
9497
 * In a modest violation of good coding practice, the gs_composite_common
9498
 * fields are "known" to be simple (contain no pointers to garbage
9499
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9500
 * to be simple, so we just create a trivial structure descriptor for the
9501
 * entire gs_pdf14trans_s structure.
9502
 */
9503
#define private_st_gs_pdf14trans_t()\
9504
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9505
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9506
9507
/* GC descriptor for gs_pdf14trans_t */
9508
private_st_gs_pdf14trans_t();
9509
9510
/*
9511
 * Check for equality of two PDF 1.4 transparency compositor objects.
9512
 *
9513
 * We are currently always indicating that PDF 1.4 transparency compositors are
9514
 * equal.  Two transparency compositors may have teh same data but still
9515
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9516
 * operations in a row mean that we are creating a group inside of a group.
9517
 */
9518
static  bool
9519
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9520
0
{
9521
0
    return false;
9522
0
}
9523
9524
#ifdef DEBUG
9525
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9526
#endif
9527
9528
#define put_value(dp, value)\
9529
13.7M
    BEGIN\
9530
13.7M
        memcpy(dp, &value, sizeof(value));\
9531
13.7M
        dp += sizeof(value);\
9532
13.7M
    END
9533
9534
static inline int
9535
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9536
1.59M
{
9537
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9538
       because clist writer may skip this command for some bands.
9539
       For a better result we need individual CTM for each band.
9540
     */
9541
1.59M
    byte *pbuf = *ppbuf;
9542
1.59M
    int len, code;
9543
9544
1.59M
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9545
1.59M
    pbuf--; /* For cmd_write_ctm. */
9546
1.59M
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9547
1.59M
    if (code < 0)
9548
0
        return code;
9549
1.59M
    pbuf += len + 1;
9550
1.59M
    *ppbuf = pbuf;
9551
1.59M
    return 0;
9552
1.59M
}
9553
9554
/*
9555
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9556
 * list device. This is also where we update the pdf14_needed. When set the clist
9557
 * painting procs will update the trans_bbox state for bands that are affected.
9558
*/
9559
static  int
9560
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9561
                   gx_device_clist_writer *cdev)
9562
3.89M
{
9563
3.89M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9564
3.89M
    int need, avail = *psize;
9565
3.89M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9566
        to fit the data written below. We don't implement a dynamic check for
9567
        the buffer owerflow, assuming that the consistency is verified in the
9568
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9569
3.89M
    byte * pbuf = buf;
9570
3.89M
    int opcode = pparams->pdf14_op;
9571
3.89M
    int mask_size = 0;
9572
3.89M
    uint mask_id = 0;
9573
3.89M
    int code;
9574
3.89M
    bool found_icc;
9575
3.89M
    int64_t hashcode = 0;
9576
3.89M
    cmm_profile_t *icc_profile;
9577
3.89M
    gsicc_rendering_param_t render_cond;
9578
3.89M
    cmm_dev_profile_t *dev_profile;
9579
    /* We maintain and update working copies until we actually write the clist */
9580
3.89M
    int pdf14_needed = cdev->pdf14_needed;
9581
3.89M
    int trans_group_level = cdev->pdf14_trans_group_level;
9582
3.89M
    int smask_level = cdev->pdf14_smask_level;
9583
3.89M
    bool deep = device_is_deep((gx_device *)cdev);
9584
9585
3.89M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9586
3.89M
                                                     &dev_profile);
9587
3.89M
    if (code < 0)
9588
0
        return code;
9589
3.89M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9590
3.89M
                          &render_cond);
9591
3.89M
    *pbuf++ = opcode;     /* 1 byte */
9592
3.89M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9593
4
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9594
9595
3.89M
    switch (opcode) {
9596
0
        default:      /* Should not occur. */
9597
0
            break;
9598
33.9k
        case PDF14_PUSH_DEVICE:
9599
33.9k
            trans_group_level = 0;
9600
33.9k
            cdev->pdf14_smask_level = 0;
9601
33.9k
            cdev->page_pdf14_needed = false;
9602
33.9k
            put_value(pbuf, pparams->num_spot_colors);
9603
33.9k
            put_value(pbuf, pparams->num_spot_colors_int);
9604
33.9k
            put_value(pbuf, pparams->overprint_sim_push);
9605
33.9k
            put_value(pbuf, pparams->is_pattern);
9606
9607
            /* If we happen to be going to a color space like CIELAB then
9608
               we are going to do our blending in default RGB and convert
9609
               to CIELAB at the end.  To do this, we need to store the
9610
               default RGB profile in the clist so that we can grab it
9611
               later on during the clist read back and put image command */
9612
33.9k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9613
                /* Get the default RGB profile.  Set the device hash code
9614
                   so that we can extract it during the put_image operation. */
9615
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9616
0
                found_icc =
9617
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9618
0
                if (!found_icc) {
9619
                    /* Add it to the table */
9620
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9621
0
                                       pparams->iccprofile);
9622
0
                }
9623
0
            }
9624
33.9k
            break;
9625
32.3k
        case PDF14_POP_DEVICE:
9626
32.3k
            pdf14_needed = false;   /* reset pdf14_needed */
9627
32.3k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9628
32.3k
            smask_level = 0;
9629
32.3k
            put_value(pbuf, pparams->is_pattern);
9630
32.3k
            break;
9631
859k
        case PDF14_END_TRANS_GROUP:
9632
869k
        case PDF14_END_TRANS_TEXT_GROUP:
9633
869k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9634
869k
            if (smask_level == 0 && trans_group_level == 0)
9635
50.1k
                pdf14_needed = cdev->page_pdf14_needed;
9636
869k
            break;      /* No data */
9637
13.6k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9638
869k
        case PDF14_BEGIN_TRANS_GROUP:
9639
869k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9640
869k
            trans_group_level++;
9641
869k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9642
869k
            if (code < 0)
9643
0
                return code;
9644
869k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9645
869k
            *pbuf++ = pparams->blend_mode;
9646
869k
            *pbuf++ = pparams->group_color_type;
9647
869k
            *pbuf++ = pparams->page_group;
9648
869k
            put_value(pbuf, pparams->group_color_numcomps);
9649
869k
            put_value(pbuf, pparams->opacity);
9650
869k
            put_value(pbuf, pparams->shape);
9651
869k
            put_value(pbuf, pparams->bbox);
9652
869k
            put_value(pbuf, pparams->shade_group);
9653
869k
            put_value(pbuf, pparams->text_group);
9654
869k
            mask_id = pparams->mask_id;
9655
869k
            put_value(pbuf, mask_id);
9656
            /* Color space information maybe ICC based
9657
               in this case we need to store the ICC
9658
               profile or the ID if it is cached already */
9659
869k
            if (pparams->group_color_type == ICC) {
9660
                /* Check if it is already in the ICC clist table */
9661
25.3k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9662
25.3k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9663
25.3k
                if (!found_icc) {
9664
                    /* Add it to the table */
9665
7.34k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9666
7.34k
                    put_value(pbuf, hashcode);
9667
18.0k
                } else {
9668
                    /* It will be in the clist. Just write out the hashcode */
9669
18.0k
                    put_value(pbuf, hashcode);
9670
18.0k
                }
9671
844k
            } else {
9672
844k
                put_value(pbuf, hashcode);
9673
844k
            }
9674
869k
            break;
9675
728k
        case PDF14_BEGIN_TRANS_MASK:
9676
728k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9677
621k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9678
621k
                smask_level++;
9679
621k
            }
9680
728k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9681
728k
            if (code < 0)
9682
0
                return code;
9683
728k
            put_value(pbuf, pparams->subtype);
9684
728k
            *pbuf++ = pparams->group_color_type;
9685
728k
            put_value(pbuf, pparams->group_color_numcomps);
9686
728k
            *pbuf++ = pparams->replacing;
9687
728k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9688
728k
            *pbuf++ = pparams->Background_components;
9689
728k
            *pbuf++ = pparams->Matte_components;
9690
728k
            put_value(pbuf, pparams->bbox);
9691
728k
            mask_id = pparams->mask_id;
9692
728k
            put_value(pbuf, mask_id);
9693
728k
            if (pparams->Background_components) {
9694
6.02k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9695
9696
6.02k
                memcpy(pbuf, pparams->Background, l);
9697
6.02k
                pbuf += l;
9698
6.02k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9699
6.02k
                pbuf += sizeof(pparams->GrayBackground);
9700
6.02k
            }
9701
728k
            if (pparams->Matte_components) {
9702
352
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9703
9704
352
                memcpy(pbuf, pparams->Matte, m);
9705
352
                pbuf += m;
9706
352
            }
9707
728k
            if (!pparams->function_is_identity)
9708
1.41k
                mask_size = (256+deep)<<deep;
9709
            /* Color space information may be ICC based
9710
               in this case we need to store the ICC
9711
               profile or the ID if it is cached already */
9712
728k
            if (pparams->group_color_type == ICC) {
9713
                /* Check if it is already in the ICC clist table */
9714
621k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9715
621k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9716
621k
                if (!found_icc) {
9717
                    /* Add it to the table */
9718
5.27k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9719
5.27k
                    put_value(pbuf, hashcode);
9720
615k
                } else {
9721
                    /* It will be in the clist. Just write out the hashcode */
9722
615k
                    put_value(pbuf, hashcode);
9723
615k
                }
9724
621k
            } else {
9725
107k
                put_value(pbuf, hashcode);
9726
107k
            }
9727
728k
            break;
9728
621k
        case PDF14_END_TRANS_MASK:
9729
621k
            smask_level--;
9730
621k
            if (smask_level == 0 && trans_group_level == 0)
9731
18.1k
                pdf14_needed = cdev->page_pdf14_needed;
9732
621k
            break;
9733
645k
        case PDF14_SET_BLEND_PARAMS:
9734
645k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9735
0
                pparams->shape != 1.0)
9736
645k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9737
0
            else if (smask_level == 0 && trans_group_level == 0)
9738
0
                pdf14_needed = false;   /* At page level, set back to false */
9739
645k
            if (smask_level == 0 && trans_group_level == 0)
9740
219k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9741
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9742
645k
            put_value(pbuf, pparams->changed);
9743
645k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9744
59.5k
                *pbuf++ = pparams->blend_mode;
9745
645k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9746
31.4k
                *pbuf++ = pparams->text_knockout;
9747
645k
            if (pparams->changed & PDF14_SET_AIS)
9748
645k
                put_value(pbuf, pparams->ais);
9749
645k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9750
645k
                put_value(pbuf, pparams->overprint);
9751
645k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9752
645k
                put_value(pbuf, pparams->stroke_overprint);
9753
645k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9754
645k
                put_value(pbuf, pparams->fillconstantalpha);
9755
645k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9756
645k
                put_value(pbuf, pparams->strokeconstantalpha);
9757
645k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9758
645k
                put_value(pbuf, pparams->op_fs_state);
9759
645k
            break;
9760
0
        case PDF14_PUSH_TRANS_STATE:
9761
0
            break;
9762
91.3k
        case PDF14_POP_TRANS_STATE:
9763
91.3k
            break;
9764
0
        case PDF14_PUSH_SMASK_COLOR:
9765
0
            return 0;   /* We really should never be here */
9766
0
            break;
9767
0
        case PDF14_POP_SMASK_COLOR:
9768
0
            return 0;   /* We really should never be here */
9769
0
            break;
9770
3.89M
    }
9771
9772
    /* check for fit */
9773
3.89M
    need = (pbuf - buf) + mask_size;
9774
3.89M
    *psize = need;
9775
3.89M
    if (need > avail) {
9776
692k
        if (avail)
9777
0
            return_error(gs_error_rangecheck);
9778
692k
        else
9779
692k
            return gs_error_rangecheck;
9780
692k
    }
9781
9782
    /* If we are writing more than the maximum ever expected,
9783
     * return a rangecheck error. Second check is for Coverity
9784
     */
9785
3.19M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9786
3.19M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9787
0
        return_error(gs_error_rangecheck);
9788
9789
    /* Copy our serialized data into the output buffer */
9790
3.19M
    memcpy(data, buf, need - mask_size);
9791
3.19M
    if (mask_size)  /* Include the transfer mask data if present */
9792
1.05k
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9793
3.19M
    if_debug3m('v', cdev->memory,
9794
3.19M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9795
3.19M
               pdf14_opcode_names[opcode], mask_id, need);
9796
3.19M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9797
3.19M
    cdev->pdf14_trans_group_level = trans_group_level;
9798
3.19M
    cdev->pdf14_smask_level = smask_level;
9799
3.19M
    return 0;
9800
3.19M
}
9801
9802
#undef put_value
9803
9804
/* Function prototypes */
9805
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9806
                const gs_pdf14trans_params_t * pparams,
9807
                gs_memory_t * mem );
9808
9809
#define read_value(dp, value)\
9810
332M
    BEGIN\
9811
332M
        memcpy(&value, dp, sizeof(value));\
9812
332M
        dp += sizeof(value);\
9813
332M
    END
9814
9815
/*
9816
 * Convert the string representation of the PDF 1.4 transparency parameter
9817
 * into the full compositor.
9818
 */
9819
static  int
9820
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9821
                                uint size, gs_memory_t * mem )
9822
97.6M
{
9823
97.6M
    gs_pdf14trans_params_t params = {0};
9824
97.6M
    const byte * start = data;
9825
97.6M
    int used, code = 0;
9826
97.6M
    bool deep;
9827
9828
97.6M
    if (size < 1)
9829
0
        return_error(gs_error_rangecheck);
9830
9831
    /* Read PDF 1.4 compositor data from the clist */
9832
97.6M
    params.pdf14_op = *data++;
9833
97.6M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9834
97.6M
               pdf14_opcode_names[params.pdf14_op], size);
9835
97.6M
    memset(&params.ctm, 0, sizeof(params.ctm));
9836
97.6M
    switch (params.pdf14_op) {
9837
0
        default:      /* Should not occur. */
9838
0
            break;
9839
2.84M
        case PDF14_PUSH_DEVICE:
9840
2.84M
            read_value(data, params.num_spot_colors);
9841
2.84M
            read_value(data, params.num_spot_colors_int);
9842
2.84M
            read_value(data, params.overprint_sim_push);
9843
2.84M
            read_value(data, params.is_pattern);
9844
2.84M
            break;
9845
0
        case PDF14_ABORT_DEVICE:
9846
0
            break;
9847
2.84M
        case PDF14_POP_DEVICE:
9848
2.84M
            read_value(data, params.is_pattern);
9849
2.84M
            break;
9850
5.32M
        case PDF14_END_TRANS_GROUP:
9851
6.16M
        case PDF14_END_TRANS_TEXT_GROUP:
9852
#ifdef DEBUG
9853
            code += 0; /* A good place for a breakpoint. */
9854
#endif
9855
6.16M
            break;      /* No data */
9856
0
        case PDF14_PUSH_TRANS_STATE:
9857
0
            break;
9858
6.85M
        case PDF14_POP_TRANS_STATE:
9859
6.85M
            break;
9860
1.28M
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9861
6.16M
        case PDF14_BEGIN_TRANS_GROUP:
9862
            /*
9863
             * We are currently not using the bbox or the colorspace so they were
9864
             * not placed in the clist
9865
             */
9866
6.16M
            data = cmd_read_matrix(&params.ctm, data);
9867
6.16M
            params.Isolated = (*data) & 1;
9868
6.16M
            params.Knockout = (*data++ >> 1) & 1;
9869
6.16M
            params.blend_mode = *data++;
9870
6.16M
            params.group_color_type = *data++;  /* Trans group color */
9871
6.16M
            params.page_group = *data++;
9872
6.16M
            read_value(data,params.group_color_numcomps);  /* color group size */
9873
6.16M
            read_value(data, params.opacity);
9874
6.16M
            read_value(data, params.shape);
9875
6.16M
            read_value(data, params.bbox);
9876
6.16M
            read_value(data, params.shade_group);
9877
6.16M
            read_value(data, params.text_group);
9878
6.16M
            read_value(data, params.mask_id);
9879
6.16M
            read_value(data, params.icc_hash);
9880
6.16M
            break;
9881
10.6M
        case PDF14_BEGIN_TRANS_MASK:
9882
                /* This is the largest transparency parameter at this time (potentially
9883
                 * 1531 bytes in size if Background_components =
9884
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9885
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9886
                 *
9887
                 * NOTE:
9888
                 * The clist reader must be able to handle this sized device.
9889
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9890
                 * may also need to be changed correspondingly (defined in gstparam.h)
9891
                 * Also... if another compositor param should exceed this size, this
9892
                 * same condition applies.
9893
                 */
9894
10.6M
            data = cmd_read_matrix(&params.ctm, data);
9895
10.6M
            read_value(data, params.subtype);
9896
10.6M
            params.group_color_type = *data++;
9897
10.6M
            read_value(data, params.group_color_numcomps);
9898
10.6M
            params.replacing = *data++;
9899
10.6M
            params.function_is_identity = *data & 1;
9900
10.6M
            deep = (*data++)>>1;
9901
10.6M
            params.Background_components = *data++;
9902
10.6M
            params.Matte_components = *data++;
9903
10.6M
            read_value(data, params.bbox);
9904
10.6M
            read_value(data, params.mask_id);
9905
10.6M
            if (params.Background_components) {
9906
417k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9907
9908
417k
                memcpy(params.Background, data, l);
9909
417k
                data += l;
9910
417k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9911
417k
                data += sizeof(params.GrayBackground);
9912
417k
            }
9913
10.6M
            if (params.Matte_components) {
9914
9.76k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9915
9916
9.76k
                memcpy(params.Matte, data, m);
9917
9.76k
                data += m;
9918
9.76k
            }
9919
10.6M
            read_value(data, params.icc_hash);
9920
10.6M
            if (params.function_is_identity) {
9921
10.6M
                int i;
9922
9923
10.6M
                if (deep) {
9924
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9925
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9926
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9927
10.6M
                } else {
9928
2.72G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9929
2.71G
                        params.transfer_fn[i] = (byte)floor(i *
9930
2.71G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9931
2.71G
                    }
9932
10.6M
                }
9933
10.6M
            } else {
9934
41.3k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9935
41.3k
                data += (256+deep)<<deep;
9936
41.3k
            }
9937
10.6M
            break;
9938
1.15M
        case PDF14_END_TRANS_MASK:
9939
1.15M
            break;
9940
0
        case PDF14_PUSH_SMASK_COLOR:
9941
0
            return 0;
9942
0
            break;
9943
0
        case PDF14_POP_SMASK_COLOR:
9944
0
            return 0;
9945
0
            break;
9946
60.9M
        case PDF14_SET_BLEND_PARAMS:
9947
60.9M
            read_value(data, params.changed);
9948
60.9M
            if (params.changed & PDF14_SET_BLEND_MODE)
9949
6.02M
                params.blend_mode = *data++;
9950
60.9M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9951
2.77M
                params.text_knockout = *data++;
9952
60.9M
            if (params.changed & PDF14_SET_AIS)
9953
60.9M
                read_value(data, params.ais);
9954
60.9M
            if (params.changed & PDF14_SET_OVERPRINT)
9955
60.9M
                read_value(data, params.overprint);
9956
60.9M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9957
60.9M
                read_value(data, params.stroke_overprint);
9958
60.9M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9959
60.9M
                read_value(data, params.fillconstantalpha);
9960
60.9M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9961
60.9M
                read_value(data, params.strokeconstantalpha);
9962
60.9M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9963
60.9M
                read_value(data, params.op_fs_state);
9964
60.9M
            break;
9965
97.6M
    }
9966
97.6M
    code = gs_create_pdf14trans(ppct, &params, mem);
9967
97.6M
    if (code < 0)
9968
0
        return code;
9969
97.6M
    used = data - start;
9970
97.6M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9971
9972
    /* If we read more than the maximum expected, return a rangecheck error */
9973
97.6M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9974
0
        return_error(gs_error_rangecheck);
9975
97.6M
    else
9976
97.6M
        return used;
9977
97.6M
}
9978
9979
/*
9980
 * Adjust the compositor's CTM.
9981
 */
9982
static int
9983
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9984
52.1M
{
9985
52.1M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9986
52.1M
    gs_matrix mat = pct->params.ctm;
9987
9988
52.1M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9989
52.1M
               mat.xx, mat.xy, mat.yx, mat.yy,
9990
52.1M
               mat.tx, mat.ty);
9991
52.1M
    mat.tx -= x0;
9992
52.1M
    mat.ty -= y0;
9993
52.1M
    gs_gstate_setmatrix(pgs, &mat);
9994
52.1M
    return 0;
9995
52.1M
}
9996
9997
/*
9998
 * Create a PDF 1.4 transparency compositor.
9999
 *
10000
 * Note that this routine will be called only if the device is not already
10001
 * a PDF 1.4 transparency compositor.
10002
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
10003
 */
10004
static  int
10005
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
10006
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
10007
    gs_memory_t * mem)
10008
2.01M
{
10009
2.01M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
10010
2.01M
    int code = 0;
10011
10012
    /*
10013
     * We only handle the push operation.  All other operations are ignored.
10014
     * The other operations will be handled by the composite routine
10015
     * for the PDF 1.4 compositing device.
10016
     */
10017
2.01M
    switch (pdf14pct->params.pdf14_op) {
10018
1.98M
        case PDF14_PUSH_DEVICE:
10019
1.98M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
10020
            /* Change (non-error) code to 1 to indicate that we created
10021
             * a device. */
10022
1.98M
            if (code >= 0)
10023
1.98M
                code = 1;
10024
1.98M
            break;
10025
32.0k
        default:
10026
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
10027
32.0k
            *pp14dev = NULL;
10028
32.0k
            return_error(gs_error_unregistered);
10029
2.01M
    }
10030
1.98M
    return code;
10031
2.01M
}
10032
10033
/*
10034
 * Find an opening compositor op.
10035
 */
10036
static gs_compositor_closing_state
10037
find_opening_op(int opening_op, gs_composite_t **ppcte,
10038
                gs_compositor_closing_state return_code)
10039
5.57M
{
10040
    /* Assuming a right *BEGIN* - *END* operation balance. */
10041
5.57M
    gs_composite_t *pcte = *ppcte;
10042
10043
13.8M
    for (;;) {
10044
13.8M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10045
13.0M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
10046
13.0M
            int op = pct->params.pdf14_op;
10047
10048
13.0M
            *ppcte = pcte;
10049
13.0M
            if (op == opening_op)
10050
3.72M
                return return_code;
10051
9.33M
            if (op != PDF14_SET_BLEND_PARAMS) {
10052
5.83M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
10053
1.86k
                    return COMP_ENQUEUE;
10054
5.83M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10055
500k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10056
444k
                        return COMP_ENQUEUE;
10057
500k
                }
10058
5.39M
                if (opening_op == PDF14_PUSH_DEVICE) {
10059
5.33M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10060
5.26M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10061
512k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10062
296k
                        return COMP_ENQUEUE;
10063
5.33M
                }
10064
5.39M
            }
10065
9.33M
        } else
10066
800k
            return COMP_ENQUEUE;
10067
8.59M
        pcte = pcte->prev;
10068
8.59M
        if (pcte == NULL)
10069
309k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10070
8.59M
    }
10071
5.57M
}
10072
10073
/*
10074
 * Find an opening compositor op.
10075
 */
10076
static gs_compositor_closing_state
10077
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10078
50.8M
{
10079
50.8M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10080
50.8M
    gs_composite_t *pct = *ppcte;
10081
10082
50.8M
    for (;;) {
10083
50.8M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10084
43.9M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10085
10086
43.9M
            *ppcte = pct;
10087
43.9M
            if (pct_pdf14->params.pdf14_op != my_op)
10088
8.65M
                return COMP_ENQUEUE;
10089
35.2M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10090
                /* If the new parameters completely replace the old ones
10091
                   then remove the old one from the queu */
10092
35.2M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10093
35.2M
                    pct_pdf14->params.changed) {
10094
32.8M
                    return COMP_REPLACE_CURR;
10095
32.8M
                } else {
10096
2.39M
                    return COMP_ENQUEUE;
10097
2.39M
                }
10098
35.2M
            }
10099
35.2M
        } else
10100
6.88M
            return COMP_ENQUEUE;
10101
0
        pct = pct->prev;
10102
0
        if (pct == NULL)
10103
0
            return COMP_ENQUEUE; /* Not in queue. */
10104
0
    }
10105
50.8M
}
10106
10107
/*
10108
 * Check for closing compositor.
10109
 */
10110
static gs_compositor_closing_state
10111
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10112
                        gx_device *dev)
10113
85.0M
{
10114
85.0M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10115
85.0M
    int op0 = pct0->params.pdf14_op;
10116
10117
85.0M
    switch (op0) {
10118
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10119
2.11M
        case PDF14_PUSH_DEVICE:
10120
2.11M
            return COMP_ENQUEUE;
10121
0
        case PDF14_ABORT_DEVICE:
10122
0
            return COMP_ENQUEUE;
10123
2.11M
        case PDF14_POP_DEVICE:
10124
2.11M
            if (*ppcte == NULL)
10125
1.37M
                return COMP_ENQUEUE;
10126
734k
            else {
10127
734k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10128
10129
734k
                if (state == COMP_EXEC_IDLE)
10130
134k
                    return COMP_DROP_QUEUE;
10131
599k
                return state;
10132
734k
            }
10133
993k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10134
5.29M
        case PDF14_BEGIN_TRANS_GROUP:
10135
5.29M
            return COMP_ENQUEUE;
10136
4.50M
        case PDF14_END_TRANS_GROUP:
10137
5.29M
        case PDF14_END_TRANS_TEXT_GROUP:
10138
5.29M
            if (*ppcte == NULL)
10139
866k
                return COMP_EXEC_QUEUE;
10140
4.43M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10141
8.92M
        case PDF14_BEGIN_TRANS_MASK:
10142
8.92M
            return COMP_ENQUEUE;
10143
0
        case PDF14_PUSH_TRANS_STATE:
10144
0
            return COMP_ENQUEUE;
10145
5.76M
        case PDF14_POP_TRANS_STATE:
10146
5.76M
            return COMP_ENQUEUE;
10147
0
        case PDF14_PUSH_SMASK_COLOR:
10148
0
            return COMP_ENQUEUE;
10149
0
            break;
10150
0
        case PDF14_POP_SMASK_COLOR:
10151
0
            return COMP_ENQUEUE;
10152
0
            break;
10153
1.01M
        case PDF14_END_TRANS_MASK:
10154
1.01M
            if (*ppcte == NULL)
10155
603k
                return COMP_EXEC_QUEUE;
10156
410k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10157
54.4M
        case PDF14_SET_BLEND_PARAMS:
10158
54.4M
            if (*ppcte == NULL)
10159
3.66M
                return COMP_ENQUEUE;
10160
            /* hack : ignore csel - here it is always zero : */
10161
50.8M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10162
85.0M
    }
10163
85.0M
}
10164
10165
/*
10166
 * Check whether a next operation is friendly to the compositor.
10167
 */
10168
static bool
10169
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10170
8.41M
{
10171
8.41M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10172
8.41M
    int op0 = pct0->params.pdf14_op;
10173
10174
8.41M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10175
6.33M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10176
        /* Halftone commands are always passed to the target printer device,
10177
           because transparency buffers are always contone.
10178
           So we're safe to execute them before queued transparency compositors. */
10179
2.12M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10180
551k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10181
889k
            return true;
10182
1.23M
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10183
1.20M
            return true;
10184
1.23M
    }
10185
6.31M
    return false;
10186
8.41M
}
10187
10188
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10189
static composite_equal_proc(c_pdf14trans_equal);
10190
static composite_write_proc(c_pdf14trans_write);
10191
static composite_read_proc(c_pdf14trans_read);
10192
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10193
static composite_is_closing_proc(c_pdf14trans_is_closing);
10194
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10195
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10196
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10197
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10198
10199
/*
10200
 * Methods for the PDF 1.4 transparency compositor
10201
 *
10202
 * Note:  We have two set of methods.  They are the same except for the
10203
 * composite_clist_write_update method.  Once the clist write device is created,
10204
 * we use the second set of procedures.  This prevents the creation of multiple
10205
 * PDF 1.4 clist write compositor devices being chained together.
10206
 */
10207
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10208
    GX_COMPOSITOR_PDF14_TRANS,
10209
    {
10210
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10211
        c_pdf14trans_equal,                      /* procs.equal */
10212
        c_pdf14trans_write,                      /* procs.write */
10213
        c_pdf14trans_read,                       /* procs.read */
10214
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10215
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10216
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10217
                /* Create a PDF 1.4 clist write device */
10218
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10219
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10220
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10221
    }                                            /* procs */
10222
};
10223
10224
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10225
    GX_COMPOSITOR_PDF14_TRANS,
10226
    {
10227
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10228
        c_pdf14trans_equal,                      /* procs.equal */
10229
        c_pdf14trans_write,                      /* procs.write */
10230
        c_pdf14trans_read,                       /* procs.read */
10231
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10232
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10233
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10234
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10235
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10236
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10237
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10238
    }                                            /* procs */
10239
};
10240
10241
/*
10242
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10243
 */
10244
int
10245
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10246
708M
{
10247
708M
    return (pct->type == &gs_composite_pdf14trans_type
10248
558M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10249
708M
}
10250
10251
/*
10252
 * Create a PDF 1.4 transparency compositor data structure.
10253
 */
10254
static int
10255
gs_create_pdf14trans(
10256
    gs_composite_t **               ppct,
10257
    const gs_pdf14trans_params_t *  pparams,
10258
    gs_memory_t *                   mem )
10259
100M
{
10260
100M
    gs_pdf14trans_t *                pct;
10261
10262
100M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10263
100M
                             "gs_create_pdf14trans");
10264
100M
    if (pct == NULL)
10265
0
        return_error(gs_error_VMerror);
10266
100M
    pct->type = &gs_composite_pdf14trans_type;
10267
100M
    pct->id = gs_next_ids(mem, 1);
10268
100M
    pct->params = *pparams;
10269
100M
    pct->idle = false;
10270
100M
    *ppct = (gs_composite_t *)pct;
10271
100M
    return 0;
10272
100M
}
10273
10274
/*
10275
 * Send a PDF 1.4 transparency compositor action to the specified device.
10276
 */
10277
int
10278
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10279
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10280
3.04M
{
10281
3.04M
    gs_composite_t * pct = NULL;
10282
3.04M
    int code;
10283
10284
3.04M
    pparams->ctm = ctm_only(pgs);
10285
3.04M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10286
3.04M
    if (code < 0)
10287
0
        return code;
10288
3.04M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10289
3.04M
    if (code == gs_error_handled)
10290
0
        code = 0;
10291
10292
3.04M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10293
10294
3.04M
    return code;
10295
3.04M
}
10296
10297
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10298
10299
/*
10300
 * The PDF 1.4 transparency compositor device may have a different process
10301
 * color model than the output device.  If we are banding then we need to
10302
 * create two compositor devices.  The output side (clist reader) needs a
10303
 * compositor to actually composite the output.  We also need a compositor
10304
 * device before the clist writer.  This is needed to provide a process color
10305
 * model which matches the PDF 1.4 blending space.
10306
 *
10307
 * This section provides support for this device.
10308
 */
10309
10310
/*
10311
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10312
 * We actually use the same structure for both the clist writer and reader
10313
 * devices.  However we use separate names to identify the routines for each
10314
 * device.
10315
 */
10316
10317
static  dev_proc_composite(pdf14_clist_composite);
10318
static  dev_proc_composite(pdf14_clist_forward_composite);
10319
static  dev_proc_fill_path(pdf14_clist_fill_path);
10320
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10321
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10322
static  dev_proc_text_begin(pdf14_clist_text_begin);
10323
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10324
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10325
10326
static void
10327
pdf14_clist_init_procs(gx_device *dev,
10328
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10329
                       dev_proc_get_color_comp_index(get_color_comp_index))
10330
16.9k
{
10331
16.9k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10332
16.9k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10333
16.9k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10334
16.9k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10335
16.9k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10336
16.9k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10337
16.9k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10338
16.9k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10339
16.9k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10340
16.9k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10341
16.9k
    set_dev_proc(dev, put_params, pdf14_put_params);
10342
16.9k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10343
16.9k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10344
16.9k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10345
16.9k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10346
16.9k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10347
16.9k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10348
16.9k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10349
16.9k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10350
16.9k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10351
16.9k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10352
16.9k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10353
16.9k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10354
16.9k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10355
16.9k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10356
16.9k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10357
16.9k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10358
16.9k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10359
16.9k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10360
16.9k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10361
16.9k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10362
16.9k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10363
16.9k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10364
16.9k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10365
16.9k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10366
16.9k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10367
16.9k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10368
16.9k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10369
16.9k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10370
16.9k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10371
16.9k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10372
16.9k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10373
16.9k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10374
16.9k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10375
16.9k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10376
16.9k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10377
16.9k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10378
16.9k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10379
16.9k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10380
16.9k
}
10381
10382
static void
10383
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10384
4.52k
{
10385
4.52k
    pdf14_clist_init_procs(dev,
10386
4.52k
                           gx_default_DevGray_get_color_mapping_procs,
10387
4.52k
                           gx_default_DevGray_get_color_comp_index);
10388
4.52k
}
10389
10390
static void
10391
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10392
10.4k
{
10393
10.4k
    pdf14_clist_init_procs(dev,
10394
10.4k
                           gx_default_DevRGB_get_color_mapping_procs,
10395
10.4k
                           gx_default_DevRGB_get_color_comp_index);
10396
10.4k
}
10397
10398
static void
10399
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10400
13
{
10401
13
    pdf14_clist_init_procs(dev,
10402
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10403
13
                           gx_default_DevCMYK_get_color_comp_index);
10404
13
}
10405
10406
static void
10407
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10408
1.98k
{
10409
1.98k
    pdf14_clist_init_procs(dev,
10410
1.98k
                           pdf14_cmykspot_get_color_mapping_procs,
10411
1.98k
                           pdf14_cmykspot_get_color_comp_index);
10412
1.98k
}
10413
10414
static void
10415
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10416
0
{
10417
0
    pdf14_clist_init_procs(dev,
10418
0
                           pdf14_rgbspot_get_color_mapping_procs,
10419
0
                           pdf14_rgbspot_get_color_comp_index);
10420
0
}
10421
10422
#if 0 /* NOT USED */
10423
static int
10424
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10425
{
10426
    pdf14_clist_init_procs(dev,
10427
                           pdf14_grayspot_get_color_mapping_procs,
10428
                           pdf14_grayspot_get_color_comp_index);
10429
}
10430
#endif  /* NOT USED */
10431
10432
const pdf14_clist_device pdf14_clist_Gray_device = {
10433
    std_device_color_stype_body(pdf14_clist_device,
10434
                                pdf14_clist_Gray_initialize_device_procs,
10435
                                "pdf14clistgray",
10436
                                &st_pdf14_device,
10437
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10438
    { 0 },      /* Procs */
10439
    NULL,     /* target */
10440
    { 0 },      /* devn_params - not used */
10441
    &gray_pdf14_procs,
10442
    &gray_blending_procs
10443
};
10444
10445
const pdf14_clist_device pdf14_clist_RGB_device = {
10446
    std_device_color_stype_body(pdf14_clist_device,
10447
                                pdf14_clist_RGB_initialize_device_procs,
10448
                                "pdf14clistRGB",
10449
                                &st_pdf14_device,
10450
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10451
    { 0 },      /* Procs */
10452
    NULL,     /* target */
10453
    { 0 },      /* devn_params - not used */
10454
    &rgb_pdf14_procs,
10455
    &rgb_blending_procs
10456
};
10457
10458
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10459
    std_device_part1_(pdf14_device,
10460
                      pdf14_clist_RGBspot_initialize_device_procs,
10461
                      "pdf14clistrgbspot",
10462
                      &st_pdf14_device,
10463
                      open_init_closed),
10464
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10465
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10466
    offset_margin_values(0, 0, 0, 0, 0, 0),
10467
    std_device_part3_(),
10468
    { 0 },      /* Procs */
10469
    NULL,     /* target */
10470
    /* DeviceN parameters */
10471
    { 8,      /* Not used - Bits per color */
10472
      DeviceRGBComponents,  /* Names of color model colorants */
10473
      3,      /* Number colorants for CMYK */
10474
      0,      /* MaxSeparations has not been specified */
10475
      -1,     /* PageSpotColors has not been specified */
10476
      {0},      /* SeparationNames */
10477
      0,      /* SeparationOrder names */
10478
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10479
    },
10480
    &rgbspot_pdf14_procs,
10481
    &rgb_blending_procs
10482
};
10483
10484
const pdf14_clist_device pdf14_clist_CMYK_device = {
10485
    std_device_std_color_full_body_type(pdf14_clist_device,
10486
                                        pdf14_clist_CMYK_initialize_device_procs,
10487
                                        "pdf14clistcmyk",
10488
                                        &st_pdf14_device,
10489
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10490
                                        0, 0, 0, 0, 0, 0),
10491
    { 0 },      /* Procs */
10492
    NULL,     /* target */
10493
    { 0 },      /* devn_params - not used */
10494
    &cmyk_pdf14_procs,
10495
    &cmyk_blending_procs
10496
};
10497
10498
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10499
    std_device_part1_(pdf14_device,
10500
                      pdf14_clist_CMYKspot_initialize_device_procs,
10501
                      "pdf14clistcmykspot",
10502
                      &st_pdf14_device,
10503
                      open_init_closed),
10504
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10505
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10506
    offset_margin_values(0, 0, 0, 0, 0, 0),
10507
    std_device_part3_(),
10508
    { 0 },      /* Procs */
10509
    NULL,     /* target */
10510
    /* DeviceN parameters */
10511
    { 8,      /* Not used - Bits per color */
10512
      DeviceCMYKComponents, /* Names of color model colorants */
10513
      4,      /* Number colorants for CMYK */
10514
      0,      /* MaxSeparations has not been specified */
10515
      -1,     /* PageSpotColors has not been specified */
10516
      {0},      /* SeparationNames */
10517
      0,      /* SeparationOrder names */
10518
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10519
    },
10520
    &cmykspot_pdf14_procs,
10521
    &cmyk_blending_procs
10522
};
10523
10524
const pdf14_clist_device pdf14_clist_custom_device = {
10525
    std_device_part1_(pdf14_device,
10526
                      pdf14_clist_CMYKspot_initialize_device_procs,
10527
                      "pdf14clistcustom",
10528
                      &st_pdf14_device,
10529
                      open_init_closed),
10530
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10531
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10532
    offset_margin_values(0, 0, 0, 0, 0, 0),
10533
    std_device_part3_(),
10534
    { 0 },      /* Procs */
10535
    NULL,     /* target */
10536
    /* DeviceN parameters */
10537
    { 8,      /* Not used - Bits per color */
10538
      DeviceCMYKComponents, /* Names of color model colorants */
10539
      4,      /* Number colorants for CMYK */
10540
      0,      /* MaxSeparations has not been specified */
10541
      -1,     /* PageSpotColors has not been specified */
10542
      {0},      /* SeparationNames */
10543
      0,      /* SeparationOrder names */
10544
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10545
    },
10546
    &custom_pdf14_procs,
10547
    &custom_blending_procs
10548
};
10549
10550
/*
10551
 * the PDF 1.4 transparency spec says that color space for blending
10552
 * operations can be based upon either a color space specified in the
10553
 * group or a default value based upon the output device.  We are
10554
 * currently only using a color space based upon the device.
10555
 */
10556
static  int
10557
get_pdf14_clist_device_proto(gx_device          *dev,
10558
                             pdf14_clist_device *pdevproto,
10559
                             gs_gstate          *pgs,
10560
                       const gs_pdf14trans_t    *pdf14pct,
10561
                             bool                use_pdf14_accum)
10562
16.9k
{
10563
16.9k
    pdf14_blend_cs_t blend_cs_state;
10564
16.9k
    pdf14_default_colorspace_t dev_cs =
10565
16.9k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10566
16.9k
                                                 &blend_cs_state);
10567
16.9k
    bool deep = device_is_deep(dev);
10568
16.9k
    int num_spots = pdf14pct->params.num_spot_colors;
10569
10570
    /* overprint overide */
10571
16.9k
    if (pdf14pct->params.overprint_sim_push &&
10572
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10573
10574
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10575
0
            dev_cs = PDF14_DeviceCMYKspot;
10576
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10577
0
        } else
10578
0
            dev_cs = PDF14_DeviceCMYK;
10579
0
    }
10580
10581
16.9k
    switch (dev_cs) {
10582
4.52k
        case PDF14_DeviceGray:
10583
           /* We want gray to be single channel.  Low level
10584
               initialization of gray device prototype is
10585
               peculiar in that in dci_std_color_num_components
10586
               the comment is
10587
              "A device is monochrome only if it is bi-level"
10588
              Here we want monochrome anytime we have a gray device.
10589
              To avoid breaking things elsewhere, we will overide
10590
              the prototype intialization here */
10591
4.52k
            *pdevproto = pdf14_clist_Gray_device;
10592
4.52k
            pdevproto->color_info.max_components = 1;
10593
4.52k
            pdevproto->color_info.num_components =
10594
4.52k
                                    pdevproto->color_info.max_components;
10595
4.52k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10596
4.52k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10597
4.52k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10598
4.52k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10599
4.52k
            pdevproto->color_info.depth = deep ? 16 : 8;
10600
4.52k
            pdevproto->sep_device = false;
10601
4.52k
            break;
10602
10.4k
        case PDF14_DeviceRGB:
10603
10.4k
            *pdevproto = pdf14_clist_RGB_device;
10604
10.4k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10605
10.4k
            pdevproto->sep_device = false;
10606
10.4k
            if (deep) {
10607
0
                pdevproto->color_info.depth = 3*16;
10608
0
                pdevproto->color_info.max_color = 65535;
10609
0
                pdevproto->color_info.max_gray = 65535;
10610
0
                pdevproto->color_info.dither_colors = 65536;
10611
0
                pdevproto->color_info.dither_grays = 65536;
10612
0
            }
10613
10.4k
            break;
10614
13
        case PDF14_DeviceCMYK:
10615
13
            *pdevproto = pdf14_clist_CMYK_device;
10616
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10617
13
            pdevproto->sep_device = false;
10618
13
            if (deep) {
10619
0
                pdevproto->color_info.depth = 4*16;
10620
0
                pdevproto->color_info.max_color = 65535;
10621
0
                pdevproto->color_info.max_gray = 65535;
10622
0
                pdevproto->color_info.dither_colors = 65536;
10623
0
                pdevproto->color_info.dither_grays = 65536;
10624
0
            }
10625
13
            break;
10626
1.98k
        case PDF14_DeviceCMYKspot:
10627
1.98k
            *pdevproto = pdf14_clist_CMYKspot_device;
10628
            /*
10629
             * The number of components for the PDF14 device is the sum
10630
             * of the process components and the number of spot colors
10631
             * for the page. If we are using an NCLR ICC profile at
10632
             * the output device, those spot colors are skipped. They
10633
             * do not appear in the transparency buffer, but appear
10634
             * during put image transform of the page group to the target
10635
             * color space.
10636
             */
10637
1.98k
            if (num_spots >= 0) {
10638
1.98k
                pdevproto->devn_params.page_spot_colors = num_spots;
10639
1.98k
                pdevproto->color_info.num_components =
10640
1.98k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10641
1.98k
                if (pdevproto->color_info.num_components >
10642
1.98k
                              pdevproto->color_info.max_components)
10643
0
                    pdevproto->color_info.num_components =
10644
0
                              pdevproto->color_info.max_components;
10645
1.98k
                pdevproto->color_info.depth =
10646
1.98k
                              pdevproto->color_info.num_components * (8<<deep);
10647
1.98k
            }
10648
1.98k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10649
1.98k
            pdevproto->sep_device = true;
10650
1.98k
            break;
10651
0
        case PDF14_DeviceRGBspot:
10652
0
            *pdevproto = pdf14_clist_RGBspot_device;
10653
            /*
10654
             * The number of components for the PDF14 device is the sum
10655
             * of the process components and the number of spot colors
10656
             * for the page. If we are using an NCLR ICC profile at
10657
             * the output device, those spot colors are skipped. They
10658
             * do not appear in the transparency buffer, but appear
10659
             * during put image transform of the page group to the target
10660
             * color space.
10661
             */
10662
0
            if (num_spots >= 0) {
10663
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10664
0
                pdevproto->color_info.num_components =
10665
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10666
0
                if (pdevproto->color_info.num_components >
10667
0
                    pdevproto->color_info.max_components)
10668
0
                    pdevproto->color_info.num_components =
10669
0
                        pdevproto->color_info.max_components;
10670
0
                pdevproto->color_info.depth =
10671
0
                    pdevproto->color_info.num_components * (8 << deep);
10672
0
            }
10673
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10674
0
            pdevproto->sep_device = true;
10675
0
            break;
10676
0
        case PDF14_DeviceCustom:
10677
            /*
10678
             * We are using the output device's process color model.  The
10679
             * color_info for the PDF 1.4 compositing device needs to match
10680
             * the output device.
10681
             */
10682
0
            *pdevproto = pdf14_clist_custom_device;
10683
0
            pdevproto->color_info = dev->color_info;
10684
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10685
0
            pdevproto->color_info.depth =
10686
0
                pdevproto->color_info.num_components * (8<<deep);
10687
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10688
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10689
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10690
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10691
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10692
0
            break;
10693
0
        default:      /* Should not occur */
10694
0
            return_error(gs_error_rangecheck);
10695
16.9k
    }
10696
16.9k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10697
16.9k
    pdevproto->blend_cs_state = blend_cs_state;
10698
16.9k
    return 0;
10699
16.9k
}
10700
10701
static  int
10702
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10703
                                gx_device ** ppdev, gx_device * target,
10704
                                const gs_pdf14trans_t * pdf14pct)
10705
16.9k
{
10706
16.9k
    pdf14_clist_device dev_proto;
10707
16.9k
    pdf14_clist_device * pdev;
10708
16.9k
    int code;
10709
16.9k
    bool has_tags = device_encodes_tags(target);
10710
16.9k
    cmm_profile_t *target_profile;
10711
16.9k
    gsicc_rendering_param_t render_cond;
10712
16.9k
    cmm_dev_profile_t *dev_profile;
10713
16.9k
    uchar k;
10714
16.9k
    bool deep = device_is_deep(target);
10715
16.9k
    cmm_profile_t *icc_profile;
10716
16.9k
    int nc;
10717
10718
16.9k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10719
16.9k
    if (code < 0)
10720
0
        return code;
10721
16.9k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10722
16.9k
                          &render_cond);
10723
16.9k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10724
    /* Prototypes never include tags. We add those in later. */
10725
16.9k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10726
16.9k
                                        pgs, pdf14pct, false);
10727
16.9k
    if (code < 0)
10728
0
        return code;
10729
16.9k
    code = gs_copydevice((gx_device **) &pdev,
10730
16.9k
                         (const gx_device *) &dev_proto, mem);
10731
16.9k
    if (code < 0)
10732
0
        return code;
10733
10734
16.9k
    nc = pdev->color_info.num_components;
10735
    /* If we are not using a blending color space, the number of color planes
10736
       should not exceed that of the target */
10737
16.9k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10738
16.9k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10739
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10740
16.9k
        if (pdev->color_info.max_components > target->color_info.max_components)
10741
2.06k
            pdev->color_info.max_components = target->color_info.max_components;
10742
16.9k
    }
10743
16.9k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10744
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10745
10746
16.9k
    pdev->color_info.num_components = nc;
10747
16.9k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10748
16.9k
    pdev->pad = target->pad;
10749
16.9k
    pdev->log2_align_mod = target->log2_align_mod;
10750
10751
16.9k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10752
10753
16.9k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10754
10755
16.9k
    if (deep) {
10756
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10757
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10758
0
    }
10759
    /* If we have a tag device then go ahead and do a special encoder decoder
10760
       for the pdf14 device to make sure we maintain this information in the
10761
       encoded color information.  We could use the target device's methods but
10762
       the PDF14 device has to maintain 8 bit color always and we could run
10763
       into other issues if the number of colorants became large.  If we need to
10764
       do compressed color with tags that will be a special project at that time */
10765
16.9k
    if (has_tags) {
10766
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10767
0
    }
10768
16.9k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10769
16.9k
    gx_device_fill_in_procs((gx_device *)pdev);
10770
    /* Copying the params adds the tags to the color_info if required. */
10771
16.9k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10772
16.9k
    if (target->num_planar_planes > 0)
10773
2.13k
        pdev->num_planar_planes = pdev->color_info.num_components;
10774
16.9k
    gx_device_set_target((gx_device_forward *)pdev, target);
10775
10776
    /* Components shift, etc have to be based upon 8 bit */
10777
60.9k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10778
43.9k
        pdev->color_info.comp_bits[k] = 8<<deep;
10779
43.9k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10780
43.9k
    }
10781
16.9k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10782
16.9k
    if (code < 0)
10783
0
        return code;
10784
16.9k
    pdev->pclist_device = target;
10785
10786
16.9k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10787
16.9k
    if (code < 0)
10788
0
        return code;
10789
16.9k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10790
16.9k
        &render_cond);
10791
16.9k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10792
10793
    /* Simulated overprint case.  We have to use CMYK-based profile
10794
       Also if the target profile is NCLR, we are going to use a pdf14
10795
       device that is CMYK based and do the mapping to the NCLR profile
10796
       when the put_image occurs */
10797
16.9k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10798
16.9k
         icc_profile->data_cs == gsNCHANNEL) {
10799
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10800
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10801
0
            -1, "pdf14_create_clist_device");
10802
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10803
16.9k
    } else {
10804
        /* If the target profile was CIELAB, then overide with default RGB for
10805
           proper blending.  During put_image we will convert from RGB to
10806
           CIELAB */
10807
16.9k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10808
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10809
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10810
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10811
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10812
0
        }
10813
16.9k
    }
10814
10815
16.9k
    if (pdf14pct->params.overprint_sim_push &&
10816
0
        pdf14pct->params.num_spot_colors_int > 0) {
10817
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10818
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10819
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10820
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10821
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10822
0
    }
10823
    /* if the device has separations already defined (by SeparationOrderNames) */
10824
    /* we need to copy them (allocating new names) so the colorants are in the */
10825
    /* same order as the target device.                                        */
10826
16.9k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10827
2.13k
        code = devn_copy_params(target, (gx_device *)pdev);
10828
2.13k
        if (code < 0)
10829
0
            return code;
10830
2.13k
    }
10831
16.9k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10832
16.9k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10833
16.9k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10834
16.9k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10835
16.9k
    pdev->color_info.separable_and_linear =
10836
16.9k
        target->color_info.separable_and_linear;
10837
16.9k
    *ppdev = (gx_device *) pdev;
10838
16.9k
    return code;
10839
16.9k
}
10840
10841
/*
10842
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10843
 * compositor device is never removed.  (We do not have a remove compositor
10844
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10845
 * routine implements that action.
10846
 */
10847
static  int
10848
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10849
                                gx_device * dev)
10850
16.1k
{
10851
16.1k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10852
16.1k
    gx_device * target = pdev->target;
10853
10854
16.1k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10855
10856
    /*
10857
     * To disable the action of this device, we forward all device
10858
     * procedures to the target except the composite and copy
10859
     * the target's color_info.
10860
     */
10861
16.1k
    dev->color_info = target->color_info;
10862
16.1k
    pdf14_forward_device_procs(dev);
10863
16.1k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10864
16.1k
    return 0;
10865
16.1k
}
10866
10867
/*
10868
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10869
 * compositor device is never removed.  (We do not have a remove compositor
10870
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10871
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10872
 * again.
10873
 */
10874
static  int
10875
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10876
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10877
0
{
10878
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10879
0
    gx_device * target = pdev->target;
10880
0
    pdf14_clist_device dev_proto;
10881
0
    int code;
10882
10883
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10884
    /*
10885
     * We will not use the entire prototype device but we will set the
10886
     * color related info to match the prototype.
10887
     */
10888
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10889
0
                                        pgs, pdf14pct, false);
10890
0
    if (code < 0)
10891
0
        return code;
10892
0
    pdev->color_info = dev_proto.color_info;
10893
10894
0
    if (dev_proto.initialize_device_procs != NULL)
10895
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10896
10897
0
    pdev->procs = dev_proto.procs;
10898
0
    pdev->pad = target->pad;
10899
0
    pdev->log2_align_mod = target->log2_align_mod;
10900
10901
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10902
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10903
0
    else
10904
0
        pdev->num_planar_planes = target->num_planar_planes;
10905
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10906
10907
0
    copy_tag_setup(dev, target);
10908
10909
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10910
0
    gx_device_fill_in_procs((gx_device *)pdev);
10911
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10912
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10913
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10914
0
    check_device_separable((gx_device *)pdev);
10915
0
    return code;
10916
0
}
10917
10918
/*
10919
 * devicen params
10920
 */
10921
gs_devn_params *
10922
pdf14_ret_devn_params(gx_device *pdev)
10923
4.11M
{
10924
4.11M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10925
10926
4.11M
    return &(p14dev->devn_params);
10927
4.11M
}
10928
10929
/*
10930
 * devicen params
10931
 */
10932
gs_devn_params *
10933
pdf14_accum_ret_devn_params(gx_device *pdev)
10934
0
{
10935
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10936
10937
0
    return &(p14dev->devn_params);
10938
0
}
10939
10940
static int
10941
pdf14_accum_get_color_comp_index(gx_device * dev,
10942
    const char * pname, int name_size, int component_type)
10943
0
{
10944
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10945
0
    gx_device *target = p14dev->target;
10946
0
    int colorant_number = devn_get_color_comp_index(dev,
10947
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10948
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10949
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10950
10951
0
    if (target != NULL)
10952
        /* colorant_number returned here _should_ be the same as from above */
10953
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10954
0
                              (target, (const char *)pname, name_size, component_type);
10955
0
    return colorant_number;
10956
0
}
10957
10958
/*
10959
 * The following procedures are used to map the standard color spaces into
10960
 * the separation color components for the pdf14_accum device.
10961
 */
10962
static void
10963
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10964
0
{
10965
0
    int * map =
10966
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10967
10968
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10969
0
}
10970
10971
static void
10972
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10973
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10974
0
{
10975
0
    int * map =
10976
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10977
10978
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10979
0
}
10980
10981
static void
10982
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10983
    frac c, frac m, frac y, frac k, frac out[])
10984
0
{
10985
0
    const int * map =
10986
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10987
10988
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10989
0
}
10990
10991
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10992
    pdf14_accum_gray_cs_to_cmyk_cm,
10993
    pdf14_accum_rgb_cs_to_cmyk_cm,
10994
    pdf14_accum_cmyk_cs_to_cmyk_cm
10995
};
10996
10997
static const gx_cm_color_map_procs *
10998
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10999
0
{
11000
0
    *map_dev = dev;
11001
0
    return &pdf14_accum_cm_procs;
11002
0
}
11003
11004
/*
11005
 *  Device proc for updating the equivalent CMYK color for spot colors.
11006
 */
11007
static int
11008
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
11009
0
{
11010
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
11011
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
11012
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
11013
0
                                              &pdev->equiv_cmyk_colors);
11014
11015
0
    if (code >= 0 && tdev != NULL)
11016
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
11017
0
    return code;
11018
0
}
11019
11020
/* Used when doing overprint simulation and have spot colors */
11021
static int
11022
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
11023
0
{
11024
0
    pdf14_device *pdev = (pdf14_device *)dev;
11025
0
    int code;
11026
11027
    /* Make sure we are not All or None */
11028
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
11029
0
        pcs->params.separation.sep_type != SEP_OTHER)
11030
0
            return 0;
11031
11032
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
11033
0
        &pdev->op_pequiv_cmyk_colors);
11034
0
    return code;
11035
0
}
11036
11037
/*
11038
 * Retrieve a list of spot color names for the PDF14 device.
11039
 */
11040
int
11041
put_param_pdf14_spot_names(gx_device * pdev,
11042
                gs_separations * pseparations, gs_param_list * plist)
11043
90.5k
{
11044
90.5k
    int code, num_spot_colors, i;
11045
90.5k
    gs_param_string str;
11046
11047
    /* Check if the given keyname is present. */
11048
90.5k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
11049
90.5k
                                                &num_spot_colors);
11050
90.5k
    switch (code) {
11051
0
        default:
11052
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
11053
0
            break;
11054
90.5k
        case 1:
11055
90.5k
            return 0;
11056
0
        case 0:
11057
0
            if (num_spot_colors < 1 ||
11058
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11059
0
                return_error(gs_error_rangecheck);
11060
0
            for (i = 0; i < num_spot_colors; i++) {
11061
0
                char buff[20];
11062
0
                byte * sep_name;
11063
11064
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11065
0
                code = param_read_string(plist, buff, &str);
11066
0
                switch (code) {
11067
0
                    default:
11068
0
                        param_signal_error(plist, buff, code);
11069
0
                        break;
11070
0
                    case 0:
11071
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11072
0
                                str.size, "put_param_pdf14_spot_names");
11073
0
                        if (sep_name == NULL)
11074
0
                            return_error(gs_error_VMerror);
11075
11076
0
                        memcpy(sep_name, str.data, str.size);
11077
0
                        pseparations->names[i].size = str.size;
11078
0
                        pseparations->names[i].data = sep_name;
11079
0
                }
11080
0
            }
11081
0
            pseparations->num_separations = num_spot_colors;
11082
0
            break;
11083
90.5k
    }
11084
0
    return 0;;
11085
0
}
11086
11087
/*
11088
 * This procedure will have information from the PDF 1.4 clist writing
11089
 * clist compositior device.  This is information output the compressed
11090
 * color list info which is needed for the support of spot colors in
11091
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11092
 * clist reading compositor.  However this device is not created until
11093
 * the clist is read.  To get this info to that device, we have to
11094
 * temporarily store that info in the output device.  This routine saves
11095
 * that info in the output device.
11096
 */
11097
int
11098
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11099
                                        gs_param_list * plist)
11100
90.5k
{
11101
90.5k
    int code;
11102
90.5k
    code = put_param_pdf14_spot_names(pdev,
11103
90.5k
                       &pdevn_params->pdf14_separations, plist);
11104
90.5k
    return code;
11105
90.5k
}
11106
11107
/*
11108
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11109
 * when we are creating the clist.  The second is for imaging the data from
11110
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11111
 * This routine is only called once the PDF 1.4 clist write compositor already
11112
 * exists.
11113
 */
11114
static  int
11115
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11116
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11117
    gx_device *cdev)
11118
3.91M
{
11119
3.91M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11120
3.91M
    int code, is_pdf14_compositor;
11121
3.91M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11122
3.91M
    bool deep = device_is_deep(dev);
11123
11124
    /* We only handle a few PDF 1.4 transparency operations */
11125
3.91M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11126
2.56M
        switch (pdf14pct->params.pdf14_op) {
11127
0
            case PDF14_PUSH_DEVICE:
11128
                /* Re-activate the PDF 1.4 compositor */
11129
/*
11130
                We previously did:
11131
11132
                pdev->saved_target_color_info = pdev->target->color_info;
11133
11134
                Here, but since we already saved and modified the the color_info
11135
                of the target clist device in gs_pdf14_clist_device_push() this is
11136
                overwriting saved_target_color_info that we already saved with the
11137
                group color_info, meaning when we set it back again, it's incorrect.
11138
*/
11139
0
                pdev->target->color_info = pdev->color_info;
11140
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11141
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11142
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11143
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11144
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11145
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11146
0
                pdev->saved_target_get_color_mapping_procs =
11147
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11148
0
                pdev->saved_target_get_color_comp_index =
11149
0
                                        dev_proc(pdev->target, get_color_comp_index);
11150
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11151
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11152
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11153
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11154
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11155
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11156
0
                gx_set_cmap_procs(pgs, dev);
11157
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11158
0
                pdev->blend_mode = pdev->text_knockout = 0;
11159
0
                pdev->opacity = pdev->shape = 0.0;
11160
0
                if (code < 0)
11161
0
                    return code;
11162
                /*
11163
                 * This routine is part of the PDF 1.4 clist write device.
11164
                 * Change the compositor procs to not create another since we
11165
                 * do not need to create a chain of identical devices.
11166
                 */
11167
0
                {
11168
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11169
11170
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11171
0
                    code = dev_proc(pdev->target, composite)
11172
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11173
                    /* We should never have created a new device here. */
11174
0
                    assert(code != 1);
11175
0
                    return code;
11176
0
                }
11177
16.1k
            case PDF14_POP_DEVICE:
11178
16.1k
            {
11179
16.1k
                gx_device *clistdev = pdev->target;
11180
11181
                /* Find the clist device */
11182
16.1k
                while (1) {
11183
16.1k
                    gxdso_device_child_request req;
11184
                    /* Ignore any errors here, that's expected as non-clist
11185
                     * devices don't implement it. */
11186
16.1k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11187
16.1k
                    if (code == 1)
11188
16.1k
                        break;
11189
0
                    req.n = 0;
11190
0
                    req.target = clistdev;
11191
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11192
0
                    if (code < 0)
11193
0
                        return code;
11194
0
                    clistdev = req.target;
11195
0
                }
11196
11197
                /* If we have overprint simulation spot color information, store
11198
                   it in a pseudo-band of the clist */
11199
16.1k
                if (pdev->overprint_sim &&
11200
0
                    pdev->devn_params.page_spot_colors > 0) {
11201
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11202
0
                        &pdev->op_pequiv_cmyk_colors);
11203
0
                    if (code < 0)
11204
0
                        return code;
11205
0
                }
11206
11207
                /* If we hit an error during an SMask, we need to undo the color
11208
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11209
                 * for itself if it needs to take action.
11210
                 */
11211
16.1k
                pdf14_decrement_smask_color(pgs, dev);
11212
                /* Restore the color_info for the clist device */
11213
16.1k
                clistdev->color_info = pdev->saved_target_color_info;
11214
16.1k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11215
16.1k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11216
16.1k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11217
16.1k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11218
16.1k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11219
16.1k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11220
16.1k
                gx_set_cmap_procs(pgs, clistdev);
11221
16.1k
                gx_device_decache_colors(clistdev);
11222
                /* Disable the PDF 1.4 compositor */
11223
16.1k
                pdf14_disable_clist_device(mem, pgs, dev);
11224
                /*
11225
                 * Make sure that the transfer funtions, etc. are current.
11226
                 */
11227
16.1k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11228
16.1k
                if (code < 0)
11229
0
                    return code;
11230
16.1k
                break;
11231
16.1k
            }
11232
16.1k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11233
86.0k
            case PDF14_BEGIN_TRANS_GROUP:
11234
86.0k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11235
39.0k
                    pdev->depth_within_smask++;
11236
86.0k
                pdev->smask_constructed = 0;
11237
                /*
11238
                 * Keep track of any changes made in the blending parameters.
11239
                   These need to be written out in the same bands as the group
11240
                   information is written.  Hence the passing of the dimensions
11241
                   for the group. */
11242
86.0k
                code = pdf14_clist_update_params(pdev, pgs, true,
11243
86.0k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11244
86.0k
                if (code < 0)
11245
0
                    return code;
11246
86.0k
                if (pdf14pct->params.Background_components != 0 &&
11247
0
                    pdf14pct->params.Background_components !=
11248
0
                    pdev->color_info.num_components)
11249
0
                    return_error(gs_error_rangecheck);
11250
11251
                /* We need to update the clist writer device procs based upon the
11252
                   the group color space. This ensures the proper color data is
11253
                   written out to the device. For simplicity, the list item is
11254
                   created even if the color space did not change */
11255
86.0k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11256
86.0k
                if (code < 0)
11257
0
                    return code;
11258
11259
86.0k
                break;
11260
87.1k
            case PDF14_BEGIN_TRANS_MASK:
11261
                /* We need to update the clist writer device procs based upon the
11262
                   the group color space.  For simplicity, the list item is created
11263
                   even if the color space did not change */
11264
                /* First store the current ones */
11265
87.1k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11266
47.8k
                    break;
11267
11268
                /* Update the color settings of the clist writer.  Store information in stack */
11269
39.3k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11270
39.3k
                if (code < 0)
11271
0
                    return code;
11272
11273
                /* Also, if the BC is a value that may end up as something other
11274
                  than transparent. We must use the parent colors bounding box in
11275
                  determining the range of bands in which this mask can affect.
11276
                  So, if needed change the masks bounding box at this time */
11277
39.3k
                pdev->in_smask_construction++;
11278
39.3k
                break;
11279
1.04M
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11280
1.04M
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11281
0
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11282
0
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11283
0
                } else
11284
1.04M
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11285
1.04M
                *pcdev = dev;
11286
1.04M
                return 0; /* Never put into clist. Only used during writing */
11287
1.08M
            case PDF14_END_TRANS_TEXT_GROUP:
11288
1.08M
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11289
1.08M
                    *pcdev = dev;
11290
1.08M
                    return 0; /* Avoids spurious ET calls in interpreter */
11291
1.08M
                }
11292
4.22k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11293
4.22k
                code = pdf14_clist_pop_color_model(dev, pgs);
11294
4.22k
                if (code < 0)
11295
0
                    return code;
11296
4.22k
                break;
11297
39.3k
            case PDF14_END_TRANS_MASK:
11298
39.3k
                pdev->in_smask_construction--;
11299
39.3k
                if (pdev->in_smask_construction < 0)
11300
0
                    pdev->in_smask_construction = 0;
11301
39.3k
                if (pdev->in_smask_construction == 0)
11302
39.2k
                    pdev->smask_constructed = 1;
11303
                /* fallthrough */
11304
121k
            case PDF14_END_TRANS_GROUP:
11305
                /* We need to update the clist writer device procs based upon the
11306
                   the group color space. */
11307
121k
                code = pdf14_clist_pop_color_model(dev, pgs);
11308
121k
                if (pdev->depth_within_smask)
11309
39.0k
                    pdev->depth_within_smask--;
11310
121k
                if (code < 0)
11311
0
                    return code;
11312
121k
                break;
11313
121k
            case PDF14_PUSH_TRANS_STATE:
11314
0
                break;
11315
38.1k
            case PDF14_POP_TRANS_STATE:
11316
38.1k
                break;
11317
39.3k
            case PDF14_PUSH_SMASK_COLOR:
11318
39.3k
                code = pdf14_increment_smask_color(pgs,dev);
11319
39.3k
                *pcdev = dev;
11320
39.3k
                return code;  /* Note, this are NOT put in the clist */
11321
0
                break;
11322
39.3k
            case PDF14_POP_SMASK_COLOR:
11323
39.3k
                code = pdf14_decrement_smask_color(pgs,dev);
11324
39.3k
                *pcdev = dev;
11325
39.3k
                return code;  /* Note, this are NOT put in the clist */
11326
0
                break;
11327
0
            case PDF14_SET_BLEND_PARAMS:
11328
                /* If there is a change we go ahead and apply it to the target */
11329
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11330
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11331
0
                *pcdev = dev;
11332
0
                return code;
11333
0
                break;
11334
0
            case PDF14_ABORT_DEVICE:
11335
0
                code = gx_abort_trans_device(pgs, dev);
11336
0
                if (pdev->free_devicen) {
11337
0
                    devn_free_params(dev);
11338
0
                }
11339
0
                pdf14_disable_device(dev);
11340
0
                pdf14_close(dev);
11341
0
                *pcdev = dev;
11342
0
                return code;
11343
0
                break;
11344
0
            default:
11345
0
                break;   /* Pass remaining ops to target */
11346
2.56M
        }
11347
2.56M
    }
11348
1.70M
    code = dev_proc(pdev->target, composite)
11349
1.70M
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11350
    /* If we were accumulating into a pdf14-clist-accum device, */
11351
    /* we now have to render the page into it's target device */
11352
1.70M
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11353
16.1k
        pdev->target->stype == &st_gx_devn_accum_device) {
11354
11355
7.00k
        int i, y, rows_used;
11356
7.00k
        byte *linebuf;
11357
7.00k
        byte *actual_data;
11358
7.00k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11359
        /* get the target device we want to send the image to */
11360
7.00k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11361
7.00k
        gs_image1_t image;
11362
7.00k
        gs_color_space *pcs;
11363
7.00k
        gx_image_enum_common_t *info = NULL;
11364
7.00k
        gx_image_plane_t planes;
11365
7.00k
        gsicc_rendering_param_t render_cond;
11366
7.00k
        cmm_dev_profile_t *dev_profile;
11367
7.00k
        bool save_planar = pdev->num_planar_planes;
11368
7.00k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11369
7.00k
        int save_num_separations;
11370
7.00k
        gs_int_rect rect;
11371
11372
7.00k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11373
7.00k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11374
7.00k
        pdev->num_planar_planes = save_planar;
11375
11376
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11377
         * colors do require devn support
11378
         */
11379
7.00k
        if (tdev->color_info.num_components <= 4 ||
11380
7.00k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11381
            /*
11382
             * Set color space in preparation for sending an image.
11383
             */
11384
7.00k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11385
7.00k
            if (code < 0)
11386
0
                goto put_accum_error;
11387
11388
            /* Need to set this to avoid color management during the
11389
               image color render operation.  Exception is for the special case
11390
               when the destination was CIELAB.  Then we need to convert from
11391
               default RGB to CIELAB in the put image operation.  That will happen
11392
               here as we should have set the profile for the pdf14 device to RGB
11393
               and the target will be CIELAB */
11394
7.00k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11395
7.00k
            if (code < 0)
11396
0
                goto put_accum_error;
11397
7.00k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11398
7.00k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11399
            /* pcs takes a reference to the profile data it just retrieved. */
11400
7.00k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11401
7.00k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11402
7.00k
        } else {
11403
             /* DeviceN case -- need to handle spot colors */
11404
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11405
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11406
0
            if (code < 0)
11407
0
                goto put_accum_error;
11408
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11409
0
            pcs->params.device_n.use_alt_cspace = false;
11410
11411
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11412
0
                goto put_accum_error;
11413
0
            }
11414
            /* One last thing -- we need to fudge the pgs->color_component_map */
11415
0
            for (i=0; i < tdev->color_info.num_components; i++)
11416
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11417
            /* copy devn_params that were accumulated into the target device's devn_params */
11418
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11419
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11420
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11421
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11422
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11423
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11424
0
            target_devn_params->separations = tdev->devn_params.separations;
11425
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11426
0
                   sizeof(gs_separation_map));
11427
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11428
0
        }
11429
7.00k
        if (linebuf == NULL) {
11430
0
            code = gs_error_VMerror;
11431
0
            goto put_accum_error;
11432
0
        }
11433
7.00k
        gs_image_t_init_adjust(&image, pcs, false);
11434
7.00k
        image.ImageMatrix.xx = (float)pdev->width;
11435
7.00k
        image.ImageMatrix.yy = (float)pdev->height;
11436
7.00k
        image.Width = pdev->width;
11437
7.00k
        image.Height = pdev->height;
11438
7.00k
        image.BitsPerComponent = 8<<deep;
11439
7.00k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11440
7.00k
        ctm_only_writable(pgs).xy = 0;
11441
7.00k
        ctm_only_writable(pgs).yx = 0;
11442
7.00k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11443
7.00k
        ctm_only_writable(pgs).tx = 0.0;
11444
7.00k
        ctm_only_writable(pgs).ty = 0.0;
11445
7.00k
        code = dev_proc(target, begin_typed_image) (target,
11446
7.00k
                                                    pgs, NULL,
11447
7.00k
                                                    (gs_image_common_t *)&image,
11448
7.00k
                                                    NULL, NULL, NULL,
11449
7.00k
                                                    pgs->memory, &info);
11450
7.00k
        if (code < 0)
11451
0
            goto put_accum_error;
11452
7.00k
        rect.p.x = 0;
11453
7.00k
        rect.q.x = tdev->width;
11454
15.6M
        for (y=0; y < tdev->height; y++) {
11455
15.6M
            gs_get_bits_params_t params;
11456
11457
15.6M
            params.options = (GB_ALIGN_ANY |
11458
15.6M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11459
15.6M
                              GB_OFFSET_0 |
11460
15.6M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11461
15.6M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11462
15.6M
            params.x_offset = 0;
11463
15.6M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11464
15.6M
            params.data[0] = linebuf;
11465
15.6M
            rect.p.y = y;
11466
15.6M
            rect.q.y = y+1;
11467
15.6M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11468
15.6M
                                                      &rect, &params);
11469
15.6M
            if (code < 0)
11470
8
                goto put_accum_error;
11471
15.6M
            actual_data = params.data[0];
11472
15.6M
            planes.data = actual_data;
11473
15.6M
            planes.data_x = 0;
11474
15.6M
            planes.raster = tdev->width * tdev->color_info.num_components;
11475
15.6M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11476
0
                goto put_accum_error;
11477
15.6M
        }
11478
11479
7.00k
put_accum_error:
11480
7.00k
        if (info != NULL) {
11481
7.00k
            if (code < 0)
11482
8
                (void)info->procs->end_image(info, true);
11483
6.99k
            else
11484
6.99k
                code = info->procs->end_image(info, true);
11485
7.00k
        }
11486
11487
7.00k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11488
        /* This will also decrement the device profile */
11489
7.00k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11490
7.00k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11491
        /* Now unhook the clist device and hook to the original so we can clean up */
11492
7.00k
        gx_device_set_target((gx_device_forward *)pdev,
11493
7.00k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11494
7.00k
        pdev->pclist_device = pdev->target;
11495
7.00k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11496
7.00k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11497
7.00k
        if (target_devn_params != NULL) {
11498
            /* prevent devn_free_params from freeing names still in use by target device */
11499
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11500
0
            tdev->devn_params.separations.num_separations = 0;
11501
0
        }
11502
7.00k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11503
7.00k
        if (target_devn_params != NULL) {
11504
0
            target_devn_params->separations.num_separations = save_num_separations;
11505
0
        }
11506
7.00k
        return code;    /* DON'T perform set_target */
11507
7.00k
    }
11508
1.69M
    if (code == 1) {
11509
        /* We just wrapped pdev->target, so we need to update that.*/
11510
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11511
0
        code = 0; /* We did not wrap dev. */
11512
0
    }
11513
1.69M
    *pcdev = dev;
11514
1.69M
    return code;
11515
1.70M
}
11516
11517
/*
11518
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11519
 * compositor' method.  However the compositor is disabled when we are not
11520
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11521
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11522
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11523
 * to the targer.
11524
 */
11525
static  int
11526
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11527
        const gs_composite_t * pct, gs_gstate * pgs,
11528
        gs_memory_t * mem, gx_device *cdev)
11529
0
{
11530
0
    pdf14_device *pdev = (pdf14_device *)dev;
11531
0
    gx_device * tdev = pdev->target;
11532
0
    gx_device * ndev;
11533
0
    int code;
11534
11535
0
    *pcdev = dev;
11536
0
    if (gs_is_pdf14trans_compositor(pct)) {
11537
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11538
11539
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11540
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11541
0
        return 0;
11542
0
    }
11543
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11544
0
    if (code == 1) {
11545
        /* We just wrapped tdev, so update our target. */
11546
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11547
0
        code = 0; /* We did not wrap dev. */
11548
0
    }
11549
0
    return code;
11550
0
}
11551
11552
/*
11553
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11554
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11555
 */
11556
static  int
11557
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11558
                          bool crop_blend_params,
11559
                          gs_pdf14trans_params_t *group_params)
11560
9.15M
{
11561
9.15M
    gs_pdf14trans_params_t params = { 0 };
11562
9.15M
    gx_device * pcdev;
11563
9.15M
    int changed = 0;
11564
9.15M
    int code = 0;
11565
9.15M
    gs_composite_t *pct_new = NULL;
11566
11567
9.15M
    params.crop_blend_params = crop_blend_params;
11568
11569
9.15M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11570
9.15M
    if (pgs->blend_mode != pdev->blend_mode) {
11571
29.7k
        changed |= PDF14_SET_BLEND_MODE;
11572
29.7k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11573
29.7k
    }
11574
9.15M
    if (pgs->text_knockout != pdev->text_knockout) {
11575
15.7k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11576
15.7k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11577
15.7k
    }
11578
9.15M
    if (pgs->alphaisshape != pdev->ais) {
11579
5.88k
        changed |= PDF14_SET_AIS;
11580
5.88k
        params.ais = pdev->ais = pgs->alphaisshape;
11581
5.88k
    }
11582
9.15M
    if (pgs->overprint != pdev->overprint) {
11583
34.2k
        changed |= PDF14_SET_OVERPRINT;
11584
34.2k
        params.overprint = pdev->overprint = pgs->overprint;
11585
34.2k
    }
11586
9.15M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11587
34.1k
        changed |= PDF14_SET_STROKEOVERPRINT;
11588
34.1k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11589
34.1k
    }
11590
9.15M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11591
62.4k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11592
62.4k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11593
62.4k
    }
11594
9.15M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11595
50.1k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11596
50.1k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11597
50.1k
    }
11598
9.15M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11599
101k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11600
101k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11601
101k
        if_debug0m('v', pgs->memory,
11602
101k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11603
101k
    }
11604
9.15M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11605
102k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11606
102k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11607
102k
        if_debug0m('v', pgs->memory,
11608
102k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11609
102k
    }
11610
9.15M
    if (crop_blend_params) {
11611
86.0k
        params.ctm = group_params->ctm;
11612
86.0k
        params.bbox = group_params->bbox;
11613
86.0k
    }
11614
9.15M
    params.changed = changed;
11615
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11616
       now to the target.  Otherwise we send the compositor action
11617
       to the pdf14 device at this time.  This is due to the fact that we
11618
       need to often perform this operation when we are already starting to
11619
       do a compositor action */
11620
9.15M
    if (changed != 0) {
11621
322k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11622
322k
        if (code < 0)
11623
0
            return code;
11624
322k
        code = dev_proc(pdev->target, composite)
11625
322k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11626
322k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11627
322k
    }
11628
9.15M
    return code;
11629
9.15M
}
11630
11631
/*
11632
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11633
 * writing the clist.
11634
 */
11635
static  int
11636
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11637
                           gx_path *ppath, const gx_fill_params *params,
11638
                           const gx_drawing_color *pdcolor,
11639
                           const gx_clip_path *pcpath)
11640
2.99M
{
11641
2.99M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11642
2.99M
    gs_gstate new_pgs = *pgs;
11643
2.99M
    int code;
11644
2.99M
    gs_pattern2_instance_t *pinst = NULL;
11645
2.99M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11646
2.99M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11647
2.99M
    gsicc_rendering_param_t render_cond;
11648
2.99M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11649
2.99M
    int push_group = 0;
11650
11651
2.99M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11652
2.99M
    if (code < 0)
11653
0
        return code;
11654
2.99M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11655
2.99M
    if (code < 0)
11656
0
        return code;
11657
11658
2.99M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11659
1.39k
        check_device_separable(dev);
11660
11661
2.99M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11662
2.99M
                          &render_cond);
11663
2.99M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11664
2.99M
                          &render_cond);
11665
11666
    /*
11667
     * Ensure that that the PDF 1.4 reading compositor will have the current
11668
     * blending parameters.  This is needed since the fill_rectangle routines
11669
     * do not have access to the gs_gstate.  Thus we have to pass any
11670
     * changes explictly.
11671
     */
11672
2.99M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11673
2.99M
    if (code < 0)
11674
0
        return code;
11675
    /* If we are doing a shading fill and we are in a transparency group of a
11676
       different color space, then we do not want to do the shading in the
11677
       device color space. It must occur in the source space.  To handle it in
11678
       the device space would require knowing all the nested transparency group
11679
       color space as well as the transparency.  Some of the shading code ignores
11680
       this, so we have to pass on the clist_writer device to enable proper
11681
       mapping to the transparency group color space. */
11682
11683
2.99M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11684
        /* Non-idempotent blends require a transparency
11685
         * group to be pushed because shadings might
11686
         * paint several pixels twice. */
11687
77.2k
        push_group = pgs->fillconstantalpha != 1.0 ||
11688
73.6k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11689
77.2k
        pinst =
11690
77.2k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11691
77.2k
           pinst->saved->has_transparency = true;
11692
           /* The transparency color space operations are driven by the pdf14
11693
              clist writer device.  */
11694
77.2k
           pinst->saved->trans_device = dev;
11695
77.2k
    }
11696
2.99M
    if (push_group) {
11697
3.67k
        gs_fixed_rect box;
11698
3.67k
        gs_fixed_rect dev_bbox;
11699
11700
3.67k
        if (pcpath) {
11701
3.67k
            gx_cpath_outer_box(pcpath, &box);
11702
3.67k
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11703
3.67k
            rect_intersect(box, dev_bbox);
11704
3.67k
        } else
11705
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11706
11707
3.67k
        if (ppath) {
11708
26
            gs_fixed_rect path_box;
11709
11710
26
            gx_path_bbox(ppath, &path_box);
11711
26
            if (box.p.x < path_box.p.x)
11712
26
                box.p.x = path_box.p.x;
11713
26
            if (box.p.y < path_box.p.y)
11714
26
                box.p.y = path_box.p.y;
11715
26
            if (box.q.x > path_box.q.x)
11716
26
                box.q.x = path_box.q.x;
11717
26
            if (box.q.y > path_box.q.y)
11718
26
                box.q.y = path_box.q.y;
11719
26
        }
11720
11721
3.67k
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11722
            /* No need to do anything */
11723
891
            if (pinst != NULL) {
11724
891
                pinst->saved->trans_device = NULL;
11725
891
            }
11726
891
            return 0;
11727
891
        }
11728
11729
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11730
2.78k
        code = push_shfill_group(pdev, &new_pgs, &box);
11731
2.78k
    } else
11732
2.99M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11733
2.99M
    if (code >= 0) {
11734
2.99M
        new_pgs.trans_device = dev;
11735
2.99M
        new_pgs.has_transparency = true;
11736
2.99M
        if (gx_dc_is_pattern2_color(pdcolor))
11737
76.4k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11738
2.92M
        else
11739
2.92M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11740
2.99M
        new_pgs.trans_device = NULL;
11741
2.99M
        new_pgs.has_transparency = false;
11742
2.99M
    }
11743
2.99M
    if (code >= 0 && push_group) {
11744
2.78k
        code = pop_shfill_group(&new_pgs);
11745
2.78k
        if (code >= 0)
11746
2.78k
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11747
2.78k
    }
11748
2.99M
    if (pinst != NULL){
11749
76.4k
        pinst->saved->trans_device = NULL;
11750
76.4k
    }
11751
2.99M
    return code;
11752
2.99M
}
11753
11754
/*
11755
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11756
 * writing the clist.
11757
 */
11758
static  int
11759
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11760
                             gx_path *ppath, const gx_stroke_params *params,
11761
                             const gx_drawing_color *pdcolor,
11762
                             const gx_clip_path *pcpath)
11763
852k
{
11764
852k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11765
852k
    gs_gstate new_pgs = *pgs;
11766
852k
    int code = 0;
11767
852k
    gs_pattern2_instance_t *pinst = NULL;
11768
852k
    int push_group = 0;
11769
11770
    /*
11771
     * Ensure that that the PDF 1.4 reading compositor will have the current
11772
     * blending parameters.  This is needed since the fill_rectangle routines
11773
     * do not have access to the gs_gstate.  Thus we have to pass any
11774
     * changes explictly.
11775
     */
11776
852k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11777
852k
    if (code < 0)
11778
0
        return code;
11779
    /* If we are doing a shading stroke and we are in a transparency group of a
11780
       different color space, then we need to get the proper device information
11781
       passed along so that we use the correct color procs and colorinfo about
11782
       the transparency device and not the final target device */
11783
852k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11784
        /* Non-idempotent blends require a transparency
11785
         * group to be pushed because shadings might
11786
         * paint several pixels twice. */
11787
333
        push_group = pgs->strokeconstantalpha != 1.0 ||
11788
333
               !blend_is_idempotent(gs_currentblendmode(pgs));
11789
333
        if (pdev->color_model_stack != NULL) {
11790
333
            pinst =
11791
333
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11792
333
            pinst->saved->has_transparency = true;
11793
            /* The transparency color space operations are driven
11794
              by the pdf14 clist writer device.  */
11795
333
            pinst->saved->trans_device = dev;
11796
333
        }
11797
333
    }
11798
852k
    if (push_group) {
11799
0
        gs_fixed_rect box;
11800
0
        if (pcpath)
11801
0
            gx_cpath_outer_box(pcpath, &box);
11802
0
        else
11803
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11804
0
        if (ppath) {
11805
0
            gs_fixed_rect path_box;
11806
0
            gs_fixed_point expansion;
11807
11808
0
            gx_path_bbox(ppath, &path_box);
11809
            /* Expand the path bounding box by the scaled line width. */
11810
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11811
                /* The expansion is so large it caused a limitcheck. */
11812
0
                path_box.p.x = path_box.p.y = min_fixed;
11813
0
                path_box.q.x = path_box.q.y = max_fixed;
11814
0
            } else {
11815
0
                expansion.x += pgs->fill_adjust.x;
11816
0
                expansion.y += pgs->fill_adjust.y;
11817
                /*
11818
                 * It's theoretically possible for the following computations to
11819
                 * overflow, so we need to check for this.
11820
                 */
11821
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11822
0
                                path_box.p.x - expansion.x);
11823
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11824
0
                                path_box.p.y - expansion.y);
11825
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11826
0
                                path_box.q.x + expansion.x);
11827
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11828
0
                                path_box.q.y + expansion.y);
11829
0
            }
11830
0
            if (box.p.x < path_box.p.x)
11831
0
                box.p.x = path_box.p.x;
11832
0
            if (box.p.y < path_box.p.y)
11833
0
                box.p.y = path_box.p.y;
11834
0
            if (box.q.x > path_box.q.x)
11835
0
                box.q.x = path_box.q.x;
11836
0
            if (box.q.y > path_box.q.y)
11837
0
                box.q.y = path_box.q.y;
11838
0
        }
11839
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11840
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11841
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11842
0
    } else
11843
852k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11844
11845
852k
    if (code >= 0) {
11846
852k
        new_pgs.trans_device = dev;
11847
852k
        new_pgs.has_transparency = true;
11848
852k
        if (gx_dc_is_pattern2_color(pdcolor))
11849
333
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11850
852k
        else
11851
852k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11852
852k
        new_pgs.trans_device = NULL;
11853
852k
        new_pgs.has_transparency = false;
11854
852k
    }
11855
852k
    if (code >= 0 && push_group) {
11856
0
        code = pop_shfill_group(&new_pgs);
11857
0
        if (code >= 0)
11858
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11859
0
    }
11860
852k
    if (pinst != NULL)
11861
333
        pinst->saved->trans_device = NULL;
11862
852k
    return code;
11863
852k
}
11864
11865
/* Set up work for doing shading patterns in fill stroke through
11866
   the clist.  We have to do all the dirty work now since we are
11867
   going through the default fill and stroke operations individually */
11868
static int
11869
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11870
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11871
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11872
    const gx_clip_path* pcpath)
11873
0
{
11874
0
    union {
11875
0
        const gs_gstate *cpgs;
11876
0
        gs_gstate *pgs;
11877
0
    } const_breaker;
11878
0
    gs_gstate *pgs;
11879
0
    int code, code2;
11880
0
    gs_transparency_group_params_t params = { 0 };
11881
0
    gs_fixed_rect clip_bbox;
11882
0
    gs_rect bbox, group_stroke_box;
11883
0
    float fill_alpha;
11884
0
    float stroke_alpha;
11885
0
    gs_blend_mode_t blend_mode;
11886
0
    gs_fixed_rect path_bbox;
11887
0
    int expansion_code;
11888
0
    gs_fixed_point expansion;
11889
11890
    /* Break const just once, neatly */
11891
0
    const_breaker.cpgs = cpgs;
11892
0
    pgs = const_breaker.pgs;
11893
11894
0
    fill_alpha = pgs->fillconstantalpha;
11895
0
    stroke_alpha = pgs->strokeconstantalpha;
11896
0
    blend_mode = pgs->blend_mode;
11897
11898
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11899
0
    if (code < 0 && code != gs_error_unknownerror)
11900
0
        return code;
11901
0
    if (code == gs_error_unknownerror) {
11902
        /* didn't get clip box from gx_curr_fixed_bbox */
11903
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11904
0
        clip_bbox.q.x = int2fixed(dev->width);
11905
0
        clip_bbox.q.y = int2fixed(dev->height);
11906
0
    }
11907
0
    if (pcpath)
11908
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11909
11910
    /* expand the ppath using stroke expansion rule, then intersect it */
11911
0
    code = gx_path_bbox(ppath, &path_bbox);
11912
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11913
0
        return 0;   /* ignore empty path */
11914
0
    if (code < 0)
11915
0
        return code;
11916
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11917
0
    if (expansion_code >= 0) {
11918
0
        path_bbox.p.x -= expansion.x;
11919
0
        path_bbox.p.y -= expansion.y;
11920
0
        path_bbox.q.x += expansion.x;
11921
0
        path_bbox.q.y += expansion.y;
11922
0
    }
11923
0
    rect_intersect(path_bbox, clip_bbox);
11924
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11925
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11926
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11927
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11928
11929
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11930
0
    if (code < 0)
11931
0
        return code;
11932
11933
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11934
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11935
0
        pgs->overprint && pgs->stroke_overprint &&
11936
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11937
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11938
11939
0
        params.Isolated = false;
11940
0
        params.group_color_type = UNKNOWN;
11941
0
        params.Knockout = false;
11942
0
        params.page_group = false;
11943
0
        params.group_opacity = fill_alpha;
11944
0
        params.group_shape = 1.0;
11945
11946
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11947
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11948
0
        if (code < 0)
11949
0
            return code;
11950
11951
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11952
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11953
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11954
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11955
11956
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11957
0
        if (code < 0)
11958
0
            goto cleanup;
11959
11960
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11961
0
        if (code < 0)
11962
0
            goto cleanup;
11963
11964
0
    } else {
11965
        /* Push a non-isolated knockout group. Do not change the alpha or
11966
           blend modes */
11967
0
        params.Isolated = false;
11968
0
        params.group_color_type = UNKNOWN;
11969
0
        params.Knockout = true;
11970
0
        params.page_group = false;
11971
0
        params.group_opacity = 1.0;
11972
0
        params.group_shape = 1.0;
11973
11974
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11975
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11976
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11977
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11978
11979
        /* restore blend mode for actual drawing in the group */
11980
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11981
11982
0
        if (fill_alpha > 0.0) {
11983
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11984
11985
            /* If we are in an overprint situation, set the blend mode to compatible
11986
               overprint */
11987
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11988
0
                pgs->overprint &&
11989
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11990
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11991
11992
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11993
0
            if (code < 0)
11994
0
                goto cleanup;
11995
11996
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11997
0
                pgs->overprint &&
11998
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11999
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12000
0
        }
12001
12002
0
        if (stroke_alpha > 0.0) {
12003
            /* Note that the stroke can end up looking like a fill here */
12004
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
12005
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
12006
12007
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
12008
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
12009
12010
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
12011
0
            if (code < 0)
12012
0
                goto cleanup;
12013
12014
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
12015
0
                pgs->overprint &&
12016
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
12017
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12018
0
        }
12019
0
    }
12020
12021
0
cleanup:
12022
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
12023
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
12024
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
12025
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
12026
12027
    /* Restore where we were. If an error occured while in the group push
12028
       return that error code but try to do the cleanup */
12029
0
    code2 = gs_end_transparency_group(pgs);
12030
0
    if (code2 < 0) {
12031
        /* At this point things have gone very wrong. We should just shut down */
12032
0
        code = gs_abort_pdf14trans_device(pgs);
12033
0
        return code2;
12034
0
    }
12035
12036
    /* Restore if there were any changes */
12037
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
12038
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
12039
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
12040
12041
0
    return code;
12042
0
}
12043
12044
/*
12045
 * fill_path routine for the PDF 1.4 transaprency compositor device for
12046
 * writing the clist.
12047
 */
12048
static  int
12049
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
12050
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
12051
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
12052
                             const gx_clip_path *pcpath)
12053
17.1k
{
12054
17.1k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12055
17.1k
    gs_gstate new_pgs = *pgs;
12056
17.1k
    int code;
12057
12058
17.1k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12059
17.0k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12060
94
        return 0;
12061
12062
    /*
12063
     * Ensure that that the PDF 1.4 reading compositor will have the current
12064
     * blending parameters.  This is needed since the fill_rectangle routines
12065
     * do not have access to the gs_gstate.  Thus we have to pass any
12066
     * changes explictly.
12067
     */
12068
17.0k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12069
17.0k
    if (code < 0)
12070
0
        return code;
12071
    /* If we are doing a shading fill or stroke, the clist can't
12072
       deal with this and end up in the pdf_fill_stroke operation.
12073
       We will need to break up the fill stroke now and do
12074
       the appropriate group pushes and set up. */
12075
12076
17.0k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12077
17.0k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12078
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12079
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12080
0
    }
12081
17.0k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12082
17.0k
    new_pgs.trans_device = dev;
12083
17.0k
    new_pgs.has_transparency = true;
12084
17.0k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12085
17.0k
                                       params_stroke, pdevc_stroke, pcpath);
12086
17.0k
    new_pgs.trans_device = NULL;
12087
17.0k
    new_pgs.has_transparency = false;
12088
17.0k
    return code;
12089
17.0k
}
12090
12091
/*
12092
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12093
 * writing the clist.
12094
 */
12095
static  int
12096
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12097
                 const gs_text_params_t * text, gs_font * font,
12098
                 const gx_clip_path * pcpath,
12099
                 gs_text_enum_t ** ppenum)
12100
5.10M
{
12101
5.10M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12102
5.10M
    gs_text_enum_t *penum;
12103
5.10M
    int code;
12104
5.10M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12105
5.10M
    float opacity = pgs->fillconstantalpha;
12106
5.10M
    float shape = 1.0;
12107
5.10M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12108
5.10M
    bool draw = !(text->operation & TEXT_DO_NONE);
12109
5.10M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12110
5.10M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12111
5.10M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12112
12113
5.10M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12114
    /*
12115
     * Ensure that that the PDF 1.4 reading compositor will have the current
12116
     * blending parameters.  This is needed since the fill_rectangle routines
12117
     * do not have access to the gs_gstate.  Thus we have to pass any
12118
     * changes explictly.
12119
     */
12120
5.10M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12121
5.10M
    if (code < 0)
12122
0
        return code;
12123
    /* Pass text_begin to the target */
12124
5.10M
    code = gx_forward_text_begin(dev, pgs, text, font,
12125
5.10M
                                 pcpath, &penum);
12126
5.10M
    if (code < 0)
12127
1.52k
        return code;
12128
12129
   /* Catch case where we already pushed a group and are trying to push another one.
12130
   In that case, we will pop the current one first, as we don't want to be left
12131
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12132
   will not be caught until we do the put_image and notice that the stack is not
12133
   empty. */
12134
5.10M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12135
0
        code = gs_end_transparency_group(pgs);
12136
0
        if (code < 0)
12137
0
            return code;
12138
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12139
0
    }
12140
12141
    /* We may need to push a non-isolated transparency group if the following
12142
    is true.
12143
    1) We are not currently in one that we pushed for text.  This is
12144
    is determined by looking at the pdf14 device.
12145
    2) The blend mode is not Normal or the opacity is not 1.0
12146
    3) Text knockout is set to true
12147
    4) And we are actually drawing text
12148
    */
12149
12150
5.10M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12151
5.10M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12152
5.08M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12153
17.9k
        text_mode != 3 && /* don't bother with invisible text */
12154
17.8k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12155
4.24k
        if (draw) {
12156
4.24k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12157
4.24k
            if (code == 0)
12158
4.24k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12159
4.24k
        }
12160
4.24k
    }
12161
5.10M
    *ppenum = (gs_text_enum_t *)penum;
12162
5.10M
    return code;
12163
5.10M
}
12164
12165
static  int
12166
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12167
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12168
                           const gs_int_rect * prect,
12169
                           const gx_drawing_color * pdcolor,
12170
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12171
                           gx_image_enum_common_t ** pinfo)
12172
84.4k
{
12173
84.4k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12174
84.4k
    int code;
12175
84.4k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12176
84.4k
    const gs_image_t *pim = (const gs_image_t *)pic;
12177
84.4k
    gx_image_enum *penum;
12178
84.4k
    gx_color_tile *ptile;
12179
84.4k
    gs_rect bbox_in, bbox_out;
12180
84.4k
    gs_transparency_group_params_t tgp;
12181
    /*
12182
     * Ensure that that the PDF 1.4 reading compositor will have the current
12183
     * blending parameters.  This is needed since the fill_rectangle routines
12184
     * do not have access to the gs_gstate.  Thus we have to pass any
12185
     * changes explictly.
12186
     */
12187
84.4k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12188
84.4k
    if (code < 0)
12189
0
        return code;
12190
    /* Pass image to the target */
12191
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12192
       case the clist writer cannot handle this image itself.  In such a case,
12193
       we want to make sure we dont use the target device.  I don't necc. like
12194
       doing it this way.  Probably need to go back and do something a bit
12195
       more elegant. */
12196
84.4k
    pgs_noconst->has_transparency = true;
12197
84.4k
    pgs_noconst->trans_device = dev;
12198
12199
    /* If we are filling an image mask with a pattern that has a transparency
12200
       then we need to do some special handling */
12201
84.4k
    if (pim->ImageMask) {
12202
71
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12203
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12204
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12205
0
                    ptile = pdcolor->colors.pattern.p_tile;
12206
                    /* Set up things in the ptile so that we get the proper
12207
                       blending etc */
12208
                    /* Set the blending procs and the is_additive setting based
12209
                       upon the number of channels */
12210
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12211
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12212
0
                        ptile->ttrans->is_additive = true;
12213
0
                    } else {
12214
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12215
0
                        ptile->ttrans->is_additive = false;
12216
0
                    }
12217
                    /* Set the blending mode in the ptile based upon the current
12218
                       setting in the gs_gstate */
12219
0
                    ptile->blending_mode = pgs->blend_mode;
12220
                    /* Set the procs so that we use the proper filling method. */
12221
                    /* Let the imaging stuff get set up */
12222
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12223
0
                                                        prect, pdcolor,
12224
0
                                                        pcpath, mem, pinfo);
12225
0
                    if (code < 0)
12226
0
                        return code;
12227
12228
0
                    penum = (gx_image_enum *) *pinfo;
12229
                    /* Apply inverse of the image matrix to our
12230
                       image size to get our bounding box. */
12231
0
                    bbox_in.p.x = 0;
12232
0
                    bbox_in.p.y = 0;
12233
0
                    bbox_in.q.x = pim->Width;
12234
0
                    bbox_in.q.y = pim->Height;
12235
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12236
0
                                                     &bbox_out);
12237
0
                    if (code < 0)
12238
0
                        return code;
12239
                    /* Set up a compositor action for pushing the group */
12240
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12241
0
                    tgp.Isolated = true;
12242
0
                    tgp.Knockout = false;
12243
0
                    tgp.page_group = false;
12244
0
                    tgp.mask_id = 0;
12245
0
                    tgp.image_with_SMask = false;
12246
0
                    tgp.idle = false;
12247
0
                    tgp.iccprofile = NULL;
12248
0
                    tgp.icc_hashcode = 0;
12249
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12250
0
                    tgp.ColorSpace = NULL;
12251
0
                    tgp.text_group = 0;
12252
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12253
0
                    tgp.group_shape = 1.0;
12254
                    /* This will handle the compositor command */
12255
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12256
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12257
0
                    ptile->ttrans->image_render = penum->render;
12258
0
                    penum->render = &pdf14_pattern_trans_render;
12259
0
                    ptile->trans_group_popped = false;
12260
0
                    pgs_noconst->has_transparency = false;
12261
0
                    pgs_noconst->trans_device = NULL;
12262
0
                    return code;
12263
0
                }
12264
0
            }
12265
21
        }
12266
71
    }
12267
    /* This basically tries high level images for clist. If that fails
12268
       then we do the default */
12269
84.4k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12270
84.4k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12271
84.4k
    if (code < 0){
12272
24.2k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12273
24.2k
                                        pdcolor, pcpath, mem, pinfo);
12274
24.2k
        pgs_noconst->has_transparency = false;
12275
24.2k
        pgs_noconst->trans_device = NULL;
12276
24.2k
        return code;
12277
60.1k
    } else {
12278
60.1k
        pgs_noconst->has_transparency = false;
12279
60.1k
        pgs_noconst->trans_device = NULL;
12280
60.1k
        return code;
12281
60.1k
    }
12282
84.4k
}
12283
12284
static int
12285
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12286
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12287
2.45k
{
12288
2.45k
    int code;
12289
12290
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12291
2.45k
                                  x, y, w, h, plane_height);
12292
2.45k
    return code;
12293
2.45k
}
12294
12295
static int
12296
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12297
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12298
16.9k
{
12299
16.9k
    int code;
12300
16.9k
    pdf14_clist_device *p14dev;
12301
16.9k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12302
12303
16.9k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12304
16.9k
    if (code < 0)
12305
0
        return code;
12306
    /*
12307
     * Set the color_info of the clist device to match the compositing
12308
     * device.  We will restore it when the compositor is popped.
12309
     * See pdf14_clist_composite for the restore.  Do the
12310
     * same with the gs_gstate's get_cmap_procs.  We do not want
12311
     * the gs_gstate to use transfer functions on our color values.
12312
     * The transfer functions will be applied at the end after we
12313
     * have done our PDF 1.4 blend operations.
12314
     */
12315
16.9k
    p14dev = (pdf14_clist_device *)(*pcdev);
12316
16.9k
    p14dev->saved_target_color_info = dev->color_info;
12317
16.9k
    dev->color_info = (*pcdev)->color_info;
12318
    /* Make sure that we keep the anti-alias information though */
12319
16.9k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12320
16.9k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12321
12322
    /* adjust the clist_color_info now */
12323
16.9k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12324
16.9k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12325
16.9k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12326
16.9k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12327
16.9k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12328
12329
16.9k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12330
16.9k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12331
16.9k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12332
16.9k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12333
16.9k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12334
16.9k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12335
16.9k
    p14dev->saved_target_get_color_mapping_procs =
12336
16.9k
                              dev_proc(dev, get_color_mapping_procs);
12337
16.9k
    p14dev->saved_target_get_color_comp_index =
12338
16.9k
                              dev_proc(dev, get_color_comp_index);
12339
16.9k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12340
16.9k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12341
16.9k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12342
16.9k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12343
16.9k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12344
16.9k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12345
16.9k
    gx_set_cmap_procs(pgs, dev);
12346
16.9k
    return code;
12347
16.9k
}
12348
/*
12349
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12350
 * to create a compositing device for clist writing.  The primary purpose of
12351
 * this device is to provide support for the process color model in which
12352
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12353
 * model of the output device.)  The actual work of compositing the image is
12354
 * done on the output (reader) side of the clist.
12355
 */
12356
static  int
12357
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12358
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12359
692k
{
12360
692k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12361
692k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12362
692k
    int code = 0;
12363
12364
    /* We only handle the push/pop operations */
12365
692k
    switch (pdf14pct->params.pdf14_op) {
12366
16.9k
        case PDF14_PUSH_DEVICE:
12367
16.9k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12368
            /* Change (non-error) code to 1 to indicate that we created
12369
             * a device. */
12370
16.9k
            if (code >= 0)
12371
16.9k
                code = 1;
12372
16.9k
            return code;
12373
12374
16.1k
        case PDF14_POP_DEVICE:
12375
16.1k
            code = clist_writer_check_empty_cropping_stack(cdev);
12376
16.1k
            break;
12377
12378
6.81k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12379
86.0k
        case PDF14_BEGIN_TRANS_GROUP:
12380
86.0k
            { /* HACK: store mask_id into our params for subsequent
12381
                   calls of c_pdf14trans_write. To do this we must
12382
                   break const. */
12383
86.0k
                gs_pdf14trans_t * pdf14pct_noconst;
12384
12385
86.0k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12386
                /* What ever the current mask ID is, that is the
12387
                   softmask group through which this transparency
12388
                   group must be rendered. Store it now. */
12389
86.0k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12390
86.0k
                if_debug1m('v', pgs->memory,
12391
86.0k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12392
86.0k
                           cdev->mask_id);
12393
86.0k
            }
12394
86.0k
            break;
12395
81.7k
        case PDF14_END_TRANS_GROUP:
12396
86.0k
        case PDF14_END_TRANS_TEXT_GROUP:
12397
86.0k
            code = 0; /* A place for breakpoint. */
12398
86.0k
            break;
12399
87.1k
        case PDF14_BEGIN_TRANS_MASK:
12400
            /* A new mask has been started */
12401
87.1k
            cdev->mask_id = ++cdev->mask_id_count;
12402
            /* replacing is set everytime that we
12403
               have a zpushtransparencymaskgroup */
12404
87.1k
            { /* HACK: store mask_id into our params for subsequent
12405
                   calls of c_pdf14trans_write. To do this we must
12406
                   break const. */
12407
87.1k
                gs_pdf14trans_t * pdf14pct_noconst;
12408
12409
87.1k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12410
87.1k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12411
87.1k
                if_debug1m('v', pgs->memory,
12412
87.1k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12413
87.1k
                           cdev->mask_id);
12414
87.1k
            }
12415
87.1k
            break;
12416
39.3k
        case PDF14_END_TRANS_MASK:
12417
39.3k
            code = 0; /* A place for breakpoint. */
12418
39.3k
            break;
12419
0
        case PDF14_PUSH_TRANS_STATE:
12420
0
            code = 0; /* A place for breakpoint. */
12421
0
            break;
12422
38.1k
        case PDF14_POP_TRANS_STATE:
12423
38.1k
            code = 0; /* A place for breakpoint. */
12424
38.1k
            break;
12425
0
        case PDF14_ABORT_DEVICE:
12426
0
            code = 0;
12427
0
            break;
12428
0
        case PDF14_PUSH_SMASK_COLOR:
12429
0
            *pcdev = dev;
12430
0
            return 0;
12431
0
            break;
12432
0
        case PDF14_POP_SMASK_COLOR:
12433
0
            *pcdev = dev;
12434
0
            return 0;
12435
0
            break;
12436
322k
        default:
12437
322k
            break;   /* do nothing for remaining ops */
12438
692k
    }
12439
675k
    *pcdev = dev;
12440
675k
    if (code < 0)
12441
0
        return code;
12442
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12443
       apply_composite. */
12444
675k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12445
    /* Wrote an extra ctm. */
12446
675k
    cmd_clear_known(cdev, ctm_known);
12447
12448
675k
    return code;
12449
675k
}
12450
12451
/*
12452
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12453
 * device color_info data match the compositing device.  We need to do this
12454
 * since the PDF 1.4 transparency compositing device may use a different
12455
 * process color model than the output device.  We do not need to modify the
12456
 * color related device procs since the compositing device has its own.  We
12457
 * restore the color_info data when the transparency device is popped.
12458
 */
12459
static  int
12460
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12461
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12462
51.3M
{
12463
51.3M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12464
51.3M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12465
51.3M
    gs_devn_params * pclist_devn_params;
12466
51.3M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12467
51.3M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12468
51.3M
    gsicc_rendering_param_t render_cond;
12469
51.3M
    cmm_dev_profile_t *dev_profile;
12470
12471
51.3M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12472
51.3M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12473
51.3M
                          &render_cond);
12474
12475
    /* If we are using the blending color space, then be sure to use that. */
12476
51.3M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12477
0
        dev_profile->blend_profile != NULL)
12478
0
        cl_icc_profile = dev_profile->blend_profile;
12479
51.3M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12480
0
        dev_profile->oi_profile != NULL)
12481
0
        cl_icc_profile = dev_profile->oi_profile;
12482
12483
51.3M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12484
51.3M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12485
51.3M
                          &render_cond);
12486
    /*
12487
     * We only handle the push/pop operations. Save and restore the color_info
12488
     * field for the clist device.  This is needed since the process color
12489
     * model of the clist device needs to match the PDF 1.4 compositing
12490
     * device.
12491
     */
12492
51.3M
    switch (pdf14pct->params.pdf14_op) {
12493
1.97M
    case PDF14_PUSH_DEVICE:
12494
        /* Overprint simulation sets the profile at prototype creation, as does
12495
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12496
1.97M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12497
1.97M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12498
1.97M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12499
1.97M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12500
1.97M
                -1, "c_pdf14trans_clist_read_update");
12501
1.97M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12502
1.97M
        }
12503
            /*
12504
             * If we are blending using spot colors (i.e. the output device
12505
             * supports spot colors) then we need to transfer
12506
             * color info from the clist PDF 1.4 compositing reader device
12507
             * to the clist writer PDF 1.4 compositing device.
12508
             * This info was transfered from that device to the output
12509
             * device as a set of device parameters.  However the clist
12510
             * reader PDF 1.4 compositing device did not exist when the
12511
             * device parameters were read from the clist.  So that info
12512
             * was buffered into the output device.
12513
             */
12514
1.97M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12515
1.97M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12516
6.12k
                int num_comp = p14dev->color_info.num_components;
12517
6.12k
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12518
                /*
12519
                 * The number of components for the PDF14 device is the sum
12520
                 * of the process components and the number of spot colors
12521
                 * for the page.  If the color capabilities of the parent
12522
                 * device (which coming into this are the same as the p14dev)
12523
                 * are smaller than the number of page spot colors then
12524
                 * use that for the number of components. Otherwise use
12525
                 * the page_spot_colors.  The exception is, if we had used
12526
                 * the sICCOutputColors setting, then just use that, which
12527
                 * should be already baked into num_comp. With clist patterns,
12528
                 * cdev->icc_struct may be null.
12529
                 */
12530
12531
6.12k
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12532
6.12k
                    p14dev->devn_params.page_spot_colors =
12533
6.12k
                        pclist_devn_params->page_spot_colors;
12534
6.12k
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12535
0
                        if (p14dev->num_planar_planes > 0)
12536
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12537
0
                        p14dev->color_info.num_components = num_comp;
12538
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12539
6.12k
                    } else {
12540
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12541
6.12k
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12542
6.12k
                            int n = p14dev->num_std_colorants +
12543
6.12k
                                    p14dev->devn_params.page_spot_colors + has_tags;
12544
6.12k
                            if (p14dev->num_planar_planes > 0)
12545
6.12k
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12546
6.12k
                            p14dev->color_info.num_components = n;
12547
6.12k
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12548
6.12k
                        }
12549
6.12k
                    }
12550
6.12k
                }
12551
                /* limit the num_components to the max. */
12552
6.12k
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12553
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12554
                /* Transfer the data for the spot color names
12555
                   But we have to free what may be there before we do this */
12556
6.12k
                devn_free_params((gx_device*) p14dev);
12557
6.12k
                p14dev->devn_params.separations =
12558
6.12k
                    pclist_devn_params->pdf14_separations;
12559
6.12k
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12560
6.12k
                if (num_comp != p14dev->color_info.num_components) {
12561
                    /* Historically, there has been a comment here:
12562
                       "When the pdf14 device is opened it creates a context and some
12563
                       soft mask related objects.  The push device compositor action
12564
                       will have already created these but they are the wrong size.
12565
                       We must destroy them though before reopening the device."
12566
                       I can't see why this is the case, and testing in the cluster
12567
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12568
                       shows that this freeing/NULLing the ctx here causes problems
12569
                       when the freed ctx is reinserted at the end of clist pattern
12570
                       files. Accordingly, I'm removing the freeing/NULLing for now
12571
                       at least. */
12572
0
                    int code = dev_proc(tdev, open_device) (tdev);
12573
0
                    if (code < 0)
12574
0
                        return code;
12575
0
                }
12576
6.12k
            }
12577
            /* Check if we need to swap out the ICC profile for the pdf14
12578
               device.  This will occur if our source profile for our device
12579
               happens to be something like CIELAB.  Then we will blend in
12580
               RGB (unless a trans group is specified) */
12581
1.97M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12582
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12583
0
                                        -1, "c_pdf14trans_clist_read_update");
12584
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12585
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12586
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12587
                /* Keep a pointer to the clist device */
12588
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12589
0
            }
12590
1.97M
            break;
12591
12592
1.97M
        case PDF14_POP_DEVICE:
12593
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12594
                    the clist playback. This code is not executed while clist
12595
                    writing. */
12596
            cdev->color_info = p14dev->saved_target_color_info;
12597
#     endif
12598
1.97M
           break;
12599
12600
47.3M
        default:
12601
47.3M
            break;   /* do nothing for remaining ops */
12602
51.3M
    }
12603
12604
51.3M
    return 0;
12605
51.3M
}
12606
12607
/*
12608
 * Get cropping for the compositor command.
12609
 */
12610
static  int
12611
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12612
                          int cropping_min, int cropping_max)
12613
692k
{
12614
692k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12615
692k
    switch (pdf14pct->params.pdf14_op) {
12616
16.9k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12617
16.1k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12618
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12619
6.81k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12620
86.0k
        case PDF14_BEGIN_TRANS_GROUP:
12621
86.0k
            { gs_int_rect rect;
12622
12623
                /* Text group always uses parents size*/
12624
86.0k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12625
4.24k
                    *ry = cropping_min;
12626
4.24k
                    *rheight = cropping_max - *ry;
12627
81.7k
                } else {
12628
81.7k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12629
81.7k
                        &pdf14pct->params.bbox, &rect);
12630
                    /* We have to crop this by the parent object.   */
12631
81.7k
                    *ry = max(rect.p.y, cropping_min);
12632
81.7k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12633
81.7k
                }
12634
86.0k
                return PUSHCROP; /* Push cropping. */
12635
6.81k
            }
12636
87.1k
        case PDF14_BEGIN_TRANS_MASK:
12637
87.1k
            { gs_int_rect rect;
12638
12639
87.1k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12640
87.1k
                                                    &pdf14pct->params.bbox, &rect);
12641
                /* We have to crop this by the parent object and worry about the BC outside
12642
                   the range, except for image SMask which don't affect areas outside the image.
12643
                   The presence of a transfer function opens the possibility of issues with this */
12644
87.1k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12645
36.0k
                      pdf14pct->params.function_is_identity)) {
12646
                    /* In this case there will not be a background effect to
12647
                       worry about.  The mask will not have any effect outside
12648
                       the bounding box.  This is NOT the default or common case. */
12649
36.0k
                    *ry = max(rect.p.y, cropping_min);
12650
36.0k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12651
36.0k
                    return PUSHCROP; /* Push cropping. */
12652
51.1k
                }  else {
12653
                    /* We need to make the soft mask range as large as the parent
12654
                       due to the fact that the background color can have an impact
12655
                       OUTSIDE the bounding box of the soft mask */
12656
51.1k
                    *ry = cropping_min;
12657
51.1k
                    *rheight = cropping_max - cropping_min;
12658
51.1k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12659
47.8k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12660
3.31k
                    else
12661
3.31k
                        return PUSHCROP; /* Push cropping. */
12662
51.1k
                }
12663
87.1k
            }
12664
81.7k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12665
4.22k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12666
39.3k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12667
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12668
38.1k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12669
322k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12670
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12671
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12672
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12673
692k
    }
12674
0
    return ALLBANDS;
12675
692k
}
12676
12677
/*
12678
 * This routine will check to see if the color component name matches those
12679
 * that are available amoung the current device's color components.  If the
12680
 * color name is known to the output device then we add it to the list of
12681
 * colorants for the PDF 1.4 transparency compositor.
12682
 *
12683
 * Notes:  There are currently three different versions of The PDF 1.4
12684
 * transparency compositor device.  The choice of which one is being used
12685
 * depends upon the process color model of the output device.  This procedure
12686
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12687
 * plus spot color process color model.
12688
 *
12689
 * Parameters:
12690
 *   dev - pointer to device data structure.
12691
 *   pname - pointer to name (zero termination not required)
12692
 *   nlength - length of the name
12693
 *   number of process colorants (either 1, 3, or 4)
12694
 *
12695
 * This routine returns a positive value (0 to n) which is the device colorant
12696
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12697
 * the colorant is not being used due to a SeparationOrder device parameter.
12698
 * It returns a negative value if not found.
12699
 */
12700
static int
12701
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12702
    int name_size, int component_type, int num_process_colors, int cmyk)
12703
30.3k
{
12704
30.3k
    pdf14_device *pdev = (pdf14_device *)dev;
12705
30.3k
    gx_device *tdev = pdev->target;
12706
30.3k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12707
30.3k
    gs_separations *pseparations;
12708
30.3k
    int comp_index;
12709
30.3k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12710
30.3k
    int offset;
12711
12712
30.3k
    while (tdev->child) {
12713
0
        tdev = tdev->child;
12714
0
    }
12715
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12716
    /* get the devn_params from the target to avoid accessing using the wrong  */
12717
    /* pointer. Bug 696372.                                                    */
12718
30.3k
    if (tdev == (gx_device *)pdev)
12719
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12720
30.3k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12721
30.3k
    pseparations = &pdevn_params->separations;
12722
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12723
     * where we are in a blend color space that is RGB or Gray based and we
12724
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12725
     * Yellow or Black, then we should use the alternate tint transform */
12726
30.3k
    if (num_process_colors < 4) {
12727
884
        int k;
12728
4.42k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12729
3.53k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12730
0
                return -1;
12731
3.53k
        }
12732
884
    }
12733
12734
30.3k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12735
12736
    /* The pdf14_clist_composite may have set the color procs.
12737
       We need the real target procs, but not if we are doing simulated
12738
       overprint */
12739
30.3k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12740
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index) &&
12741
30.3k
        !pdev->overprint_sim)
12742
30.3k
        target_get_color_comp_index =
12743
30.3k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12744
    /*
12745
    * If this is not a separation name then simply forward it to the target
12746
    * device or return -1 if we are doing overprint simulation.
12747
    * The halftone setup expects this.
12748
    */
12749
30.3k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12750
30.3k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12751
22.8k
            if (target_get_color_comp_index != NULL)
12752
22.8k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12753
0
            else
12754
0
                return -1;
12755
22.8k
    }
12756
7.52k
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12757
0
        return -1;
12758
0
    }
12759
12760
    /*
12761
    * Check if the component is in either the process color model list
12762
    * or in the SeparationNames list.
12763
    */
12764
7.52k
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12765
7.52k
        name_size, component_type);
12766
12767
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12768
     * This is a decision we take here to avoid problems with PDFI not
12769
     * counting such colorants as spots. */
12770
7.52k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12771
52
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12772
0
            return -1;
12773
52
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12774
0
            return -1;
12775
52
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12776
0
            return -1;
12777
52
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12778
0
            return -1;
12779
52
    }
12780
    /* A psdrgb device, with simulate overprint will have become a cmyk
12781
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12782
     * either, but we need to return real numbers for them as the underlying
12783
     * routine won't know about these. */
12784
7.52k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12785
1
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12786
0
            return 3;
12787
1
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12788
0
            return 0;
12789
1
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12790
0
            return 1;
12791
1
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12792
0
            return 2;
12793
1
    }
12794
12795
    /*
12796
    * Return the colorant number if we know this name.  Note adjustment for
12797
    * compensating of blend color space.
12798
    */
12799
7.52k
    if (comp_index >= 0)
12800
7.47k
        return comp_index - offset;
12801
12802
    /* Only worry about the target if we are not doing an overprint simulation */
12803
53
    if (!pdev->overprint_sim) {
12804
        /*
12805
        * If we do not know this color, check if the output (target) device does.
12806
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12807
        * the colorant so we will only get < 0 returned when we hit the max. for
12808
        * the target device.
12809
        */
12810
53
        if (target_get_color_comp_index != NULL)
12811
53
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12812
0
        else
12813
0
            return -1;
12814
        /*
12815
        * Ignore color if unknown to the output device or if color is not being
12816
        * imaged due to the SeparationOrder device parameter.
12817
        */
12818
53
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12819
0
            return comp_index - offset;
12820
53
    }
12821
12822
    /*
12823
    * This is a new colorant.  Add it to our list of colorants.
12824
    * The limit accounts for the number of process colors (at least 4).
12825
    */
12826
53
    if ((pseparations->num_separations + 1) <
12827
53
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12828
53
        int sep_num = pseparations->num_separations++;
12829
53
        int color_component_number;
12830
53
        byte * sep_name;
12831
12832
53
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12833
53
            name_size, "pdf14_spot_get_color_comp_index");
12834
53
        if (sep_name == NULL) {
12835
0
            pseparations->num_separations--;  /* we didn't add it */
12836
0
            return -1;
12837
0
        }
12838
53
        memcpy(sep_name, pname, name_size);
12839
53
        pseparations->names[sep_num].size = name_size;
12840
53
        pseparations->names[sep_num].data = sep_name;
12841
53
        color_component_number = sep_num + num_process_colors;
12842
53
        if (color_component_number >= dev->color_info.max_components)
12843
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12844
53
        else
12845
53
            pdevn_params->separation_order_map[color_component_number] =
12846
53
            color_component_number;
12847
12848
        /* Indicate that we need to find equivalent CMYK color. */
12849
53
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12850
53
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12851
12852
53
        return color_component_number;
12853
53
    }
12854
12855
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12856
53
}
12857
12858
12859
/* CMYK process + spots */
12860
static int
12861
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12862
    int name_size, int component_type)
12863
29.4k
{
12864
29.4k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12865
29.4k
}
12866
12867
/* RGB process + spots */
12868
static int
12869
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12870
    int name_size, int component_type)
12871
884
{
12872
884
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12873
884
}
12874
12875
/* Gray process + spots */
12876
static int
12877
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12878
    int name_size, int component_type)
12879
0
{
12880
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12881
0
}
12882
12883
/* These functions keep track of when we are dealing with soft masks.
12884
   In such a case, we set the default color profiles to ones that ensure
12885
   proper soft mask rendering. */
12886
static int
12887
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12888
57.0k
{
12889
57.0k
    pdf14_device * pdev = (pdf14_device *) dev;
12890
57.0k
    pdf14_smaskcolor_t *result;
12891
57.0k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12892
57.0k
    int k;
12893
12894
    /* See if we have profiles already in place.   Note we also have to
12895
       worry about a corner case where this device does not have a
12896
       smaskcolor stucture to store the profiles AND the profiles were
12897
       already swapped out in the icc_manager.  This can occur when we
12898
       pushed a transparency mask and then inside the mask we have a pattern
12899
       which also has a transparency mask.   The state of the icc_manager
12900
       is that it already has done the swap and there is no need to fool
12901
       with any of this while dealing with the soft mask within the pattern */
12902
57.0k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12903
56.8k
        pgs->icc_manager->smask_profiles->swapped) {
12904
0
            return 0;
12905
0
    }
12906
57.0k
    if (pdev->smaskcolor != NULL) {
12907
136
        pdev->smaskcolor->ref_count++;
12908
136
        if_debug1m(gs_debug_flag_icc, dev->memory,
12909
136
                   "[icc] Increment smask color now %d\n",
12910
136
                   pdev->smaskcolor->ref_count);
12911
56.8k
    } else {
12912
        /* Allocate and swap out the current profiles.  The softmask
12913
           profiles should already be in place */
12914
56.8k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12915
56.8k
                                &st_pdf14_smaskcolor,
12916
56.8k
                                "pdf14_increment_smask_color");
12917
56.8k
        if (result == NULL)
12918
0
            return gs_error_VMerror;
12919
12920
56.8k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12921
56.8k
        if (result->profiles == NULL)
12922
0
            return gs_error_VMerror;
12923
12924
56.8k
        pdev->smaskcolor = result;
12925
12926
56.8k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12927
56.8k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12928
56.8k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12929
56.8k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12930
56.8k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12931
56.8k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12932
56.8k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12933
56.8k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12934
56.8k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12935
56.8k
        pgs->icc_manager->smask_profiles->swapped = true;
12936
56.8k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12937
56.8k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12938
56.8k
        pdev->smaskcolor->ref_count = 1;
12939
        /* We also need to update the profile that is currently in the
12940
           color spaces of the graphic state.  Otherwise this can be
12941
           referenced, which will result in a mismatch.  What we want to do
12942
           is see if it was the original default and only swap in that case. */
12943
170k
        for (k = 0; k < 2; k++) {
12944
113k
            gs_color_space *pcs     = pgs->color[k].color_space;
12945
113k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12946
113k
            if (profile != NULL) {
12947
110k
                switch(profile->data_cs) {
12948
60.4k
                    case gsGRAY:
12949
60.4k
                        if (profile->hashcode ==
12950
60.4k
                            result->profiles->smask_gray->hashcode) {
12951
56.8k
                                profile = pgs->icc_manager->default_gray;
12952
56.8k
                        }
12953
60.4k
                        break;
12954
48.9k
                    case gsRGB:
12955
48.9k
                        if (profile->hashcode ==
12956
48.9k
                            result->profiles->smask_rgb->hashcode) {
12957
21.3k
                                profile = pgs->icc_manager->default_rgb;
12958
21.3k
                        }
12959
48.9k
                        break;
12960
920
                    case gsCMYK:
12961
920
                        if (profile->hashcode ==
12962
920
                            result->profiles->smask_cmyk->hashcode) {
12963
920
                                profile = pgs->icc_manager->default_cmyk;
12964
920
                        }
12965
920
                        break;
12966
0
                    default:
12967
12968
0
                        break;
12969
110k
                }
12970
110k
                if (pcs->cmm_icc_profile_data != profile) {
12971
79.0k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12972
79.0k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12973
79.0k
                    pcs->cmm_icc_profile_data = profile;
12974
79.0k
                }
12975
110k
            }
12976
113k
        }
12977
56.8k
    }
12978
57.0k
    return 0;
12979
57.0k
}
12980
12981
static int
12982
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12983
73.2k
{
12984
73.2k
    pdf14_device * pdev = (pdf14_device *) dev;
12985
73.2k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12986
73.2k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12987
73.2k
    int k;
12988
12989
    /* See comment in pdf14_increment_smask_color to understand this one */
12990
73.2k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12991
8.07k
        pgs->icc_manager->smask_profiles->swapped) {
12992
0
            return 0;
12993
0
    }
12994
73.2k
    if (smaskcolor != NULL) {
12995
57.0k
        smaskcolor->ref_count--;
12996
57.0k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12997
57.0k
                   "[icc] Decrement smask color.  Now %d\n",
12998
57.0k
                   smaskcolor->ref_count);
12999
57.0k
        if (smaskcolor->ref_count == 0) {
13000
56.8k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
13001
            /* Lets return the profiles and clean up */
13002
            /* First see if we need to "reset" the profiles that are in
13003
               the graphic state */
13004
56.8k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
13005
170k
            for (k = 0; k < 2; k++) {
13006
113k
                gs_color_space *pcs = pgs->color[k].color_space;
13007
113k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
13008
113k
                if (profile != NULL) {
13009
110k
                    switch(profile->data_cs) {
13010
60.4k
                        case gsGRAY:
13011
60.4k
                            if (profile->hashcode ==
13012
60.4k
                                pgs->icc_manager->default_gray->hashcode) {
13013
56.8k
                                    profile =
13014
56.8k
                                        smaskcolor->profiles->smask_gray;
13015
56.8k
                            }
13016
60.4k
                            break;
13017
48.9k
                        case gsRGB:
13018
48.9k
                            if (profile->hashcode ==
13019
48.9k
                                pgs->icc_manager->default_rgb->hashcode) {
13020
21.3k
                                    profile =
13021
21.3k
                                        smaskcolor->profiles->smask_rgb;
13022
21.3k
                            }
13023
48.9k
                            break;
13024
920
                        case gsCMYK:
13025
920
                            if (profile->hashcode ==
13026
920
                                pgs->icc_manager->default_cmyk->hashcode) {
13027
920
                                    profile =
13028
920
                                        smaskcolor->profiles->smask_cmyk;
13029
920
                            }
13030
920
                            break;
13031
0
                        default:
13032
13033
0
                            break;
13034
110k
                    }
13035
110k
                    if (pcs->cmm_icc_profile_data != profile) {
13036
79.0k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
13037
79.0k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
13038
79.0k
                        pcs->cmm_icc_profile_data = profile;
13039
79.0k
                    }
13040
110k
                }
13041
113k
            }
13042
13043
56.8k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
13044
56.8k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
13045
56.8k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
13046
56.8k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
13047
56.8k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13048
56.8k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13049
56.8k
            icc_manager->smask_profiles->swapped = false;
13050
            /* We didn't increment the reference count when we assigned these
13051
             * so NULL them to avoid decrementing when smaskcolor is freed
13052
             */
13053
56.8k
            smaskcolor->profiles->smask_gray =
13054
56.8k
              smaskcolor->profiles->smask_rgb =
13055
56.8k
              smaskcolor->profiles->smask_cmyk = NULL;
13056
13057
56.8k
            pdf14_free_smask_color(pdev);
13058
56.8k
        }
13059
57.0k
    }
13060
73.2k
    return 0;
13061
73.2k
}
13062
13063
static void
13064
pdf14_free_smask_color(pdf14_device * pdev)
13065
56.8k
{
13066
56.8k
    if (pdev->smaskcolor != NULL) {
13067
56.8k
        if ( pdev->smaskcolor->profiles != NULL) {
13068
            /* Do not decrement the profiles - the references were moved
13069
               here and moved back again, so the ref counts don't change
13070
             */
13071
56.8k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13072
56.8k
                        "pdf14_free_smask_color");
13073
56.8k
        }
13074
56.8k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13075
56.8k
        pdev->smaskcolor = NULL;
13076
56.8k
    }
13077
56.8k
}
13078
13079
static void
13080
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13081
2.00M
{
13082
2.00M
    gx_device * const dev = (gx_device *)vptr;
13083
2.00M
    pdf14_device * pdev = (pdf14_device *)dev;
13084
2.00M
    int k;
13085
13086
2.00M
    pdf14_cleanup_group_color_profiles (pdev);
13087
13088
2.00M
    if (pdev->ctx) {
13089
18
        pdf14_ctx_free(pdev->ctx);
13090
18
        pdev->ctx = NULL;
13091
18
    }
13092
13093
2.00M
    while (pdev->color_model_stack) {
13094
22
        pdf14_pop_group_color(dev, NULL);
13095
22
    }
13096
13097
2.00M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13098
53
        if (pdev->devn_params.separations.names[k].data) {
13099
53
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13100
53
            pdev->devn_params.separations.names[k].data = NULL;
13101
53
        }
13102
53
    }
13103
13104
2.00M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13105
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13106
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13107
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13108
0
        }
13109
0
    }
13110
13111
2.00M
    gx_device_finalize(cmem, vptr);
13112
2.00M
}
13113
13114
#if DUMP_MASK_STACK
13115
13116
static void
13117
dump_mask_stack(pdf14_mask_t *mask_stack)
13118
{
13119
    pdf14_mask_t *curr_mask = mask_stack;
13120
    int level = 0;
13121
13122
    while (curr_mask != NULL) {
13123
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13124
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13125
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13126
        level++;
13127
        curr_mask = curr_mask->previous;
13128
    }
13129
}
13130
13131
/* A function to display the current state of the mask stack */
13132
static void
13133
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13134
{
13135
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13136
    if (ctx->mask_stack != NULL) {
13137
        dump_mask_stack(ctx->mask_stack);
13138
    }
13139
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13140
    if (ctx->stack != NULL) {
13141
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13142
        if (ctx->stack->mask_stack != NULL) {
13143
            dump_mask_stack(ctx->stack->mask_stack);
13144
        }
13145
    }
13146
}
13147
13148
#else
13149
13150
#ifdef DEBUG
13151
static void
13152
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13153
{
13154
    return;
13155
}
13156
#endif
13157
13158
#endif /* DUMP_MASK_STACK */