Coverage Report

Created: 2026-10-28 08:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
#include "gdevkrnlsclass.h"
74
75
#if RAW_DUMP
76
unsigned int global_index = 0;
77
unsigned int clist_band_count = 0;
78
#endif
79
80
#define DUMP_MASK_STACK 0
81
82
/* Static prototypes */
83
/* Used for filling rects when we are doing a fill with a pattern that
84
   has transparency */
85
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
86
                                   gx_path * ppath, const gx_fill_params * params,
87
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
88
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
89
static void pdf14_free_smask_color(pdf14_device * pdev);
90
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
91
                                         const gs_rect *pbbox, gs_gstate *pgs);
92
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
93
                                     const gs_gstate * pgs,
94
                                     bool crop_blend_params,
95
                                     gs_pdf14trans_params_t *group_params);
96
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
97
                                               int w, int h, gx_color_index color,
98
                                               const gx_device_color *pdc,
99
                                               bool devn);
100
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
101
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
102
                                  gx_color_index color, const gx_device_color *pdc,
103
                                  int depth, bool devn);
104
105
/* Functions for dealing with soft mask color */
106
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
107
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
108
109
/*
110
 * We chose the blending color space based upon the process color model of the
111
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
112
 * usually simple.  For other devices or if the user is doing custom color
113
 * processing then the user may want to control this choice.
114
 */
115
#define AUTO_USE_CUSTOM_BLENDING 0
116
#define ALWAYS_USE_CUSTOM_BLENDING 1
117
#define DO_NOT_USE_CUSTOM_BLENDING 2
118
119
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
120
121
# define INCR(v) DO_NOTHING
122
123
/* Forward prototypes */
124
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
125
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
126
                                gx_device ** pdev, gx_device * target,
127
                                const gs_pdf14trans_t * pdf14pct);
128
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
129
                                      gx_device ** pdev, gx_device * target,
130
                                      const gs_pdf14trans_t * pdf14pct);
131
static int pdf14_tile_pattern_fill(gx_device * pdev,
132
                const gs_gstate * pgs, gx_path * ppath,
133
                const gx_fill_params * params,
134
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    GS_OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    mask_buf, previous);
169
170
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
171
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
172
                    profiles);
173
174
/* ------ The device descriptors ------ */
175
176
/*
177
 * Default X and Y resolution.
178
 */
179
#define X_DPI 72
180
#define Y_DPI 72
181
182
static int pdf14_initialize_device(gx_device *dev);
183
184
static  int pdf14_open(gx_device * pdev);
185
static  dev_proc_close_device(pdf14_close);
186
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
187
static  dev_proc_put_params(pdf14_put_params);
188
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
189
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
190
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
191
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
192
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
193
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
194
dev_proc_encode_color(pdf14_encode_color);
195
dev_proc_encode_color(pdf14_encode_color_tag);
196
dev_proc_decode_color(pdf14_decode_color);
197
dev_proc_encode_color(pdf14_encode_color16);
198
dev_proc_encode_color(pdf14_encode_color16_tag);
199
dev_proc_decode_color(pdf14_decode_color16);
200
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
201
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
202
static  dev_proc_fill_path(pdf14_fill_path);
203
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
204
static  dev_proc_copy_mono(pdf14_copy_mono);
205
static  dev_proc_fill_mask(pdf14_fill_mask);
206
static  dev_proc_stroke_path(pdf14_stroke_path);
207
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
208
static  dev_proc_text_begin(pdf14_text_begin);
209
static  dev_proc_composite(pdf14_composite);
210
static  dev_proc_composite(pdf14_forward_composite);
211
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
212
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
213
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
214
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
215
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
216
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
217
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
218
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
219
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
220
static  dev_proc_copy_alpha(pdf14_copy_alpha);
221
static  dev_proc_copy_planes(pdf14_copy_planes);
222
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
223
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
224
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
225
static  const gx_color_map_procs *
226
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
227
228
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
229
#define YSIZE (int)(11 * Y_DPI)
230
231
/* 24-bit color. */
232
233
static void
234
pdf14_procs_initialize(gx_device *dev,
235
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
236
                       dev_proc_get_color_comp_index(get_color_comp_index),
237
                       dev_proc_encode_color(encode_color),
238
                       dev_proc_decode_color(decode_color))
239
5.09M
{
240
5.09M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
5.09M
    set_dev_proc(dev, open_device, pdf14_open);
242
5.09M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
5.09M
    set_dev_proc(dev, close_device, pdf14_close);
244
5.09M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
5.09M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
5.09M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
5.09M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
5.09M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
5.09M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
5.09M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
5.09M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
5.09M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
5.09M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
5.09M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
5.09M
    set_dev_proc(dev, composite, pdf14_composite);
256
5.09M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
5.09M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
5.09M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
5.09M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
5.09M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
5.09M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
5.09M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
5.09M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
5.09M
    set_dev_proc(dev, encode_color, encode_color);
265
5.09M
    set_dev_proc(dev, decode_color, decode_color);
266
5.09M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
5.09M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
5.09M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
5.09M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
5.09M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
5.09M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
5.09M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
5.09M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
5.09M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
5.09M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
5.09M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
5.09M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.72M
{
282
1.72M
    pdf14_procs_initialize(dev,
283
1.72M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.72M
                           gx_default_DevGray_get_color_comp_index,
285
1.72M
                           pdf14_encode_color,
286
1.72M
                           pdf14_decode_color);
287
1.72M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
2.85M
{
292
2.85M
    pdf14_procs_initialize(dev,
293
2.85M
                           gx_default_DevRGB_get_color_mapping_procs,
294
2.85M
                           gx_default_DevRGB_get_color_comp_index,
295
2.85M
                           pdf14_encode_color,
296
2.85M
                           pdf14_decode_color);
297
2.85M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
257k
{
302
257k
    pdf14_procs_initialize(dev,
303
257k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
257k
                           gx_default_DevCMYK_get_color_comp_index,
305
257k
                           pdf14_encode_color,
306
257k
                           pdf14_decode_color);
307
257k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
191k
{
312
191k
    pdf14_procs_initialize(dev,
313
191k
                           pdf14_cmykspot_get_color_mapping_procs,
314
191k
                           pdf14_cmykspot_get_color_comp_index,
315
191k
                           pdf14_encode_color,
316
191k
                           pdf14_decode_color);
317
191k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
60.6k
{
322
60.6k
    pdf14_procs_initialize(dev,
323
60.6k
                           pdf14_rgbspot_get_color_mapping_procs,
324
60.6k
                           pdf14_rgbspot_get_color_comp_index,
325
60.6k
                           pdf14_encode_color,
326
60.6k
                           pdf14_decode_color);
327
60.6k
}
328
329
static void
330
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           pdf14_grayspot_get_color_mapping_procs,
334
0
                           pdf14_grayspot_get_color_comp_index,
335
0
                           pdf14_encode_color,
336
0
                           pdf14_decode_color);
337
0
}
338
339
static void
340
pdf14_custom_initialize_device_procs(gx_device *dev)
341
0
{
342
0
    pdf14_procs_initialize(dev,
343
0
                           gx_forward_get_color_mapping_procs,
344
0
                           gx_forward_get_color_comp_index,
345
0
                           gx_forward_encode_color,
346
0
                           gx_forward_decode_color);
347
0
}
348
349
static struct_proc_finalize(pdf14_device_finalize);
350
351
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
352
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
353
                          pdf14_device_finalize);
354
355
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
356
                                                        gx_device * target);
357
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
358
                                                        gx_device * target);
359
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
362
/* Alter pdf14 device color model based upon group or softmask. This occurs
363
   post clist or in immediate rendering case. Data stored with buffer */
364
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
365
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
366
                              cmm_profile_t *iccprofile, bool is_mask);
367
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
368
369
/* Alter clist writer device color model based upon group or softmask. Data
370
   stored in the device color model stack */
371
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
372
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
373
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
374
375
/* Used for cleaning up the stack if things go wrong */
376
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
377
378
static const pdf14_procs_t gray_pdf14_procs = {
379
    pdf14_unpack_additive,
380
    pdf14_put_image,
381
    pdf14_unpack16_additive
382
};
383
384
static const pdf14_procs_t rgb_pdf14_procs = {
385
    pdf14_unpack_additive,
386
    pdf14_put_image,
387
    pdf14_unpack16_additive
388
};
389
390
static const pdf14_procs_t cmyk_pdf14_procs = {
391
    pdf14_unpack_subtractive,
392
    pdf14_put_image,
393
    pdf14_unpack16_subtractive
394
};
395
396
static const pdf14_procs_t cmykspot_pdf14_procs = {
397
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
398
    pdf14_cmykspot_put_image,
399
    pdf14_unpack16_custom /* should never be used since we will use devn values */
400
};
401
402
static const pdf14_procs_t rgbspot_pdf14_procs = {
403
    pdf14_unpack_rgb_mix,
404
    pdf14_cmykspot_put_image,
405
    pdf14_unpack16_rgb_mix
406
};
407
408
static const pdf14_procs_t grayspot_pdf14_procs = {
409
    pdf14_unpack_gray_mix,
410
    pdf14_cmykspot_put_image,
411
    pdf14_unpack16_gray_mix
412
};
413
414
static const pdf14_procs_t custom_pdf14_procs = {
415
    pdf14_unpack_custom,
416
    pdf14_custom_put_image,
417
    pdf14_unpack16_custom
418
};
419
420
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
421
    art_blend_luminosity_custom_8,
422
    art_blend_saturation_custom_8,
423
    art_blend_luminosity_custom_16,
424
    art_blend_saturation_custom_16
425
};
426
427
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
428
    art_blend_luminosity_rgb_8,
429
    art_blend_saturation_rgb_8,
430
    art_blend_luminosity_rgb_16,
431
    art_blend_saturation_rgb_16
432
};
433
434
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
435
    art_blend_luminosity_cmyk_8,
436
    art_blend_saturation_cmyk_8,
437
    art_blend_luminosity_cmyk_16,
438
    art_blend_saturation_cmyk_16
439
};
440
441
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
442
    art_blend_luminosity_rgb_8,
443
    art_blend_saturation_rgb_8,
444
    art_blend_luminosity_rgb_16,
445
    art_blend_saturation_rgb_16
446
};
447
448
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
449
    art_blend_luminosity_custom_8,
450
    art_blend_saturation_custom_8,
451
    art_blend_luminosity_custom_16,
452
    art_blend_saturation_custom_16
453
};
454
455
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
456
    art_blend_luminosity_custom_8,
457
    art_blend_saturation_custom_8,
458
    art_blend_luminosity_custom_16,
459
    art_blend_saturation_custom_16
460
};
461
462
const pdf14_device gs_pdf14_Gray_device = {
463
    std_device_std_color_full_body_type(pdf14_device,
464
                                        pdf14_Gray_initialize_device_procs,
465
                                        "pdf14gray",
466
                                        &st_pdf14_device,
467
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
468
                                        0, 0, 0, 0, 0, 0),
469
    { 0 },      /* Procs */
470
    NULL,     /* target */
471
    { 0 },      /* devn_params - not used */
472
    &gray_pdf14_procs,
473
    &gray_blending_procs,
474
    1
475
};
476
477
const pdf14_device gs_pdf14_RGB_device = {
478
    std_device_color_stype_body(pdf14_device,
479
                                pdf14_RGB_initialize_device_procs,
480
                                "pdf14RGB",
481
                                &st_pdf14_device,
482
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
483
    { 0 },      /* Procs */
484
    NULL,     /* target */
485
    { 0 },      /* devn_params - not used */
486
    &rgb_pdf14_procs,
487
    &rgb_blending_procs,
488
    3
489
};
490
491
const pdf14_device gs_pdf14_CMYK_device = {
492
    std_device_std_color_full_body_type(pdf14_device,
493
                                        pdf14_CMYK_initialize_device_procs,
494
                                        "pdf14cmyk",
495
                                        &st_pdf14_device,
496
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
497
                                        0, 0, 0, 0, 0, 0),
498
    { 0 },      /* Procs */
499
    NULL,     /* target */
500
    { 0 },      /* devn_params - not used */
501
    &cmyk_pdf14_procs,
502
    &cmyk_blending_procs,
503
    4
504
};
505
506
const pdf14_device gs_pdf14_CMYKspot_device = {
507
    std_device_part1_(pdf14_device,
508
                      pdf14_CMYKspot_initialize_device_procs,
509
                      "pdf14cmykspot",
510
                      &st_pdf14_device,
511
                      open_init_closed),
512
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
513
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
514
    offset_margin_values(0, 0, 0, 0, 0, 0),
515
    std_device_part3_(),
516
    { 0 },      /* Procs */
517
    NULL,     /* target */
518
    /* DeviceN parameters */
519
    { 8,      /* Not used - Bits per color */
520
      DeviceCMYKComponents, /* Names of color model colorants */
521
      4,      /* Number colorants for CMYK */
522
      0,      /* MaxSeparations has not been specified */
523
      -1,     /* PageSpotColors has not been specified */
524
      {0},      /* SeparationNames */
525
      0,      /* SeparationOrder names */
526
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
527
    },
528
    &cmykspot_pdf14_procs,
529
    &cmyk_blending_procs,
530
    4
531
};
532
533
const pdf14_device gs_pdf14_RGBspot_device = {
534
    std_device_part1_(pdf14_device,
535
                      pdf14_RGBspot_initialize_device_procs,
536
                      "pdf14rgbspot",
537
                      &st_pdf14_device,
538
                      open_init_closed),
539
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
540
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
541
    offset_margin_values(0, 0, 0, 0, 0, 0),
542
    std_device_part3_(),
543
    { 0 },      /* Procs */
544
    NULL,     /* target */
545
                    /* DeviceN parameters */
546
    { 8,      /* Not used - Bits per color */
547
    0,              /* Names of color model colorants */
548
    3,          /* Number colorants for RGB */
549
    0,          /* MaxSeparations has not been specified */
550
    -1,         /* PageSpotColors has not been specified */
551
    { 0 },      /* SeparationNames */
552
    0,          /* SeparationOrder names */
553
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
554
    },
555
    &rgbspot_pdf14_procs,
556
    &rgbspot_blending_procs,
557
    3
558
};
559
560
const pdf14_device gs_pdf14_Grayspot_device = {
561
    std_device_part1_(pdf14_device,
562
                      pdf14_Grayspot_initialize_device_procs,
563
                      "pdf14grayspot",
564
                      &st_pdf14_device,
565
                      open_init_closed),
566
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
567
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
568
    offset_margin_values(0, 0, 0, 0, 0, 0),
569
    std_device_part3_(),
570
    { 0 },      /* Procs */
571
    NULL,     /* target */
572
                    /* DeviceN parameters */
573
    { 8,      /* Not used - Bits per color */
574
    0,              /* Names of color model colorants */
575
    3,          /* Number colorants for RGB */
576
    0,          /* MaxSeparations has not been specified */
577
    -1,         /* PageSpotColors has not been specified */
578
    { 0 },      /* SeparationNames */
579
    0,          /* SeparationOrder names */
580
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
581
    },
582
    &grayspot_pdf14_procs,
583
    &grayspot_blending_procs,
584
    1
585
};
586
587
/*
588
 * The 'custom' PDF 1.4 compositor device is for working with those devices
589
 * which support spot colors but do not have a CMYK process color model.
590
 *
591
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
592
 * blending modes.  These blending modes are 'non separable' and depend upon
593
 * knowing the details of the blending color space.  However we use the
594
 * process color model of the output device for our blending color space.
595
 * With an unknown process color model, we have to fall back to some 'guesses'
596
 * about how to treat these blending modes.
597
 */
598
const pdf14_device gs_pdf14_custom_device = {
599
    std_device_part1_(pdf14_device,
600
                      pdf14_custom_initialize_device_procs,
601
                      "pdf14custom",
602
                      &st_pdf14_device,
603
                      open_init_closed),
604
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
605
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
606
    offset_margin_values(0, 0, 0, 0, 0, 0),
607
    std_device_part3_(),
608
    { 0 },      /* Procs */
609
    NULL,     /* target */
610
    /* DeviceN parameters */
611
    { 8,      /* Not used - Bits per color */
612
      DeviceCMYKComponents, /* Names of color model colorants */
613
      4,      /* Number colorants for CMYK */
614
      0,      /* MaxSeparations has not been specified */
615
      -1,     /* PageSpotColors has not been specified */
616
      {0},      /* SeparationNames */
617
      0,      /* SeparationOrder names */
618
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
619
    },
620
    &custom_pdf14_procs,
621
    &custom_blending_procs,
622
    4
623
};
624
625
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
626
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
627
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
628
629
static dev_proc_print_page(no_print_page);
630
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
631
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
632
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
633
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
634
635
static int
636
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
637
0
{
638
0
    return_error(gs_error_unknownerror);
639
0
}
640
641
struct gx_device_pdf14_accum_s {
642
    gx_devn_prn_device_common;
643
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
644
};
645
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
646
647
int
648
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
649
5.76M
{
650
5.76M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
5.76M
    if (dev_spec_op == gxdso_device_child) {
653
1.92k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
1.92k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
1.92k
        req->target = adev->save_p14dev;
657
1.92k
        req->n = 0;
658
1.92k
        return 0;
659
1.92k
    }
660
661
5.76M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
5.76M
}
663
664
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
665
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
666
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
667
668
static void
669
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
670
660
{
671
660
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
660
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
660
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
660
}
676
677
const gx_device_pdf14_accum pdf14_accum_Gray = {
678
    prn_device_stype_body(gx_device_pdf14_accum,
679
                          pdf14_accum_Gray_initialize_device_procs,
680
                          "pdf14-accum-Gray",
681
                          &st_gx_devn_accum_device,
682
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
683
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
684
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
685
                          256/*dither_grays*/, 0/*dither_colors*/,
686
                          no_print_page),
687
    { 0 },      /* devn_params - not used */
688
    { 0 },      /* equivalent_cmyk_color_params - not used */
689
    0/*save_p14dev*/
690
};
691
692
static void
693
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
694
2.64k
{
695
2.64k
    gdev_prn_initialize_device_procs_rgb(dev);
696
2.64k
}
697
698
const gx_device_pdf14_accum pdf14_accum_RGB = {
699
    prn_device_stype_body(gx_device_pdf14_accum,
700
                          pdf14_accum_RGB_initialize_device_procs,
701
                          "pdf14-accum-RGB",
702
                          &st_gx_devn_accum_device,
703
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
704
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
705
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
706
                          1/*dither_grays*/, 256/*dither_colors*/,
707
                          no_print_page),
708
    { 0 },      /* devn_params - not used */
709
    { 0 },      /* equivalent_cmyk_color_params - not used */
710
    0/*save_p14dev*/
711
};
712
713
static void
714
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
715
0
{
716
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
717
718
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
719
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
720
0
}
721
722
const gx_device_pdf14_accum pdf14_accum_CMYK = {
723
    prn_device_stype_body(gx_device_pdf14_accum,
724
                          pdf14_accum_CMYK_initialize_device_procs,
725
                          "pdf14-accum-CMYK",
726
                          &st_gx_devn_accum_device,
727
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
728
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
729
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
730
                          256/*dither_grays*/, 256/*dither_colors*/,
731
                          no_print_page),
732
    { 0 },      /* devn_params - not used */
733
    { 0 },      /* equivalent_cmyk_color_params - not used */
734
    0/*save_p14dev*/
735
};
736
737
static void
738
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
739
0
{
740
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
741
742
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
743
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
744
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
745
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
746
0
}
747
748
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
749
    prn_device_stype_body(gx_device_pdf14_accum,
750
                          pdf14_accum_initialize_device_procs_cmykspot,
751
                          "pdf14-accum-CMYKspot",
752
                          &st_gx_devn_accum_device,
753
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
754
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
755
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
756
                          256/*dither_grays*/, 256/*dither_colors*/,
757
                          no_print_page),
758
    /* DeviceN parameters */
759
    { 8,      /* Not used - Bits per color */
760
      DeviceCMYKComponents, /* Names of color model colorants */
761
      4,      /* Number colorants for CMYK */
762
      0,      /* MaxSeparations has not been specified */
763
      -1,     /* PageSpotColors has not been specified */
764
      { 0 },      /* SeparationNames */
765
      0,      /* SeparationOrder names */
766
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
767
    },
768
    { true },     /* equivalent_cmyk_color_params */
769
    0/*save_p14dev*/
770
};
771
772
/* GC procedures */
773
static
774
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
775
0
{
776
0
    index -= 5;
777
0
    if (index < pdev->devn_params.separations.num_separations)
778
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
779
0
    index -= pdev->devn_params.separations.num_separations;
780
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
781
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
782
0
    return 0;
783
0
}
784
0
case 0: return ENUM_OBJ(pdev->ctx);
785
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
786
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
787
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
788
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
789
0
ENUM_PTRS_END
790
791
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
792
0
{
793
0
    {
794
0
        int i;
795
796
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
797
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
798
0
        }
799
0
    }
800
0
    RELOC_VAR(pdev->ctx);
801
0
    RELOC_VAR(pdev->smaskcolor);
802
0
    RELOC_VAR(pdev->color_model_stack);
803
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
804
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
805
0
}
806
0
RELOC_PTRS_END
807
808
/* ------ Private definitions ------ */
809
810
static void
811
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
812
              int width, int height, cmm_profile_t *src_profile, int deep)
813
1.53k
{
814
1.53k
    if (deep) {
815
0
        int x, y, i;
816
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
817
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
818
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
819
820
0
        src_planestride >>= 1;
821
0
        src_rowstride >>= 1;
822
823
0
        for (y = 0; y < height; y++) {
824
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
825
0
            uint16_t *src_curr_ptr = src_row_ptr;
826
0
            for (x = 0; x < width; x++) {
827
0
                uint16_t idx = *mask_curr_ptr;
828
0
                byte     top = idx>>8;
829
0
                uint16_t a   = mask_tr_fn[top];
830
0
                int      b   = mask_tr_fn[top+1]-a;
831
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
832
833
                /* matte's happen rarely enough that we allow ourselves to
834
                 * resort to 64bit here. */
835
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
836
0
                    for (i = 0; i < src_profile->num_comps; i++) {
837
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
838
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
839
840
                        /* clip */
841
0
                        if (temp > 0xffff)
842
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
843
0
                        else if (temp < 0)
844
0
                            src_curr_ptr[i * src_planestride] = 0;
845
0
                        else
846
0
                            src_curr_ptr[i * src_planestride] = temp;
847
0
                    }
848
0
                }
849
0
                mask_curr_ptr++;
850
0
                src_curr_ptr++;
851
0
            }
852
0
            src_row_ptr += src_rowstride;
853
0
            mask_row_ptr += (maskbuf->rowstride>>1);
854
0
        }
855
1.53k
    } else {
856
1.53k
        int x, y, i;
857
1.53k
        byte *mask_row_ptr  = maskbuf->data;
858
1.53k
        byte *src_row_ptr   = src_data;
859
1.53k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
860
861
19.7k
        for (y = 0; y < height; y++) {
862
18.2k
            byte *mask_curr_ptr = mask_row_ptr;
863
18.2k
            byte *src_curr_ptr = src_row_ptr;
864
22.9M
            for (x = 0; x < width; x++) {
865
22.9M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
866
22.9M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
867
9.25M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
6.94M
                        byte matte = maskbuf->matte[i]>>8;
869
6.94M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
6.94M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
6.94M
                        if (temp > 0xff)
874
4.69M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
2.24M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
2.24M
                        else
878
2.24M
                            src_curr_ptr[i * src_planestride] = temp;
879
6.94M
                    }
880
2.31M
                }
881
22.9M
                mask_curr_ptr++;
882
22.9M
                src_curr_ptr++;
883
22.9M
            }
884
18.2k
            src_row_ptr += src_rowstride;
885
18.2k
            mask_row_ptr += maskbuf->rowstride;
886
18.2k
        }
887
1.53k
    }
888
1.53k
}
889
890
/* Transform of color data and copy noncolor data.  Used in
891
   group pop and during the pdf14 put image calls when the blend color space
892
   is different than the target device color space.  The function will try do
893
   in-place conversion if possible.  If not, it will do an allocation.  The
894
   put_image call needs to know if an allocation was made so that it can adjust
895
   for the fact that we likely don't have a full page any longer and we don't
896
   need to do the offset to our data in the buffer. Bug 700686: If we are in
897
   a softmask that includes a matte entry, then we need to undo the matte
898
   entry here at this time in the image's native color space not the parent
899
   color space.   The endian_swap term here is only set to true if the data
900
   has been baked as BE during the put_image blending operation and we are
901
   on a LE machine.  */
902
static forceinline pdf14_buf*
903
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
904
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
905
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
906
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
907
12.5k
{
908
12.5k
    gsicc_rendering_param_t rendering_params;
909
12.5k
    gsicc_link_t *icc_link;
910
12.5k
    gsicc_bufferdesc_t src_buff_desc;
911
12.5k
    gsicc_bufferdesc_t des_buff_desc;
912
12.5k
    intptr_t src_planestride = src_buf->planestride;
913
12.5k
    intptr_t src_rowstride = src_buf->rowstride;
914
12.5k
    int src_n_planes = src_buf->n_planes;
915
12.5k
    int src_n_chan = src_buf->n_chan;
916
12.5k
    intptr_t des_planestride = src_planestride;
917
12.5k
    intptr_t des_rowstride = src_rowstride;
918
12.5k
    int des_n_planes = src_n_planes;
919
12.5k
    int des_n_chan = src_n_chan;
920
12.5k
    int diff;
921
12.5k
    int k, j;
922
12.5k
    byte *des_data = NULL;
923
12.5k
    pdf14_buf *output = src_buf;
924
12.5k
    pdf14_mask_t *mask_stack;
925
12.5k
    pdf14_buf *maskbuf;
926
12.5k
    int code;
927
928
12.5k
    *did_alloc = false;
929
930
    /* Same profile */
931
12.5k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
932
0
        return src_buf;
933
934
    /* Define the rendering intent get the link */
935
12.5k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
936
12.5k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
937
12.5k
    rendering_params.override_icc = false;
938
12.5k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
939
12.5k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
940
12.5k
    rendering_params.cmm = gsCMM_DEFAULT;
941
12.5k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
942
12.5k
        &rendering_params, pgs->memory, false);
943
12.5k
    if (icc_link == NULL)
944
0
        return NULL;
945
946
    /* If different data sizes, we have to do an allocation */
947
12.5k
    diff = des_profile->num_comps - src_profile->num_comps;
948
12.5k
    if (diff != 0) {
949
12.0k
        byte *src_ptr;
950
12.0k
        byte *des_ptr;
951
952
12.0k
        *did_alloc = true;
953
12.0k
        des_rowstride = ((width + 3) & -4)<<deep;
954
12.0k
        des_planestride = height * des_rowstride;
955
12.0k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
12.0k
        des_n_chan = src_n_chan + diff;
957
12.0k
        des_data = gs_alloc_bytes(ctx->memory,
958
12.0k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
12.0k
                                  "pdf14_transform_color_buffer");
960
12.0k
        if (des_data == NULL)
961
0
            return NULL;
962
963
        /* Copy over the noncolor planes. May only be a dirty part, so have
964
           to copy row by row */
965
12.0k
        src_ptr = src_data;
966
12.0k
        des_ptr = des_data;
967
132k
        for (j = 0; j < height; j++) {
968
242k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
121k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
121k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
121k
                       width<<deep);
972
121k
            }
973
120k
            src_ptr += src_rowstride;
974
120k
            des_ptr += des_rowstride;
975
120k
        }
976
12.0k
    } else
977
464
        des_data = src_data;
978
979
    /* Set up the buffer descriptors. */
980
12.5k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
981
12.5k
                      false, true, src_planestride, src_rowstride, height, width);
982
12.5k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
983
12.5k
                      false, true, des_planestride, des_rowstride, height, width);
984
985
12.5k
    src_buff_desc.endian_swap = endian_swap;
986
12.5k
    des_buff_desc.endian_swap = endian_swap;
987
988
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
989
       context to ensure that this is not done again during the group
990
       composition */
991
12.5k
    if (has_matte &&
992
        /* Should always happen, but check for safety */
993
1.81k
        ((mask_stack = ctx->mask_stack) != NULL) &&
994
1.81k
        ((maskbuf = mask_stack->mask_buf) != NULL) &&
995
1.81k
         (maskbuf->data != NULL))
996
1.53k
    {
997
1.53k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
998
1.53k
    }
999
1000
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1001
       Gray buffers, this transform does not need to worry about the cmap procs
1002
       of the target device. */
1003
12.5k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1004
12.5k
        src_data, des_data);
1005
12.5k
    gsicc_release_link(icc_link);
1006
12.5k
    if (code < 0)
1007
0
        return NULL;
1008
1009
12.5k
    output->planestride = des_planestride;
1010
12.5k
    output->rowstride = des_rowstride;
1011
12.5k
    output->n_planes = des_n_planes;
1012
12.5k
    output->n_chan = des_n_chan;
1013
    /* If not in-place conversion, then release. */
1014
12.5k
    if (des_data != src_data) {
1015
12.0k
        gs_free_object(ctx->memory, output->data,
1016
12.0k
            "pdf14_transform_color_buffer");
1017
12.0k
        output->data = des_data;
1018
        /* Note, this is needed for case where we did a put image, as the
1019
           resulting transformed buffer may not be a full page. */
1020
12.0k
        output->rect.p.x = x0;
1021
12.0k
        output->rect.p.y = y0;
1022
12.0k
        output->rect.q.x = x0 + width;
1023
12.0k
        output->rect.q.y = y0 + height;
1024
12.0k
    }
1025
12.5k
    return output;
1026
12.5k
}
1027
1028
/* This is a routine to do memset's but with 16 bit values.
1029
 * Note, that we still take bytes, NOT "num values to set".
1030
 * We assume dest is 16 bit aligned. We assume that bytes is
1031
 * a multiple of 2. */
1032
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1033
0
{
1034
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1035
0
    uint32_t v;
1036
0
    if (bytes < 0)
1037
0
        return;
1038
0
    if (((intptr_t)dest) & 2) {
1039
0
        *dest++ = value;
1040
0
        bytes--;
1041
0
        if (bytes == 0)
1042
0
            return;
1043
0
    }
1044
0
    v = value | (value<<16);
1045
0
    bytes -= 2;
1046
0
    while (bytes > 0) {
1047
0
        *(uint32_t *)dest = v;
1048
0
        dest += 2;
1049
0
        bytes -= 4;
1050
0
    }
1051
0
    bytes += 2;
1052
0
    if (bytes & 2) {
1053
0
        *dest = value;
1054
0
    }
1055
0
}
1056
1057
static pdf14_buf*
1058
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1059
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1060
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1061
    bool deep, bool endian_swap, int num_channels_to_lose)
1062
10.7k
{
1063
10.7k
    if (deep)
1064
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1065
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1066
10.7k
    else
1067
10.7k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
10.7k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
10.7k
}
1070
1071
static pdf14_buf*
1072
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1073
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1074
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1075
    bool deep, bool endian_swap)
1076
1.81k
{
1077
1.81k
    if (deep)
1078
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1079
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1080
1.81k
    else
1081
1.81k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1082
1.81k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1083
1.81k
}
1084
1085
/**
1086
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1087
 * @n_chan: Number of pixel channels including alpha, but not including
1088
 * shape, group alpha, or tags.
1089
 *
1090
 * Return value: Newly allocated buffer, or NULL on failure.
1091
 **/
1092
static  pdf14_buf *
1093
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1094
              bool has_shape, bool idle, int n_chan, int num_spots,
1095
              gs_memory_t *memory, bool deep)
1096
3.38M
{
1097
1098
    /* Note that alpha_g is the alpha for the GROUP */
1099
    /* This is distinct from the alpha that may also exist */
1100
    /* for the objects within the group.  Hence it can introduce */
1101
    /* yet another plane */
1102
1103
3.38M
    pdf14_buf *result;
1104
3.38M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
3.38M
    int64_t height = (rect->q.y - rect->p.y);
1106
3.38M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
3.38M
                   (has_tags ? 1 : 0);
1108
3.38M
    size_t planestride;
1109
#if ARCH_SIZEOF_SIZE_T <= 4
1110
    int64_t dsize = rowstride * height * n_planes;
1111
1112
    if (dsize > max_size_t)
1113
        return NULL;
1114
#endif
1115
1116
3.38M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
3.38M
                             "pdf14_buf_new");
1118
3.38M
    if (result == NULL)
1119
0
        return result;
1120
1121
3.38M
    result->memory = memory;
1122
3.38M
    result->backdrop = NULL;
1123
3.38M
    result->saved = NULL;
1124
3.38M
    result->isolated = false;
1125
3.38M
    result->knockout = false;
1126
3.38M
    result->has_alpha_g = has_alpha_g;
1127
3.38M
    result->has_shape = has_shape;
1128
3.38M
    result->has_tags = has_tags;
1129
3.38M
    result->rect = *rect;
1130
3.38M
    result->n_chan = n_chan;
1131
3.38M
    result->n_planes = n_planes;
1132
3.38M
    result->rowstride = rowstride;
1133
3.38M
    result->transfer_fn = NULL;
1134
3.38M
    result->is_ident = true;
1135
3.38M
    result->matte_num_comps = 0;
1136
3.38M
    result->matte = NULL;
1137
3.38M
    result->mask_stack = NULL;
1138
3.38M
    result->idle = idle;
1139
3.38M
    result->mask_id = 0;
1140
3.38M
    result->num_spots = num_spots;
1141
3.38M
    result->deep = deep;
1142
3.38M
    result->page_group = false;
1143
3.38M
    result->group_color_info = NULL;
1144
3.38M
    result->group_popped = false;
1145
1146
3.38M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.64M
        result->planestride = 0;
1149
1.64M
        result->data = 0;
1150
1.74M
    } else {
1151
1.74M
        planestride = rowstride * height;
1152
1.74M
        result->planestride = planestride;
1153
1.74M
        result->data = gs_alloc_bytes(memory,
1154
1.74M
                                      planestride * n_planes + CAL_SLOP,
1155
1.74M
                                      "pdf14_buf_new");
1156
1.74M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.74M
        if (has_alpha_g) {
1161
433k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
433k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
433k
        }
1165
1.74M
        if (has_tags) {
1166
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
0
            memset (result->data + tags_plane * planestride,
1169
0
                    GS_UNTOUCHED_TAG, planestride);
1170
0
        }
1171
1.74M
    }
1172
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1173
     * Any future drawing will make it valid again, so we won't blend back
1174
     * more than we need. */
1175
3.38M
    result->dirty.p.x = rect->q.x;
1176
3.38M
    result->dirty.p.y = rect->q.y;
1177
3.38M
    result->dirty.q.x = rect->p.x;
1178
3.38M
    result->dirty.q.y = rect->p.y;
1179
3.38M
    return result;
1180
3.38M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
3.38M
{
1185
3.38M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
3.38M
    gs_memory_t *memory = buf->memory;
1187
1188
3.38M
    if (buf->mask_stack)
1189
3.38M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
3.38M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
3.38M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
3.38M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
6.76M
    while (group_color_info) {
1196
3.38M
       if (group_color_info->icc_profile != NULL) {
1197
3.38M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
3.38M
       }
1199
3.38M
       buf->group_color_info = group_color_info->previous;
1200
3.38M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
3.38M
       group_color_info = buf->group_color_info;
1202
3.38M
    }
1203
1204
3.38M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
3.38M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
3.38M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
1.10M
{
1211
1.10M
    pdf14_ctx *result;
1212
1.10M
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
1.10M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
1.10M
    if (result == NULL)
1216
0
        return result;
1217
1.10M
    result->stack = NULL;
1218
1.10M
    result->mask_stack = pdf14_mask_element_new(memory);
1219
1.10M
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
1.10M
    result->memory = memory;
1224
1.10M
    result->smask_depth = 0;
1225
1.10M
    result->smask_blend = false;
1226
1.10M
    result->deep = deep;
1227
1.10M
    result->base_color = NULL;
1228
1.10M
    return result;
1229
1.10M
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
1.10M
{
1234
1.10M
    pdf14_buf *buf, *next;
1235
1236
1.10M
    if (ctx->base_color) {
1237
581k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
581k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
581k
    }
1240
1.10M
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
537k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
537k
    }
1244
2.04M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
938k
        next = buf->saved;
1246
938k
        pdf14_buf_free(buf);
1247
938k
    }
1248
1.10M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
1.10M
}
1250
1251
/**
1252
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1253
 *
1254
 * Return value: Backdrop buffer for current group operation, or NULL
1255
 * if backdrop is fully transparent.
1256
 **/
1257
static  pdf14_buf *
1258
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1259
976k
{
1260
    /* Our new buffer is buf */
1261
976k
    pdf14_buf *buf = ctx->stack;
1262
1263
976k
    *is_backdrop = false;
1264
1265
976k
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
976k
        if (buf->isolated) return NULL;
1268
1269
        /* If the previous buffer is a knockout group
1270
           then we need to use its backdrop as the backdrop. If
1271
           it was isolated then that back drop was NULL */
1272
433k
        if (buf->saved != NULL && buf->saved->knockout) {
1273
            /* Per the spec, if we have a non-isolated group
1274
               in a knockout group the non-isolated group
1275
               uses the backdrop of its parent group (the knockout group)
1276
               as its own backdrop.  The non-isolated group must
1277
               go through the standard re-composition operation
1278
               to avoid the double application of the backdrop */
1279
17
            *is_backdrop = true;
1280
17
            return buf->saved;
1281
17
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
433k
        if (buf->saved != NULL) {
1285
433k
            return buf->saved;
1286
433k
        }
1287
433k
    }
1288
0
    return NULL;
1289
976k
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
581k
{
1294
581k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
581k
    pdf14_group_color_t* group_color;
1296
581k
    bool deep = pdev->ctx->deep;
1297
581k
    bool has_tags = device_encodes_tags(dev);
1298
1299
581k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
581k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
581k
        pdf14_group_color_t, &st_pdf14_clr,
1303
581k
        "pdf14_make_base_group_color");
1304
1305
581k
    if (group_color == NULL)
1306
0
        return NULL;
1307
581k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
581k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
581k
    group_color->blend_procs = pdev->blend_procs;
1311
581k
    group_color->polarity = pdev->color_info.polarity;
1312
581k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
581k
    group_color->isadditive = pdev->ctx->additive;
1314
581k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
581k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
581k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
581k
    group_color->depth = pdev->color_info.depth;
1318
581k
    group_color->decode = dev_proc(pdev, decode_color);
1319
581k
    group_color->encode = dev_proc(pdev, encode_color);
1320
581k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
581k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
581k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
581k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
581k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
581k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
581k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
581k
    group_color->icc_profile =
1328
581k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
581k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
581k
    return group_color;
1332
581k
}
1333
1334
/* This wil create the first buffer when we have
1335
   either the first drawing operation or transparency
1336
   group push.  At that time, the color space in which
1337
   we are going to be doing the alpha blend will be known. */
1338
static int
1339
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1340
381M
{
1341
381M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
381M
    bool has_tags = device_encodes_tags(dev);
1343
381M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
381M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
381M
    int num_spots = pdev->ctx->num_spots;
1346
381M
    pdf14_buf* buf;
1347
381M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
381M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1351
0
        pdev->ctx->stack->idle) {
1352
0
        pdf14_buf_free(pdev->ctx->stack);
1353
0
        pdev->ctx->stack = NULL;
1354
0
    }
1355
1356
381M
    if (pdev->ctx->stack != NULL)
1357
381M
        return 0;
1358
1359
381M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
513k
        dev->width, dev->height);
1361
1362
513k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
513k
        num_spots, memory, pdev->ctx->deep);
1364
513k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
513k
    if_debug5m('v', memory,
1368
513k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
513k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
513k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
513k
    buf->saved = NULL;
1373
513k
    pdev->ctx->stack = buf;
1374
513k
    pdev->ctx->additive = additive;
1375
1376
    /* Every buffer needs group color information including the base
1377
       one that is created for when we have no group */
1378
513k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
513k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
513k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
513k
    if (pgs != NULL)
1384
269k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
243k
    else
1386
243k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
513k
    buf->group_color_info->group_color_mapping_procs =
1389
513k
        dev_proc(pdev, get_color_mapping_procs);
1390
513k
    buf->group_color_info->group_color_comp_index =
1391
513k
        dev_proc(pdev, get_color_comp_index);
1392
513k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
513k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
513k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
513k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
513k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
513k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
513k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
513k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
513k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
513k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
513k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
513k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
513k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
513k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
513k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
513k
    buf->group_color_info->icc_profile =
1408
513k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
513k
    if (buf->group_color_info->icc_profile != NULL)
1410
513k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
513k
    return 0;
1413
513k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
18.4k
{
1418
18.4k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
18.4k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
18.4k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
18.4k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
18.4k
    if (des->icc_profile != NULL)
1425
18.4k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
18.4k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
18.4k
    return des;
1429
18.4k
}
1430
1431
static  int
1432
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1433
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1434
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1435
                              int numcomps, bool cm_back_drop, bool shade_group,
1436
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1437
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1438
                              gx_device *dev)
1439
2.44M
{
1440
2.44M
    pdf14_buf *tos = ctx->stack;
1441
2.44M
    pdf14_buf *buf, * pdf14_backdrop;
1442
2.44M
    bool has_shape = false;
1443
2.44M
    bool is_backdrop;
1444
2.44M
    int num_spots;
1445
1446
2.44M
    if_debug1m('v', ctx->memory,
1447
2.44M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
2.44M
    if (tos != NULL)
1450
2.02M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
2.44M
    if (ctx->smask_depth > 0)
1453
1.44k
        num_spots = 0;
1454
2.44M
    else
1455
2.44M
        num_spots = ctx->num_spots;
1456
1457
1458
2.44M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
2.44M
                        num_spots, ctx->memory, ctx->deep);
1460
2.44M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
2.44M
    if_debug4m('v', ctx->memory,
1464
2.44M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
2.44M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
2.44M
    buf->isolated = isolated;
1467
2.44M
    buf->knockout = knockout;
1468
2.44M
    buf->alpha = alpha;
1469
2.44M
    buf->shape = shape;
1470
2.44M
    buf->opacity = opacity;
1471
2.44M
    buf->blend_mode = blend_mode;
1472
2.44M
    buf->mask_id = mask_id;
1473
2.44M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
2.44M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
2.44M
    buf->saved = tos;
1478
2.44M
    buf->group_color_info = group_color;
1479
1480
2.44M
    if (tos == NULL)
1481
425k
        buf->page_group = true;
1482
1483
2.44M
    ctx->stack = buf;
1484
2.44M
    if (buf->data == NULL)
1485
1.47M
        return 0;
1486
976k
    if (idle)
1487
0
        return 0;
1488
976k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
976k
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1492
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1493
        /* Memsetting by 0, so this copes with the deep case too */
1494
543k
        memset(buf->data, 0, buf->planestride *
1495
543k
                                          (buf->n_chan +
1496
543k
                                           (buf->has_shape ? 1 : 0) +
1497
543k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
543k
    } else {
1499
433k
        if (!cm_back_drop) {
1500
433k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
433k
                                    );
1505
433k
        } else {
1506
            /* We must have an non-isolated group with a mismatch in color spaces.
1507
                In this case, we can't just copy the buffer but must CM it */
1508
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1509
0
                                        ctx->memory, pgs, dev, is_backdrop);
1510
0
        }
1511
433k
    }
1512
1513
    /* If our new group is a non-isolated knockout group, we have to maintain
1514
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1515
       knockout group. They have to always blend with the groups backdrop
1516
       not what is currently drawn in the group. Selection of the backdrop
1517
       depends upon the properties of the parent group. For example, if
1518
       the parent itself is a knockout group we actually
1519
       need to blend with its backdrop. This could be NULL if the parent was
1520
       an isolated knockout group. */
1521
976k
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
42.2k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
42.2k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
42.2k
                                       "pdf14_push_transparency_group");
1525
42.2k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
42.2k
        memcpy(buf->backdrop, buf->data,
1530
42.2k
               buf->planestride * buf->n_planes);
1531
1532
#if RAW_DUMP
1533
        /* Dump the current buffer to see what we have. */
1534
        dump_raw_buffer(ctx->memory,
1535
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1536
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1537
            ctx->stack->planestride, ctx->stack->rowstride,
1538
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1539
        global_index++;
1540
#endif
1541
42.2k
    }
1542
#if RAW_DUMP
1543
    /* Dump the current buffer to see what we have. */
1544
    dump_raw_buffer(ctx->memory,
1545
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1546
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1547
                    ctx->stack->planestride, ctx->stack->rowstride,
1548
                    "TransGroupPush", ctx->stack->data, buf->deep);
1549
    global_index++;
1550
#endif
1551
976k
    return 0;
1552
976k
}
1553
1554
static  int
1555
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1556
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1557
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1558
2.44M
{
1559
2.44M
    pdf14_buf *tos = ctx->stack;
1560
2.44M
    pdf14_buf *nos = tos->saved;
1561
2.44M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
2.44M
    pdf14_buf *maskbuf;
1563
2.44M
    int x0, x1, y0, y1;
1564
2.44M
    int nos_num_color_comp;
1565
2.44M
    bool no_icc_match;
1566
2.44M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
2.44M
    bool overprint = pdev->overprint;
1568
2.44M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
2.44M
    bool has_matte = false;
1570
2.44M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
2.44M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
2.44M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
3.77k
        has_matte = true;
1578
1579
    /* Check if this is our last buffer, if yes, there is nothing to
1580
       compose to.  Keep this buffer until we have the put image.
1581
       If we have another group push, this group must be destroyed.
1582
       This only occurs sometimes when at clist creation time
1583
       push_shfill_group occured and nothing was drawn in this group.
1584
       There is also the complication if we have a softmask.  There
1585
       are two approaches to this problem.  Apply the softmask during
1586
       the put image or handle it now.  I choose the later as the
1587
       put_image code is already way to complicated. */
1588
2.44M
    if (nos == NULL && maskbuf == NULL) {
1589
424k
        tos->group_popped = true;
1590
424k
        return 0;
1591
424k
    }
1592
1593
    /* Here is the case with the soft mask.  Go ahead and create a new
1594
       target buffer (nos) with the same color information etc, but blank
1595
       and go ahead and do the blend with the softmask so that it gets applied. */
1596
2.02M
    if (nos == NULL && maskbuf != NULL) {
1597
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1598
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1599
0
        if (nos == NULL) {
1600
0
            code = gs_error_VMerror;
1601
0
            goto exit;
1602
0
        }
1603
1604
0
        if_debug4m('v', ctx->memory,
1605
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1606
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1607
1608
0
        nos->dirty = tos->dirty;
1609
0
        nos->isolated = tos->isolated;
1610
0
        nos->knockout = tos->knockout;
1611
0
        nos->alpha = 65535;
1612
0
        nos->shape = 65535;
1613
0
        nos->opacity = 65535;
1614
0
        nos->blend_mode = tos->blend_mode;
1615
0
        nos->mask_id = tos->mask_id;
1616
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1617
1618
0
        if (nos->data != NULL)
1619
0
            memset(nos->data, 0,
1620
0
                   nos->planestride * (nos->n_chan +
1621
0
                                       (nos->has_shape ? 1 : 0) +
1622
0
                                       (nos->has_alpha_g ? 1 : 0)));
1623
0
    }
1624
1625
    /* Before we get started, lets see if we have somehow gotten into
1626
       what should be an impossible situation where the group color
1627
       information does not match the buffer color information. This
1628
       can occur is there were memory issues that have perhaps blown
1629
       away information, or in the example of Bug 705197 the PDF interpreter
1630
       reuses a pattern during a circular reference causing an aliasing
1631
       of two nested patterns, one of which has a softmask. The change in
1632
       the buffer size of the inner one blows away the buffer of the
1633
       outer one leading to a mismatch of color spaces. Here
1634
       we can at least catch the case when the color space sizes have
1635
       changed and avoid buffer over-runs that would occur when we try
1636
       to do the group composition */
1637
2.02M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
2.02M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
2.02M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
2.02M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1643
1644
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1645
     * have made them overly large. */
1646
2.02M
    rect_intersect(tos->dirty, tos->rect);
1647
2.02M
    rect_intersect(nos->dirty, nos->rect);
1648
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1649
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1650
2.02M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
2.02M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
2.02M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
2.02M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
2.02M
    if (ctx->mask_stack) {
1655
        /* This can occur when we have a situation where we are ending out of
1656
           a group that has internal to it a soft mask and another group.
1657
           The soft mask left over from the previous trans group pop is put
1658
           into ctx->masbuf, since it is still active if another trans group
1659
           push occurs to use it.  If one does not occur, but instead we find
1660
           ourselves popping from a parent group, then this softmask is no
1661
           longer needed.  We will rc_decrement and set it to NULL. */
1662
96
        rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_group");
1663
96
        ctx->mask_stack = NULL;
1664
96
    }
1665
2.02M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
2.02M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
2.02M
    if (tos->idle)
1668
1.43M
        goto exit;
1669
585k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1670
0
        goto exit;
1671
1672
#if RAW_DUMP
1673
    /* Dump the current buffer to see what we have. */
1674
    dump_raw_buffer(ctx->memory,
1675
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1676
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1677
                    ctx->stack->planestride, ctx->stack->rowstride,
1678
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1679
    global_index++;
1680
#endif
1681
/* Note currently if a pattern space has transparency, the ICC profile is not used
1682
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1683
   This is partially due to the fact that pdf14_pop_transparency_group and
1684
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1685
   operations called in the tile transparency code.  Instead we may want to
1686
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1687
   is where all the ICC information is handled.  We will return to look at that later */
1688
585k
    if (nos->group_color_info->icc_profile != NULL) {
1689
585k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
585k
    } else {
1691
        /* Let the other tests make the decision if we need to transform */
1692
0
        no_icc_match = false;
1693
0
    }
1694
    /* If the color spaces are different and we actually did do a swap of
1695
       the procs for color */
1696
585k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
585k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
4.53k
        if (x0 < x1 && y0 < y1) {
1699
4.26k
            pdf14_buf *result;
1700
4.26k
            bool did_alloc; /* We don't care here */
1701
1702
4.26k
            if (has_matte) {
1703
1.81k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1704
1.81k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1705
1.81k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1706
1.81k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1707
1.81k
                has_matte = false;
1708
2.44k
            } else {
1709
2.44k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
2.44k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
2.44k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
2.44k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
2.44k
            }
1714
4.26k
            if (result == NULL) {
1715
                /* Clean up and return error code */
1716
0
                code = gs_error_unknownerror;
1717
0
                goto exit;
1718
0
            }
1719
1720
#if RAW_DUMP
1721
            /* Dump the current buffer to see what we have. */
1722
            dump_raw_buffer(ctx->memory,
1723
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1724
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1725
                            ctx->stack->planestride, ctx->stack->rowstride,
1726
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1727
                            ctx->stack->deep);
1728
#endif
1729
             /* compose. never do overprint in this case */
1730
4.26k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
4.26k
                 nos->group_color_info->isadditive,
1732
4.26k
                 nos->group_color_info->blend_procs,
1733
4.26k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
4.26k
        }
1735
580k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
580k
        if (x0 < x1 && y0 < y1)
1738
333k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
333k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
333k
                                drawn_comps, ctx->memory, dev);
1741
580k
    }
1742
2.02M
exit:
1743
2.02M
    ctx->stack = nos;
1744
    /* We want to detect the cases where we have luminosity soft masks embedded
1745
       within one another.  The "alpha" channel really needs to be merged into
1746
       the luminosity channel in this case.  This will occur during the mask pop */
1747
2.02M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1748
        /* Set the trigger so that we will blend if not alpha. Since
1749
           we have softmasks embedded in softmasks */
1750
632
        ctx->smask_blend = true;
1751
632
    }
1752
2.02M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
2.02M
    pdf14_buf_free(tos);
1754
2.02M
    if (code < 0)
1755
0
        return_error(code);
1756
2.02M
    return 0;
1757
2.02M
}
1758
1759
/*
1760
 * Create a transparency mask that will be used as the mask for
1761
 * the next transparency group that is created afterwards.
1762
 * The sequence of calls is:
1763
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1764
 */
1765
static  int
1766
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1767
                             byte *transfer_fn, bool is_ident, bool idle,
1768
                             bool replacing, uint mask_id,
1769
                             gs_transparency_mask_subtype_t subtype,
1770
                             int numcomps, int Background_components,
1771
                             const float Background[], int Matte_components,
1772
                             const float Matte[], const float GrayBackground,
1773
                             pdf14_group_color_t* group_color)
1774
420k
{
1775
420k
    pdf14_buf *buf;
1776
420k
    int i;
1777
1778
420k
    if_debug2m('v', ctx->memory,
1779
420k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
420k
               idle, replacing);
1781
420k
    ctx->smask_depth += 1;
1782
1783
420k
    if (ctx->stack == NULL) {
1784
0
        return_error(gs_error_VMerror);
1785
0
    }
1786
1787
    /* An optimization to consider is that if the SubType is Alpha
1788
       then we really should only be allocating the alpha band and
1789
       only draw with that channel.  Current architecture makes that
1790
       a bit tricky.  We need to create this based upon the size of
1791
       the color space + an alpha channel. NOT the device size
1792
       or the previous ctx size */
1793
    /* A mask doesn't worry about tags */
1794
420k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
420k
                        ctx->memory, ctx->deep);
1796
420k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
420k
    buf->alpha = bg_alpha;
1799
420k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
420k
    buf->isolated = true;
1802
420k
    buf->knockout = false;
1803
420k
    buf->shape = 0xffff;
1804
420k
    buf->blend_mode = BLEND_MODE_Normal;
1805
420k
    buf->transfer_fn = transfer_fn;
1806
420k
    buf->matte_num_comps = Matte_components;
1807
420k
    buf->group_color_info = group_color;
1808
1809
420k
    if (Matte_components) {
1810
3.77k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
3.77k
                                                "pdf14_push_transparency_mask");
1812
3.77k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
15.0k
        for (i = 0; i < Matte_components; i++) {
1815
11.3k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
11.3k
        }
1817
3.77k
    }
1818
420k
    buf->mask_id = mask_id;
1819
    /* If replacing=false, we start the mask for an image with SMask.
1820
       In this case the image's SMask temporary replaces the
1821
       mask of the containing group. Save the containing droup's mask
1822
       in buf->mask_stack */
1823
420k
    buf->mask_stack = ctx->mask_stack;
1824
420k
    if (buf->mask_stack)
1825
420k
        rc_increment(buf->mask_stack);
1826
#if RAW_DUMP
1827
    /* Dump the current buffer to see what we have. */
1828
    if (ctx->stack->planestride > 0 ){
1829
        dump_raw_buffer(ctx->memory,
1830
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1831
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1832
                        ctx->stack->planestride, ctx->stack->rowstride,
1833
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1834
        global_index++;
1835
    }
1836
#endif
1837
420k
    buf->saved = ctx->stack;
1838
420k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
420k
    buf->SMask_SubType = subtype;
1842
420k
    if (buf->data != NULL) {
1843
        /* We need to initialize it to the BC if it existed */
1844
        /* According to the spec, the CS has to be the same */
1845
        /* If the back ground component is black, then don't bother
1846
           with this.  Since we are forcing the rendering to gray
1847
           earlier now, go ahead and just use the GrayBackGround color
1848
           directly. */
1849
252k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
140
            if (buf->deep) {
1851
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1852
0
                gs_memset16(buf->data, gray, buf->planestride);
1853
                /* If we have a background component that was not black, then we
1854
                   need to set the alpha for this mask as if we had drawn in the
1855
                   entire soft mask buffer */
1856
0
                gs_memset16(buf->data + buf->planestride, 65535,
1857
0
                            buf->planestride *(buf->n_chan - 1));
1858
140
            } else {
1859
140
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
140
                memset(buf->data, gray, buf->planestride);
1861
                /* If we have a background component that was not black, then we
1862
                   need to set the alpha for this mask as if we had drawn in the
1863
                   entire soft mask buffer */
1864
140
                memset(buf->data + buf->planestride, 255,
1865
140
                       buf->planestride * (buf->n_chan - 1));
1866
140
            }
1867
252k
        } else {
1868
            /* Compose mask with opaque background */
1869
252k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
252k
        }
1871
252k
    }
1872
420k
    return 0;
1873
420k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
420k
{
1878
420k
    pdf14_buf* tos = ctx->stack;
1879
420k
    pdf14_buf* nos = tos->saved;
1880
420k
    byte *new_data_buf;
1881
420k
    int icc_match;
1882
420k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
420k
    cmm_profile_t *src_profile;
1884
420k
    gsicc_rendering_param_t rendering_params;
1885
420k
    gsicc_link_t *icc_link;
1886
420k
    gsicc_rendering_param_t render_cond;
1887
420k
    cmm_dev_profile_t *dev_profile;
1888
420k
    int code = 0;
1889
1890
420k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
420k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
420k
                          &render_cond);
1893
420k
    ctx->smask_depth -= 1;
1894
    /* icc_match == -1 means old non-icc code.
1895
       icc_match == 0 means use icc code
1896
       icc_match == 1 mean no conversion needed */
1897
420k
    if (des_profile != NULL && src_profile != NULL ) {
1898
420k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
420k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
420k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
420k
               tos->idle);
1904
420k
    ctx->stack = tos->saved;
1905
420k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
420k
    if (tos->mask_stack) {
1907
        /* During the soft mask push, the mask_stack was copied (not moved) from
1908
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1909
           just set to NULL.  However, before we do that we must perform
1910
           rc decrement to match the increment that occured was made.  Also,
1911
           if this is the last ref count of the rc_mask, we should free the
1912
           buffer now since no other groups need it. */
1913
111k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
111k
        tos->mask_stack = NULL;
1915
111k
    }
1916
1917
420k
    if (tos->data == NULL ) {
1918
        /* This can occur in clist rendering if the soft mask does
1919
           not intersect the current band.  It would be nice to
1920
           catch this earlier and just avoid creating the structure
1921
           to begin with.  For now we need to delete the structure
1922
           that was created.  Only delete if the alpha value is 65535 */
1923
167k
        if (ctx->mask_stack != NULL) {
1924
45.0k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
45.0k
            ctx->mask_stack = NULL;
1926
45.0k
        }
1927
167k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
167k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
4.85k
            pdf14_buf_free(tos);
1930
163k
        } else {
1931
            /* Assign as mask buffer */
1932
163k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
163k
            if (ctx->mask_stack == NULL) {
1934
0
                pdf14_buf_free(tos);
1935
0
                return gs_note_error(gs_error_VMerror);
1936
0
            }
1937
163k
            ctx->mask_stack->mask_buf = tos;
1938
163k
        }
1939
167k
        ctx->smask_blend = false;  /* just in case */
1940
252k
    } else {
1941
        /* If we are already in the source space then there is no reason
1942
           to do the transformation */
1943
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1944
        /* This will reduce our memory.  We won't reuse the existing one, due */
1945
        /* Due to the fact that on certain systems we may have issues recovering */
1946
        /* the data after a resize */
1947
252k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1948
252k
                                        "pdf14_pop_transparency_mask");
1949
252k
        if (new_data_buf == NULL) {
1950
0
            pdf14_buf_free(tos);
1951
0
            return_error(gs_error_VMerror);
1952
0
        }
1953
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
1954
           we won't be filling everything during the remap if it had not been
1955
           written into by the PDF14 fill rect */
1956
252k
        memset(new_data_buf, 0, tos->planestride);
1957
        /* If the subtype was alpha, then just grab the alpha channel now
1958
           and we are all done */
1959
252k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1960
40.6k
            ctx->smask_blend = false;  /* not used in this case */
1961
40.6k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1962
40.6k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1963
40.6k
                       tos->rowstride,
1964
40.6k
                       (tos->data)+tos->planestride, new_data_buf);
1965
#if RAW_DUMP
1966
            /* Dump the current buffer to see what we have. */
1967
            dump_raw_buffer(ctx->memory,
1968
                            tos->rect.q.y-tos->rect.p.y,
1969
                            tos->rowstride>>tos->deep, 1,
1970
                            tos->planestride, tos->rowstride,
1971
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
1972
                            tos->deep);
1973
            global_index++;
1974
#endif
1975
212k
        } else {
1976
212k
            if (icc_match == 1 || tos->n_chan == 2) {
1977
#if RAW_DUMP
1978
                /* Dump the current buffer to see what we have. */
1979
                dump_raw_buffer(ctx->memory,
1980
                                tos->rect.q.y-tos->rect.p.y,
1981
                                tos->rowstride>>tos->deep, tos->n_planes,
1982
                                tos->planestride, tos->rowstride,
1983
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
1984
                                tos->deep);
1985
                global_index++;
1986
#endif
1987
                /* There is no need to color convert.  Data is already gray scale.
1988
                   We just need to copy the gray plane.  However it is
1989
                   possible that the soft mask could have a soft mask which
1990
                   would end us up with some alpha blending information
1991
                   (Bug691803). In fact, according to the spec, the alpha
1992
                   blending has to occur.  See FTS test fts_26_2601.pdf
1993
                   for an example of this.  Softmask buffer is intialized
1994
                   with BG values.  It would be nice to keep track if buffer
1995
                   ever has a alpha value not 1 so that we could detect and
1996
                   avoid this blend if not needed. */
1997
212k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1998
212k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1999
212k
                            tos->planestride, tos->deep);
2000
#if RAW_DUMP
2001
                /* Dump the current buffer to see what we have. */
2002
                dump_raw_buffer(ctx->memory,
2003
                                tos->rect.q.y-tos->rect.p.y,
2004
                                tos->rowstride>>tos->deep, 1,
2005
                                tos->planestride, tos->rowstride,
2006
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2007
                                tos->deep);
2008
                global_index++;
2009
#endif
2010
212k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2011
212k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2012
212k
                           tos->rowstride, tos->data, new_data_buf);
2013
212k
            } else {
2014
0
                if ( icc_match == -1 ) {
2015
                    /* The slow old fashioned way */
2016
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2017
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2018
0
                        tos->rowstride, tos->planestride,
2019
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2020
0
                        tos->deep
2021
#if RAW_DUMP
2022
                        , ctx->memory
2023
#endif
2024
0
                        );
2025
0
                } else {
2026
                    /* ICC case where we use the CMM */
2027
                    /* Request the ICC link for the transform that we will need to use */
2028
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2029
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2030
0
                    rendering_params.override_icc = false;
2031
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2032
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2033
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2034
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2035
0
                        src_profile, &rendering_params, pgs->memory, false);
2036
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2037
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2038
0
                              tos->rowstride, tos->planestride,
2039
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2040
                    /* Release the link */
2041
0
                    gsicc_release_link(icc_link);
2042
0
                }
2043
0
            }
2044
212k
        }
2045
        /* Free the old object, NULL test was above */
2046
252k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2047
252k
        tos->data = new_data_buf;
2048
        /* Data is single channel now */
2049
252k
        tos->n_chan = 1;
2050
252k
        tos->n_planes = 1;
2051
        /* Assign as reference counted mask buffer */
2052
252k
        if (ctx->mask_stack != NULL) {
2053
            /* In this case, the source file is wacky as it already had a
2054
               softmask and now is getting a replacement. We need to clean
2055
               up the softmask stack before doing this free and creating
2056
               a new stack. Bug 693312 */
2057
65.8k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2058
65.8k
        }
2059
252k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2060
252k
        if (ctx->mask_stack == NULL) {
2061
0
            pdf14_buf_free(tos);
2062
0
            return gs_note_error(gs_error_VMerror);
2063
0
        }
2064
252k
        ctx->mask_stack->mask_buf = tos;
2065
252k
    }
2066
420k
    return code;
2067
420k
}
2068
2069
static void
2070
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2071
1.52M
{
2072
    /* Ending the mask buffer. */
2073
1.52M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2074
    /* free the pdf14 buffer. */
2075
1.52M
    if (mask->mask_buf != NULL) {
2076
108k
        pdf14_buf_free(mask->mask_buf);
2077
108k
    }
2078
1.52M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2079
1.52M
}
2080
2081
static pdf14_mask_t *
2082
pdf14_mask_element_new(gs_memory_t *memory)
2083
1.52M
{
2084
1.52M
    pdf14_mask_t *result;
2085
2086
1.52M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2087
1.52M
                             "pdf14_mask_element_new");
2088
1.52M
    if (result == NULL)
2089
0
        return NULL;
2090
2091
1.52M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2092
2093
1.52M
    result->mask_buf = NULL;
2094
1.52M
    result->memory = memory;
2095
1.52M
    result->previous = NULL;
2096
2097
1.52M
    return result;
2098
1.52M
}
2099
2100
static int
2101
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2102
0
{
2103
    /* We need to push the current soft mask.  We need to
2104
       be able to recover it if we draw a new one and
2105
       then obtain a Q operation ( a pop ) */
2106
2107
0
    pdf14_device *pdev = (pdf14_device *)dev;
2108
0
    pdf14_ctx *ctx = pdev->ctx;
2109
0
    pdf14_mask_t *new_mask;
2110
2111
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2112
    /* We need to push the current mask buffer   */
2113
    /* Allocate a new element for the stack.
2114
       Don't do anything if there is no mask present.*/
2115
0
    if (ctx->mask_stack != NULL) {
2116
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2117
0
        if (new_mask == NULL)
2118
0
            return gs_note_error(gs_error_VMerror);
2119
0
        new_mask->previous = ctx->mask_stack;
2120
0
        ctx->mask_stack = new_mask;
2121
0
    }
2122
#ifdef DEBUG
2123
    pdf14_debug_mask_stack_state(pdev->ctx);
2124
#endif
2125
0
    return 0;
2126
0
}
2127
2128
static int
2129
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2130
2.81M
{
2131
    /* Pop the soft mask.  It is no longer needed. Likely due to
2132
       a Q that has occurred. */
2133
2.81M
    pdf14_device *pdev = (pdf14_device *)dev;
2134
2.81M
    pdf14_ctx *ctx = pdev->ctx;
2135
2.81M
    pdf14_mask_t *old_mask;
2136
2137
2.81M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2138
    /* rc decrement the current link after we break it from
2139
       the list, then free the stack element.  Don't do
2140
       anything if there is no mask present. */
2141
2.81M
    if (ctx->mask_stack != NULL) {
2142
451k
        old_mask = ctx->mask_stack;
2143
451k
        ctx->mask_stack = ctx->mask_stack->previous;
2144
451k
        rc_decrement(old_mask, "pdf14_pop_transparency_state");
2145
        /* We need to have some special handling here for when we have nested
2146
           soft masks.  There may be a copy in the stack that we may need to
2147
           adjust. */
2148
451k
        if (ctx->smask_depth > 0) {
2149
            /* RJW: This logic was introduced by mvrhel as:
2150
             *    if (ctx->stack != NULL && ctx->stack->mask_stack != NULL)
2151
             * back in commit f0208a3d621. Unfortunately no record exists of the bug
2152
             * that this was supposed to solve. Bug 709701 shows this up as being wrong
2153
             * in at least some cases. In that bug it overwrites a valid smask entry
2154
             * with a NULL one. So the fix, implemented here is never to overwrite
2155
             * with a NULL entry. This shows no diffs in the cluster. More information
2156
             * on the bug.
2157
             */
2158
222
            if (ctx->stack != NULL && ctx->mask_stack != NULL) {
2159
0
                ctx->stack->mask_stack = ctx->mask_stack;
2160
0
            }
2161
222
        }
2162
451k
    }
2163
#ifdef DEBUG
2164
    pdf14_debug_mask_stack_state(pdev->ctx);
2165
#endif
2166
2.81M
    return 0;
2167
2.81M
}
2168
2169
static  int
2170
pdf14_open(gx_device *dev)
2171
1.10M
{
2172
1.10M
    pdf14_device *pdev = (pdf14_device *)dev;
2173
2174
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2175
1.10M
    if (pdev->ctx == NULL) {
2176
1.10M
        bool has_tags = device_encodes_tags(dev);
2177
1.10M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2178
1.10M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2179
1.10M
        if (pdev->ctx == NULL)
2180
0
            return_error(gs_error_VMerror);
2181
2182
1.10M
        pdev->ctx->rect.p.x = 0;
2183
1.10M
        pdev->ctx->rect.p.y = 0;
2184
1.10M
        pdev->ctx->rect.q.x = dev->width;
2185
1.10M
        pdev->ctx->rect.q.y = dev->height;
2186
1.10M
        pdev->ctx->has_tags = has_tags;
2187
1.10M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2188
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2189
         * is. I am not sure how to fix that. */
2190
1.10M
        if (pdev->ctx->num_spots < 0)
2191
0
            pdev->ctx->num_spots = 0;
2192
1.10M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2193
1.10M
    }
2194
1.10M
    pdev->free_devicen = true;
2195
1.10M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2196
1.10M
    return 0;
2197
1.10M
}
2198
2199
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2200
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2201
};
2202
2203
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2204
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2205
};
2206
2207
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2208
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2209
};
2210
2211
static const gx_cm_color_map_procs *
2212
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2213
8.42M
{
2214
8.42M
    *tdev = dev;
2215
8.42M
    return &pdf14_DeviceCMYKspot_procs;
2216
8.42M
}
2217
2218
static const gx_cm_color_map_procs *
2219
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2220
2.90M
{
2221
2.90M
    *tdev = dev;
2222
2.90M
    return &pdf14_DeviceRGBspot_procs;
2223
2.90M
}
2224
2225
static const gx_cm_color_map_procs *
2226
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2227
0
{
2228
0
    *tdev = dev;
2229
0
    return &pdf14_DeviceGrayspot_procs;
2230
0
}
2231
2232
static void
2233
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2234
0
{
2235
0
    for (; n != 0; n--) {
2236
0
        uint16_t in = *src++;
2237
0
        ((byte *)dst)[0] = in>>8;
2238
0
        ((byte *)dst)[1] = in;
2239
0
        dst++;
2240
0
    }
2241
0
}
2242
2243
/* Used to pass along information about the buffer created by the
2244
   pdf14 device.  This is used by the pattern accumulator when the
2245
   pattern contains transparency.  Note that if free_device is true then
2246
   we need to go ahead and get the buffer data copied and free up the
2247
   device.  This only occurs at the end of a pattern accumulation operation */
2248
int
2249
pdf14_get_buffer_information(const gx_device * dev,
2250
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2251
                             bool free_device)
2252
23.2k
{
2253
23.2k
    const pdf14_device * pdev = (pdf14_device *)dev;
2254
23.2k
    pdf14_buf *buf;
2255
23.2k
    gs_int_rect rect;
2256
23.2k
    int x1,y1,width,height;
2257
2258
23.2k
    if ( pdev->ctx == NULL){
2259
0
        return 0;  /* this can occur if the pattern is a clist */
2260
0
    }
2261
#ifdef DEBUG
2262
    pdf14_debug_mask_stack_state(pdev->ctx);
2263
#endif
2264
23.2k
    buf = pdev->ctx->stack;
2265
23.2k
    rect = buf->rect;
2266
23.2k
    transbuff->buf = (free_device ? NULL : buf);
2267
23.2k
    x1 = min(pdev->width, rect.q.x);
2268
23.2k
    y1 = min(pdev->height, rect.q.y);
2269
23.2k
    width = x1 - rect.p.x;
2270
23.2k
    height = y1 - rect.p.y;
2271
2272
23.2k
    transbuff->n_chan    = buf->n_chan;
2273
23.2k
    transbuff->has_tags  = buf->has_tags;
2274
23.2k
    transbuff->has_shape = buf->has_shape;
2275
23.2k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2276
23.2k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2277
23.2k
    transbuff->deep      = buf->deep;
2278
2279
23.2k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2280
8.23k
        transbuff->planestride = 0;
2281
8.23k
        transbuff->rowstride = 0;
2282
8.23k
        return 0;
2283
8.23k
    }
2284
2285
15.0k
    if (free_device) {
2286
4.80k
        transbuff->pdev14 = NULL;
2287
4.80k
        transbuff->rect = rect;
2288
4.80k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2289
            /* If the bbox is smaller than the whole buffer than go ahead and
2290
               create a new one to use.  This can occur if we drew in a smaller
2291
               area than was specified by the transparency group rect. */
2292
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2293
0
            intptr_t planestride = rowstride * height;
2294
0
            int k, j;
2295
0
            byte *buff_ptr_src, *buff_ptr_des;
2296
2297
0
            transbuff->planestride = planestride;
2298
0
            transbuff->rowstride = rowstride;
2299
0
            transbuff->transbytes =
2300
0
                         gs_alloc_bytes(mem,
2301
0
                                        planestride *
2302
0
                                                (buf->n_chan +
2303
0
                                                 (buf->has_tags ? 1 : 0)) + CAL_SLOP,
2304
0
                                        "pdf14_get_buffer_information");
2305
0
            if (transbuff->transbytes == NULL)
2306
0
                return gs_error_VMerror;
2307
2308
0
            transbuff->mem = mem;
2309
0
            if (transbuff->deep) {
2310
0
                for (j = 0; j < transbuff->n_chan; j++) {
2311
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2312
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2313
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2314
0
                    for (k = 0; k < height; k++) {
2315
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2316
0
                        buff_ptr_des += rowstride;
2317
0
                        buff_ptr_src += buf->rowstride;
2318
0
                    }
2319
0
                }
2320
0
            } else {
2321
0
                for (j = 0; j < transbuff->n_chan; j++) {
2322
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2323
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2324
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2325
0
                    for (k = 0; k < height; k++) {
2326
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2327
0
                        buff_ptr_des += rowstride;
2328
0
                        buff_ptr_src += buf->rowstride;
2329
0
                    }
2330
0
                }
2331
0
            }
2332
2333
4.80k
        } else {
2334
            /* The entire buffer is used.  Go ahead and grab the pointer and
2335
               clear the pointer in the pdf14 device data buffer so it is not
2336
               freed when we close the device */
2337
4.80k
            transbuff->planestride = buf->planestride;
2338
4.80k
            transbuff->rowstride = buf->rowstride;
2339
4.80k
            transbuff->transbytes = buf->data;
2340
4.80k
            transbuff->mem = buf->memory;
2341
4.80k
            buf->data = NULL;  /* So that the buffer is not freed */
2342
4.80k
            if (transbuff->deep) {
2343
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2344
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2345
0
                uint16_t *buff_ptr;
2346
0
                int j, k, z;
2347
0
                intptr_t rowstride = transbuff->rowstride>>1;
2348
0
                intptr_t planestride = transbuff->planestride;
2349
0
                for (j = 0; j < transbuff->n_chan; j++) {
2350
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2351
0
                    for (k = 0; k < height; k++) {
2352
0
                        for (z = 0; z < width; z++) {
2353
0
                            uint16_t in = buff_ptr[z];
2354
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2355
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2356
0
                        }
2357
0
                        buff_ptr += rowstride;
2358
0
                    }
2359
0
                }
2360
0
            }
2361
4.80k
        }
2362
#if RAW_DUMP
2363
        /* Dump the buffer that should be going into the pattern */;
2364
        dump_raw_buffer_be(buf->memory,
2365
                           height, width, transbuff->n_chan,
2366
                           transbuff->planestride, transbuff->rowstride,
2367
                           "pdf14_pattern_buff", transbuff->transbytes,
2368
                           transbuff->deep);
2369
        global_index++;
2370
#endif
2371
        /* Go ahead and free up the pdf14 device */
2372
4.80k
        dev_proc(dev, close_device)((gx_device *)dev);
2373
10.2k
    } else {
2374
        /* Here we are coming from one of the fill image / pattern / mask
2375
           operations */
2376
10.2k
        transbuff->pdev14 = dev;
2377
10.2k
        transbuff->planestride = buf->planestride;
2378
10.2k
        transbuff->rowstride = buf->rowstride;
2379
10.2k
        transbuff->transbytes = buf->data;
2380
10.2k
        transbuff->mem = buf->memory;
2381
10.2k
        transbuff->rect = rect;
2382
#if RAW_DUMP
2383
    /* Dump the buffer that should be going into the pattern */;
2384
        dump_raw_buffer(buf->memory,
2385
                        height, width, buf->n_chan,
2386
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2387
                        "pdf14_pattern_buff",
2388
                        buf->data,
2389
                        transbuff->deep);
2390
        global_index++;
2391
#endif
2392
10.2k
    }
2393
15.0k
    return 0;
2394
15.0k
}
2395
2396
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2397
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2398
2399
2400
static int
2401
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2402
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2403
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2404
8.25k
{
2405
8.25k
    pdf14_buf* cm_result = NULL;
2406
8.25k
    cmm_profile_t* des_profile;
2407
8.25k
    gsicc_rendering_param_t render_cond;
2408
8.25k
    bool did_alloc;
2409
8.25k
    bool endian_swap;
2410
2411
8.25k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2412
8.25k
        &render_cond);
2413
2414
#if RAW_DUMP
2415
#if !ARCH_IS_BIG_ENDIAN
2416
    if (was_blended && (*buf)->deep)
2417
      dump_raw_buffer_be(dev->ctx->memory,
2418
          height, width, (*buf)->n_planes, (*buf)->planestride,
2419
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2420
    else
2421
#endif
2422
      dump_raw_buffer(dev->ctx->memory,
2423
          height, width, (*buf)->n_planes, (*buf)->planestride,
2424
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2425
    global_index++;
2426
#endif
2427
2428
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2429
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2430
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2431
       will need to know if it is dealing with native or BE data. */
2432
8.25k
    if (was_blended && (*buf)->deep) {
2433
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2434
           color conversion */
2435
#if ARCH_IS_BIG_ENDIAN
2436
        endian_swap = false;
2437
#else
2438
0
        endian_swap = true;
2439
0
#endif
2440
8.25k
    } else {
2441
        /* Data is in native format. No swap needed for CMM */
2442
8.25k
        endian_swap = false;
2443
8.25k
    }
2444
2445
8.25k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2446
8.25k
        *buf_ptr, src_profile, des_profile, x, y, width,
2447
8.25k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2448
2449
8.25k
    if (cm_result == NULL)
2450
0
        return_error(gs_error_VMerror);
2451
2452
    /* Update */
2453
8.25k
    *buf = cm_result;
2454
2455
    /* Make sure our buf_ptr is pointing to the proper location */
2456
8.25k
    if (did_alloc)
2457
8.25k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2458
2459
#if RAW_DUMP
2460
    dump_raw_buffer(dev->ctx->memory,
2461
        height, width, (*buf)->n_planes, (*buf)->planestride,
2462
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2463
    global_index++;
2464
#endif
2465
8.25k
    return 0;
2466
8.25k
}
2467
2468
/**
2469
 * pdf14_put_image: Put rendered image to target device.
2470
 * @pdev: The PDF 1.4 rendering device.
2471
 * @pgs: State for image draw operation.
2472
 * @target: The target device.
2473
 *
2474
 * Puts the rendered image in @pdev's buffer to @target. This is called
2475
 * as part of the sequence of popping the PDF 1.4 device filter.
2476
 *
2477
 * Return code: negative on error.
2478
 **/
2479
static  int
2480
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2481
1.02M
{
2482
1.02M
    const pdf14_device * pdev = (pdf14_device *)dev;
2483
1.02M
    int code;
2484
1.02M
    gs_image1_t image;
2485
1.02M
    gx_image_enum_common_t *info;
2486
1.02M
    pdf14_buf *buf = pdev->ctx->stack;
2487
1.02M
    gs_int_rect rect;
2488
1.02M
    int y;
2489
1.02M
    int num_comp;
2490
1.02M
    byte *linebuf, *linebuf_unaligned;
2491
1.02M
    gs_color_space *pcs;
2492
1.02M
    int x1, y1, width, height;
2493
1.02M
    byte *buf_ptr;
2494
1.02M
    int num_rows_left;
2495
1.02M
    cmm_profile_t* src_profile = NULL;
2496
1.02M
    cmm_profile_t* des_profile = NULL;
2497
1.02M
    cmm_dev_profile_t *pdf14dev_profile;
2498
1.02M
    cmm_dev_profile_t *dev_target_profile;
2499
1.02M
    uint16_t bg;
2500
1.02M
    bool has_tags = device_encodes_tags(dev);
2501
1.02M
    bool deep = pdev->ctx->deep;
2502
1.02M
    intptr_t planestride;
2503
1.02M
    intptr_t rowstride;
2504
1.02M
    blend_image_row_proc_t *blend_row;
2505
1.02M
    bool color_mismatch = false;
2506
1.02M
    bool supports_alpha = false;
2507
1.02M
    int i;
2508
1.02M
    int alpha_offset, tag_offset;
2509
1.02M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2510
1.02M
    int rendering_intent_saved;
2511
1.02M
    int additive;
2512
2513
    /* Nothing was ever drawn. */
2514
1.02M
    if (buf == NULL)
2515
140k
        return 0;
2516
2517
886k
    additive = buf->group_color_info->isadditive;
2518
2519
886k
    src_profile = buf->group_color_info->icc_profile;
2520
2521
886k
    num_comp = buf->n_chan - 1;
2522
886k
    rect = buf->rect;
2523
886k
    planestride = buf->planestride;
2524
886k
    rowstride = buf->rowstride;
2525
2526
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2527
       potential problem. Bug 694190 */
2528
886k
    if (buf->saved != NULL) {
2529
15
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2530
15
    }
2531
886k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2532
886k
    rect_intersect(rect, buf->dirty);
2533
886k
    x1 = min(pdev->width, rect.q.x);
2534
886k
    y1 = min(pdev->height, rect.q.y);
2535
886k
    width = x1 - rect.p.x;
2536
886k
    height = y1 - rect.p.y;
2537
#ifdef DUMP_TO_PNG
2538
    dump_planar_rgba(pdev->memory, buf);
2539
#endif
2540
886k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2541
235k
        return 0;
2542
650k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2543
2544
    /* Check that target is OK.  From fuzzing results the target could have been
2545
       destroyed, for e.g if it were a pattern accumulator that was closed
2546
       prematurely (Bug 694154).  We should always be able to to get an ICC
2547
       profile from the target. */
2548
650k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2549
650k
    if (code < 0)
2550
0
        return code;
2551
650k
    if (dev_target_profile == NULL)
2552
0
        return gs_throw_code(gs_error_Fatal);
2553
2554
650k
    if (src_profile == NULL) {
2555
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2556
0
        if (code < 0) {
2557
0
            return code;
2558
0
        }
2559
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2560
0
    }
2561
2562
    /* Check if we have a color conversion issue */
2563
650k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2564
650k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2565
134k
        color_mismatch = true;
2566
2567
    /* Check if target supports alpha */
2568
650k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2569
650k
    code = 0;
2570
2571
#if RAW_DUMP
2572
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2573
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2574
        "pre_final_blend", buf_ptr, deep);
2575
#endif
2576
2577
    /* Note. The logic below will need a little rework if we ever
2578
       have a device that has tags and alpha support */
2579
650k
    if (supports_alpha) {
2580
0
        if (!color_mismatch) {
2581
0
            alpha_offset = num_comp;
2582
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2583
2584
0
            for (i = 0; i < buf->n_planes; i++)
2585
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2586
0
            for (; i < target->color_info.num_components; i++)
2587
0
                buf_ptrs[i] = 0;
2588
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2589
0
                rect.p.x, rect.p.y, width, height,
2590
0
                rowstride, alpha_offset,
2591
0
                tag_offset);
2592
            /* Right now code has number of rows written */
2593
0
        } else {
2594
            /* In this case, just color convert and maintain alpha.  This is a case
2595
               where we either either blend in the right color space and have no
2596
               alpha for the output device or hand back the wrong color space with
2597
               alpha data.  We choose the later. */
2598
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2599
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2600
0
                width, height, false);
2601
0
            if (code < 0)
2602
0
                return code;
2603
2604
            /* reset */
2605
0
            rowstride = buf->rowstride;
2606
0
            planestride = buf->planestride;
2607
0
            num_comp = buf->n_chan - 1;
2608
0
            alpha_offset = num_comp;
2609
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2610
2611
            /* And then out */
2612
0
            for (i = 0; i < buf->n_planes; i++)
2613
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2614
0
            for (; i < target->color_info.num_components; i++)
2615
0
                buf_ptrs[i] = 0;
2616
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2617
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2618
0
                tag_offset);
2619
            /* Right now code has number of rows written */
2620
0
        }
2621
650k
    } else if (has_tags) {
2622
        /* We are going out to a device that supports tags */
2623
0
        if (deep) {
2624
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2625
0
                buf->planestride, num_comp, additive, false);
2626
0
        } else {
2627
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2628
0
                buf->planestride, num_comp, additive);
2629
0
        }
2630
2631
#if RAW_DUMP
2632
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2633
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2634
            "post_final_blend", buf_ptr, deep);
2635
#endif
2636
2637
        /* Take care of color issues */
2638
0
        if (color_mismatch) {
2639
            /* In this case, just color convert and maintain alpha.  This is a case
2640
               where we either either blend in the right color space and have no
2641
               alpha for the output device or hand back the wrong color space with
2642
               alpha data.  We choose the later. */
2643
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2644
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2645
0
            if (code < 0)
2646
0
                return code;
2647
2648
#if RAW_DUMP
2649
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2650
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2651
                "final_color_manage", buf_ptr, deep);
2652
            global_index++;
2653
#endif
2654
0
        }
2655
2656
        /* reset */
2657
0
        rowstride = buf->rowstride;
2658
0
        planestride = buf->planestride;
2659
0
        num_comp = buf->n_chan - 1;
2660
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2661
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2662
2663
        /* And then out */
2664
0
        for (i = 0; i < buf->n_planes; i++)
2665
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2666
0
        for (; i < target->color_info.num_components; i++)
2667
0
            buf_ptrs[i] = 0;
2668
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2669
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2670
0
            tag_offset);
2671
        /* Right now code has number of rows written */
2672
2673
0
    }
2674
2675
    /* If code > 0 then put image worked.  Let it finish and then exit */
2676
650k
    if (code > 0) {
2677
        /* We processed some or all of the rows.  Continue until we are done */
2678
0
        num_rows_left = height - code;
2679
0
        while (num_rows_left > 0) {
2680
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2681
0
                                                rect.p.x, rect.p.y + code, width,
2682
0
                                                num_rows_left, rowstride,
2683
0
                                                alpha_offset, tag_offset);
2684
0
            num_rows_left = num_rows_left - code;
2685
0
        }
2686
0
        return 0;
2687
0
    }
2688
2689
    /* Target device did not support alpha or tags.
2690
     * Set color space in preparation for sending an image.
2691
     * color conversion will occur after blending with through
2692
     * the begin typed image work flow.
2693
     */
2694
2695
650k
    planestride = buf->planestride;
2696
650k
    rowstride = buf->rowstride;
2697
650k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2698
650k
    if (code < 0)
2699
0
        return code;
2700
    /* Need to set this to avoid color management during the image color render
2701
       operation.  Exception is for the special case when the destination was
2702
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2703
       image operation.  That will happen here as we should have set the profile
2704
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2705
       the case when we have a blend color space that is different than the
2706
       target device color space */
2707
650k
    pcs->cmm_icc_profile_data = src_profile;
2708
2709
    /* pcs takes a reference to the profile data it just retrieved. */
2710
650k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2711
650k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
2712
0
        return_error(gs_error_rangecheck);
2713
2714
650k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2715
650k
    gs_image_t_init_adjust(&image, pcs, false);
2716
650k
    image.ImageMatrix.xx = (float)width;
2717
650k
    image.ImageMatrix.yy = (float)height;
2718
650k
    image.Width = width;
2719
650k
    image.Height = height;
2720
650k
    image.BitsPerComponent = deep ? 16 : 8;
2721
650k
    image.ColorSpace = pcs;
2722
650k
    ctm_only_writable(pgs).xx = (float)width;
2723
650k
    ctm_only_writable(pgs).xy = 0;
2724
650k
    ctm_only_writable(pgs).yx = 0;
2725
650k
    ctm_only_writable(pgs).yy = (float)height;
2726
650k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2727
650k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2728
    /* Make sure that the relative colorimetric rendering intent is
2729
       used for this image. */
2730
650k
    rendering_intent_saved = pgs->renderingintent;
2731
650k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2732
650k
    code = dev_proc(target, begin_typed_image) (target,
2733
650k
                                                pgs, NULL,
2734
650k
                                                (gs_image_common_t *)&image,
2735
650k
                                                NULL, NULL, NULL,
2736
650k
                                                pgs->memory, &info);
2737
650k
    pgs->renderingintent = rendering_intent_saved;
2738
650k
    if (code < 0) {
2739
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2740
0
        return code;
2741
0
    }
2742
#if RAW_DUMP
2743
    /* Dump the current buffer to see what we have. */
2744
    dump_raw_buffer(pdev->ctx->memory,
2745
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2746
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2747
                    pdev->ctx->stack->n_planes,
2748
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2749
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2750
    dump_raw_buffer(pdev->ctx->memory,
2751
                    height, width, buf->n_planes,
2752
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2753
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2754
    global_index++;
2755
    clist_band_count++;
2756
#endif
2757
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2758
    /* 28 byte overflow for AVX CMYK case. */
2759
650k
#define SSE_ALIGN 32
2760
650k
#define SSE_OVERFLOW 28
2761
650k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2762
650k
    if (linebuf_unaligned == NULL)
2763
0
        return gs_error_VMerror;
2764
650k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2765
2766
650k
    blend_row = deep ? gx_build_blended_image_row16 :
2767
650k
                       gx_build_blended_image_row;
2768
#ifdef WITH_CAL
2769
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2770
                                  blend_row, num_comp, deep);
2771
#endif
2772
2773
650k
    bg = additive ? (deep ? 65535 : 255) : 0;
2774
7.20M
    for (y = 0; y < height; y++) {
2775
6.55M
        gx_image_plane_t planes;
2776
6.55M
        int rows_used;
2777
2778
6.55M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2779
6.55M
        planes.data = linebuf;
2780
6.55M
        planes.data_x = 0;
2781
6.55M
        planes.raster = width * num_comp;
2782
6.55M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2783
        /* todo: check return value */
2784
6.55M
        buf_ptr += buf->rowstride;
2785
6.55M
    }
2786
650k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2787
650k
    info->procs->end_image(info, true);
2788
    /* This will also decrement the device profile */
2789
650k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2790
650k
    return code;
2791
650k
}
2792
2793
/* Overprint simulation with spots.  Collapse to CMYK */
2794
static void
2795
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2796
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2797
    cmyk_composite_map *map, bool keep_alpha)
2798
0
{
2799
0
    int comp_num;
2800
0
    uint cyan, magenta, yellow, black;
2801
0
    cmyk_composite_map *cmyk_map_entry;
2802
0
    int x, y;
2803
0
    intptr_t position;
2804
0
    byte comp, a;
2805
2806
0
    for (y = 0; y < height; y++) {
2807
0
        position = y * rowstride;
2808
0
        for (x = 0; x < width; x++) {
2809
0
            a = buf_ptr[position + planestride * num_comp];
2810
0
            if (a != 0) {
2811
0
                cyan = buf_ptr[position] * frac_1;
2812
0
                magenta = buf_ptr[position + planestride] * frac_1;
2813
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2814
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2815
0
                cmyk_map_entry = &(map[4]);
2816
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2817
0
                    comp = buf_ptr[position + planestride * comp_num];
2818
0
                    cyan += cmyk_map_entry->c * comp;
2819
0
                    magenta += cmyk_map_entry->m * comp;
2820
0
                    yellow += cmyk_map_entry->y * comp;
2821
0
                    black += cmyk_map_entry->k * comp;
2822
0
                    cmyk_map_entry++;
2823
0
                }
2824
0
                cyan /= frac_1;
2825
0
                magenta /= frac_1;
2826
0
                yellow /= frac_1;
2827
0
                black /= frac_1;
2828
2829
0
                if (cyan > 255)
2830
0
                    cyan = 255;
2831
0
                if (magenta > 255)
2832
0
                    magenta = 255;
2833
0
                if (yellow > 255)
2834
0
                    yellow = 255;
2835
0
                if (black > 255)
2836
0
                    black = 255;
2837
2838
0
                buf_ptr[position] = cyan;
2839
0
                buf_ptr[position + planestride] = magenta;
2840
0
                buf_ptr[position + planestride * 2] = yellow;
2841
0
                buf_ptr[position + planestride * 3] = black;
2842
0
            }
2843
0
            if (keep_alpha) {
2844
                /* Move the alpha and tag data */
2845
0
                buf_ptr[position + planestride * 4] = a;
2846
0
                if (tag_offset > 0) {
2847
0
                    buf_ptr[position + planestride * 5] =
2848
0
                        buf_ptr[position + planestride * tag_offset];
2849
0
                }
2850
0
            } else {
2851
                /* Remove alpha but keep tags */
2852
0
                if (tag_offset > 0) {
2853
0
                    buf_ptr[position + planestride * 4] =
2854
0
                        buf_ptr[position + planestride * tag_offset];
2855
0
                }
2856
2857
0
            }
2858
0
            position += 1;
2859
0
        }
2860
0
    }
2861
0
}
2862
2863
static void
2864
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2865
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2866
    cmyk_composite_map *map, bool keep_alpha)
2867
0
{
2868
0
    int comp_num;
2869
0
    ulong cyan, magenta, yellow, black;
2870
0
    cmyk_composite_map *cmyk_map_entry;
2871
0
    int x, y;
2872
0
    intptr_t position;
2873
0
    ulong comp, a;
2874
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2875
2876
    /* planestride and rowstride are in bytes, and we want them in shorts */
2877
0
    planestride >>= 1;
2878
0
    rowstride >>= 1;
2879
2880
0
    for (y = 0; y < height; y++) {
2881
0
        position = y * rowstride;
2882
0
        for (x = 0; x < width; x++) {
2883
0
            a = buf_ptr[position + planestride * num_comp];
2884
0
            if (a != 0) {
2885
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2886
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2887
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2888
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2889
0
                cmyk_map_entry = &(map[4]);
2890
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2891
0
                    comp = buf_ptr[position + planestride * comp_num];
2892
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2893
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2894
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2895
0
                    black += (ulong)cmyk_map_entry->k * comp;
2896
0
                    cmyk_map_entry++;
2897
0
                }
2898
0
                cyan /= frac_1_long;
2899
0
                magenta /= frac_1_long;
2900
0
                yellow /= frac_1_long;
2901
0
                black /= frac_1_long;
2902
2903
0
                if (cyan > 65535)
2904
0
                    cyan = 65535;
2905
0
                if (magenta > 65535)
2906
0
                    magenta = 65535;
2907
0
                if (yellow > 65535)
2908
0
                    yellow = 65535;
2909
0
                if (black > 65535)
2910
0
                    black = 65535;
2911
2912
#if ARCH_IS_BIG_ENDIAN
2913
                buf_ptr[position] = cyan;
2914
                buf_ptr[position + planestride] = magenta;
2915
                buf_ptr[position + planestride * 2] = yellow;
2916
                buf_ptr[position + planestride * 3] = black;
2917
#else
2918
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2919
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2920
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2921
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2922
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2923
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2924
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2925
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2926
0
#endif
2927
0
            }
2928
            /* Move the alpha and tag data */
2929
#if ARCH_IS_BIG_ENDIAN
2930
            if (keep_alpha) {
2931
                buf_ptr[position + planestride * 4] = a;
2932
                if (tag_offset > 0) {
2933
                    buf_ptr[position + planestride * 5] =
2934
                        buf_ptr[position + planestride * tag_offset];
2935
                }
2936
            } else {
2937
                if (tag_offset > 0) {
2938
                    buf_ptr[position + planestride * 4] =
2939
                        buf_ptr[position + planestride * tag_offset];
2940
                }
2941
            }
2942
#else
2943
0
            if (keep_alpha) {
2944
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2945
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2946
0
                if (tag_offset > 0) {
2947
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2948
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2949
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2950
0
                        buf_ptr[position + planestride * tag_offset];
2951
0
                }
2952
0
            } else {
2953
0
                if (tag_offset > 0) {
2954
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2955
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2956
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2957
0
                        buf_ptr[position + planestride * tag_offset];
2958
0
                }
2959
0
            }
2960
0
#endif
2961
0
            position += 1;
2962
0
        }
2963
0
    }
2964
0
}
2965
2966
static void
2967
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2968
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2969
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2970
0
{
2971
0
    if (deep) {
2972
0
        if (keep_alpha) {
2973
0
            if (tag_offset > 0) {
2974
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2975
0
                    planestride, num_comp, spot_start, tag_offset,
2976
0
                    map, true);
2977
0
            } else {
2978
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2979
0
                    planestride, num_comp, spot_start, 0,
2980
0
                    map, true);
2981
0
            }
2982
0
        } else {
2983
0
            if (tag_offset > 0) {
2984
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2985
0
                    planestride, num_comp, spot_start, tag_offset,
2986
0
                    map, false);
2987
0
            } else {
2988
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2989
0
                    planestride, num_comp, spot_start, 0,
2990
0
                    map, false);
2991
0
            }
2992
0
        }
2993
0
    } else {
2994
0
        if (keep_alpha) {
2995
0
            if (tag_offset > 0) {
2996
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2997
0
                    planestride, num_comp, spot_start, tag_offset,
2998
0
                    map, true);
2999
0
            } else {
3000
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3001
0
                    planestride, num_comp, spot_start, 0,
3002
0
                    map, true);
3003
0
            }
3004
0
        } else {
3005
0
            if (tag_offset > 0) {
3006
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3007
0
                    planestride, num_comp, spot_start, tag_offset,
3008
0
                    map, false);
3009
0
            } else {
3010
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3011
0
                    planestride, num_comp, spot_start, 0,
3012
0
                    map, false);
3013
0
            }
3014
0
        }
3015
0
    }
3016
0
}
3017
3018
/* This is for the case where we have mixture of spots and additive color.
3019
   For example, RGB + spots or Gray + spots */
3020
static void
3021
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3022
    intptr_t planestride, int num_comp, int spot_start)
3023
8.25k
{
3024
8.25k
    int x, y;
3025
8.25k
    intptr_t position;
3026
8.25k
    byte comp, a;
3027
8.25k
    int tmp, comp_num;
3028
3029
86.1k
    for (y = 0; y < height; y++) {
3030
77.8k
        position = y * rowstride;
3031
71.4M
        for (x = 0; x < width; x++) {
3032
71.3M
            a = buf_ptr[position + planestride * num_comp];
3033
71.3M
            if ((a + 1) & 0xfe) {
3034
818k
                a ^= 0xff;
3035
3.27M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3036
2.45M
                    comp = buf_ptr[position + planestride * comp_num];
3037
2.45M
                    tmp = ((0xff - comp) * a) + 0x80;
3038
2.45M
                    comp += (tmp + (tmp >> 8)) >> 8;
3039
2.45M
                    buf_ptr[position + planestride * comp_num] = comp;
3040
2.45M
                }
3041
818k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3042
0
                    comp = buf_ptr[position + planestride * comp_num];
3043
0
                    tmp = ((-comp) * a) + 0x80;
3044
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3045
0
                    buf_ptr[position + planestride * comp_num] = comp;
3046
0
                }
3047
70.5M
            } else if (a == 0) {
3048
62.1M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3049
46.5M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3050
46.5M
                }
3051
16.1M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3052
596k
                    buf_ptr[position + planestride * comp_num] = 0;
3053
596k
                }
3054
15.5M
            }
3055
71.3M
            position += 1;
3056
71.3M
        }
3057
77.8k
    }
3058
8.25k
}
3059
3060
static void
3061
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3062
    intptr_t planestride, int num_comp, int spot_start)
3063
0
{
3064
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3065
0
    int x, y;
3066
0
    intptr_t position;
3067
0
    int comp, a;
3068
0
    int tmp, comp_num;
3069
3070
    /* planestride and rowstride are in bytes, and we want them in shorts */
3071
0
    planestride >>= 1;
3072
0
    rowstride >>= 1;
3073
3074
    /* Note that the input here is native endian, and the output must be in big endian! */
3075
0
    for (y = 0; y < height; y++) {
3076
0
        position = y * rowstride;
3077
0
        for (x = 0; x < width; x++) {
3078
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3079
0
            a = buf_ptr[position + planestride * num_comp];
3080
0
            if (a == 0) {
3081
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3082
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3083
0
                }
3084
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3085
0
                    buf_ptr[position + planestride * comp_num] = 0;
3086
0
                }
3087
0
            } else if (a == 0xffff) {
3088
#if ARCH_IS_BIG_ENDIAN
3089
#else
3090
                /* Convert from native -> big endian */
3091
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3092
0
                    comp = buf_ptr[position + planestride * comp_num];
3093
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3094
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3095
0
                }
3096
0
#endif
3097
0
            } else {
3098
0
                a ^= 0xffff;
3099
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3100
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3101
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3102
0
                    comp = buf_ptr[position + planestride * comp_num];
3103
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3104
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3105
                    /* Store as big endian */
3106
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3107
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3108
0
                }
3109
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3110
0
                    comp = buf_ptr[position + planestride * comp_num];
3111
0
                    tmp = ((0 - comp) * a) + 0x4000;
3112
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3113
                    /* Store as big endian */
3114
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3115
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3116
0
                }
3117
0
            }
3118
0
            position += 1;
3119
0
        }
3120
0
    }
3121
0
}
3122
3123
static int
3124
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3125
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3126
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3127
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3128
    gs_separations* pseparations, bool deep)
3129
26.6k
{
3130
26.6k
    pdf14_device* pdev = (pdf14_device*)dev;
3131
26.6k
    int code = 0;
3132
26.6k
    int y;
3133
26.6k
    int num_rows_left;
3134
26.6k
    int i;
3135
26.6k
    gs_int_rect rect = rect_in;
3136
26.6k
    intptr_t planestride = planestride_in;
3137
26.6k
    intptr_t rowstride = rowstride_in;
3138
26.6k
    byte* buf_ptr = NULL;
3139
26.6k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3140
26.6k
    cmm_profile_t* des_profile = NULL;
3141
26.6k
    cmm_dev_profile_t* dev_target_profile;
3142
26.6k
    cmm_dev_profile_t* pdf14dev_profile;
3143
26.6k
    bool color_mismatch = false;
3144
26.6k
    bool supports_alpha = false;
3145
26.6k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3146
26.6k
    int alpha_offset = num_comp;
3147
26.6k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3148
26.6k
    gs_color_space *pcs;
3149
26.6k
    gs_image1_t image;
3150
26.6k
    gx_image_enum_common_t *info;
3151
26.6k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3152
26.6k
    pdf14_buf *cm_result = NULL;
3153
26.6k
    bool did_alloc;
3154
26.6k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3155
26.6k
    bool has_spots = pdev->ctx->num_spots > 0;
3156
26.6k
    bool blend_spots = !target_sep_device && has_spots;
3157
26.6k
    bool lose_channels = false;
3158
3159
    /* Check if group color space is CMYK based */
3160
26.6k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3161
26.6k
    if (code < 0)
3162
0
        return code;
3163
26.6k
    if (dev_target_profile == NULL)
3164
0
        return gs_throw_code(gs_error_Fatal);
3165
3166
26.6k
    if (src_profile == NULL) {
3167
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3168
0
        if (code < 0) {
3169
0
            return code;
3170
0
        }
3171
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3172
0
    }
3173
3174
    /* If the target device does not support spot colors and we have spot colors
3175
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3176
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3177
26.6k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3178
3179
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3180
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3181
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3182
0
        if (cm_result == NULL)
3183
0
            return_error(gs_error_VMerror);
3184
3185
        /* Update */
3186
0
        buf = cm_result;
3187
0
        src_profile = pgs->icc_manager->default_cmyk;
3188
0
        num_comp = buf->n_chan - 1;
3189
0
        additive = 0;
3190
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3191
0
        alpha_offset = num_comp;
3192
3193
#if RAW_DUMP
3194
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3195
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3196
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3197
        global_index++;
3198
#endif
3199
0
    }
3200
3201
    /* Fix order map if needed */
3202
124k
    for (i = 0; i < num_comp; i++) {
3203
98.3k
        pdev->devn_params.separation_order_map[i] = i;
3204
98.3k
    }
3205
3206
    /* Check if we have a color conversion issue */
3207
26.6k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3208
26.6k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3209
8.25k
        color_mismatch = true;
3210
26.6k
    if (des_profile->data_cs == gsNCHANNEL)
3211
0
        lose_channels = true;
3212
3213
    /* Check if target supports alpha */
3214
26.6k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3215
26.6k
    code = 0;
3216
3217
26.6k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3218
3219
    /* Note. The logic below will need a little rework if we ever
3220
       have a device that has tags and alpha support */
3221
26.6k
    if (supports_alpha) {
3222
3223
        /* If doing simulated overprint, Bring the spot color channels into
3224
           CMYK. Data is planar and 16 bit data in native format. */
3225
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3226
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3227
3228
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3229
0
            if (pdev->pclist_device != NULL) {
3230
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3231
3232
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3233
0
                if (code < 0)
3234
0
                    return code;
3235
0
            }
3236
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3237
3238
            /* Now we go to big endian */
3239
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3240
0
                planestride, num_comp, src_profile->num_comps,
3241
0
                tag_offset, cmyk_map, true, deep);
3242
3243
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3244
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3245
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3246
0
            buf->num_spots = 0;
3247
0
            num_comp = buf->n_chan - 1;
3248
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3249
0
        }
3250
3251
0
        if (!color_mismatch) {
3252
0
            for (i = 0; i < buf->n_planes; i++)
3253
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3254
0
            for (; i < target->color_info.num_components; i++)
3255
0
                buf_ptrs[i] = 0;
3256
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3257
0
                rect.p.x, rect.p.y, width, height,
3258
0
                rowstride, alpha_offset, tag_offset);
3259
            /* Right now code has number of rows written */
3260
0
        } else {
3261
            /* In this case, just color convert and maintain alpha.
3262
               This is a case where we either either blend in the
3263
               right color space and have no alpha for the output
3264
               device or hand back the wrong color space with
3265
               alpha data.  We choose the later. */
3266
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3267
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3268
0
                        rect.p.y, width, height, false);
3269
0
            if (code < 0)
3270
0
                return code;
3271
3272
            /* reset */
3273
0
            rowstride = buf->rowstride;
3274
0
            planestride = buf->planestride;
3275
0
            num_comp = buf->n_chan - 1;
3276
0
            alpha_offset = num_comp;
3277
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3278
3279
            /* And then out */
3280
0
            for (i = 0; i < buf->n_planes; i++)
3281
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3282
0
            for (; i < target->color_info.num_components; i++)
3283
0
                buf_ptrs[i] = 0;
3284
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3285
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3286
0
                tag_offset);
3287
            /* Right now code has number of rows written.  Writing continues below */
3288
0
        }
3289
26.6k
    } else {
3290
        /* Device could not handle the alpha data (we actually don't have
3291
           a device that does spot colorants and has an alpha channel so
3292
           the above code is untested.  Go ahead and preblend now and then
3293
           color convert if needed */
3294
#if RAW_DUMP
3295
           /* Dump before and after the blend to make sure we are doing that ok */
3296
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3297
            "pre_put_image_blend_image", buf_ptr, deep);
3298
        global_index++;
3299
#endif
3300
3301
26.6k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3302
8.25k
            if (deep) {
3303
            /* In this case, we are NOT going to bring the spots into the CMYK
3304
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3305
               16 bit data will be converted now from native endian to big endian during
3306
               the blending process */
3307
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3308
0
                    planestride, num_comp, src_profile->num_comps);
3309
8.25k
            } else {
3310
8.25k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3311
8.25k
                    planestride, num_comp, src_profile->num_comps);
3312
8.25k
            }
3313
18.3k
        } else {
3314
18.3k
            if (deep) {
3315
            /* In this case, if blend_spots == true, we will shortly be bringing
3316
               the spot colors to CMYK equivalent colors. It is at that time that
3317
               we will convert from native endian to big endian. In all other
3318
               cases this blending will due to conversion from native to BE */
3319
0
                bool keep_native = (blend_spots == true);
3320
3321
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3322
0
                    planestride, num_comp, additive, keep_native);
3323
18.3k
            } else {
3324
18.3k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3325
18.3k
                    planestride, num_comp, additive);
3326
18.3k
            }
3327
18.3k
        }
3328
3329
26.6k
        if (deep && has_tags)
3330
0
        {
3331
            /* We still need to convert the tags from Native to BE */
3332
#if ARCH_IS_BIG_ENDIAN
3333
#else
3334
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3335
0
            int i, j;
3336
0
            for (j = 0; j < height; j++)
3337
0
            {
3338
0
                for (i = 0; i < width; i++)
3339
0
                {
3340
0
                    uint16_t tag = *tags++;
3341
0
                    ((byte *)tags)[-2] = tag >> 8;
3342
0
                    ((byte *)tags)[-1] = tag;
3343
0
                }
3344
0
                tags += (buf->rowstride>>1) - width;
3345
0
            }
3346
0
#endif
3347
0
        }
3348
3349
#if RAW_DUMP
3350
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3351
            "post_put_image_blend_image", buf_ptr, deep);
3352
        global_index++;
3353
#endif
3354
3355
        /* If doing simulated overprint and we are not going to a sep device and
3356
           we have spot colors, then bring the spot color channels into CMYK
3357
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3358
           At this point, data is planar and 16 bit data is still in native format. It is
3359
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3360
           above during the alpha blend operation. */
3361
26.6k
        if (blend_spots) {
3362
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3363
3364
            /* In the clist case, we need to get equiv spots out of the
3365
               pseudo-band. */
3366
0
            if (pdev->pclist_device != NULL) {
3367
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3368
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3369
0
                if (code < 0)
3370
0
                    return code;
3371
0
            }
3372
3373
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3374
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3375
0
                planestride, num_comp, src_profile->num_comps,
3376
0
                tag_offset, cmyk_map, false, deep);
3377
3378
            /* Reset buffer information. We have CMYK and maybe tags */
3379
0
            num_comp = 4;
3380
0
            alpha_offset = 0;
3381
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3382
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3383
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3384
0
            buf->num_spots = 0;
3385
3386
#if RAW_DUMP
3387
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3388
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3389
            global_index++;
3390
#endif
3391
0
        }
3392
3393
        /* Map to the destination color space */
3394
26.6k
        if (color_mismatch) {
3395
            /* We started out with the original process colorants, and spots. If we have an
3396
             * nchannel output profile, this can mean that the first few spots might come from
3397
             * that and the rest from the document itself. e.g:
3398
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3399
             * Then we might have a blend space that changes the process colorants:
3400
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3401
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3402
             * If we're not careful, we'll end up with:
3403
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3404
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3405
             */
3406
8.25k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3407
8.25k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3408
8.25k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3409
8.25k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3410
8.25k
            if (code < 0)
3411
0
                return code;
3412
3413
            /* reset */
3414
8.25k
            rowstride = buf->rowstride;
3415
8.25k
            planestride = buf->planestride;
3416
8.25k
            num_comp = buf->n_chan;
3417
8.25k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3418
8.25k
        }
3419
3420
#if RAW_DUMP
3421
        /* Dump after the CS transform */
3422
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3423
            "post_put_image_color_convert", buf_ptr, deep);
3424
        global_index++;
3425
        /* clist_band_count++; */
3426
#endif
3427
3428
        /* Try put_image again. This can occur if the
3429
           target, like psdcmyk and tiffsep, support put_image */
3430
26.6k
        alpha_offset = 0;
3431
159k
        for (i = 0; i < buf->n_planes; i++)
3432
133k
            buf_ptrs[i] = buf_ptr + i * planestride;
3433
26.6k
        for (; i < target->color_info.num_components; i++)
3434
0
            buf_ptrs[i] = 0;
3435
26.6k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3436
26.6k
            rect.p.x, rect.p.y, width, height,
3437
26.6k
            rowstride, alpha_offset, tag_offset);
3438
26.6k
    }
3439
3440
    /* Put image was succesful.  We processed some or all of the rows.
3441
       Continue until we are done */
3442
26.6k
    if (code > 0) {
3443
55
        num_rows_left = height - code;
3444
55
        while (num_rows_left > 0) {
3445
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3446
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3447
0
                alpha_offset, tag_offset);
3448
0
            if (code < 0) {
3449
0
                return code;
3450
0
            }
3451
0
            num_rows_left = num_rows_left - code;
3452
0
        }
3453
55
        return 0;
3454
55
    }
3455
3456
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3457
       as well as those devices that support alpha (pngalpha,
3458
       png16malpha). If we are here, then we are doing an
3459
       overprint simulation on some other device. Image data
3460
       is aleady blended and in device color space. */
3461
26.5k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3462
26.5k
    if (code < 0)
3463
0
        return code;
3464
3465
    /* Already in destination CS */
3466
26.5k
    pcs->cmm_icc_profile_data = des_profile;
3467
3468
    /* pcs takes a reference to the profile data it just retrieved. */
3469
26.5k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3470
26.5k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
3471
0
        return_error(gs_error_rangecheck);
3472
26.5k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3473
3474
    /* If we have more components to write out than are in the des_profile,
3475
     * then just using a PCS based on des_profile, will result in us dropping
3476
     * the spot colors.
3477
     * So, if our target supports devn colors, we instead construct a
3478
     * DevN device space with colors names taken from the devn_params, and
3479
     * use that instead. */
3480
26.5k
    if (des_profile->num_comps != target->color_info.num_components &&
3481
195
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3482
195
    {
3483
195
        int num_std;
3484
195
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3485
195
        gs_color_space *pcs2 = pcs;
3486
195
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3487
195
                                     pcs2, pgs->memory->non_gc_memory);
3488
195
        if (code < 0)
3489
0
            return code;
3490
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3491
195
        pcs->params.device_n.use_alt_cspace = false;
3492
195
        num_std = devn_params->num_std_colorant_names;
3493
975
        for (i = 0; i < num_std; i++) {
3494
780
            const char *name = devn_params->std_colorant_names[i];
3495
780
            size_t len = strlen(name);
3496
780
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3497
780
            if (pcs->params.device_n.names[i] == NULL) {
3498
0
                int j = 0;
3499
0
                for (j = 0;j < i; j++) {
3500
0
                    if (pcs->params.device_n.names[j] != NULL)
3501
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3502
0
                    pcs->params.device_n.names[j] = NULL;
3503
0
                }
3504
0
                return_error(gs_error_VMerror);
3505
0
            }
3506
780
            strcpy(pcs->params.device_n.names[i], name);
3507
780
        }
3508
195
        for (; i < devn_params->separations.num_separations; i++) {
3509
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3510
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");
3511
0
            if (pcs->params.device_n.names[i] == NULL) {
3512
0
                int j = 0;
3513
0
                for (j = 0;j < i; j++) {
3514
0
                    if (pcs->params.device_n.names[j] != NULL)
3515
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3516
0
                    pcs->params.device_n.names[j] = NULL;
3517
0
                }
3518
0
                return_error(gs_error_VMerror);
3519
0
            }
3520
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3521
0
            pcs->params.device_n.names[i][name->size] = 0;
3522
0
        }
3523
195
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3524
0
            return code;
3525
0
        }
3526
        /* One last thing -- we need to fudge the pgs->color_component_map */
3527
1.17k
        for (i=0; i < dev->color_info.num_components; i++)
3528
975
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3529
195
    }
3530
3531
26.5k
    gs_image_t_init_adjust(&image, pcs, false);
3532
26.5k
    image.ImageMatrix.xx = (float)width;
3533
26.5k
    image.ImageMatrix.yy = (float)height;
3534
26.5k
    image.Width = width;
3535
26.5k
    image.Height = height;
3536
26.5k
    image.BitsPerComponent = deep ? 16 : 8;
3537
26.5k
    image.ColorSpace = pcs;
3538
26.5k
    image.format = gs_image_format_component_planar;
3539
3540
26.5k
    ctm_only_writable(pgs).xx = (float)width;
3541
26.5k
    ctm_only_writable(pgs).xy = 0;
3542
26.5k
    ctm_only_writable(pgs).yx = 0;
3543
26.5k
    ctm_only_writable(pgs).yy = (float)height;
3544
26.5k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3545
26.5k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3546
26.5k
    code = dev_proc(target, begin_typed_image) (target,
3547
26.5k
        pgs, NULL, (gs_image_common_t *)&image,
3548
26.5k
        NULL, NULL, NULL, pgs->memory, &info);
3549
26.5k
    if (code < 0) {
3550
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3551
0
        return code;
3552
0
    }
3553
#if RAW_DUMP
3554
    /* Dump the current buffer to see what we have. */
3555
    dump_raw_buffer(pdev->ctx->memory,
3556
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3557
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3558
        pdev->ctx->stack->n_planes,
3559
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3560
        "put_image_final_big", pdev->ctx->stack->data, deep);
3561
    dump_raw_buffer(pdev->ctx->memory,
3562
        height, width, buf->n_planes,
3563
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3564
        "put_image_final_small", buf_ptr, deep);
3565
    global_index++;
3566
    clist_band_count++;
3567
#endif
3568
3569
141k
    for (i = 0; i < num_comp; i++) {
3570
114k
        planes[i].data = buf_ptr + i * planestride;
3571
114k
        planes[i].data_x = 0;
3572
114k
        planes[i].raster = buf->rowstride;
3573
114k
    }
3574
3575
290k
    for (y = 0; y < height; y++) {
3576
264k
        int rows_used;
3577
3578
264k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3579
3580
1.40M
        for (i = 0; i < num_comp; i++) {
3581
1.13M
            planes[i].data += buf->rowstride;
3582
1.13M
        }
3583
264k
    }
3584
26.5k
    info->procs->end_image(info, true);
3585
3586
    /* This will also decrement the profile */
3587
26.5k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3588
26.5k
    return code;
3589
26.5k
}
3590
3591
/**
3592
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3593
 * @pdev: The PDF 1.4 rendering device.
3594
 * @pgs: State for image draw operation.
3595
 * @target: The target device.
3596
 *
3597
 * Puts the rendered image in @pdev's buffer to @target. This is called
3598
 * as part of the sequence of popping the PDF 1.4 device filter.
3599
 *
3600
 * Return code: negative on error.
3601
 **/
3602
static  int
3603
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3604
71.8k
{
3605
71.8k
    pdf14_device *pdev = (pdf14_device *)dev;
3606
71.8k
    pdf14_buf *buf = pdev->ctx->stack;
3607
71.8k
    gs_int_rect rect;
3608
71.8k
    int x1, y1, width, height;
3609
71.8k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3610
71.8k
    gs_separations *pseparations = &pdevn_params->separations;
3611
71.8k
    intptr_t planestride;
3612
71.8k
    intptr_t rowstride;
3613
71.8k
    bool deep = pdev->ctx->deep;
3614
71.8k
    int num_comp;
3615
3616
    /* Nothing was ever drawn. */
3617
71.8k
    if (buf == NULL)
3618
26.8k
        return 0;
3619
3620
44.9k
    num_comp = buf->n_chan - 1;
3621
44.9k
    rect = buf->rect;
3622
44.9k
    planestride = buf->planestride;
3623
44.9k
    rowstride = buf->rowstride;
3624
3625
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3626
       potential problem. Bug 694190 */
3627
44.9k
    if (buf->saved != NULL) {
3628
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3629
0
    }
3630
44.9k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3631
44.9k
    rect_intersect(rect, buf->dirty);
3632
44.9k
    x1 = min(pdev->width, rect.q.x);
3633
44.9k
    y1 = min(pdev->height, rect.q.y);
3634
44.9k
    width = x1 - rect.p.x;
3635
44.9k
    height = y1 - rect.p.y;
3636
44.9k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3637
18.3k
        return 0;
3638
3639
#if RAW_DUMP
3640
    /* Dump the current buffer to see what we have. */
3641
    dump_raw_buffer(pdev->ctx->memory,
3642
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3643
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3644
                    pdev->ctx->stack->n_planes,
3645
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3646
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3647
                    pdev->ctx->stack->deep);
3648
3649
    global_index++;
3650
    clist_band_count++;
3651
#endif
3652
3653
26.6k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3654
26.6k
                      buf, planestride, rowstride,
3655
26.6k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3656
26.6k
                      buf->has_tags, rect, pseparations, deep);
3657
44.9k
}
3658
3659
/**
3660
 * pdf14_custom_put_image: Put rendered image to target device.
3661
 * @pdev: The PDF 1.4 rendering device.
3662
 * @pgs: State for image draw operation.
3663
 * @target: The target device.
3664
 *
3665
 * Puts the rendered image in @pdev's buffer to @target. This is called
3666
 * as part of the sequence of popping the PDF 1.4 device filter.
3667
 *
3668
 * Return code: negative on error.
3669
 **/
3670
static  int
3671
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3672
0
{
3673
0
    pdf14_device * pdev = (pdf14_device *)dev;
3674
0
    pdf14_buf *buf = pdev->ctx->stack;
3675
0
    bool deep = pdev->ctx->deep;
3676
0
    gs_int_rect rect;
3677
0
    int x0, y0;
3678
0
    intptr_t planestride;
3679
0
    intptr_t rowstride;
3680
0
    int num_comp;
3681
0
    uint16_t bg;
3682
0
    int x1, y1, width, height;
3683
0
    byte *buf_ptr;
3684
3685
    /* Nothing was ever drawn. */
3686
0
    if (buf == NULL)
3687
0
        return 0;
3688
3689
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3690
0
    num_comp = buf->n_chan - 1;
3691
0
    rect = buf->rect;
3692
0
    x0 = rect.p.x;
3693
0
    y0 = rect.p.y;
3694
0
    planestride = buf->planestride;
3695
0
    rowstride = buf->rowstride;
3696
3697
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3698
       potential problem. Bug 694190 */
3699
0
    if (buf->saved != NULL) {
3700
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3701
0
    }
3702
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3703
0
    rect_intersect(rect, buf->dirty);
3704
0
    x1 = min(pdev->width, rect.q.x);
3705
0
    y1 = min(pdev->height, rect.q.y);
3706
0
    width = x1 - rect.p.x;
3707
0
    height = y1 - rect.p.y;
3708
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3709
0
        return 0;
3710
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3711
3712
0
    return gx_put_blended_image_custom(target, buf_ptr,
3713
0
                      planestride, rowstride,
3714
0
                      x0, y0, width, height, num_comp, bg, deep);
3715
0
}
3716
3717
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3718
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3719
 * putting everything back how it was, and cleaning up the reference counts.
3720
 */
3721
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3722
2.23M
{
3723
2.23M
    if (pdev->ctx && pdev->ctx->stack) {
3724
938k
        pdf14_buf *buf, *next;
3725
3726
938k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3727
18
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3728
18
            next = buf->saved;
3729
36
            while (group_color_info) {
3730
18
               if (group_color_info->icc_profile != NULL) {
3731
18
                   cmm_profile_t *group_profile;
3732
18
                   gsicc_rendering_param_t render_cond;
3733
18
                   cmm_dev_profile_t *dev_profile;
3734
18
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3735
3736
18
                   if (code >= 0) {
3737
18
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3738
18
                                             &render_cond);
3739
3740
18
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3741
18
                                               -1, "pdf14_end_transparency_group");
3742
18
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3743
18
                           group_color_info->icc_profile;
3744
18
                       group_color_info->icc_profile = NULL;
3745
18
                   }
3746
18
               }
3747
3748
18
               group_color_info = group_color_info->previous;
3749
18
            }
3750
18
        }
3751
938k
    }
3752
2.23M
}
3753
3754
static  int
3755
pdf14_close(gx_device *dev)
3756
1.11M
{
3757
1.11M
    pdf14_device *pdev = (pdf14_device *)dev;
3758
3759
1.11M
    pdf14_cleanup_group_color_profiles(pdev);
3760
3761
1.11M
    if (pdev->ctx) {
3762
1.10M
        pdf14_ctx_free(pdev->ctx);
3763
1.10M
        pdev->ctx = NULL;
3764
1.10M
    }
3765
1.11M
    return 0;
3766
1.11M
}
3767
3768
/* This is called when something has gone wrong and the interpreter received a
3769
   stop while in the middle of doing something with the PDF14 device.  We need
3770
   to clean up and end this in a graceful manner */
3771
static int
3772
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3773
0
{
3774
0
    pdf14_device *pdev = (pdf14_device *)dev;
3775
    /* The things that need to be cleaned up */
3776
0
    pdf14_ctx *ctx = pdev->ctx;
3777
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3778
3779
    /* Free up the smask color */
3780
0
    if (smaskcolor != NULL) {
3781
0
        smaskcolor->ref_count = 1;
3782
0
        pdf14_decrement_smask_color(pgs, dev);
3783
0
        pdev->smaskcolor = NULL;
3784
0
    }
3785
3786
    /* Free up the nested color procs and decrement the profiles */
3787
0
    while (pdev->color_model_stack)
3788
0
        pdf14_pop_group_color(dev, NULL);
3789
3790
    /* Start the context clean up */
3791
0
    if (ctx != NULL) {
3792
0
        pdf14_buf *buf, *next;
3793
0
        pdf14_group_color_t *procs, *prev_procs;
3794
3795
0
        if (ctx->mask_stack != NULL) {
3796
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3797
0
        }
3798
3799
        /* Now the stack of buffers */
3800
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3801
0
            next = buf->saved;
3802
3803
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3804
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3805
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3806
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3807
            /* During the soft mask push, the mask_stack was copied (not moved) from
3808
               the ctx to the tos mask_stack. We are done with this now so it is safe
3809
               to free this one object */
3810
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3811
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3812
0
                prev_procs = procs->previous;
3813
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3814
0
            }
3815
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3816
0
        }
3817
        /* Finally the context itself */
3818
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3819
0
        pdev->ctx = NULL;
3820
0
    }
3821
0
    return 0;
3822
0
}
3823
3824
static  int
3825
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3826
0
{
3827
0
    pdf14_device * pdev = (pdf14_device *)dev;
3828
3829
0
    if (pdev->target != NULL)
3830
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3831
0
    return 0;
3832
0
}
3833
3834
8.97M
#define COPY_PARAM(p) dev->p = target->p
3835
5.61M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3836
3837
static void
3838
copy_tag_setup(gx_device *dev, const gx_device *target)
3839
1.12M
{
3840
1.12M
    bool deep = device_is_deep(target);
3841
1.12M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3842
1.12M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3843
1.12M
    COPY_PARAM(graphics_type_tag);
3844
1.12M
    if (had_tags && !has_tags)
3845
0
    {
3846
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3847
0
        dev->color_info.num_components--;
3848
0
        dev->color_info.depth -= deep ? 16 : 8;
3849
0
    }
3850
1.12M
    else if (!had_tags && has_tags)
3851
0
    {
3852
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3853
0
        dev->color_info.num_components++;
3854
0
        dev->color_info.depth += deep ? 16 : 8;
3855
0
    }
3856
1.12M
}
3857
3858
/*
3859
 * Copy device parameters back from a target.  This copies all standard
3860
 * parameters related to page size and resolution, but not any of the
3861
 * color-related parameters, as the pdf14 device retains its own color
3862
 * handling. This routine is parallel to gx_device_copy_params().
3863
 * Note that it DOES copy the devn_params since these are required to
3864
 * keep agreement with colorant name->number mapping, and don't change
3865
 * with the pdf14 color handling.
3866
 */
3867
static  int
3868
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3869
1.12M
{
3870
1.12M
    cmm_dev_profile_t *profile_targ;
3871
1.12M
    cmm_dev_profile_t *profile_dev14;
3872
1.12M
    pdf14_device *pdev = (pdf14_device*) dev;
3873
1.12M
    cmm_profile_t *blend_profile = NULL;
3874
1.12M
    int k;
3875
3876
1.12M
    COPY_PARAM(width);
3877
1.12M
    COPY_PARAM(height);
3878
1.12M
    COPY_ARRAY_PARAM(MediaSize);
3879
1.12M
    COPY_ARRAY_PARAM(ImagingBBox);
3880
1.12M
    COPY_PARAM(ImagingBBox_set);
3881
1.12M
    COPY_ARRAY_PARAM(HWResolution);
3882
1.12M
    COPY_ARRAY_PARAM(Margins);
3883
1.12M
    COPY_ARRAY_PARAM(HWMargins);
3884
1.12M
    COPY_PARAM(PageCount);
3885
1.12M
    COPY_PARAM(MaxPatternBitmap);
3886
3887
3888
    /* Supposedly this function isn't supposed to change the color setup of dev.
3889
     * BUT... if we change the tags value, we have to change the color setup to
3890
     * keep it valid. This is because num_components and depth include tags. */
3891
1.12M
    copy_tag_setup(dev, target);
3892
1.12M
    COPY_PARAM(interpolate_control);
3893
1.12M
    COPY_PARAM(non_strict_bounds);
3894
1.12M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3895
3896
1.12M
    if (dev->icc_struct == NULL) {
3897
1.12M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3898
1.12M
        if (dev->icc_struct == NULL)
3899
0
            return_error(gs_error_VMerror);
3900
1.12M
        profile_dev14 = dev->icc_struct;
3901
1.12M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3902
1.12M
                                          &(profile_targ));
3903
3904
5.61M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3905
4.48M
            if (profile_targ->device_profile[k] != NULL) {
3906
1.12M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3907
1.12M
            }
3908
4.48M
            if (profile_dev14->device_profile[k] != NULL) {
3909
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3910
0
            }
3911
4.48M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3912
4.48M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3913
4.48M
        }
3914
3915
1.12M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3916
1.12M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3917
1.12M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3918
1.12M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3919
1.12M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3920
1.12M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3921
1.12M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3922
1.12M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3923
1.12M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3924
3925
1.12M
        switch (pdev->blend_cs_state) {
3926
1.12M
            case PDF14_BLEND_CS_UNSPECIFIED:
3927
1.12M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3928
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3929
                   during the device push, when we have
3930
                   access to the pgs */
3931
1.12M
                break;
3932
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3933
0
                blend_profile = profile_targ->oi_profile;
3934
0
                break;
3935
0
            case PDF14_BLEND_CS_SPECIFIED:
3936
0
                blend_profile = profile_targ->blend_profile;
3937
0
                break;
3938
0
            default:
3939
0
                break;
3940
1.12M
        }
3941
3942
1.12M
        if (blend_profile != NULL) {
3943
            /* Set the device profile to the blend profile. Note only default profile is set */
3944
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3945
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3946
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3947
0
        }
3948
3949
1.12M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3950
1.12M
    }
3951
1.12M
#undef COPY_ARRAY_PARAM
3952
1.12M
#undef COPY_PARAM
3953
1.12M
    return 0;
3954
1.12M
}
3955
3956
/*
3957
 * This is a forwarding version of the put_params device proc.  It is only
3958
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3959
 * check if the target device has closed and, if so, close itself.  The routine
3960
 * also sync the device parameters.
3961
 */
3962
static  int
3963
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3964
0
{
3965
0
    pdf14_device * pdev = (pdf14_device *)dev;
3966
0
    gx_device * tdev = pdev->target;
3967
0
    bool was_open = tdev->is_open;
3968
0
    int code = 0;
3969
3970
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3971
0
        gx_device_decache_colors(dev);
3972
0
        if (!tdev->is_open) {
3973
0
            code = gs_closedevice(dev);
3974
0
            if (code == 0)
3975
0
                code = was_open ? 1 : 0;   /* target device closed */
3976
0
        }
3977
0
        gx_device_copy_params(dev, tdev);
3978
0
    }
3979
0
    return code;
3980
0
}
3981
3982
/* Function prototypes */
3983
int put_param_pdf14_spot_names(gx_device * pdev,
3984
                gs_separations * pseparations, gs_param_list * plist);
3985
84.0k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3986
3987
/*
3988
 * The put_params method for the PDF 1.4 device will check if the
3989
 * target device has closed and, if so, close itself.  Note:  This routine is
3990
 * currently being used by both the pdf14_clist_device and the pdf_device.
3991
 * Please make sure that any changes are either applicable to both devices
3992
 * or clone the routine for each device.
3993
 */
3994
static  int
3995
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3996
0
{
3997
0
    pdf14_device * pdev = (pdf14_device *)dev;
3998
0
    gx_device * tdev = pdev->target;
3999
0
    bool was_open = tdev->is_open;
4000
0
    int code = 0, code2 = 0;
4001
4002
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4003
0
        gx_device_decache_colors(dev);
4004
0
        if (!tdev->is_open) {
4005
0
            code = gs_closedevice(dev);
4006
0
            if (code == 0)
4007
0
                code = was_open ? 1 : 0;   /* target device closed */
4008
0
        }
4009
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4010
0
        if (code2 < 0)
4011
0
            code = code2;
4012
0
    }
4013
0
    return code;
4014
0
}
4015
4016
/*
4017
 * Copy marking related parameters into the PDF 1.4 device structure for use
4018
 * by pdf14_fill_rectangle.
4019
 */
4020
static  void
4021
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4022
32.4M
{
4023
32.4M
    pdf14_device * pdev = (pdf14_device *)dev;
4024
4025
32.4M
    if (pgs->alphaisshape) {
4026
415k
        pdev->opacity = 1.0;
4027
415k
        if (pgs->is_fill_color) {
4028
403k
            pdev->shape = pgs->fillconstantalpha;
4029
403k
        } else {
4030
12.1k
            pdev->shape = pgs->strokeconstantalpha;
4031
12.1k
        }
4032
32.0M
    } else {
4033
32.0M
        pdev->shape = 1.0;
4034
32.0M
        if (pgs->is_fill_color) {
4035
11.8M
            pdev->opacity = pgs->fillconstantalpha;
4036
20.1M
        } else {
4037
20.1M
            pdev->opacity = pgs->strokeconstantalpha;
4038
20.1M
        }
4039
32.0M
    }
4040
32.4M
    pdev->alpha = pdev->opacity * pdev->shape;
4041
32.4M
    pdev->blend_mode = pgs->blend_mode;
4042
32.4M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4043
32.4M
        pdev->overprint = pgs->overprint;
4044
32.4M
        pdev->stroke_overprint = pgs->stroke_overprint;
4045
32.4M
    } else {
4046
0
        pdev->overprint = false;
4047
0
        pdev->stroke_overprint = false;
4048
0
    }
4049
4050
32.4M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4051
32.4M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4052
4053
32.4M
    if (pgs->is_fill_color)
4054
12.2M
        pdev->op_state = GS_OP_STATE_FILL;
4055
20.2M
    else
4056
20.2M
        pdev->op_state = GS_OP_STATE_STROKE;
4057
4058
32.4M
    if_debug6m('v', dev->memory,
4059
32.4M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4060
32.4M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4061
32.4M
               pdev->stroke_effective_op_mode);
4062
32.4M
}
4063
4064
static  void
4065
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4066
23.3M
{
4067
23.3M
    bool hastrans = false;
4068
4069
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4070
     * makes other operations much slower. We have no option however, if the
4071
     * current colour involves transparency, or if it's anything other than
4072
     * a completely solid (or transparent) operation in the normal blend mode.
4073
     */
4074
23.3M
    if (pdcolor != NULL)
4075
23.3M
    {
4076
23.3M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4077
471k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4078
4.83k
            hastrans = true;
4079
23.3M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4080
            /* FIXME: Here we assume that ALL type 2 patterns are
4081
             * transparent - this test could be better. */
4082
10.4k
            hastrans = true;
4083
10.4k
        }
4084
23.3M
    }
4085
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4086
       This appears to be the only place where this test is done so
4087
       not adding a is_idempotent method */
4088
23.3M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4089
132k
        pgs->blend_mode != BLEND_MODE_Darken &&
4090
126k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4091
23.2M
        (pgs->fillconstantalpha != 1.0) ||
4092
23.0M
        (pgs->strokeconstantalpha != 1.0) ||
4093
23.0M
        (hastrans))
4094
388k
    {
4095
        /*
4096
         * The blend operations are not idempotent.  Force non-idempotent
4097
         * filling and stroking operations.
4098
         */
4099
388k
        pgs->log_op |= lop_pdf14;
4100
388k
    }
4101
23.3M
}
4102
4103
static int
4104
push_shfill_group(pdf14_clist_device *pdev,
4105
                  gs_gstate *pgs,
4106
                  gs_fixed_rect *box)
4107
335
{
4108
335
    gs_transparency_group_params_t params = { 0 };
4109
335
    int code;
4110
335
    gs_rect cb;
4111
335
    gs_gstate fudged_pgs = *pgs;
4112
4113
335
    params.shade_group = true;
4114
4115
    /* gs_begin_transparency_group takes a bbox that it then
4116
     * transforms by ctm. Our bbox has already been transformed,
4117
     * so clear out the ctm. */
4118
335
    fudged_pgs.ctm.xx = 1.0;
4119
335
    fudged_pgs.ctm.xy = 0;
4120
335
    fudged_pgs.ctm.yx = 0;
4121
335
    fudged_pgs.ctm.yy = 1.0;
4122
335
    fudged_pgs.ctm.tx = 0;
4123
335
    fudged_pgs.ctm.ty = 0;
4124
335
    cb.p.x = fixed2int_pixround(box->p.x);
4125
335
    cb.p.y = fixed2int_pixround(box->p.y);
4126
335
    cb.q.x = fixed2int_pixround(box->q.x);
4127
335
    cb.q.y = fixed2int_pixround(box->q.y);
4128
4129
335
    params.Isolated = false;
4130
335
    params.Knockout = true;
4131
335
    params.page_group = false;
4132
335
    params.group_opacity = fudged_pgs.fillconstantalpha;
4133
335
    params.group_shape = 1.0;
4134
335
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4135
4136
    /* We have the group handle the blendmode and the opacity,
4137
     * and continue with the existing graphics state reset
4138
     * to normal, opaque operation. We could do it the other
4139
     * way around, but this way means that if we push a knockout
4140
     * group for a stroke, and then the code calls back into
4141
     * the fill operation as part of doing the stroking, we don't
4142
     * push another one. */
4143
335
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4144
335
    gs_setfillconstantalpha(pgs, 1.0);
4145
335
    gs_setstrokeconstantalpha(pgs, 1.0);
4146
335
    if (pdev) {
4147
335
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4148
335
        if (code < 0)
4149
0
            return code;
4150
335
    }
4151
4152
335
    return code;
4153
335
}
4154
4155
static int
4156
pop_shfill_group(gs_gstate *pgs)
4157
332
{
4158
332
     return gs_end_transparency_group(pgs);
4159
332
}
4160
4161
static int
4162
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4163
                           gx_path *ppath, const gx_fill_params *params,
4164
                           const gx_drawing_color *pdcolor,
4165
                           const gx_clip_path *pcpath)
4166
17.7M
{
4167
17.7M
    gs_gstate new_pgs = *pgs;
4168
17.7M
    int code = 0;
4169
17.7M
    gs_pattern2_instance_t *pinst = NULL;
4170
17.7M
    int push_group = 0;
4171
4172
17.7M
    code = pdf14_initialize_ctx(dev, pgs);
4173
17.7M
    if (code < 0)
4174
0
        return code;
4175
4176
17.7M
    if (pdcolor == NULL)
4177
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4178
17.7M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_STROKE;
4179
17.7M
    if (gx_dc_is_pattern1_color(pdcolor)){
4180
521k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4181
502k
            gx_pattern1_clist_has_trans(pdcolor) ){
4182
            /* In this case, we need to push a transparency group
4183
               and tile the pattern color, which is stored in
4184
               a pdf14 device buffer in the ctile object memember
4185
               variable ttrans */
4186
#if RAW_DUMP
4187
            /* Since we do not get a put_image to view what
4188
               we have do it now */
4189
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4190
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4191
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4192
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4193
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4194
                        ppatdev14->ctx->stack->rect.p.y *
4195
                        ppatdev14->ctx->stack->rowstride +
4196
                        ppatdev14->ctx->stack->rect.p.x;
4197
                    dump_raw_buffer(ppatdev14->ctx->memory,
4198
                                    (ppatdev14->ctx->stack->rect.q.y -
4199
                                     ppatdev14->ctx->stack->rect.p.y),
4200
                                    (ppatdev14->ctx->stack->rect.q.x -
4201
                                     ppatdev14->ctx->stack->rect.p.x),
4202
                                    ppatdev14->ctx->stack->n_planes,
4203
                                    ppatdev14->ctx->stack->planestride,
4204
                                    ppatdev14->ctx->stack->rowstride,
4205
                                    "Pattern_Fill", buf_ptr,
4206
                                    ppatdev14->ctx->stack->deep);
4207
                    global_index++;
4208
                } else {
4209
                     gx_pattern_trans_t *patt_trans =
4210
                                        pdcolor->colors.pattern.p_tile->ttrans;
4211
                     dump_raw_buffer(patt_trans->mem,
4212
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4213
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4214
                                     patt_trans->n_chan,
4215
                                     patt_trans->planestride, patt_trans->rowstride,
4216
                                     "Pattern_Fill_clist",
4217
                                     patt_trans->transbytes +
4218
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4219
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4220
                                     patt_trans->deep);
4221
                    global_index++;
4222
                }
4223
            }
4224
#endif
4225
57.8k
            pdf14_set_marking_params(dev, &new_pgs);
4226
57.8k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4227
57.8k
                params, pdcolor, pcpath);
4228
57.8k
            new_pgs.trans_device = NULL;
4229
57.8k
            new_pgs.has_transparency = false;
4230
57.8k
            return code;
4231
57.8k
        }
4232
521k
    }
4233
17.6M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4234
17.6M
        pdcolor->type == &gx_dc_devn_masked) {
4235
        /* Non-idempotent blends require a transparency
4236
         * group to be pushed because shadings might
4237
         * paint several pixels twice. */
4238
19
        push_group = pgs->fillconstantalpha != 1.0 ||
4239
19
               !blend_is_idempotent(gs_currentblendmode(pgs));
4240
19
        pinst =
4241
19
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4242
19
        pinst->saved->has_transparency = true;
4243
        /* The transparency color space operations are driven
4244
           by the pdf14 clist writer device.  */
4245
19
        pinst->saved->trans_device = dev;
4246
19
    }
4247
17.6M
    if (push_group) {
4248
0
        gs_fixed_rect box;
4249
0
        if (pcpath)
4250
0
            gx_cpath_outer_box(pcpath, &box);
4251
0
        else
4252
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4253
0
        if (ppath) {
4254
0
            gs_fixed_rect path_box;
4255
4256
0
            gx_path_bbox(ppath, &path_box);
4257
0
            if (box.p.x < path_box.p.x)
4258
0
                box.p.x = path_box.p.x;
4259
0
            if (box.p.y < path_box.p.y)
4260
0
                box.p.y = path_box.p.y;
4261
0
            if (box.q.x > path_box.q.x)
4262
0
                box.q.x = path_box.q.x;
4263
0
            if (box.q.y > path_box.q.y)
4264
0
                box.q.y = path_box.q.y;
4265
0
        }
4266
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4267
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4268
0
    } else
4269
17.6M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4270
17.6M
    pdf14_set_marking_params(dev, &new_pgs);
4271
17.6M
    if (code >= 0) {
4272
17.6M
        new_pgs.trans_device = dev;
4273
17.6M
        new_pgs.has_transparency = true;
4274
        /* ppath can permissibly be NULL here, if we want to have a
4275
         * shading or a pattern fill the clipping path. This upsets
4276
         * coverity, which is not smart enough to realise that the
4277
         * validity of a NULL ppath depends on the type of pdcolor.
4278
         * We'll mark it as a false positive. */
4279
17.6M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4280
17.6M
        new_pgs.trans_device = NULL;
4281
17.6M
        new_pgs.has_transparency = false;
4282
17.6M
    }
4283
17.6M
    if (code >= 0 && push_group) {
4284
0
        code = pop_shfill_group(&new_pgs);
4285
0
        pdf14_set_marking_params(dev, pgs);
4286
0
    }
4287
17.6M
    if (pinst != NULL){
4288
19
        pinst->saved->trans_device = NULL;
4289
19
    }
4290
17.6M
    return code;
4291
17.7M
}
4292
4293
static  int
4294
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4295
                             gx_path *ppath, const gx_stroke_params *params,
4296
                             const gx_drawing_color *pdcolor,
4297
                             const gx_clip_path *pcpath)
4298
4.44M
{
4299
4.44M
    gs_gstate new_pgs = *pgs;
4300
4.44M
    int push_group = 0;
4301
4.44M
    int code = 0;
4302
4303
4.44M
    if (pdcolor == NULL)
4304
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4305
4306
4.44M
    code = pdf14_initialize_ctx(dev, pgs);
4307
4.44M
    if (code < 0)
4308
0
        return code;
4309
4310
4.44M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4311
        /* Non-idempotent blends require a transparency
4312
         * group to be pushed because shadings might
4313
         * paint several pixels twice. */
4314
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4315
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4316
0
    }
4317
4.44M
    if (push_group) {
4318
0
        gs_fixed_rect box;
4319
0
        if (pcpath)
4320
0
            gx_cpath_outer_box(pcpath, &box);
4321
0
        else
4322
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4323
4324
        /* For fill_path, we accept ppath == NULL to mean
4325
         * fill the entire clipping region. That makes no
4326
         * sense for stroke_path, hence ppath is always non
4327
         * NULL here. */
4328
0
        {
4329
0
            gs_fixed_rect path_box;
4330
0
            gs_fixed_point expansion;
4331
4332
0
            gx_path_bbox(ppath, &path_box);
4333
            /* Expand the path bounding box by the scaled line width. */
4334
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4335
                /* The expansion is so large it caused a limitcheck. */
4336
0
                path_box.p.x = path_box.p.y = min_fixed;
4337
0
                path_box.q.x = path_box.q.y = max_fixed;
4338
0
            } else {
4339
0
                expansion.x += pgs->fill_adjust.x;
4340
0
                expansion.y += pgs->fill_adjust.y;
4341
                /*
4342
                 * It's theoretically possible for the following computations to
4343
                 * overflow, so we need to check for this.
4344
                 */
4345
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4346
0
                                path_box.p.x - expansion.x);
4347
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4348
0
                                path_box.p.y - expansion.y);
4349
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4350
0
                                path_box.q.x + expansion.x);
4351
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4352
0
                                path_box.q.y + expansion.y);
4353
0
            }
4354
0
            if (box.p.x < path_box.p.x)
4355
0
                box.p.x = path_box.p.x;
4356
0
            if (box.p.y < path_box.p.y)
4357
0
                box.p.y = path_box.p.y;
4358
0
            if (box.q.x > path_box.q.x)
4359
0
                box.q.x = path_box.q.x;
4360
0
            if (box.q.y > path_box.q.y)
4361
0
                box.q.y = path_box.q.y;
4362
0
        }
4363
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4364
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4365
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4366
0
    } else
4367
4.44M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4368
4.44M
    pdf14_set_marking_params(dev, &new_pgs);
4369
4.44M
    if (code >= 0) {
4370
4.44M
        GS_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4371
4372
4.44M
        ((pdf14_device*)dev)->op_state = GS_OP_STATE_STROKE;
4373
4.44M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4374
4.44M
        ((pdf14_device*)dev)->op_state = save_op_state;
4375
4.44M
    }
4376
4.44M
    if (code >= 0 && push_group) {
4377
0
        code = pop_shfill_group(&new_pgs);
4378
0
        pdf14_set_marking_params(dev, pgs);
4379
0
    }
4380
4381
4.44M
    return code;
4382
4.44M
}
4383
4384
/* Pull out steps of transparency updates for fill/stroke
4385
   so that they can be invoked elsewhere (e.g.
4386
   when the abuf device is handling the stroke/fill */
4387
4388
/* Set-up prior to fill operation in fill-stroke */
4389
static int
4390
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4391
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4392
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4393
27.6k
{
4394
27.6k
    int code = 0;
4395
27.6k
    gs_transparency_group_params_t params = { 0 };
4396
27.6k
    gs_fixed_rect clip_bbox;
4397
27.6k
    gs_rect bbox, group_stroke_box;
4398
27.6k
    gs_fixed_rect path_bbox;
4399
27.6k
    int expansion_code;
4400
27.6k
    gs_fixed_point expansion;
4401
27.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4402
4403
27.6k
    *path_empty = false;
4404
4405
27.6k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4406
27.5k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4407
54
    {
4408
54
        *op_ca_eq_CA = true;
4409
54
        *path_empty = true;
4410
54
        return 0;
4411
54
    }
4412
4413
    /* The clip box returned here is scaled up by path_log2scale, so we need
4414
     * to scale down by this later. */
4415
27.5k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4416
27.5k
    if (code < 0 && code != gs_error_unknownerror)
4417
0
        return code;
4418
4419
27.5k
    if (code == gs_error_unknownerror) {
4420
        /* didn't get clip box from gx_curr_fixed_bbox */
4421
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4422
         * scaling down by this in a moment. */
4423
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4424
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4425
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4426
0
    }
4427
    /* pcpath->outer_box is scaled by path_log2scale too. */
4428
27.5k
    if (pcpath)
4429
27.5k
        rect_intersect(clip_bbox, pcpath->outer_box);
4430
4431
    /* expand the ppath using stroke expansion rule, then intersect it */
4432
27.5k
    code = gx_path_bbox(ppath, &path_bbox);
4433
4434
    /* If we are coming from the abuf device, the path has been scaled
4435
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4436
       on the path_bbox so that we get the proper bounding box for our group. */
4437
27.5k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4438
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4439
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4440
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4441
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4442
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4443
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4444
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4445
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4446
0
    }
4447
4448
27.5k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4449
1.92k
        *path_empty = true;
4450
1.92k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4451
                     there are simply too many return cases that I can't account for. */
4452
1.92k
    }
4453
25.6k
    if (code < 0)
4454
0
        return code;
4455
4456
25.6k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4457
25.6k
    if (expansion_code >= 0) {
4458
25.5k
        path_bbox.p.x -= expansion.x;
4459
25.5k
        path_bbox.p.y -= expansion.y;
4460
25.5k
        path_bbox.q.x += expansion.x;
4461
25.5k
        path_bbox.q.y += expansion.y;
4462
25.5k
    }
4463
25.6k
    rect_intersect(path_bbox, clip_bbox);
4464
25.6k
    bbox.p.x = fixed2float(path_bbox.p.x);
4465
25.6k
    bbox.p.y = fixed2float(path_bbox.p.y);
4466
25.6k
    bbox.q.x = fixed2float(path_bbox.q.x);
4467
25.6k
    bbox.q.y = fixed2float(path_bbox.q.y);
4468
4469
25.6k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4470
25.6k
    if (code < 0)
4471
2
        return code;
4472
4473
25.6k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4474
0
        p14dev->overprint = pgs->overprint;
4475
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4476
0
    }
4477
4478
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4479
25.6k
    if (fill_alpha == stroke_alpha &&
4480
4.77k
        p14dev->overprint && p14dev->stroke_overprint &&
4481
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4482
4483
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4484
           compatible overprint mode.  Group will be composited with
4485
           original alpha and blend mode */
4486
0
        *op_ca_eq_CA = true;
4487
0
        params.Isolated = false;
4488
0
        params.group_color_type = UNKNOWN;
4489
0
        params.Knockout = false;
4490
0
        params.page_group = false;
4491
0
        params.group_opacity = 1.0;
4492
0
        params.group_shape = fill_alpha;
4493
4494
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4495
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4496
0
        if (code < 0)
4497
0
            return code;
4498
4499
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4500
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4501
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4502
4503
25.6k
    } else {
4504
        /* Push a non-isolated knockout group. Do not change the alpha or
4505
            blend modes. Note: we need to draw those that have alpha = 0 */
4506
25.6k
        *op_ca_eq_CA = false;
4507
25.6k
        params.Isolated = false;
4508
25.6k
        params.group_color_type = UNKNOWN;
4509
25.6k
        params.Knockout = true;
4510
25.6k
        params.page_group = false;
4511
25.6k
        params.group_shape = 1.0;
4512
25.6k
        params.group_opacity = 1.0;
4513
4514
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4515
25.6k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4516
25.6k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4517
25.6k
        if (code < 0)
4518
0
            return code;
4519
4520
        /* restore blend mode for actual drawing in the group */
4521
25.6k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4522
4523
        /* If we are in an overprint situation, set the blend mode to compatible
4524
            overprint */
4525
25.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4526
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4527
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4528
25.6k
    }
4529
25.6k
    p14dev->op_state = GS_OP_STATE_FILL;
4530
25.6k
    return code;
4531
25.6k
}
4532
4533
/* Set-up prior to stroke operation in fill-stroke */
4534
static void
4535
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4536
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4537
25.6k
{
4538
25.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4539
4540
25.6k
    if (op_ca_eq_CA) {
4541
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4542
25.6k
    } else {
4543
25.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4544
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4545
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4546
4547
        /* Note that the stroke can end up doing fill methods */
4548
25.6k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4549
4550
25.6k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4551
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4552
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4553
25.6k
    }
4554
25.6k
    p14dev->op_state = GS_OP_STATE_STROKE;
4555
25.6k
}
4556
4557
/* Cleanup after the stroke in fill-stroke  */
4558
static int
4559
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4560
25.6k
{
4561
25.6k
    int code;
4562
4563
25.6k
    if (!op_ca_eq_CA) {
4564
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4565
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4566
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4567
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4568
          * We therefore need to make sure it is set according to the current fill state.
4569
          */
4570
25.6k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4571
25.6k
        code = gs_update_trans_marking_params(pgs);
4572
25.6k
        if (code < 0)
4573
0
            return code;
4574
25.6k
        pdf14_set_marking_params(dev, pgs);
4575
25.6k
    }
4576
4577
25.6k
    return 0;
4578
25.6k
}
4579
4580
/* cleanup in fill-stroke  */
4581
static int
4582
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4583
    gs_blend_mode_t blend_mode, GS_OP_FS_STATE save_op_state)
4584
25.6k
{
4585
25.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4586
25.6k
    int code2;
4587
25.6k
    int code = 0;
4588
4589
    /* Restore the state */
4590
25.6k
    p14dev->op_state = save_op_state;
4591
25.6k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4592
25.6k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4593
25.6k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4594
4595
25.6k
    code2 = gs_end_transparency_group(pgs);
4596
25.6k
    if (code2 < 0) {
4597
        /* At this point things have gone very wrong. We should just shut down */
4598
0
        code = gs_abort_pdf14trans_device(pgs);
4599
0
        return code2;
4600
0
    }
4601
25.6k
    return code;
4602
25.6k
}
4603
4604
static int
4605
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4606
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4607
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4608
    const gx_clip_path *pcpath)
4609
97.3k
{
4610
97.3k
    bool op_ca_eq_CA;
4611
97.3k
    bool path_empty;
4612
97.3k
    int code;
4613
97.3k
    float stroke_alpha = cpgs->strokeconstantalpha;
4614
97.3k
    float fill_alpha = cpgs->fillconstantalpha;
4615
97.3k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4616
97.3k
    pdf14_device* p14dev = (pdf14_device*)dev;
4617
97.3k
    GS_OP_FS_STATE save_op_state = p14dev->op_state;
4618
97.3k
    gs_log2_scale_point path_log2scale;
4619
97.3k
    bool group_needed = true;
4620
97.3k
    gx_device* curr_pgs_dev = cpgs->device;
4621
4622
97.3k
    union {
4623
97.3k
        const gs_gstate* cpgs;
4624
97.3k
        gs_gstate* pgs;
4625
97.3k
    } const_breaker;
4626
97.3k
    gs_gstate* pgs;
4627
4628
    /* Break const just once, neatly */
4629
97.3k
    const_breaker.cpgs = cpgs;
4630
97.3k
    pgs = const_breaker.pgs;
4631
97.3k
    path_log2scale.x = 0;
4632
97.3k
    path_log2scale.y = 0;
4633
4634
97.3k
    code = pdf14_initialize_ctx(dev, pgs);
4635
97.3k
    if (code < 0)
4636
0
        return code;
4637
4638
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4639
     * blend is normal we don't do a group push. Just do the stroke
4640
     * and the fill, even with overprint */
4641
97.3k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4642
69.7k
        group_needed = false;
4643
4644
97.3k
    if (group_needed) {
4645
27.6k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4646
                              can be called on the clist writer side when dealing
4647
                              with the abuf/pdf14 interaction. Those calls have to
4648
                              go through the gs_trans API not the gx_trans or pdf14
4649
                              methods.  Perhaps these methods should have a different
4650
                              suffix, but they are static methods here in the pdf14
4651
                              file. */
4652
27.6k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4653
27.6k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4654
27.6k
        pgs->device = curr_pgs_dev;
4655
27.6k
        if (code < 0)
4656
2
            goto cleanup;
4657
27.6k
        if (path_empty)
4658
1.97k
            return 0;
4659
27.6k
    }
4660
4661
95.3k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4662
95.3k
    if (code < 0)
4663
0
        goto cleanup;
4664
4665
95.3k
    if (group_needed)
4666
25.6k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4667
95.3k
    gs_swapcolors_quick(pgs);
4668
4669
4670
#if RAW_DUMP
4671
    /* Dump the current buffer to see what we have. */
4672
    dump_raw_buffer(p14dev->ctx->memory,
4673
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4674
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4675
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4676
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4677
    global_index++;
4678
#endif
4679
4680
95.3k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4681
95.3k
    gs_swapcolors_quick(pgs);
4682
95.3k
    if (code < 0) {
4683
0
        goto cleanup;
4684
0
    }
4685
4686
#if RAW_DUMP
4687
    /* Dump the current buffer to see what we have. */
4688
    dump_raw_buffer(p14dev->ctx->memory,
4689
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4690
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4691
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4692
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4693
    global_index++;
4694
#endif
4695
95.3k
    if (group_needed)
4696
25.6k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4697
4698
95.3k
cleanup:
4699
95.3k
    if (group_needed) {
4700
25.6k
        int code1;
4701
25.6k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4702
25.6k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4703
25.6k
            save_op_state);
4704
25.6k
        if (code1 < 0)
4705
0
            code = code1;
4706
25.6k
        pgs->device = curr_pgs_dev;
4707
25.6k
    }
4708
95.3k
    return code;
4709
95.3k
}
4710
4711
static int
4712
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4713
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4714
                      gx_color_index color, int depth)
4715
0
{
4716
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4717
0
                                  color, NULL, depth, false);
4718
0
}
4719
4720
static int
4721
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4722
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4723
                      const gx_drawing_color *pdcolor, int depth)
4724
0
{
4725
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4726
0
                                  0, pdcolor, depth, true);
4727
0
}
4728
4729
static int
4730
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4731
                          int aa_raster, gx_bitmap_id id, int x, int y,
4732
                          int w, int h, gx_color_index color,
4733
                          const gx_device_color *pdc, int depth, bool devn)
4734
0
{
4735
0
    const byte *aa_row;
4736
0
    pdf14_device *pdev = (pdf14_device *)dev;
4737
0
    pdf14_buf *buf = pdev->ctx->stack;
4738
0
    int i, j, k;
4739
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4740
0
    byte src[PDF14_MAX_PLANES];
4741
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4742
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4743
0
    bool additive = pdev->ctx->additive;
4744
0
    intptr_t rowstride = buf->rowstride;
4745
0
    intptr_t planestride = buf->planestride;
4746
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4747
0
    bool has_alpha_g = buf->has_alpha_g;
4748
0
    bool has_shape = buf->has_shape;
4749
0
    bool has_tags = buf->has_tags;
4750
0
    bool knockout = buf->knockout;
4751
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4752
0
        blend_mode == BLEND_MODE_Compatible ||
4753
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4754
0
    int num_chan = buf->n_chan;
4755
0
    int num_comp = num_chan - 1;
4756
0
    intptr_t shape_off = num_chan * planestride;
4757
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4758
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4759
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4760
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4761
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4762
0
    gx_color_index comps;
4763
0
    byte shape = 0; /* Quiet compiler. */
4764
0
    byte src_alpha;
4765
0
    int alpha2_aa, alpha_aa, sx;
4766
0
    int alpha_aa_act;
4767
0
    int xoff;
4768
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4769
0
    int shift = 8;
4770
0
    bool has_backdrop = buf->backdrop != NULL;
4771
4772
0
    if (buf->data == NULL)
4773
0
        return 0;
4774
0
    aa_row = data;
4775
0
    if (has_tags) {
4776
0
        if (devn)
4777
0
            curr_tag = pdc->tag;
4778
0
        else
4779
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4780
0
    }
4781
4782
0
    if (devn) {
4783
0
        if (additive) {
4784
0
            for (j = 0; j < num_comp; j++) {
4785
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4786
0
            }
4787
0
        } else {
4788
0
            for (j = 0; j < num_comp; j++) {
4789
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4790
0
            }
4791
0
        }
4792
0
    } else
4793
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4794
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4795
0
    if (has_shape)
4796
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4797
    /* Limit the area we write to the bounding rectangle for this buffer */
4798
0
    if (x < buf->rect.p.x) {
4799
0
        xoff = data_x + buf->rect.p.x - x;
4800
0
        w += x - buf->rect.p.x;
4801
0
        x = buf->rect.p.x;
4802
0
    } else {
4803
0
        xoff = data_x;
4804
0
    }
4805
0
    if (y < buf->rect.p.y) {
4806
0
      h += y - buf->rect.p.y;
4807
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4808
0
      y = buf->rect.p.y;
4809
0
    }
4810
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4811
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4812
    /* Update the dirty rectangle. */
4813
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4814
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4815
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4816
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4817
4818
    /* composite with backdrop only. */
4819
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4820
0
    if (knockout && has_backdrop)
4821
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4822
0
    else
4823
0
        bline = line;
4824
4825
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4826
0
        back_ptr = bline;
4827
0
        dst_ptr = line;
4828
0
        sx = xoff;
4829
0
        for (i = 0; i < w; ++i, ++sx) {
4830
            /* Complement the components for subtractive color spaces */
4831
0
            if (additive) {
4832
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4833
0
                    dst[k] = back_ptr[k * planestride];
4834
0
            } else { /* Complement the components for subtractive color spaces */
4835
0
                for (k = 0; k < num_comp; ++k)
4836
0
                    dst[k] = 255 - back_ptr[k * planestride];
4837
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4838
0
            }
4839
            /* Get the aa alpha from the buffer */
4840
0
            switch(depth)
4841
0
            {
4842
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4843
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4844
0
                break;
4845
0
            case 4:
4846
0
                alpha2_aa = aa_row[sx >> 1];
4847
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4848
0
                break;
4849
0
            case 8:
4850
0
                alpha_aa = aa_row[sx];
4851
0
                break;
4852
0
            default:
4853
0
                return_error(gs_error_rangecheck);
4854
0
            }
4855
0
            if (alpha_aa != 0) {  /* This does happen */
4856
0
                if (alpha_aa != 255) {
4857
                    /* We have an alpha value from aa */
4858
0
                    alpha_aa_act = alpha_aa;
4859
0
                    if (src_alpha != 255) {
4860
                        /* Need to combine it with the existing alpha */
4861
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4862
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4863
0
                    }
4864
                    /* Set our source alpha value appropriately */
4865
0
                    src[num_comp] = alpha_aa_act;
4866
0
                } else {
4867
                    /* We may have to reset this is it was changed as we
4868
                       moved across the row */
4869
0
                    src[num_comp] = src_alpha;
4870
0
                }
4871
0
                if (knockout) {
4872
0
                    if (buf->isolated) {
4873
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4874
0
                    } else {
4875
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4876
0
                            blend_mode, pdev->blend_procs, pdev);
4877
0
                    }
4878
0
                } else {
4879
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4880
0
                                                    pdev->blend_procs, pdev);
4881
0
                }
4882
                /* Complement the results for subtractive color spaces */
4883
0
                if (additive) {
4884
0
                    for (k = 0; k < num_chan; ++k)
4885
0
                        dst_ptr[k * planestride] = dst[k];
4886
0
                } else {
4887
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4888
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4889
0
                                ++k, comps >>= 1) {
4890
0
                            if ((comps & 0x1) != 0) {
4891
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4892
0
                            }
4893
0
                        }
4894
                        /* The alpha channel */
4895
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4896
0
                    } else {
4897
0
                        for (k = 0; k < num_comp; ++k)
4898
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4899
                        /* The alpha channel */
4900
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4901
0
                    }
4902
0
                }
4903
0
                if (has_alpha_g) {
4904
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4905
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4906
0
                }
4907
0
                if (has_shape) {
4908
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4909
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4910
0
                }
4911
0
                if (has_tags) {
4912
                    /* If alpha is 100% then set to curr_tag, else or */
4913
                    /* other than Normal BM, we always OR */
4914
0
                    if (src[num_comp] == 255 && tag_blend) {
4915
0
                        dst_ptr[tag_off] = curr_tag;
4916
0
                    } else {
4917
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4918
0
                    }
4919
0
                }
4920
0
            }
4921
0
            ++dst_ptr;
4922
0
            ++back_ptr;
4923
0
        }
4924
0
        line += rowstride;
4925
0
        bline += rowstride;
4926
0
    }
4927
0
    return 0;
4928
0
}
4929
4930
static int
4931
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4932
                             int aa_raster, gx_bitmap_id id, int x, int y,
4933
                             int w, int h, gx_color_index color,
4934
                             const gx_device_color *pdc, int depth, bool devn)
4935
0
{
4936
0
    const byte *aa_row;
4937
0
    pdf14_device *pdev = (pdf14_device *)dev;
4938
0
    pdf14_buf *buf = pdev->ctx->stack;
4939
0
    int i, j, k;
4940
0
    byte *bline, *line;
4941
0
    uint16_t *dst_ptr, *back_ptr;
4942
0
    uint16_t src[PDF14_MAX_PLANES];
4943
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4944
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4945
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4946
0
        blend_mode == BLEND_MODE_Compatible ||
4947
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4948
0
    bool additive = pdev->ctx->additive;
4949
0
    intptr_t rowstride = buf->rowstride;
4950
0
    int planestride = buf->planestride;
4951
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4952
0
    bool has_alpha_g = buf->has_alpha_g;
4953
0
    bool has_shape = buf->has_shape;
4954
0
    bool has_tags = buf->has_tags;
4955
0
    bool knockout = buf->knockout;
4956
0
    int num_chan = buf->n_chan;
4957
0
    int num_comp = num_chan - 1;
4958
0
    intptr_t shape_off = num_chan * planestride;
4959
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4960
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4961
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4962
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4963
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4964
0
    gx_color_index comps;
4965
0
    uint16_t shape = 0; /* Quiet compiler. */
4966
0
    uint16_t src_alpha;
4967
0
    int alpha2_aa, alpha_aa, sx;
4968
0
    int alpha_aa_act;
4969
0
    int xoff;
4970
0
    bool has_backdrop = buf->backdrop != NULL;
4971
4972
0
    if (buf->data == NULL)
4973
0
        return 0;
4974
0
    aa_row = data;
4975
0
    if (has_tags) {
4976
0
        if (devn)
4977
0
            curr_tag = pdc->tag;
4978
0
        else
4979
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4980
0
    }
4981
4982
0
    if (devn) {
4983
0
        if (additive) {
4984
0
            for (j = 0; j < num_comp; j++) {
4985
0
                src[j] = pdc->colors.devn.values[j];
4986
0
            }
4987
0
        } else {
4988
0
            for (j = 0; j < num_comp; j++) {
4989
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4990
0
            }
4991
0
        }
4992
0
    } else
4993
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4994
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4995
0
    if (has_shape)
4996
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4997
    /* Limit the area we write to the bounding rectangle for this buffer */
4998
0
    if (x < buf->rect.p.x) {
4999
0
        xoff = data_x + buf->rect.p.x - x;
5000
0
        w += x - buf->rect.p.x;
5001
0
        x = buf->rect.p.x;
5002
0
    } else {
5003
0
        xoff = data_x;
5004
0
    }
5005
0
    if (y < buf->rect.p.y) {
5006
0
      h += y - buf->rect.p.y;
5007
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5008
0
      y = buf->rect.p.y;
5009
0
    }
5010
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5011
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5012
    /* Update the dirty rectangle. */
5013
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5014
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5015
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5016
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5017
5018
    /* composite with backdrop only. */
5019
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5020
0
    if (knockout && has_backdrop)
5021
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5022
0
    else
5023
0
        bline = line;
5024
5025
0
    planestride >>= 1;
5026
0
    rowstride   >>= 1;
5027
0
    alpha_g_off >>= 1;
5028
0
    shape_off   >>= 1;
5029
0
    tag_off     >>= 1;
5030
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5031
0
        back_ptr = (uint16_t *)(void *)bline;
5032
0
        dst_ptr = (uint16_t *)(void *)line;
5033
0
        sx = xoff;
5034
0
        for (i = 0; i < w; ++i, ++sx) {
5035
            /* Complement the components for subtractive color spaces */
5036
0
            if (additive) {
5037
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5038
0
                    dst[k] = back_ptr[k * planestride];
5039
0
            } else { /* Complement the components for subtractive color spaces */
5040
0
                for (k = 0; k < num_comp; ++k)
5041
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5042
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5043
0
            }
5044
            /* Get the aa alpha from the buffer */
5045
0
            switch(depth)
5046
0
            {
5047
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5048
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5049
0
                break;
5050
0
            case 4:
5051
0
                alpha2_aa = aa_row[sx >> 1];
5052
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5053
0
                break;
5054
0
            case 8:
5055
0
                alpha_aa = aa_row[sx];
5056
0
                break;
5057
0
            default:
5058
0
                return_error(gs_error_rangecheck);
5059
0
            }
5060
0
            if (alpha_aa != 0) {  /* This does happen */
5061
0
                if (alpha_aa != 255) {
5062
                    /* We have an alpha value from aa */
5063
0
                    alpha_aa_act = alpha_aa * 0x101;
5064
0
                    if (src_alpha != 65535) {
5065
                        /* Need to combine it with the existing alpha */
5066
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5067
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5068
0
                    }
5069
                    /* Set our source alpha value appropriately */
5070
0
                    src[num_comp] = alpha_aa_act;
5071
0
                } else {
5072
                    /* We may have to reset this is it was changed as we
5073
                       moved across the row */
5074
0
                    src[num_comp] = src_alpha;
5075
0
                }
5076
0
                if (knockout) {
5077
0
                    if (buf->isolated) {
5078
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5079
0
                    } else {
5080
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5081
0
                            blend_mode, pdev->blend_procs, pdev);
5082
0
                    }
5083
0
                } else {
5084
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5085
0
                                                     pdev->blend_procs, pdev);
5086
0
                }
5087
                /* Complement the results for subtractive color spaces */
5088
0
                if (additive) {
5089
0
                    for (k = 0; k < num_chan; ++k)
5090
0
                        dst_ptr[k * planestride] = dst[k];
5091
0
                } else {
5092
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5093
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5094
0
                                ++k, comps >>= 1) {
5095
0
                            if ((comps & 0x1) != 0) {
5096
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5097
0
                            }
5098
0
                        }
5099
                        /* The alpha channel */
5100
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5101
0
                    } else {
5102
0
                        for (k = 0; k < num_comp; ++k)
5103
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5104
                        /* The alpha channel */
5105
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5106
0
                    }
5107
0
                }
5108
0
                if (has_alpha_g) {
5109
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5110
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5111
0
                }
5112
0
                if (has_shape) {
5113
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5114
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5115
0
                }
5116
0
                if (has_tags) {
5117
                    /* If alpha is 100% then set to curr_tag, else or */
5118
                    /* other than Normal BM, we always OR */
5119
0
                    if (src[num_comp] == 65535 && tag_blend) {
5120
0
                        dst_ptr[tag_off] = curr_tag;
5121
0
                    } else {
5122
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5123
0
                    }
5124
0
                }
5125
0
            }
5126
0
            ++dst_ptr;
5127
0
            ++back_ptr;
5128
0
        }
5129
0
        line += rowstride;
5130
0
        bline += rowstride;
5131
0
    }
5132
0
    return 0;
5133
0
}
5134
5135
static int
5136
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5137
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5138
                      gx_color_index color, const gx_device_color *pdc,
5139
                      int depth, bool devn)
5140
0
{
5141
0
    bool deep = device_is_deep(dev);
5142
0
    int code;
5143
5144
0
    code = pdf14_initialize_ctx(dev, NULL);
5145
0
    if (code < 0)
5146
0
        return code;
5147
5148
0
    if (deep)
5149
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5150
0
                                            id, x, y, w, h,
5151
0
                                            color, pdc, depth, devn);
5152
0
    else
5153
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5154
0
                                         id, x, y, w, h,
5155
0
                                         color, pdc, depth, devn);
5156
0
}
5157
5158
static  int
5159
pdf14_fill_mask(gx_device * orig_dev,
5160
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5161
                     int x, int y, int w, int h,
5162
                     const gx_drawing_color * pdcolor, int depth,
5163
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5164
12.7M
{
5165
12.7M
    gx_device *dev;
5166
12.7M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5167
12.7M
    gx_device_clip cdev;
5168
12.7M
    gx_color_tile *ptile = NULL;
5169
12.7M
    int code = 0;
5170
12.7M
    gs_int_rect group_rect;
5171
12.7M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5172
12.7M
    bool has_pattern_trans = false;
5173
12.7M
    cmm_dev_profile_t *dev_profile;
5174
5175
12.7M
    if (pdcolor == NULL)
5176
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5177
5178
12.7M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5179
12.7M
    if (code < 0)
5180
0
        return code;
5181
5182
    /* If we are doing a fill with a pattern that has a transparency then
5183
       go ahead and do a push and a pop of the transparency group */
5184
12.7M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5185
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5186
0
            ptile = pdcolor->colors.pattern.p_tile;
5187
            /* Set up things in the ptile so that we get the proper
5188
               blending etc */
5189
            /* Set the blending procs and the is_additive setting based
5190
               upon the number of channels */
5191
0
            if (ptile->ttrans->n_chan-1 < 4) {
5192
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5193
0
                ptile->ttrans->is_additive = true;
5194
0
            } else {
5195
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5196
0
                ptile->ttrans->is_additive = false;
5197
0
            }
5198
            /* Set the procs so that we use the proper filling method. */
5199
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5200
            /* Based upon if the tiles overlap pick the type of rect
5201
               fill that we will want to use */
5202
0
            if (ptile->has_overlap) {
5203
                /* This one does blending since there is tile overlap */
5204
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5205
0
            } else {
5206
                /* This one does no blending since there is no tile overlap */
5207
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5208
0
            }
5209
            /* Push the group */
5210
0
            group_rect.p.x = x;
5211
0
            group_rect.p.y = max(0,y);
5212
0
            group_rect.q.x = x + w;
5213
0
            group_rect.q.y = y + h;
5214
0
            if (!(w <= 0 || h <= 0)) {
5215
5216
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5217
0
                if (group_color_info == NULL)
5218
0
                    return_error(gs_error_VMerror);
5219
5220
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5221
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5222
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5223
0
                     group_color_info, NULL, NULL);
5224
0
                if (code < 0)
5225
0
                    return code;
5226
                /* Set up the output buffer information now that we have
5227
                   pushed the group */
5228
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5229
0
                if (fill_trans_buffer == NULL)
5230
0
                    return_error(gs_error_VMerror);
5231
5232
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5233
0
                                              fill_trans_buffer, NULL, false);
5234
                /* Store this in the appropriate place in pdcolor.  This
5235
                   is released later after the mask fill */
5236
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5237
0
                has_pattern_trans = true;
5238
0
            }
5239
0
        }
5240
0
    }
5241
12.7M
    if (pcpath != 0) {
5242
1.60M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5243
1.60M
        dev = (gx_device *) & cdev;
5244
1.60M
    } else
5245
11.1M
        dev = orig_dev;
5246
12.7M
    if (depth > 1) {
5247
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5248
0
        code = (*dev_proc(dev, copy_alpha))
5249
0
            (dev, data, dx, raster, id, x, y, w, h,
5250
0
             gx_dc_pure_color(pdcolor), depth);
5251
12.7M
    } else {
5252
12.7M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5253
12.7M
                                          x, y, w, h, dev, lop, false);
5254
12.7M
    }
5255
12.7M
    if (has_pattern_trans) {
5256
0
        bool has_tags = device_encodes_tags(dev);
5257
0
        if (code >= 0)
5258
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5259
0
        if (code >= 0)
5260
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5261
0
                                                p14dev->blend_procs,
5262
0
                                                p14dev->color_info.num_components - has_tags,
5263
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5264
0
                                                orig_dev);
5265
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5266
0
                       "pdf14_fill_mask");
5267
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5268
0
    }
5269
12.7M
    if (pcpath != 0)
5270
1.60M
        gx_destroy_clip_device_on_stack(&cdev);
5271
12.7M
    return code;
5272
12.7M
}
5273
5274
5275
5276
/* Used for filling rects when we are doing a fill with a pattern that
5277
   has transparency */
5278
static  int
5279
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5280
                        gx_path * ppath, const gx_fill_params * params,
5281
                        const gx_device_color * pdevc,
5282
                        const gx_clip_path * pcpath)
5283
57.8k
{
5284
57.8k
    int code;
5285
57.8k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5286
57.8k
    gs_fixed_rect clip_box;
5287
57.8k
    gs_fixed_rect outer_box;
5288
57.8k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5289
57.8k
    gs_int_rect rect;
5290
57.8k
    gx_clip_rect *curr_clip_rect;
5291
57.8k
    gx_color_tile *ptile = NULL;
5292
57.8k
    int k;
5293
57.8k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5294
57.8k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5295
57.8k
    int n_chan_tile;
5296
57.8k
    gx_clip_path cpath_intersection;
5297
57.8k
    gx_path path_ttrans;
5298
57.8k
    pdf14_group_color_t *group_color_info;
5299
57.8k
    bool has_tags = device_encodes_tags(pdev);
5300
5301
57.8k
    if (ppath == NULL)
5302
0
        return_error(gs_error_unknownerror);  /* should not happen */
5303
57.8k
    if (pcpath != NULL) {
5304
54.3k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5305
54.3k
    } else {
5306
3.58k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5307
3.58k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5308
3.58k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5309
3.58k
    }
5310
57.8k
    if (code < 0)
5311
0
        return code;
5312
57.8k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5313
57.8k
                                          params->rule, pgs_noconst, params);
5314
57.8k
    if (code < 0)
5315
0
        return code;
5316
    /* One (common) case worth optimising for is where we have a pattern that
5317
     * is positioned such that only one repeat of the tile is actually
5318
     * visible. In this case, we can restrict the size of the blending group
5319
     * we need to produce to be that of the actual area of the tile that is
5320
     * used. */
5321
57.8k
    ptile = pdevc->colors.pattern.p_tile;
5322
57.8k
    if (ptile->ttrans != NULL)
5323
18.4k
    {
5324
18.4k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5325
18.4k
            (cpath_intersection.outer_box.p.y < 0) ||
5326
18.4k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5327
11.5k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5328
7.44k
        {
5329
            /* More than one repeat of the tile would be visible, so we can't
5330
             * use the optimisation here. (Actually, this test isn't quite
5331
             * right - it actually tests whether more than the '0th' repeat
5332
             * of the tile is visible. A better test would test if just one
5333
             * repeat of the tile was visible, irrespective of which one.
5334
             * This is (hopefully) relatively rare, and would make the code
5335
             * below more complex too, so we're ignoring that for now. If it
5336
             * becomes evident that it's a case that matters we can revisit
5337
             * it.) */
5338
11.0k
        } else {
5339
            /* Only the 0th repeat is visible. Restrict the size further to
5340
             * just the used area of that patch. */
5341
11.0k
            gx_path_init_local(&path_ttrans, ppath->memory);
5342
11.0k
            code = gx_path_add_rectangle(&path_ttrans,
5343
11.0k
                                         int2fixed(ptile->ttrans->rect.p.x),
5344
11.0k
                                         int2fixed(ptile->ttrans->rect.p.y),
5345
11.0k
                                         int2fixed(ptile->ttrans->rect.q.x),
5346
11.0k
                                         int2fixed(ptile->ttrans->rect.q.y));
5347
11.0k
            if (code < 0)
5348
0
                return code;
5349
11.0k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5350
11.0k
                                      params->rule, pgs_noconst);
5351
11.0k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5352
11.0k
            if (code < 0)
5353
0
                return code;
5354
11.0k
        }
5355
18.4k
    }
5356
    /* Now let us push a transparency group into which we are
5357
     * going to tile the pattern.  */
5358
57.8k
    if (ppath != NULL) {
5359
57.8k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5360
5361
57.8k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5362
57.8k
        rect.p.x = fixed2int(outer_box.p.x);
5363
57.8k
        rect.p.y = fixed2int(outer_box.p.y);
5364
57.8k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5365
57.8k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5366
5367
        /* The color space of this group must be the same as that of the
5368
           tile.  Then when we pop the group, if there is a mismatch between
5369
           the tile color space and the current context we will do the proper
5370
           conversion.  In this way, we ensure that if the tile has any overlapping
5371
           occuring it will be blended in the proper manner i.e in the tile
5372
           underlying color space. */
5373
57.8k
        if (ptile->cdev == NULL) {
5374
18.4k
            if (ptile->ttrans == NULL)
5375
0
                return_error(gs_error_unknownerror);  /* should not happen */
5376
18.4k
            n_chan_tile = ptile->ttrans->n_chan;
5377
39.4k
        } else {
5378
39.4k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5379
39.4k
        }
5380
57.8k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5381
5382
        /* Transparency handling with patterns confuses me, so some notes...
5383
         *
5384
         * For simple, non-transparent patterns, like you'd get in PS, we've
5385
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5386
         * times. To cope with unmarked pixels, we have a "transparency" plane
5387
         * (simple on/off) that says whether a pixel is marked or not.
5388
         *
5389
         * For patterns with transparency (but not blending), we can create an
5390
         * isolated transparency group, tile all the bitmap tiles into that, and
5391
         * then blend that back with the required alpha at the end. This works
5392
         * because the alpha values of the individual objects within the tile are
5393
         * recorded in that group.
5394
         *
5395
         * We can't do that for groups that use blending though, as each object
5396
         * in the pattern might use a different blend, and we don't (can't) record
5397
         * the blending mode. An isolated group doesn't even allow us to actually
5398
         * do the blending at all. So, for such patterns (any patterns that sets (or
5399
         * just has a resource that mentions) a non-normal blend mode), we use
5400
         * a pattern clist.
5401
         */
5402
57.8k
        if (ptile->cdev == NULL) {
5403
18.4k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5404
18.4k
            if (group_color_info == NULL)
5405
0
                return gs_error_VMerror;
5406
5407
18.4k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5408
18.4k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5409
18.4k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5410
18.4k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5411
18.4k
            if (code < 0)
5412
0
                return code;
5413
18.4k
        }
5414
5415
        /* Set the blending procs and the is_additive setting based
5416
           upon the number of channels */
5417
57.8k
        if (ptile->cdev == NULL) {
5418
18.4k
            if (n_chan_tile-1 < 4) {
5419
17.5k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5420
17.5k
                ptile->ttrans->is_additive = true;
5421
17.5k
            } else {
5422
904
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5423
904
                ptile->ttrans->is_additive = false;
5424
904
            }
5425
18.4k
        }
5426
        /* Now lets go through the rect list and fill with the pattern */
5427
        /* First get the buffer that we will be filling */
5428
57.8k
        if (ptile->cdev == NULL) {
5429
18.4k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5430
18.4k
            if (fill_trans_buffer == NULL) {
5431
0
                p14dev->pclist_device = NULL;
5432
0
                return_error(gs_error_VMerror);
5433
0
            }
5434
18.4k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5435
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5436
               want to use */
5437
18.4k
            if (ptile->has_overlap) {
5438
                /* This one does blending since there is tile overlap */
5439
1.49k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5440
16.9k
            } else {
5441
                /* This one does no blending since there is no tile overlap */
5442
16.9k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5443
16.9k
            }
5444
            /* fill the rectangles */
5445
18.4k
            phase.x = pdevc->phase.x;
5446
18.4k
            phase.y = pdevc->phase.y;
5447
18.4k
            if (cpath_intersection.rect_list->list.head != NULL){
5448
852
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5449
14.1k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5450
13.3k
                    if_debug5m('v', pgs->memory,
5451
13.3k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5452
13.3k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5453
13.3k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5454
13.3k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5455
13.3k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5456
13.3k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5457
13.3k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5458
13.3k
                    curr_clip_rect = curr_clip_rect->next;
5459
13.3k
                }
5460
17.6k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5461
                /* The case when there is just a single rect */
5462
17.3k
                if_debug5m('v', pgs->memory,
5463
17.3k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5464
17.3k
                           cpath_intersection.rect_list->list.single.xmin,
5465
17.3k
                           cpath_intersection.rect_list->list.single.ymin,
5466
17.3k
                           cpath_intersection.rect_list->list.single.xmax-
5467
17.3k
                              cpath_intersection.rect_list->list.single.xmin,
5468
17.3k
                           cpath_intersection.rect_list->list.single.ymax-
5469
17.3k
                              cpath_intersection.rect_list->list.single.ymin,
5470
17.3k
                           (int)ptile->id);
5471
17.3k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5472
17.3k
                                                  cpath_intersection.rect_list->list.single.ymin,
5473
17.3k
                                                  cpath_intersection.rect_list->list.single.xmax,
5474
17.3k
                                                  cpath_intersection.rect_list->list.single.ymax,
5475
17.3k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5476
17.3k
            }
5477
39.4k
        } else {
5478
            /* Clist pattern with transparency.  Create a clip device from our
5479
               cpath_intersection.  The above non-clist case could probably be
5480
               done this way too, which will reduce the amount of code here.
5481
               That is for another day though due to time constraints*/
5482
39.4k
            gx_device *dev;
5483
39.4k
            gx_device_clip clipdev;
5484
5485
39.4k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5486
39.4k
            dev = (gx_device *)&clipdev;
5487
39.4k
            phase.x = pdevc->phase.x;
5488
39.4k
            phase.y = pdevc->phase.y;
5489
39.4k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5490
39.4k
                                              ptile, fill_trans_buffer, phase,
5491
39.4k
                                              dev, pdevc, 1);
5492
39.4k
            gx_destroy_clip_device_on_stack(&clipdev);
5493
39.4k
        }
5494
        /* We're done drawing with the pattern, remove the reference to the
5495
         * pattern device
5496
         */
5497
57.8k
        p14dev->pclist_device = NULL;
5498
57.8k
        if (code < 0)
5499
0
            return code;
5500
5501
        /* free our buffer object */
5502
57.8k
        if (fill_trans_buffer != NULL) {
5503
18.4k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5504
18.4k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5505
18.4k
        }
5506
57.8k
        if (ptile->cdev == NULL) {
5507
            /* pop our transparency group which will force the blending.
5508
               This was all needed for Bug 693498 */
5509
18.4k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5510
18.4k
                                                p14dev->blend_procs,
5511
18.4k
                                                p14dev->color_info.num_components - has_tags,
5512
18.4k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5513
18.4k
                                                pdev);
5514
18.4k
        }
5515
57.8k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5516
57.8k
        p14dev->pclist_device = NULL;
5517
57.8k
    }
5518
57.8k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5519
57.8k
    return code;
5520
57.8k
}
5521
5522
/* Useful function that should probably go elsewhere.
5523
 * Call this function to find the topmost pdf14 device in the device chain,
5524
 * or NULL if there is not one.
5525
 */
5526
static pdf14_device *find_pdf14_device(gx_device *dev)
5527
0
{
5528
0
    pdf14_device *pdev;
5529
5530
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5531
0
        return NULL;
5532
0
    return pdev;
5533
0
}
5534
5535
/* Imager render for pattern transparency filling.  This is just here to catch
5536
   the final flush, at which time we will pop the group and reset a few items */
5537
static  int
5538
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5539
                    uint w, int h, gx_device * dev)
5540
0
{
5541
0
    int code;
5542
0
    pdf14_device * p14dev;
5543
0
    const gs_gstate * pgs = penum->pgs;
5544
0
    gx_device_color * pdcolor = (penum->icolor1);
5545
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5546
0
    bool has_tags = device_encodes_tags(dev);
5547
5548
    /* Pass along to the original renderer */
5549
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5550
0
    if (code < 0)
5551
0
        return code;
5552
    /* On our final time through here, go ahead and pop the transparency
5553
       group and reset the procs in the device color. And free the fill
5554
       trans buffer object */
5555
0
    if (h == 0 && ptile->trans_group_popped == false) {
5556
0
        p14dev = find_pdf14_device(dev);
5557
5558
0
        if (p14dev->pclist_device == NULL) {
5559
            /* Used if we are on clist writing phase.  Would only
5560
               occur if we somehow failed in high level clist
5561
               image writing */
5562
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5563
0
        } else {
5564
            /* Used if we are on clist reading phase.  If we had high level
5565
               image in clist */
5566
0
            cmm_dev_profile_t *dev_profile;
5567
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5568
0
            if (code < 0)
5569
0
                return code;
5570
5571
0
            if_debug2m('v', p14dev->ctx->memory,
5572
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5573
0
                       ptile->uid.id, ptile->id);
5574
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5575
0
                    p14dev->color_info.num_components - has_tags,
5576
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5577
0
                    (gx_device *) p14dev);
5578
0
        }
5579
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5580
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5581
0
                       "pdf14_pattern_trans_render");
5582
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5583
0
    }
5584
0
    return code;
5585
0
}
5586
5587
/* This function is used to get things in place for filling a mask image
5588
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5589
   and pdf14_clist_begin_type_image */
5590
static int
5591
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5592
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5593
                           const gs_int_rect * prect,
5594
                           const gx_drawing_color * pdcolor,
5595
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5596
                           gx_image_enum_common_t ** pinfo)
5597
0
{
5598
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5599
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5600
0
    gx_color_tile *ptile;
5601
0
    int code;
5602
0
    gs_int_rect group_rect;
5603
0
    gx_image_enum *penum;
5604
0
    gs_rect bbox_in, bbox_out;
5605
0
    gx_pattern_trans_t *fill_trans_buffer;
5606
5607
0
    ptile = pdcolor->colors.pattern.p_tile;
5608
    /* Set up things in the ptile so that we get the proper
5609
       blending etc */
5610
    /* Set the blending procs and the is_additive setting based
5611
       upon the number of channels */
5612
0
    if (ptile->ttrans->n_chan-1 < 4) {
5613
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5614
0
        ptile->ttrans->is_additive = true;
5615
0
    } else {
5616
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5617
0
        ptile->ttrans->is_additive = false;
5618
0
    }
5619
    /* Set the blending mode in the ptile based upon the current
5620
       setting in the gs_gstate */
5621
0
    ptile->blending_mode = pgs->blend_mode;
5622
    /* Based upon if the tiles overlap pick the type of rect
5623
       fill that we will want to use */
5624
0
    if (ptile->has_overlap) {
5625
        /* This one does blending since there is tile overlap */
5626
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5627
0
    } else {
5628
        /* This one does no blending since there is no tile overlap */
5629
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5630
0
    }
5631
    /* Set the procs so that we use the proper filling method. */
5632
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5633
    /* Let the imaging stuff get set up */
5634
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5635
0
                            prect, pdcolor,pcpath, mem, pinfo);
5636
0
    if (code < 0)
5637
0
        return code;
5638
    /* Now Push the group */
5639
    /* First apply the inverse of the image matrix to our
5640
       image size to get our bounding box. */
5641
0
    bbox_in.p.x = 0;
5642
0
    bbox_in.p.y = 0;
5643
0
    bbox_in.q.x = pim->Width;
5644
0
    bbox_in.q.y = pim->Height;
5645
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5646
0
                                &bbox_out);
5647
0
    if (code < 0)
5648
0
        return code;
5649
    /* That in turn will get hit by the matrix in the gs_gstate */
5650
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5651
0
                                            &bbox_out, (gs_gstate *)pgs);
5652
0
    if (code < 0)
5653
0
        return code;
5654
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5655
0
        if_debug2m('v', p14dev->ctx->memory,
5656
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5657
0
                   ptile->uid.id, ptile->id);
5658
5659
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5660
0
                                             65535, pgs->blend_mode, 0, 0,
5661
0
                                             ptile->ttrans->n_chan-1, false, false,
5662
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5663
5664
        /* Set up the output buffer information now that we have
5665
           pushed the group */
5666
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5667
0
        if (fill_trans_buffer == NULL)
5668
0
            return_error(gs_error_VMerror);
5669
5670
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5671
5672
        /* Store this in the appropriate place in pdcolor.  This
5673
           is released later in pdf14_pattern_trans_render when
5674
           we are all done with the mask fill */
5675
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5676
5677
        /* Change the renderer to handle this case so we can catch the
5678
           end.  We will then pop the group and reset the pdcolor proc.
5679
           Keep the base renderer also. */
5680
0
        penum = (gx_image_enum *) *pinfo;
5681
0
        ptile->ttrans->image_render = penum->render;
5682
0
        penum->render = &pdf14_pattern_trans_render;
5683
0
        ptile->trans_group_popped = false;
5684
0
    }
5685
0
    return code;
5686
0
}
5687
5688
static  int
5689
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5690
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5691
                           const gs_int_rect * prect,
5692
                           const gx_drawing_color * pdcolor,
5693
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5694
                           gx_image_enum_common_t ** pinfo)
5695
333k
{
5696
333k
    const gs_image_t *pim = (const gs_image_t *)pic;
5697
333k
    int code;
5698
5699
333k
    code = pdf14_initialize_ctx(dev, pgs);
5700
333k
    if (code < 0)
5701
0
        return code;
5702
5703
    /* If we are filling an image mask with a pattern that has a transparency
5704
       then we need to do some special handling */
5705
333k
    if (pim->ImageMask) {
5706
93
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5707
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5708
                /* If we are in a final run through here for this case then
5709
                   go ahead and push the transparency group.   Also, update
5710
                   the proc for the pattern color so that we used the
5711
                   appropriate fill operation.  Note that the group
5712
                   is popped and the proc will be reset when we flush the
5713
                   image data.  This is handled in a special pdf14 image
5714
                   renderer which will end up installed for this case.
5715
                   Detect setting of begin_image to gx_no_begin_image.
5716
                   (final recursive call) */
5717
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5718
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5719
0
                                                prect, pdcolor, pcpath, mem,
5720
0
                                                pinfo);
5721
0
                    return code;
5722
0
                }
5723
0
            }
5724
0
        }
5725
93
    }
5726
333k
    pdf14_set_marking_params(dev, pgs);
5727
333k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5728
333k
                                        pcpath, mem, pinfo);
5729
333k
}
5730
5731
static  void
5732
pdf14_set_params(gs_gstate * pgs,
5733
                 gx_device * dev,
5734
                 const gs_pdf14trans_params_t * pparams)
5735
8.83M
{
5736
8.83M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5737
8.83M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5738
2.14M
        pgs->blend_mode = pparams->blend_mode;
5739
8.83M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5740
1.10M
        pgs->text_knockout = pparams->text_knockout;
5741
8.83M
    if (pparams->changed & PDF14_SET_AIS)
5742
304k
        pgs->alphaisshape = pparams->ais;
5743
8.83M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5744
2.54M
        pgs->overprint = pparams->overprint;
5745
8.83M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5746
2.54M
        pgs->stroke_overprint = pparams->stroke_overprint;
5747
8.83M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5748
2.92M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5749
8.83M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5750
1.98M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5751
8.83M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5752
2.00M
        gs_swapcolors_quick(pgs);
5753
2.00M
        if (pparams->op_fs_state == GS_OP_STATE_STROKE)
5754
699k
            pgs->is_fill_color = false;
5755
1.30M
        else
5756
1.30M
            pgs->is_fill_color = true;
5757
2.00M
    }
5758
8.83M
    pdf14_set_marking_params(dev, pgs);
5759
8.83M
}
5760
5761
/*
5762
 * This open_device method for the PDF 1.4 compositor devices is only used
5763
 * when these devices are disabled.  This routine is about as close to
5764
 * a pure "forwarding" open_device operation as is possible. Its only
5765
 * significant function is to ensure that the is_open field of the
5766
 * PDF 1.4 compositor devices matches that of the target device.
5767
 *
5768
 * We assume this procedure is called only if the device is not already
5769
 * open, and that gs_opendevice will take care of the is_open flag.
5770
 */
5771
static  int
5772
pdf14_forward_open_device(gx_device * dev)
5773
0
{
5774
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5775
0
    gx_device * tdev = pdev->target;
5776
0
    int code;
5777
5778
    /* The PDF 1.4 compositing devices must have a target */
5779
0
    if (tdev == 0)
5780
0
        return_error(gs_error_unknownerror);
5781
0
    if ((code = gs_opendevice(tdev)) >= 0)
5782
0
        gx_device_copy_params(dev, tdev);
5783
0
    return code;
5784
0
}
5785
5786
/*
5787
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5788
 * for setting any device procs that should not be forwarded.
5789
 */
5790
static  void
5791
pdf14_forward_device_procs(gx_device * dev)
5792
1.11M
{
5793
1.11M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5794
1.11M
    pdf14_device *p14dev = (pdf14_device*)dev;
5795
5796
    /* If doing simulated overprint with spot colors
5797
       then makes sure to reset devn setting */
5798
1.11M
    if (p14dev->overprint_sim &&
5799
0
        p14dev->color_info.num_components > 4)
5800
0
        p14dev->icc_struct->supports_devn =
5801
0
            p14dev->target_support_devn;
5802
5803
    /*
5804
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5805
     * This will ensure that any new device procs are also set.  However that
5806
     * routine only changes procs which are NULL.  Thus we start by setting all
5807
     * procs to NULL.
5808
     */
5809
1.11M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5810
1.11M
    gx_device_forward_fill_in_procs(pdev);
5811
    /*
5812
     * gx_device_forward_fill_in_procs does not forward all procs.
5813
     * Set the remainding procs to also forward.
5814
     */
5815
1.11M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5816
1.11M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5817
1.11M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5818
1.11M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5819
1.11M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5820
1.11M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5821
1.11M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5822
1.11M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5823
1.11M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5824
1.11M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5825
    /* These are forwarding devices with minor tweaks. */
5826
1.11M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5827
1.11M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5828
1.11M
}
5829
5830
/*
5831
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5832
 * compositor device is never removed.  (We do not have a remove compositor
5833
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5834
 * routine implements that action.
5835
 */
5836
int
5837
pdf14_disable_device(gx_device * dev)
5838
1.10M
{
5839
1.10M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5840
5841
1.10M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5842
1.10M
    dev->color_info = pdev->target->color_info;
5843
1.10M
    pdf14_forward_device_procs(dev);
5844
1.10M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5845
1.10M
    return 0;
5846
1.10M
}
5847
5848
/*
5849
 * The default color space for PDF 1.4 blend modes is based upon the process
5850
 * color model of the output device.
5851
 */
5852
static  pdf14_default_colorspace_t
5853
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5854
                                 pdf14_blend_cs_t *blend_cs_state)
5855
3.23M
{
5856
    /* If a blend color space was specified, then go ahead and use that to
5857
       define the default color space for the blend modes.  Only Gray, RGB
5858
       or CMYK blend color spaces are allowed.  Note we do not allow this
5859
       setting if we are dealing with a separation device. */
5860
3.23M
    cmm_dev_profile_t *dev_profile;
5861
3.23M
    cmm_profile_t *blend_profile = NULL;
5862
3.23M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5863
3.23M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5864
3.23M
    bool valid_blend_cs = false;
5865
3.23M
    int has_tags = device_encodes_tags(pdev);
5866
5867
3.23M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5868
5869
    /* Are we using a blend color space or the output intent color space? Also
5870
       is there a conflict in the settings. i.e. has someone set a blend color
5871
       space and tried to use the output intent with simulate overprint setting.
5872
    */
5873
3.23M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5874
0
        dev_profile->oi_profile != NULL &&
5875
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5876
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5877
           possible conflicting command line settings and we will err on using the blend profile
5878
           if one was specified. */
5879
0
        if (dev_profile->blend_profile != NULL &&
5880
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5881
0
            blend_profile = dev_profile->blend_profile;
5882
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5883
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5884
0
        } else {
5885
            /* All good, use the output intent profile as we have one
5886
               and are doing simulate overprint with a different device
5887
               profile set. */
5888
0
            blend_profile = dev_profile->oi_profile;
5889
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5890
0
        }
5891
3.23M
    } else if (dev_profile->blend_profile != NULL &&
5892
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5893
        /* Blend profile is different than device profile */
5894
0
        blend_profile = dev_profile->blend_profile;
5895
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5896
0
    }
5897
5898
    /* Make sure any blend color space is valid along with other cond */
5899
3.23M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5900
0
        if (!blend_profile->isdevlink &&
5901
0
            !blend_profile->islab &&
5902
0
            (blend_profile->data_cs == gsGRAY ||
5903
0
             blend_profile->data_cs == gsRGB ||
5904
0
             blend_profile->data_cs == gsCMYK)) {
5905
            /* Also, do not allow the use of the blend space when we are pushing
5906
               a pattern pdf14 device.  Those should inherit from the parent */
5907
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5908
0
                  gx_device_is_pattern_accum(pdev))) {
5909
0
                valid_blend_cs = true;
5910
0
            }
5911
0
        }
5912
0
    }
5913
5914
    /* If num components is one, just go ahead and use gray.  This avoids
5915
       issues with additive/subtractive mono color devices  */
5916
3.23M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5917
3.00M
        pdev->color_info.num_components == 1) {
5918
        /*
5919
        * Note:  We do not allow the SeparationOrder device parameter for
5920
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5921
        * and 3 colorants for DeviceRGB.
5922
        */
5923
3.00M
        if (valid_blend_cs) {
5924
0
            *blend_cs_state = temp_cs_state;
5925
0
            switch (blend_profile->num_comps) {
5926
0
            case 1:
5927
0
                return PDF14_DeviceGray;
5928
0
            case 3:
5929
0
                return PDF14_DeviceRGB;
5930
0
            case 4:
5931
0
                return PDF14_DeviceCMYK;
5932
0
            }
5933
0
        }
5934
3.00M
        if (pdev->color_info.num_components - has_tags == 1)
5935
1.26M
            return PDF14_DeviceGray;
5936
1.73M
        else if (pdev->color_info.num_components - has_tags == 3)
5937
1.73M
            return PDF14_DeviceRGB;
5938
0
        else
5939
0
            return PDF14_DeviceRGBspot;
5940
3.00M
    } else {
5941
        /*
5942
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5943
         * the CMYK plus spot colors will not support the blend color space
5944
         */
5945
231k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5946
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5947
        return PDF14_DeviceCustom;
5948
#endif
5949
        /*
5950
         * Count the number of CMYK process components supported by the output
5951
         * device.
5952
         */
5953
1.15M
        for (i = 0; i < 4; i++) {
5954
927k
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5955
5956
927k
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5957
927k
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5958
927k
            if (output_comp_num >= 0) {
5959
927k
                num_cmyk++;
5960
927k
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5961
927k
                    num_cmyk_used++;
5962
927k
            }
5963
927k
        }
5964
        /*
5965
         * Check if the device supports only CMYK.  Otherewise we assume that
5966
         * the output device supports spot colors.  Note:  This algorithm can
5967
         * be fooled if the SeparationOrder device parameter is being used by
5968
         * the output device device to only select CMYK.
5969
         */
5970
231k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5971
221k
            && pdev->color_info.max_components == 4) {
5972
41.4k
            if (valid_blend_cs) {
5973
0
                *blend_cs_state = temp_cs_state;
5974
0
                switch (blend_profile->num_comps) {
5975
0
                case 1:
5976
0
                    return PDF14_DeviceGray;
5977
0
                case 3:
5978
0
                    return PDF14_DeviceRGB;
5979
0
                case 4:
5980
0
                    return PDF14_DeviceCMYK;
5981
0
                }
5982
0
            }
5983
41.4k
            return PDF14_DeviceCMYK;
5984
41.4k
        }
5985
        /*
5986
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5987
         * This device is only needed for those devices which do not support
5988
         * a basic CMYK process color model.
5989
         */
5990
190k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5991
190k
        if (num_cmyk != 4)
5992
0
            return PDF14_DeviceCustom;
5993
190k
#endif
5994
        /*
5995
         * Otherewise we use a CMYK plus spot colors for blending.
5996
         */
5997
190k
        if (valid_blend_cs)
5998
0
            *blend_cs_state = temp_cs_state;
5999
190k
        return PDF14_DeviceCMYKspot;
6000
190k
    }
6001
3.23M
}
6002
6003
/*
6004
 * the PDF 1.4 transparency spec says that color space for blending
6005
 * operations can be based upon either a color space specified in the
6006
 * group or a default value based upon the output device.  We are
6007
 * currently only using a color space based upon the device.
6008
 */
6009
static  int
6010
get_pdf14_device_proto(gx_device       *dev,
6011
                       pdf14_device    *pdevproto,
6012
                       gs_gstate       *pgs,
6013
                 const gs_pdf14trans_t *pdf14pct,
6014
                       bool             use_pdf14_accum)
6015
1.10M
{
6016
1.10M
    pdf14_blend_cs_t blend_cs_state;
6017
1.10M
    pdf14_default_colorspace_t dev_cs =
6018
1.10M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6019
1.10M
                                                 &blend_cs_state);
6020
1.10M
    bool deep = device_is_deep(dev);
6021
1.10M
    int num_spots = pdf14pct->params.num_spot_colors;
6022
1.10M
    bool has_tags = device_encodes_tags(dev);
6023
6024
    /* overprint overide */
6025
1.10M
    if (pdf14pct->params.overprint_sim_push &&
6026
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6027
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6028
0
            dev_cs = PDF14_DeviceCMYKspot;
6029
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6030
0
        } else
6031
0
            dev_cs = PDF14_DeviceCMYK;
6032
0
    }
6033
6034
1.10M
    switch (dev_cs) {
6035
482k
        case PDF14_DeviceGray:
6036
482k
            *pdevproto = gs_pdf14_Gray_device;
6037
482k
            pdevproto->color_info.max_components = 1 + has_tags;
6038
482k
            pdevproto->color_info.num_components =
6039
482k
                                    pdevproto->color_info.max_components + has_tags;
6040
482k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6041
482k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6042
482k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6043
482k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6044
482k
            pdevproto->sep_device = false;
6045
482k
            break;
6046
550k
        case PDF14_DeviceRGB:
6047
550k
            *pdevproto = gs_pdf14_RGB_device;
6048
550k
            pdevproto->color_info.max_components += has_tags;
6049
550k
            pdevproto->color_info.num_components += has_tags;
6050
550k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6051
550k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6052
550k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6053
550k
            pdevproto->sep_device = false;
6054
550k
            break;
6055
2.99k
        case PDF14_DeviceCMYK:
6056
2.99k
            *pdevproto = gs_pdf14_CMYK_device;
6057
2.99k
            pdevproto->color_info.max_components += has_tags;
6058
2.99k
            pdevproto->color_info.num_components += has_tags;
6059
2.99k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6060
2.99k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6061
2.99k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6062
2.99k
            pdevproto->sep_device = false;
6063
2.99k
            break;
6064
73.2k
        case PDF14_DeviceCMYKspot:
6065
73.2k
            *pdevproto = gs_pdf14_CMYKspot_device;
6066
            /* Need to figure out how we want to handle the device profile
6067
               for this case */
6068
            /*
6069
             * The number of components for the PDF14 device is the sum
6070
             * of the process components and the number of spot colors
6071
             * for the page.
6072
             */
6073
73.2k
            if (num_spots >= 0) {
6074
73.2k
                pdevproto->color_info.num_components =
6075
73.2k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6076
73.2k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6077
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6078
73.2k
                pdevproto->color_info.depth =
6079
73.2k
                                    pdevproto->color_info.num_components * (8<<deep);
6080
73.2k
                pdevproto->sep_device = true;
6081
73.2k
            }
6082
0
            else
6083
0
            {
6084
0
                pdevproto->color_info.max_components += has_tags;
6085
0
                pdevproto->color_info.num_components += has_tags;
6086
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6087
0
            }
6088
73.2k
            break;
6089
0
        case PDF14_DeviceRGBspot:
6090
0
            *pdevproto = gs_pdf14_RGBspot_device;
6091
            /* Need to figure out how we want to handle the device profile
6092
               for this case */
6093
            /*
6094
             * The number of components for the PDF14 device is the sum
6095
             * of the process components and the number of spot colors
6096
             * for the page.
6097
             */
6098
0
            if (num_spots >= 0) {
6099
0
                pdevproto->color_info.num_components =
6100
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6101
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6102
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6103
0
                pdevproto->color_info.depth =
6104
0
                    pdevproto->color_info.num_components * (8 << deep);
6105
0
                pdevproto->sep_device = true;
6106
0
            }
6107
0
            else
6108
0
            {
6109
0
                pdevproto->color_info.max_components += has_tags;
6110
0
                pdevproto->color_info.num_components += has_tags;
6111
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6112
0
            }
6113
0
            break;
6114
0
        case PDF14_DeviceCustom:
6115
            /*
6116
             * We are using the output device's process color model.  The
6117
             * color_info for the PDF 1.4 compositing device needs to match
6118
             * the output device.
6119
             */
6120
0
            *pdevproto = gs_pdf14_custom_device;
6121
0
            pdevproto->color_info = dev->color_info;
6122
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6123
0
            pdevproto->color_info.depth =
6124
0
                       pdevproto->color_info.num_components * (8<<deep);
6125
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6126
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6127
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6128
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6129
0
            break;
6130
0
        default:      /* Should not occur */
6131
0
            return_error(gs_error_rangecheck);
6132
1.10M
    }
6133
1.10M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6134
1.10M
    pdevproto->blend_cs_state = blend_cs_state;
6135
1.10M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6136
1.10M
    return 0;
6137
1.10M
}
6138
6139
/* When playing back the clist, we need to know if the buffer device is compatible */
6140
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6141
/* depth are critical since these must match when reading back colors.             */
6142
bool
6143
pdf14_ok_to_optimize(gx_device *dev)
6144
2.11M
{
6145
2.11M
    pdf14_blend_cs_t blend_cs_state;
6146
2.11M
    pdf14_default_colorspace_t pdf14_cs =
6147
2.11M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6148
2.11M
    gsicc_colorbuffer_t dev_icc_cs;
6149
2.11M
    bool ok = false;
6150
2.11M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6151
2.11M
    cmm_dev_profile_t *dev_profile;
6152
2.11M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6153
2.11M
    bool deep = device_is_deep(dev);
6154
6155
2.11M
    if (code < 0)
6156
0
        return false;
6157
6158
2.11M
    check_device_compatible_encoding(dev);
6159
6160
2.11M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6161
986k
        return false;
6162
6163
1.13M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6164
    /* If the outputprofile is not "standard" then colors converted to device color */
6165
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6166
1.13M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6167
0
        return false;                           /* can't handle funky output profiles */
6168
6169
1.13M
    switch (pdf14_cs) {
6170
332k
        case PDF14_DeviceGray:
6171
332k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6172
332k
            break;
6173
682k
        case PDF14_DeviceRGB:
6174
682k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6175
682k
            break;
6176
0
        case PDF14_DeviceCMYK:
6177
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6178
0
            break;
6179
116k
        case PDF14_DeviceCMYKspot:
6180
116k
            ok = false;     /* punt for this case */
6181
116k
            break;
6182
0
        case PDF14_DeviceRGBspot:
6183
0
            ok = false;     /* punt for this case */
6184
0
            break;
6185
0
        case PDF14_DeviceCustom:
6186
            /*
6187
             * We are using the output device's process color model.  The
6188
             * color_info for the PDF 1.4 compositing device needs to match
6189
             * the output device, but it may not have been contone.
6190
             */
6191
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6192
0
            break;
6193
0
        default:      /* Should not occur */
6194
0
            ok = false;
6195
1.13M
    }
6196
1.13M
    return ok;
6197
1.13M
}
6198
6199
/*
6200
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6201
 * compositor device is never removed.  (We do not have a remove compositor
6202
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6203
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6204
 * again.
6205
 */
6206
static  int
6207
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6208
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6209
0
{
6210
0
    pdf14_device * pdev = (pdf14_device *)dev;
6211
0
    gx_device * target = pdev->target;
6212
0
    pdf14_device dev_proto;
6213
0
    bool has_tags = device_encodes_tags(dev);
6214
0
    int code;
6215
0
    bool deep = device_is_deep(dev);
6216
6217
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6218
6219
    /*
6220
     * We will not use the entire prototype device but we will set the
6221
     * color related info and the device procs to match the prototype.
6222
     */
6223
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6224
0
                                  pdf14pct, false);
6225
0
    if (code < 0)
6226
0
        return code;
6227
0
    pdev->color_info = dev_proto.color_info;
6228
0
    pdev->pad = target->pad;
6229
0
    pdev->log2_align_mod = target->log2_align_mod;
6230
6231
0
    if (target->num_planar_planes == 0)
6232
0
        pdev->num_planar_planes = 0;
6233
0
    else
6234
0
        pdev->num_planar_planes = dev->color_info.num_components;
6235
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6236
6237
0
    if (dev_proto.initialize_device_procs != NULL)
6238
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6239
0
    pdev->procs = dev_proto.procs;
6240
0
    if (deep) {
6241
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6242
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6243
0
    }
6244
0
    if (has_tags) {
6245
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6246
0
    }
6247
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6248
0
    gx_device_fill_in_procs((gx_device *)pdev);
6249
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6250
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6251
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6252
0
    check_device_separable(dev);
6253
0
    return dev_proc(pdev, open_device)(dev);
6254
0
}
6255
6256
/*
6257
 * Implement the various operations that can be specified via the PDF 1.4
6258
 * create compositor request.
6259
 */
6260
static  int
6261
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6262
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6263
22.2M
{
6264
22.2M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6265
22.2M
    gs_pdf14trans_params_t params = pdf14pct->params;
6266
22.2M
    int code = 0;
6267
6268
22.2M
    params.idle = pdf14pct->idle;
6269
22.2M
    switch (params.pdf14_op) {
6270
0
        default:      /* Should not occur. */
6271
0
            break;
6272
10.0k
        case PDF14_PUSH_DEVICE:
6273
10.0k
            if (!(params.is_pattern)) {
6274
0
                p14dev->blend_mode = 0;
6275
0
                p14dev->opacity = p14dev->shape = 0.0;
6276
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6277
0
            }
6278
10.0k
            break;
6279
0
        case PDF14_ABORT_DEVICE:
6280
            /* Something has gone very wrong.  Let transparency device clean up
6281
               what ever it has allocated and then we are shutting it down */
6282
0
            code = gx_abort_trans_device(pgs, pdev);
6283
0
            if (p14dev->free_devicen) {
6284
0
                devn_free_params(pdev);
6285
0
            }
6286
0
            pdf14_disable_device(pdev);
6287
0
            pdf14_close(pdev);
6288
0
            break;
6289
1.10M
        case PDF14_POP_DEVICE:
6290
1.10M
            if (!(params.is_pattern)) {
6291
1.09M
                if_debug0m('v', pdev->memory,
6292
1.09M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6293
1.09M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6294
1.09M
                gx_set_cmap_procs(pgs, p14dev->target);
6295
                /* Send image out raster data to output device */
6296
1.09M
                {
6297
                    /* Make a copy so we can change the ROP */
6298
1.09M
                    gs_gstate new_pgs = *pgs;
6299
6300
                    /* We don't use the gs_gstate log_op since this is for the */
6301
                    /* clist playback. Putting the image (band in the case of the */
6302
                    /* clist) only needs to use the default ROP to copy the data  */
6303
1.09M
                    new_pgs.log_op = rop3_default;
6304
1.09M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6305
1.09M
                }
6306
                /* Before we disable the device release any deviceN structures.
6307
                    free_devicen is set if the pdf14 device had inherited its
6308
                    deviceN parameters from the target clist device.  In this
6309
                    case they should not be freed */
6310
1.09M
                if (p14dev->free_devicen) {
6311
1.09M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6312
1.09M
                    if (devn_params) {
6313
1.09M
                        gxdso_spot_info si;
6314
1.09M
                        si.params = devn_params;
6315
1.09M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6316
1.09M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6317
1.09M
                    }
6318
1.09M
                    devn_free_params(pdev);
6319
1.09M
                }
6320
1.09M
                pdf14_disable_device(pdev);
6321
1.09M
                pdf14_close(pdev);
6322
1.09M
            }
6323
1.10M
            break;
6324
425k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6325
2.43M
        case PDF14_BEGIN_TRANS_GROUP:
6326
2.43M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6327
311k
                p14dev->depth_within_smask++;
6328
2.43M
            p14dev->smask_constructed = 0;
6329
2.43M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6330
2.43M
            break;
6331
1.92M
        case PDF14_END_TRANS_GROUP:
6332
1.92M
            code = gx_end_transparency_group(pgs, pdev);
6333
1.92M
            if (p14dev->depth_within_smask)
6334
311k
                p14dev->depth_within_smask--;
6335
1.92M
            break;
6336
151
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6337
151
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6338
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6339
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6340
0
            } else
6341
151
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6342
151
            break;
6343
504k
        case PDF14_END_TRANS_TEXT_GROUP:
6344
504k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6345
504k
                code = gx_end_transparency_group(pgs, pdev);
6346
504k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6347
504k
            break;
6348
4.16M
        case PDF14_BEGIN_TRANS_MASK:
6349
4.16M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6350
4.16M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6351
420k
                p14dev->in_smask_construction++;
6352
4.16M
            break;
6353
420k
        case PDF14_END_TRANS_MASK:
6354
420k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6355
420k
            if (code >= 0) {
6356
420k
                p14dev->in_smask_construction--;
6357
420k
                if (p14dev->in_smask_construction < 0)
6358
0
                    p14dev->in_smask_construction = 0;
6359
420k
                if (p14dev->in_smask_construction == 0)
6360
420k
                    p14dev->smask_constructed = 1;
6361
420k
            }
6362
420k
            break;
6363
8.83M
        case PDF14_SET_BLEND_PARAMS:
6364
8.83M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6365
8.83M
            break;
6366
0
        case PDF14_PUSH_TRANS_STATE:
6367
0
            code = gx_push_transparency_state(pgs, pdev);
6368
0
            break;
6369
2.81M
        case PDF14_POP_TRANS_STATE:
6370
2.81M
            code = gx_pop_transparency_state(pgs, pdev);
6371
2.81M
            break;
6372
4.22k
        case PDF14_PUSH_SMASK_COLOR:
6373
4.22k
            code = pdf14_increment_smask_color(pgs, pdev);
6374
4.22k
            break;
6375
4.22k
        case PDF14_POP_SMASK_COLOR:
6376
4.22k
            code = pdf14_decrement_smask_color(pgs, pdev);
6377
4.22k
            break;
6378
22.2M
    }
6379
22.2M
    return code;
6380
22.2M
}
6381
6382
/*
6383
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6384
 * compositor' method.  However the compositor is disabled when we are not
6385
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6386
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6387
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6388
 * to the target.
6389
 */
6390
static  int
6391
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6392
        const gs_composite_t * pct, gs_gstate * pgs,
6393
        gs_memory_t * mem, gx_device *cdev)
6394
2.34k
{
6395
2.34k
    pdf14_device *pdev = (pdf14_device *)dev;
6396
2.34k
    gx_device * tdev = pdev->target;
6397
2.34k
    int code;
6398
6399
2.34k
    *pcdev = dev;
6400
2.34k
    if (gs_is_pdf14trans_compositor(pct)) {
6401
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6402
6403
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6404
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6405
0
        return 0;
6406
0
    }
6407
2.34k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6408
2.34k
    if (code == 1) {
6409
        /* We have created a new compositor that wrapped tdev. This means
6410
         * that our target should be updated to point to that. */
6411
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6412
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6413
0
    }
6414
2.34k
    return code;
6415
2.34k
}
6416
6417
/*
6418
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6419
 * and return. Since the gs_pdf14_device only supports the high-level routines
6420
 * of the interface, don't bother trying to handle any other compositor.
6421
 */
6422
static int
6423
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6424
        const gs_composite_t * pct, gs_gstate * pgs,
6425
        gs_memory_t * mem, gx_device *cdev)
6426
121M
{
6427
121M
    pdf14_device *p14dev = (pdf14_device *)dev;
6428
121M
    if (gs_is_pdf14trans_compositor(pct)) {
6429
22.2M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6430
22.2M
        *pcdev = dev;
6431
        /* cdev, may be the clist reader device which may contain information that
6432
           we will need related to the ICC color spaces that define transparency
6433
           groups.  We want this propogated through all the pdf14 functions.  Store
6434
           a pointer to it in the pdf14 device */
6435
22.2M
        p14dev->pclist_device = cdev;
6436
22.2M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6437
99.3M
    } else if (gs_is_overprint_compositor(pct)) {
6438
                /* If we had an overprint compositer action, then the
6439
                   color components that were drawn should be updated.
6440
                   The overprint compositor logic and its interactions
6441
                   with the clist is a little odd as it passes uninitialized
6442
                   values around a fair amount.  Hence the forced assignement here.
6443
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6444
99.3M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6445
99.3M
                gx_color_index drawn_comps;
6446
99.3M
                GS_OP_FS_STATE curr_state = p14dev->op_state;
6447
6448
99.3M
                p14dev->op_state = op_pct->params.op_state;
6449
99.3M
                if (p14dev->op_state == GS_OP_STATE_NONE) {
6450
49.7M
                    if (op_pct->params.retain_any_comps) {
6451
104k
                        drawn_comps = op_pct->params.drawn_comps;
6452
49.6M
                    } else {
6453
                        /* Draw everything. If this parameter was not set, clist does
6454
                           not fill it in.  */
6455
49.6M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6456
49.6M
                    }
6457
6458
49.7M
                    if (op_pct->params.is_fill_color) {
6459
27.9M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6460
27.9M
                        p14dev->drawn_comps_fill = drawn_comps;
6461
27.9M
                    } else {
6462
21.7M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6463
21.7M
                        p14dev->drawn_comps_stroke = drawn_comps;
6464
21.7M
                    }
6465
                    /* We restore the NONE states as that is used just to force
6466
                       overprint settings in the overprint compositor communication */
6467
49.7M
                    p14dev->op_state = curr_state;
6468
49.7M
                }
6469
99.3M
                *pcdev = dev;
6470
99.3M
                return 0;
6471
99.3M
    } else
6472
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6473
121M
}
6474
6475
static int
6476
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6477
                      gs_blend_mode_t blend_mode, float opacity,
6478
                      float shape, bool is_clist)
6479
2.76k
{
6480
2.76k
    int code;
6481
2.76k
    gs_transparency_group_params_t params = { 0 };
6482
2.76k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6483
2.76k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6484
2.76k
    float alpha = pgs->fillconstantalpha;
6485
6486
    /* Push a non-isolated knock-out group making sure the opacity and blend
6487
       mode are correct */
6488
2.76k
    params.Isolated = false;
6489
2.76k
    params.Knockout = true;
6490
2.76k
    params.page_group = false;
6491
2.76k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6492
2.76k
    params.group_opacity = 1.0;
6493
2.76k
    params.group_shape = 1.0;
6494
6495
2.76k
    gs_setfillconstantalpha(pgs, 1.0);
6496
2.76k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6497
6498
2.76k
    if (is_clist) {
6499
2.75k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6500
2.75k
        if (code < 0)
6501
0
            return code;
6502
2.75k
    }
6503
6504
2.76k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6505
2.76k
    gs_setfillconstantalpha(pgs, alpha);
6506
2.76k
    gs_setblendmode(pgs, blend_mode);
6507
2.76k
    if (code < 0)
6508
0
        return code;
6509
6510
2.76k
    if (is_clist) {
6511
2.75k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6512
2.75k
    }
6513
2.76k
    return code;
6514
2.76k
}
6515
6516
static  int
6517
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6518
                 const gs_text_params_t * text, gs_font * font,
6519
                 const gx_clip_path * pcpath,
6520
                 gs_text_enum_t ** ppenum)
6521
343
{
6522
343
    int code;
6523
343
    gs_text_enum_t *penum;
6524
343
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6525
343
    float opacity = pgs->fillconstantalpha;
6526
343
    float shape = 1.0;
6527
343
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6528
343
    pdf14_device *pdev = (pdf14_device*)dev;
6529
343
    bool draw = !(text->operation & TEXT_DO_NONE);
6530
343
    uint text_mode = gs_currenttextrenderingmode(pgs);
6531
343
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6532
343
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6533
6534
343
    code = pdf14_initialize_ctx(dev, pgs);
6535
343
    if (code < 0)
6536
0
        return code;
6537
6538
343
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6539
343
    pdf14_set_marking_params(dev, pgs);
6540
343
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6541
343
    if (code < 0)
6542
0
        return code;
6543
6544
    /* We may need to push a non-isolated transparency group if the following
6545
       is true.
6546
       1) We are not currently in one that we pushed for text and we are in
6547
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6548
       2) The blend mode is not Normal or the opacity is not 1.0
6549
       3) Text knockout is set to true
6550
       4) We are actually doing a text drawing
6551
6552
       Special note:  If text-knockout is set to false while we are within a
6553
       BT ET pair, we should pop the group.  I need to create a test file for
6554
       this case.  */
6555
6556
       /* Catch case where we already pushed a group and are trying to push another one.
6557
       In that case, we will pop the current one first, as we don't want to be left
6558
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6559
       will not be caught until we do the put_image and notice that the stack is not
6560
       empty. */
6561
343
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6562
0
        code = gs_end_transparency_group(pgs);
6563
0
        if (code < 0)
6564
0
            return code;
6565
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6566
0
    }
6567
6568
343
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6569
342
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6570
342
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6571
1
         text_mode != 3 && /* don't bother with invisible text */
6572
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6573
1
        if (draw) {
6574
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6575
1
                false);
6576
1
        }
6577
343
    *ppenum = (gs_text_enum_t *)penum;
6578
343
    return code;
6579
343
}
6580
6581
static  int
6582
pdf14_initialize_device(gx_device *new_dev)
6583
1.10M
{
6584
1.10M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6585
6586
1.10M
    pdev->ctx = NULL;
6587
1.10M
    pdev->color_model_stack = NULL;
6588
1.10M
    pdev->smaskcolor = NULL;
6589
6590
1.10M
    return 0;
6591
1.10M
}
6592
6593
/*
6594
 * Implement copy_mono by filling lots of small rectangles.
6595
 */
6596
static int
6597
pdf14_copy_mono(gx_device * dev,
6598
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6599
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6600
12.8M
{
6601
12.8M
    const byte *sptr;
6602
12.8M
    const byte *line;
6603
12.8M
    int sbit, first_bit;
6604
12.8M
    int code, sbyte, bit, count;
6605
12.8M
    int run_length, startx, current_bit, bit_value;
6606
12.8M
    gx_color_index current_color;
6607
6608
12.8M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6609
12.8M
    line = base + (sourcex >> 3);
6610
12.8M
    sbit = sourcex & 7;
6611
12.8M
    first_bit = 7 - sbit;
6612
6613
    /* Loop through the height of the specified area. */
6614
97.7M
    while (h-- > 0) {
6615
        /* Set up for the start of each line of the area. */
6616
84.8M
        sptr = line;
6617
84.8M
        sbyte = *sptr++;
6618
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6619
         * the loop below so adding 1 means that we don't fall into the bit == 0
6620
         * case and incorrectly read a new byte from the source. This weirdness is because
6621
         * the original code wouold read off the end of the buffer if the number of bits in
6622
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6623
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6624
         * of the loop to the beginning meant we would not read past the end of the buffer
6625
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6626
         * reading another byte.
6627
         */
6628
84.8M
        bit = first_bit + 1;
6629
84.8M
        count = w;
6630
84.8M
        run_length = 0;
6631
84.8M
        startx = x;
6632
84.8M
        current_bit = 0;
6633
84.8M
        current_color = zero;
6634
6635
        /* Loop across each pixel of a line. */
6636
1.20G
        do {
6637
            /* Move to the next input bit. */
6638
1.20G
            if (bit == 0) {
6639
104M
                bit = 7;
6640
104M
                sbyte = *sptr++;
6641
104M
            }
6642
1.10G
            else
6643
1.10G
                bit--;
6644
1.20G
            bit_value = (sbyte >> bit) & 1;
6645
1.20G
            if (bit_value == current_bit) {
6646
                /* The value did not change, simply increment our run length */
6647
996M
                run_length++;
6648
996M
            } else {
6649
                /* The value changed, fill the current rectangle. */
6650
212M
                if (run_length != 0) {
6651
202M
                    if (current_color != gx_no_color_index) {
6652
87.2M
                        code = (*dev_proc(dev, fill_rectangle))
6653
87.2M
                                (dev, startx, y, run_length, 1, current_color);
6654
87.2M
                        if (code < 0)
6655
0
                            return code;
6656
87.2M
                    }
6657
202M
                    startx += run_length;
6658
202M
                }
6659
212M
                run_length = 1;
6660
212M
                current_color = bit_value ? one : zero;
6661
212M
                current_bit = bit_value;
6662
212M
            }
6663
1.20G
        } while (--count > 0);
6664
        /* Fill the last rectangle in the line. */
6665
84.8M
        if (run_length != 0 && current_color != gx_no_color_index) {
6666
37.7M
            code = (*dev_proc(dev, fill_rectangle))
6667
37.7M
                        (dev, startx, y, run_length, 1, current_color);
6668
37.7M
            if (code < 0)
6669
0
                return code;
6670
37.7M
        }
6671
        /* Move to the next line */
6672
84.8M
        line += sraster;
6673
84.8M
        y++;
6674
84.8M
    }
6675
12.8M
    return 0;
6676
12.8M
}
6677
6678
/* Added to avoid having to go back and forth between fixed and int
6679
   in some of the internal methods used for dealing with tiling
6680
   and devn colors */
6681
static int
6682
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6683
    const gx_drawing_color *pdcolor)
6684
962
{
6685
962
    pdf14_device *pdev = (pdf14_device *)dev;
6686
962
    pdf14_buf *buf;
6687
962
    int code;
6688
6689
962
    fit_fill_xywh(dev, x, y, w, h);
6690
962
    if (w <= 0 || h <= 0)
6691
0
        return 0;
6692
6693
962
    code = pdf14_initialize_ctx(dev, NULL);
6694
962
    if (code < 0)
6695
0
        return code;
6696
962
    buf = pdev->ctx->stack;
6697
6698
962
    if (buf->knockout)
6699
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6700
0
            true);
6701
962
    else
6702
962
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6703
962
}
6704
6705
/* Step through and do rect fills with the devn colors as
6706
   we hit each transition in the bitmap. It is possible
6707
   that one of the colors is not devn, but is pure and
6708
   is set to gx_no_color_index. This type of mix happens
6709
   for example from tile_clip_fill_rectangle_hl_color */
6710
static int
6711
pdf14_copy_mono_devn(gx_device *dev,
6712
    const byte *base, int sourcex, int sraster,
6713
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6714
    const gx_drawing_color *pdcolor1)
6715
248
{
6716
248
    const byte *sptr;
6717
248
    const byte *line;
6718
248
    int sbit, first_bit;
6719
248
    int code, sbyte, bit, count;
6720
248
    int run_length, startx, current_bit, bit_value;
6721
248
    const gx_drawing_color *current_color;
6722
6723
248
    if ((x | y) < 0) {
6724
0
        if (x < 0) {
6725
0
            w += x;
6726
0
            sourcex -= x;
6727
0
            x = 0;
6728
0
        }
6729
0
        if (y < 0) {
6730
0
            h += y;
6731
0
            base -= (int)(y * sraster);
6732
0
            y = 0;
6733
0
        }
6734
0
    }
6735
248
    if (w > (dev)->width - x)
6736
0
        w = (dev)->width - x;
6737
248
    if (h > (dev)->height - y)
6738
0
        h = (dev)->height - y;
6739
248
    if (w <= 0 || h <= 0)
6740
0
        return 0;
6741
6742
248
    line = base + (sourcex >> 3);
6743
248
    sbit = sourcex & 7;
6744
248
    first_bit = 7 - sbit;
6745
6746
    /* Loop through the height of the specified area. */
6747
815
    while (h-- > 0) {
6748
        /* Set up for the start of each line of the area. */
6749
567
        sptr = line;
6750
567
        sbyte = *sptr++;
6751
567
        bit = first_bit;
6752
567
        count = w;
6753
567
        run_length = 0;
6754
567
        startx = x;
6755
567
        current_bit = 0;
6756
567
        current_color = pdcolor0;
6757
6758
        /* Loop across each pixel of a line. */
6759
6.15k
        do {
6760
6.15k
            bit_value = (sbyte >> bit) & 1;
6761
6.15k
            if (bit_value == current_bit) {
6762
                /* The value did not change, simply increment our run length */
6763
4.47k
                run_length++;
6764
4.47k
            } else {
6765
                /* The value changed, fill the current rectangle. */
6766
1.67k
                if (run_length != 0) {
6767
1.51k
                    if (current_color->type != gx_dc_type_pure &&
6768
717
                        current_color->colors.pure != gx_no_color_index) {
6769
717
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6770
717
                            run_length, 1, current_color);
6771
717
                        if (code < 0)
6772
0
                            return code;
6773
717
                    }
6774
1.51k
                    startx += run_length;
6775
1.51k
                }
6776
1.67k
                run_length = 1;
6777
1.67k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6778
1.67k
                current_bit = bit_value;
6779
1.67k
            }
6780
6781
            /* Move to the next input bit. */
6782
6.15k
            if (bit == 0) {
6783
553
                bit = 7;
6784
553
                sbyte = *sptr++;
6785
553
            } else
6786
5.60k
                bit--;
6787
6.15k
        } while (--count > 0);
6788
6789
        /* Fill the last rectangle in the line. */
6790
567
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6791
245
            current_color->colors.pure != gx_no_color_index) {
6792
245
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6793
245
                run_length, 1, current_color);
6794
245
            if (code < 0)
6795
0
                return code;
6796
245
        }
6797
        /* Move to the next line */
6798
567
        line += sraster;
6799
567
        y++;
6800
567
    }
6801
248
    return 0;
6802
248
}
6803
6804
/* Step through the tiles doing essentially copy_mono but with devn colors */
6805
static int
6806
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6807
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6808
    const gx_drawing_color *pdcolor1, int px, int py)
6809
248
{   /* Fill the rectangle in chunks. */
6810
248
    int width = tiles->size.x;
6811
248
    int height = tiles->size.y;
6812
248
    int raster = tiles->raster;
6813
248
    int rwidth = tiles->rep_width;
6814
248
    int rheight = tiles->rep_height;
6815
248
    int shift = tiles->shift;
6816
6817
248
    if (rwidth == 0 || rheight == 0)
6818
0
        return_error(gs_error_unregistered);
6819
248
    fit_fill_xy(dev, x, y, w, h);
6820
6821
248
     {
6822
248
        int xoff = (shift == 0 ? px :
6823
248
                px + (y + py) / rheight * tiles->rep_shift);
6824
248
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6825
0
            (x + xoff) & (rwidth - 1) :
6826
248
            (x + xoff) % rwidth);
6827
248
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6828
0
            (y + py) & (rheight - 1) :
6829
248
            (y + py) % rheight);
6830
248
        int icw = width - irx;
6831
248
        int ch = height - ry;
6832
248
        byte *row = tiles->data + ry * raster;
6833
248
        int code = 0;
6834
6835
248
        if (ch >= h) {      /* Shallow operation */
6836
248
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6837
248
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6838
248
                    w, h, pdcolor0, pdcolor1);
6839
248
                if (code < 0)
6840
0
                    return_error(code);
6841
248
            } else {
6842
0
                int ex = x + w;
6843
0
                int fex = ex - width;
6844
0
                int cx = x + icw;
6845
6846
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6847
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6848
0
                if (code < 0)
6849
0
                    return_error(code);
6850
6851
0
                while (cx <= fex) {
6852
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6853
0
                        width, h, pdcolor0, pdcolor1);
6854
0
                    if (code < 0)
6855
0
                        return_error(code);
6856
0
                    cx += width;
6857
0
                }
6858
0
                if (cx < ex) {
6859
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6860
0
                        ex - cx, h, pdcolor0, pdcolor1);
6861
0
                    if (code < 0)
6862
0
                        return_error(code);
6863
0
                }
6864
0
            }
6865
248
        } else if (icw >= w && shift == 0) {
6866
            /* Narrow operation, no shift */
6867
0
            int ey = y + h;
6868
0
            int fey = ey - height;
6869
0
            int cy = y + ch;
6870
6871
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6872
0
                x, y, w, ch, pdcolor0, pdcolor1);
6873
0
            if (code < 0)
6874
0
                return_error(code);
6875
0
            row = tiles->data;
6876
0
            do {
6877
0
                ch = (cy > fey ? ey - cy : height);
6878
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6879
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6880
0
                if (code < 0)
6881
0
                    return_error(code);
6882
0
            } while ((cy += ch) < ey);
6883
0
        } else {
6884
            /* Full operation.  If shift != 0, some scan lines */
6885
            /* may be narrow.  We could test shift == 0 in advance */
6886
            /* and use a slightly faster loop, but right now */
6887
            /* we don't bother. */
6888
0
            int ex = x + w, ey = y + h;
6889
0
            int fex = ex - width, fey = ey - height;
6890
0
            int cx, cy;
6891
6892
0
            for (cy = y;;) {
6893
0
                if (icw >= w) {
6894
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6895
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6896
0
                    if (code < 0)
6897
0
                        return_error(code);
6898
0
                } else {
6899
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6900
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6901
0
                    if (code < 0)
6902
0
                        return_error(code);
6903
0
                    cx = x + icw;
6904
0
                    while (cx <= fex) {
6905
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6906
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6907
0
                        if (code < 0)
6908
0
                            return_error(code);
6909
0
                        cx += width;
6910
0
                    }
6911
0
                    if (cx < ex) {
6912
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6913
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6914
0
                        if (code < 0)
6915
0
                            return_error(code);
6916
0
                    }
6917
0
                }
6918
0
                if ((cy += ch) >= ey)
6919
0
                    break;
6920
0
                ch = (cy > fey ? ey - cy : height);
6921
0
                if ((irx += shift) >= rwidth)
6922
0
                    irx -= rwidth;
6923
0
                icw = width - irx;
6924
0
                row = tiles->data;
6925
0
            }
6926
0
        }
6927
248
    }
6928
248
    return 0;
6929
248
}
6930
6931
/* pdf14 device supports devn */
6932
static int
6933
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6934
    int x, int y, int w, int h,
6935
    const gx_drawing_color *pdcolor0,
6936
    const gx_drawing_color *pdcolor1, int px, int py)
6937
248
{
6938
248
    pdf14_device *pdev = (pdf14_device *)dev;
6939
248
    pdf14_buf *buf;
6940
248
    int num_comp;
6941
248
    int k;
6942
248
    bool same = false;
6943
248
    int code;
6944
6945
248
    code = pdf14_initialize_ctx(dev, NULL);
6946
248
    if (code < 0)
6947
0
        return code;
6948
248
    buf = pdev->ctx->stack;
6949
248
    num_comp = buf->n_chan - 1;
6950
6951
    /* if color0 is identical to color1, do rect fill */
6952
248
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6953
0
        same = true;
6954
0
        for (k = 0; k < num_comp; k++) {
6955
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6956
0
                same = false;
6957
0
                break;
6958
0
            }
6959
0
        }
6960
0
    }
6961
6962
248
    if (same) {
6963
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6964
248
    } else {
6965
        /* Go through the tile stepping using code stolen from
6966
           gx_default_strip_tile_rectangle and call the rect fills
6967
           using code stolen from pdf14_copy_mono but using devn
6968
           colors */
6969
248
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6970
248
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6971
248
    }
6972
248
    return code;
6973
248
}
6974
6975
/* Used in a few odd cases where the target device is planar and we have
6976
   a planar tile (pattern) and we are copying it into place here */
6977
static int
6978
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6979
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6980
2.45k
{
6981
2.45k
    pdf14_device *pdev = (pdf14_device *)dev;
6982
2.45k
    pdf14_ctx *ctx;
6983
2.45k
    pdf14_buf *buf;
6984
2.45k
    int xo = x;
6985
2.45k
    int yo = y;
6986
2.45k
    pdf14_buf fake_tos;
6987
2.45k
    int deep;
6988
6989
2.45k
    int code = pdf14_initialize_ctx(dev, NULL);
6990
2.45k
    if (code < 0)
6991
0
        return code;
6992
6993
2.45k
    fit_fill_xywh(dev, x, y, w, h);
6994
2.45k
    if (w <= 0 || h <= 0)
6995
0
        return 0;
6996
6997
2.45k
    ctx = pdev->ctx;
6998
2.45k
    buf = ctx->stack;
6999
2.45k
    deep = ctx->deep;
7000
7001
2.45k
    fake_tos.deep = deep;
7002
2.45k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7003
2.45k
    fake_tos.backdrop = NULL;
7004
2.45k
    fake_tos.blend_mode = pdev->blend_mode;
7005
2.45k
    fake_tos.color_space = buf->color_space;
7006
2.45k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7007
2.45k
    fake_tos.dirty.p.x = x;
7008
2.45k
    fake_tos.dirty.p.y = y;
7009
2.45k
    fake_tos.dirty.q.x = x + w;
7010
2.45k
    fake_tos.dirty.q.y = y + h;
7011
2.45k
    fake_tos.has_alpha_g = 0;
7012
2.45k
    fake_tos.has_shape = 0;
7013
2.45k
    fake_tos.has_tags = device_encodes_tags(dev);
7014
2.45k
    fake_tos.idle = false;
7015
2.45k
    fake_tos.isolated = false;
7016
2.45k
    fake_tos.knockout = false;
7017
2.45k
    fake_tos.mask_id = 0;
7018
2.45k
    fake_tos.mask_stack = NULL;
7019
2.45k
    fake_tos.matte = NULL;
7020
2.45k
    fake_tos.matte_num_comps = 0;
7021
2.45k
    fake_tos.memory = dev->memory;
7022
2.45k
    fake_tos.n_chan = dev->color_info.num_components;
7023
2.45k
    fake_tos.n_planes = dev->color_info.num_components;
7024
2.45k
    fake_tos.num_spots = 0;
7025
2.45k
    fake_tos.group_color_info = NULL;
7026
2.45k
    fake_tos.planestride = raster * (size_t)plane_height;
7027
2.45k
    fake_tos.rect.p.x = x;
7028
2.45k
    fake_tos.rect.p.y = y;
7029
2.45k
    fake_tos.rect.q.x = x + w;
7030
2.45k
    fake_tos.rect.q.y = y + h;
7031
2.45k
    fake_tos.rowstride = raster;
7032
2.45k
    fake_tos.saved = NULL;
7033
2.45k
    fake_tos.shape = 0xffff;
7034
2.45k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7035
2.45k
    fake_tos.transfer_fn = NULL;
7036
2.45k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7037
2.45k
                                  pdev->ctx->memory, dev);
7038
2.45k
    return 0;
7039
2.45k
}
7040
7041
static int
7042
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7043
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7044
    const gx_clip_path *pcpath)
7045
19.1M
{
7046
19.1M
    pdf14_device *pdev = (pdf14_device *)dev;
7047
19.1M
    pdf14_buf* buf;
7048
19.1M
    int code;
7049
19.1M
    int x = fixed2int(rect->p.x);
7050
19.1M
    int y = fixed2int(rect->p.y);
7051
19.1M
    int w = fixed2int(rect->q.x) - x;
7052
19.1M
    int h = fixed2int(rect->q.y) - y;
7053
7054
19.1M
    fit_fill_xywh(dev, x, y, w, h);
7055
19.1M
    if (w <= 0 || h <= 0)
7056
214k
        return 0;
7057
7058
18.9M
    code = pdf14_initialize_ctx(dev, pgs);
7059
18.9M
    if (code < 0)
7060
0
        return code;
7061
18.9M
    buf = pdev->ctx->stack;
7062
7063
18.9M
    if (buf->knockout)
7064
181k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7065
181k
                                                   true);
7066
18.7M
    else
7067
18.7M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7068
18.9M
}
7069
7070
static  int
7071
pdf14_fill_rectangle(gx_device * dev,
7072
                    int x, int y, int w, int h, gx_color_index color)
7073
333M
{
7074
333M
    pdf14_device *pdev = (pdf14_device *)dev;
7075
333M
    pdf14_buf *buf;
7076
333M
    int code;
7077
7078
333M
    fit_fill_xywh(dev, x, y, w, h);
7079
333M
    if (w <= 0 || h <= 0)
7080
10.3M
        return 0;
7081
7082
323M
    code = pdf14_initialize_ctx(dev, NULL);
7083
323M
    if (code < 0)
7084
0
        return code;
7085
7086
323M
    buf = pdev->ctx->stack;
7087
7088
323M
    if (buf->knockout)
7089
2.23M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7090
2.23M
                                                   false);
7091
321M
    else
7092
321M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7093
323M
}
7094
7095
static int
7096
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7097
                                    const gs_rect *pbbox, gs_int_rect *rect)
7098
2.42M
{
7099
2.42M
    gs_rect dev_bbox;
7100
2.42M
    int code;
7101
7102
2.42M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7103
2.42M
    if (code < 0)
7104
0
        return code;
7105
2.42M
    rect->p.x = (int)floor(dev_bbox.p.x);
7106
2.42M
    rect->p.y = (int)floor(dev_bbox.p.y);
7107
2.42M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7108
2.42M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7109
    /* Sanity check rect for insane ctms */
7110
2.42M
    if (rect->p.x < 0)
7111
262k
        rect->p.x = 0;
7112
2.42M
    if (rect->q.x < rect->p.x)
7113
2.45k
        rect->q.x = rect->p.x;
7114
2.42M
    if (rect->p.y < 0)
7115
2.22M
        rect->p.y = 0;
7116
2.42M
    if (rect->q.y < rect->p.y)
7117
49.7k
        rect->q.y = rect->p.y;
7118
2.42M
    return 0;
7119
2.42M
}
7120
7121
static  int
7122
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7123
                              const gs_rect *pbbox, gs_gstate *pgs)
7124
2.34M
{
7125
2.34M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7126
7127
2.34M
    if (code < 0)
7128
0
        return code;
7129
2.34M
    rect_intersect(*rect, pdev->ctx->rect);
7130
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7131
2.34M
    if (rect->q.x < rect->p.x)
7132
12.0k
        rect->q.x = rect->p.x;
7133
2.34M
    if (rect->q.y < rect->p.y)
7134
43.2k
        rect->q.y = rect->p.y;
7135
2.34M
    return 0;
7136
2.34M
}
7137
7138
static  int
7139
pdf14_begin_transparency_group(gx_device* dev,
7140
    const gs_transparency_group_params_t* ptgp,
7141
    const gs_rect* pbbox,
7142
    gs_gstate* pgs, gs_memory_t* mem)
7143
2.43M
{
7144
2.43M
    pdf14_device* pdev = (pdf14_device*)dev;
7145
2.43M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7146
2.43M
    gs_int_rect rect;
7147
2.43M
    int code;
7148
2.43M
    bool isolated = ptgp->Isolated;
7149
2.43M
    gs_transparency_color_t group_color_type;
7150
2.43M
    cmm_profile_t* group_profile;
7151
2.43M
    cmm_profile_t* tos_profile;
7152
2.43M
    gsicc_rendering_param_t render_cond;
7153
2.43M
    cmm_dev_profile_t* dev_profile;
7154
2.43M
    bool cm_back_drop = false;
7155
2.43M
    bool new_icc = false;
7156
2.43M
    pdf14_group_color_t* group_color_info;
7157
2.43M
    bool has_tags = device_encodes_tags(dev);
7158
7159
2.43M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7160
2.43M
    if (code < 0)
7161
0
        return code;
7162
2.43M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7163
7164
2.43M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7165
505k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7166
505k
    }
7167
7168
2.43M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7169
505k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7170
1.92M
    else
7171
1.92M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7172
7173
2.43M
    if (code < 0)
7174
0
        return code;
7175
2.43M
    if_debug5m('v', pdev->memory,
7176
2.43M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7177
2.43M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7178
7179
    /* If the group color is unknown then use the current device profile. */
7180
2.43M
    if (ptgp->group_color_type == UNKNOWN) {
7181
1.99M
        group_color_type = ICC;
7182
1.99M
        group_profile = tos_profile;
7183
1.99M
    }
7184
433k
    else {
7185
433k
        group_color_type = ptgp->group_color_type;
7186
433k
        group_profile = ptgp->iccprofile;
7187
433k
    }
7188
7189
    /* We have to handle case where the profile is in the clist */
7190
2.43M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7191
        /* Get the serialized data from the clist. */
7192
432k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7193
432k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7194
432k
        if (group_profile == NULL)
7195
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7196
        /* Keep a pointer to the clist device */
7197
432k
        group_profile->dev = (gx_device*)pcrdev;
7198
432k
        new_icc = true;
7199
432k
    }
7200
2.43M
    if (group_profile != NULL) {
7201
        /* If we have a non-isolated group and the color space is different,
7202
            we will need to CM the backdrop. */
7203
2.43M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7204
226k
            cm_back_drop = true;
7205
226k
        }
7206
2.43M
    }
7207
7208
    /* Always create the base color group information as it is only through
7209
       groups that we can have a color space change.  This will survive
7210
       the life of the context. */
7211
2.43M
    if (pdev->ctx->base_color == NULL) {
7212
581k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7213
581k
    }
7214
7215
    /* If this is not the page group and we don't yet have a group, we need
7216
       to create a buffer for the whole page so that we can handle stuff drawn
7217
       outside this current group (e.g. two non inclusive groups drawn independently) */
7218
2.43M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7219
66.7k
        code = pdf14_initialize_ctx(dev, NULL);
7220
66.7k
        if (code < 0)
7221
0
            return code;
7222
66.7k
        pdev->ctx->stack->isolated = true;
7223
66.7k
    }
7224
7225
2.43M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7226
2.43M
        group_profile, false);
7227
2.43M
    if (group_color_info == NULL)
7228
0
        return gs_error_VMerror;
7229
2.43M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7230
7231
2.43M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7232
2.43M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7233
2.43M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7234
2.43M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7235
2.43M
                                        pgs->blend_mode, ptgp->idle,
7236
2.43M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7237
2.43M
                                         cm_back_drop, ptgp->shade_group,
7238
2.43M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7239
2.43M
    if (new_icc)
7240
432k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7241
2.43M
    return code;
7242
2.43M
}
7243
7244
static void
7245
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7246
2.43M
{
7247
2.43M
    pdf14_device* pdev = (pdf14_device*)dev;
7248
7249
2.43M
    if (group_color != NULL &&
7250
2.43M
        !(group_color->group_color_mapping_procs == NULL &&
7251
2.43M
            group_color->group_color_comp_index == NULL)) {
7252
2.43M
        bool has_tags = device_encodes_tags(dev);
7253
2.43M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7254
2.43M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7255
2.43M
        pdev->color_info.polarity = group_color->polarity;
7256
2.43M
        if (pdev->num_planar_planes > 0)
7257
105k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7258
2.43M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7259
2.43M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7260
2.43M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7261
2.43M
        pdev->blend_procs = group_color->blend_procs;
7262
2.43M
        pdev->ctx->additive = group_color->isadditive;
7263
2.43M
        pdev->pdf14_procs = group_color->unpack_procs;
7264
2.43M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7265
2.43M
        pdev->color_info.depth = group_color->depth;
7266
2.43M
        pdev->color_info.max_color = group_color->max_color;
7267
2.43M
        pdev->color_info.max_gray = group_color->max_gray;
7268
2.43M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7269
2.43M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7270
2.43M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7271
2.43M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7272
2.43M
        if (group_color->icc_profile != NULL) {
7273
            /* make sure to decrement the device profile.  If it was allocated
7274
               with the push then it will be freed. */
7275
2.43M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7276
2.43M
                                    -1, "pdf14_pop_color_model");
7277
2.43M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7278
2.43M
                                    group_color->icc_profile;
7279
7280
2.43M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7281
2.43M
                                    1, "pdf14_pop_color_model");
7282
2.43M
        }
7283
2.43M
        pdev->num_std_colorants = group_color->num_std_colorants;
7284
2.43M
    }
7285
2.43M
}
7286
7287
static  int
7288
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7289
2.43M
{
7290
2.43M
    pdf14_device* pdev = (pdf14_device*)dev;
7291
2.43M
    int code;
7292
2.43M
    cmm_profile_t* group_profile;
7293
2.43M
    gsicc_rendering_param_t render_cond;
7294
2.43M
    cmm_dev_profile_t* dev_profile;
7295
2.43M
    int has_tags = device_encodes_tags(dev);
7296
7297
2.43M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7298
2.43M
    if (code < 0)
7299
0
        return code;
7300
7301
2.43M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7302
2.43M
        &render_cond);
7303
2.43M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7304
7305
2.43M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7306
2.43M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7307
2.43M
    if (code < 0)
7308
0
        return code;
7309
#ifdef DEBUG
7310
    pdf14_debug_mask_stack_state(pdev->ctx);
7311
#endif
7312
    /* If this group is the base group, then restore the color model
7313
       of the device at this time.  Note that during the actual device pop
7314
       we will need to use the profile of the buffer not the pdf14 device
7315
       as the source color space */
7316
2.43M
    if (pdev->ctx->stack->group_popped) {
7317
424k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7318
2.00M
    } else {
7319
2.00M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7320
2.00M
    }
7321
7322
2.43M
    return code;
7323
2.43M
}
7324
7325
static pdf14_group_color_t*
7326
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7327
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7328
                        bool is_mask)
7329
2.85M
{
7330
2.85M
    pdf14_device *pdevproto = NULL;
7331
2.85M
    pdf14_device *pdev = (pdf14_device *)dev;
7332
2.85M
    const pdf14_procs_t *new_14procs = NULL;
7333
2.85M
    pdf14_group_color_t *group_color;
7334
2.85M
    gx_color_polarity_t new_polarity;
7335
2.85M
    uchar new_num_comps;
7336
2.85M
    bool new_additive;
7337
2.85M
    gx_device_clist_reader *pcrdev;
7338
2.85M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7339
2.85M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7340
2.85M
    int k;
7341
2.85M
    bool has_tags = device_encodes_tags(dev);
7342
2.85M
    bool deep = pdev->ctx->deep;
7343
7344
2.85M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7345
7346
2.85M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7347
7348
2.85M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7349
2.85M
                               pdf14_group_color_t, &st_pdf14_clr,
7350
2.85M
                               "pdf14_push_color_model");
7351
2.85M
    if (group_color == NULL)
7352
0
        return NULL;
7353
7354
2.85M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7355
7356
2.85M
    switch (group_color_type) {
7357
0
        case GRAY_SCALE:
7358
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7359
0
            new_num_comps = 1;
7360
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7361
0
            new_additive = true;
7362
0
            new_14procs = &gray_pdf14_procs;
7363
0
            break;
7364
0
        case DEVICE_RGB:
7365
0
        case CIE_XYZ:
7366
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7367
0
            new_num_comps = 3;
7368
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7369
0
            new_additive = true;
7370
0
            new_14procs = &rgb_pdf14_procs;
7371
0
            break;
7372
0
        case DEVICE_CMYK:
7373
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7374
0
            new_num_comps = 4;
7375
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7376
0
            new_additive = false;
7377
            /* This is needed due to the mismatched compressed encode decode
7378
                between the device procs and the pdf14 procs */
7379
0
            if (dev->color_info.num_components > 4){
7380
0
                new_14procs = &cmykspot_pdf14_procs;
7381
0
            } else {
7382
0
                new_14procs = &cmyk_pdf14_procs;
7383
0
            }
7384
0
            break;
7385
2.85M
        case ICC:
7386
            /* If we are coming from the clist reader, then we need to get
7387
                the ICC data now  */
7388
2.85M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7389
                /* Get the serialized data from the clist.  Not the whole
7390
                    profile. */
7391
416k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7392
416k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7393
416k
                                                    icc_hashcode);
7394
416k
                if (iccprofile == NULL)
7395
0
                    return NULL;
7396
                /* Keep a pointer to the clist device */
7397
416k
                iccprofile->dev = (gx_device *) pcrdev;
7398
2.43M
            } else {
7399
                /* Go ahead and rc increment right now.  This way when
7400
                    we pop, we will make sure to decrement and avoid a
7401
                    leak for the above profile that we just created.  This
7402
                    goes with the assignment to the device's profile.
7403
                    Note that we still do the increment for the group_color
7404
                    assignment below. */
7405
2.43M
                if (iccprofile == NULL)
7406
0
                    return NULL;
7407
2.43M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7408
2.43M
            }
7409
2.85M
            new_num_comps = iccprofile->num_comps;
7410
2.85M
            if (new_num_comps == 4) {
7411
296k
                new_additive = false;
7412
296k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7413
2.55M
            } else {
7414
2.55M
                new_additive = true;
7415
2.55M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7416
2.55M
            }
7417
2.85M
            switch (new_num_comps) {
7418
742k
                case 1:
7419
742k
                    if (pdev->sep_device && !is_mask) {
7420
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7421
0
                        new_14procs = &grayspot_pdf14_procs;
7422
742k
                    } else {
7423
742k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7424
742k
                        new_14procs = &gray_pdf14_procs;
7425
742k
                    }
7426
742k
                    break;
7427
1.81M
                case 3:
7428
1.81M
                    if (pdev->sep_device) {
7429
60.2k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7430
60.2k
                        new_14procs = &rgbspot_pdf14_procs;
7431
60.2k
                    }
7432
1.75M
                    else {
7433
1.75M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7434
1.75M
                        new_14procs = &rgb_pdf14_procs;
7435
1.75M
                    }
7436
1.81M
                    break;
7437
296k
                case 4:
7438
296k
                    if (pdev->sep_device) {
7439
44.7k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7440
44.7k
                        new_14procs = &cmykspot_pdf14_procs;
7441
251k
                    } else {
7442
251k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7443
251k
                        new_14procs = &cmyk_pdf14_procs;
7444
251k
                    }
7445
296k
                    break;
7446
0
                default:
7447
0
                    return NULL;
7448
0
                    break;
7449
2.85M
            }
7450
2.85M
            break;
7451
2.85M
        default:
7452
0
            return NULL;
7453
0
            break;
7454
2.85M
    }
7455
7456
    /* We might just have changed the colorspace of the device, which means
7457
     * the number of colorants have changed. */
7458
2.85M
    group_color->num_std_colorants = new_num_comps;
7459
2.85M
    pdev->num_std_colorants = new_num_comps;
7460
7461
2.85M
    if (has_tags)
7462
0
        new_num_comps++;
7463
7464
2.85M
    if (group_color_type == ICC && iccprofile != NULL) {
7465
2.85M
        group_color->icc_profile = iccprofile;
7466
2.85M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7467
2.85M
    }
7468
7469
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7470
       spot colorants and know how to index into them */
7471
2.85M
    if (pdev->sep_device && !is_mask) {
7472
105k
        int num_spots = dev->color_info.num_components - has_tags -
7473
105k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7474
7475
105k
        if (num_spots > 0)
7476
649
            new_num_comps += num_spots;
7477
105k
    }
7478
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7479
10.2M
    for (k = 0; k < new_num_comps; k++) {
7480
7.36M
        comp_bits[k] = 8<<deep;
7481
7.36M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7482
7.36M
    }
7483
7484
    /* Set device values now and store settings in group_color.  Then they
7485
       are available when we pop the previous group */
7486
2.85M
    if_debug2m('v', pdev->memory,
7487
2.85M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7488
2.85M
                pdev->color_info.num_components,new_num_comps);
7489
2.85M
    {
7490
2.85M
        gx_device local_device;
7491
7492
2.85M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7493
2.85M
        local_device.initialize_device_procs((gx_device *)&local_device);
7494
2.85M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7495
2.85M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7496
2.85M
    }
7497
2.85M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7498
2.85M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7499
2.85M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7500
2.85M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7501
2.85M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7502
2.85M
    if (pdev->num_planar_planes > 0)
7503
135k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7504
2.85M
    group_color->num_components = new_num_comps - has_tags;
7505
2.85M
    pdev->color_info.num_components = new_num_comps;
7506
2.85M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7507
2.85M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7508
2.85M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7509
2.85M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7510
2.85M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7511
2.85M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7512
2.85M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7513
2.85M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7514
2.85M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7515
2.85M
    group_color->depth = pdev->color_info.depth;
7516
2.85M
    group_color->decode = dev_proc(pdev, decode_color);
7517
2.85M
    group_color->encode = dev_proc(pdev, encode_color);
7518
2.85M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7519
2.85M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7520
2.85M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7521
2.85M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7522
2.85M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7523
2.85M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7524
2.85M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7525
7526
    /* If the CS was ICC based, we need to update the device ICC profile
7527
        in the ICC manager, since that is the profile that is used for the
7528
        PDF14 device */
7529
2.85M
    if (group_color_type == ICC && iccprofile != NULL) {
7530
        /* iccprofile was incremented above if we had not just created it.
7531
           When we do the pop we will decrement and if we just created it, it
7532
           will be destroyed */
7533
2.85M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7534
2.85M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7535
2.85M
    }
7536
2.85M
    return group_color;
7537
2.85M
}
7538
7539
static int
7540
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7541
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7542
                             bool is_mask)
7543
58.9k
{
7544
58.9k
    pdf14_device* pdev = (pdf14_device*)dev;
7545
58.9k
    pdf14_group_color_t* new_group_color;
7546
58.9k
    gsicc_rendering_param_t render_cond;
7547
58.9k
    cmm_dev_profile_t* dev_profile;
7548
58.9k
    pdf14_device* pdevproto;
7549
58.9k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7550
58.9k
    const pdf14_procs_t* new_14procs;
7551
58.9k
    bool update_color_info;
7552
58.9k
    gx_color_polarity_t new_polarity;
7553
58.9k
    int new_num_comps;
7554
58.9k
    bool new_additive = false;
7555
58.9k
    byte new_depth;
7556
58.9k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7557
58.9k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7558
58.9k
    int k;
7559
58.9k
    bool has_tags = device_encodes_tags(dev);
7560
58.9k
    bool deep = device_is_deep(dev);
7561
58.9k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7562
58.9k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7563
58.9k
    cmm_profile_t *old_profile = NULL;
7564
7565
58.9k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7566
7567
58.9k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7568
58.9k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7569
58.9k
        &render_cond);
7570
58.9k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7571
7572
    /* Allocate a new one */
7573
58.9k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7574
58.9k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7575
7576
58.9k
    if (new_group_color == NULL)
7577
0
        return_error(gs_error_VMerror);
7578
7579
    /* Link to old one */
7580
58.9k
    new_group_color->previous = pdev->color_model_stack;
7581
7582
    /* Reassign new one to dev */
7583
58.9k
    pdev->color_model_stack = new_group_color;
7584
7585
    /* Initialize with values */
7586
58.9k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7587
58.9k
    new_group_color->group_color_mapping_procs =
7588
58.9k
        dev_proc(pdev, get_color_mapping_procs);
7589
58.9k
    new_group_color->group_color_comp_index =
7590
58.9k
        dev_proc(pdev, get_color_comp_index);
7591
58.9k
    new_group_color->blend_procs = pdev->blend_procs;
7592
58.9k
    new_group_color->polarity = pdev->color_info.polarity;
7593
58.9k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7594
58.9k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7595
58.9k
    new_group_color->depth = pdev->color_info.depth;
7596
58.9k
    new_group_color->max_color = pdev->color_info.max_color;
7597
58.9k
    new_group_color->max_gray = pdev->color_info.max_gray;
7598
58.9k
    new_group_color->decode = dev_proc(pdev, decode_color);
7599
58.9k
    new_group_color->encode = dev_proc(pdev, encode_color);
7600
58.9k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7601
58.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7602
58.9k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7603
58.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7604
7605
58.9k
    if (new_profile == NULL)
7606
36.2k
        new_group_color->icc_profile = NULL;
7607
7608
    /* isadditive is only used in ctx */
7609
58.9k
    if (pdev->ctx) {
7610
0
        new_group_color->isadditive = pdev->ctx->additive;
7611
0
    }
7612
7613
58.9k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7614
58.9k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7615
7616
58.9k
    if (group_color_type == ICC && new_profile == NULL)
7617
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7618
58.9k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7619
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7620
       are based upon the color space of the device.  We want to remain in the
7621
       color space defined by the color space of the soft mask or transparency
7622
       group as opposed to the device color space. Later, when we pop the softmask
7623
       we will collapse it to a single band and then compose with it to the device
7624
       color space (or the parent layer space).  In the case where we pop an
7625
       isolated transparency group, we will do the blending in the proper color
7626
       space and then transform the data when we pop the group.  Remember that only
7627
       isolated groups can have color spaces that are different than their parent. */
7628
58.9k
    update_color_info = false;
7629
58.9k
    switch (group_color_type) {
7630
0
    case GRAY_SCALE:
7631
0
        if (pdev->color_info.num_components != 1) {
7632
0
            update_color_info = true;
7633
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7634
0
            new_num_comps = 1;
7635
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7636
0
            new_additive = true;
7637
0
            new_14procs = &gray_pdf14_procs;
7638
0
            new_depth = 8 << deep;
7639
0
        }
7640
0
        break;
7641
0
    case DEVICE_RGB:
7642
0
    case CIE_XYZ:
7643
0
        if (pdev->color_info.num_components != 3) {
7644
0
            update_color_info = true;
7645
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7646
0
            new_num_comps = 3;
7647
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7648
0
            new_additive = true;
7649
0
            new_14procs = &rgb_pdf14_procs;
7650
0
            new_depth = 24 << deep;
7651
0
        }
7652
0
        break;
7653
0
    case DEVICE_CMYK:
7654
0
        if (pdev->color_info.num_components != 4) {
7655
0
            update_color_info = true;
7656
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7657
0
            new_num_comps = 4;
7658
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7659
0
            new_additive = false;
7660
            /* This is needed due to the mismatched compressed encode decode
7661
               between the device procs and the pdf14 procs */
7662
0
            if (dev->color_info.num_components > 4) {
7663
0
                new_14procs = &cmykspot_pdf14_procs;
7664
0
            }
7665
0
            else {
7666
0
                new_14procs = &cmyk_pdf14_procs;
7667
0
            }
7668
0
            new_depth = 32 << deep;
7669
0
        }
7670
0
        break;
7671
22.7k
    case ICC:
7672
        /* Check if the profile is different. */
7673
22.7k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7674
20.8k
            update_color_info = true;
7675
20.8k
            new_num_comps = new_profile->num_comps;
7676
20.8k
            new_depth = new_profile->num_comps * (8 << deep);
7677
20.8k
            switch (new_num_comps) {
7678
18.4k
            case 1:
7679
18.4k
                if (pdev->sep_device && !is_mask) {
7680
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7681
0
                    new_14procs = &grayspot_pdf14_procs;
7682
0
                }
7683
18.4k
                else {
7684
18.4k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7685
18.4k
                    new_14procs = &gray_pdf14_procs;
7686
18.4k
                }
7687
18.4k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7688
18.4k
                new_additive = true;
7689
18.4k
                break;
7690
2.08k
            case 3:
7691
2.08k
                if (pdev->sep_device) {
7692
420
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7693
420
                    new_14procs = &rgbspot_pdf14_procs;
7694
420
                }
7695
1.66k
                else {
7696
1.66k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7697
1.66k
                    new_14procs = &rgb_pdf14_procs;
7698
1.66k
                }
7699
2.08k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7700
2.08k
                new_additive = true;
7701
2.08k
                break;
7702
271
            case 4:
7703
271
                if (pdev->sep_device) {
7704
9
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7705
9
                    new_14procs = &cmykspot_pdf14_procs;
7706
9
                }
7707
262
                else {
7708
262
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7709
262
                    new_14procs = &cmyk_pdf14_procs;
7710
262
                }
7711
271
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7712
271
                new_additive = false;
7713
271
                break;
7714
0
            default:
7715
0
                return gs_throw(gs_error_undefinedresult,
7716
20.8k
                    "ICC Number of colorants illegal");
7717
20.8k
            }
7718
20.8k
        }
7719
22.7k
        break;
7720
36.2k
    case UNKNOWN:
7721
36.2k
        return 0;
7722
0
        break;
7723
0
    default:
7724
0
        return_error(gs_error_rangecheck);
7725
0
        break;
7726
58.9k
    }
7727
7728
22.7k
    if (!update_color_info) {
7729
        /* Profile not updated */
7730
1.88k
        new_group_color->icc_profile = NULL;
7731
1.88k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7732
1.88k
        return 0;
7733
1.88k
    }
7734
7735
20.8k
    if (has_tags) {
7736
0
        new_num_comps++;
7737
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7738
0
        if (pdev->num_planar_planes > 0)
7739
0
            new_depth += deep ? 16 : 8;
7740
0
        else
7741
0
            new_depth += 8;
7742
0
    }
7743
20.8k
    if (pdev->sep_device && !is_mask) {
7744
429
        int num_spots;
7745
7746
429
        if (old_profile == NULL)
7747
0
            return_error(gs_error_undefined);
7748
7749
429
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7750
7751
429
        if (num_spots > 0) {
7752
37
            new_num_comps += num_spots;
7753
37
            new_depth = (8 << deep) * new_num_comps;
7754
37
        }
7755
429
    }
7756
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7757
46.6k
    for (k = 0; k < new_num_comps; k++) {
7758
25.8k
        comp_bits[k] = 8 << deep;
7759
25.8k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7760
25.8k
    }
7761
20.8k
    if_debug2m('v', pdev->memory,
7762
20.8k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7763
20.8k
        pdev->color_info.num_components, new_num_comps);
7764
    /* Set new information in the device */
7765
20.8k
    {
7766
20.8k
        gx_device local_device;
7767
7768
20.8k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7769
20.8k
        local_device.initialize_device_procs((gx_device *)&local_device);
7770
20.8k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7771
20.8k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7772
20.8k
    }
7773
20.8k
    pdev->blend_procs = pdevproto->blend_procs;
7774
20.8k
    pdev->color_info.polarity = new_polarity;
7775
20.8k
    pdev->color_info.max_color = deep ? 65535 : 255;
7776
20.8k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7777
20.8k
    pdev->pdf14_procs = new_14procs;
7778
20.8k
    if (pdev->num_planar_planes > 0)
7779
2.39k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7780
20.8k
    pdev->color_info.num_components = new_num_comps;
7781
20.8k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7782
20.8k
    pdev->color_info.depth = new_depth;
7783
20.8k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7784
20.8k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7785
20.8k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7786
20.8k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7787
20.8k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7788
7789
    /* If we have a compressed color codec, and we are doing a soft mask
7790
       push operation then go ahead and update the color encode and
7791
       decode for the pdf14 device to not used compressed color
7792
       encoding while in the soft mask.  We will just check for gray
7793
       and compressed.  Note that we probably don't have_tags if we
7794
       are dealing with compressed color.  But is is possible so
7795
       we add it in to catch for future use. */
7796
20.8k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7797
20.8k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7798
20.8k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7799
20.8k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7800
20.8k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7801
20.8k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7802
    /* For the ICC profiles, we want to update the ICC profile for the
7803
       device.  We store the original in group_color.
7804
       That will be stored in the clist and restored during the reading phase. */
7805
20.8k
    if (group_color_type == ICC) {
7806
20.8k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7807
20.8k
        new_group_color->icc_profile =
7808
20.8k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7809
20.8k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7810
20.8k
    }
7811
20.8k
    if (pdev->ctx) {
7812
0
        pdev->ctx->additive = new_additive;
7813
0
    }
7814
20.8k
    return 1;  /* Lets us detect that we did do an update */
7815
20.8k
}
7816
7817
static int
7818
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7819
58.9k
{
7820
7821
58.9k
    pdf14_device *pdev = (pdf14_device *)dev;
7822
58.9k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7823
58.9k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7824
7825
58.9k
    if (group_color == NULL)
7826
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7827
7828
58.9k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7829
    /* The color procs are always pushed.  Simply restore them. */
7830
58.9k
    if (group_color->group_color_mapping_procs == NULL &&
7831
0
        group_color->group_color_comp_index == NULL) {
7832
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7833
58.9k
    } else {
7834
58.9k
        bool has_tags = device_encodes_tags(dev);
7835
58.9k
        if_debug2m('v', pdev->memory,
7836
58.9k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7837
58.9k
                   pdev->color_info.num_components,group_color->num_components);
7838
58.9k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7839
58.9k
        gx_set_cmap_procs(pgs, dev);
7840
58.9k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7841
58.9k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7842
58.9k
        pdev->color_info.polarity = group_color->polarity;
7843
58.9k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7844
58.9k
        pdev->color_info.depth = group_color->depth;
7845
58.9k
        if (pdev->num_planar_planes > 0)
7846
5.56k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7847
58.9k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7848
58.9k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7849
58.9k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7850
58.9k
        pdev->blend_procs = group_color->blend_procs;
7851
58.9k
        pdev->pdf14_procs = group_color->unpack_procs;
7852
58.9k
        pdev->color_info.max_color = group_color->max_color;
7853
58.9k
        pdev->color_info.max_gray = group_color->max_gray;
7854
58.9k
        set_dev_proc(pdev, encode_color, group_color->encode);
7855
58.9k
        set_dev_proc(pdev, decode_color, group_color->decode);
7856
58.9k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7857
58.9k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7858
58.9k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7859
58.9k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7860
7861
        /* clist writer fill rect has no access to gs_gstate */
7862
        /* and it forwards the target device.  this information */
7863
        /* is passed along to use in this case */
7864
58.9k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7865
58.9k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7866
58.9k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7867
58.9k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7868
58.9k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7869
58.9k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7870
58.9k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7871
58.9k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7872
58.9k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7873
58.9k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7874
58.9k
        if (pdev->ctx){
7875
0
            pdev->ctx->additive = group_color->isadditive;
7876
0
        }
7877
       /* The device profile must be restored. */
7878
58.9k
        if (group_color->icc_profile != NULL) {
7879
20.8k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7880
20.8k
                                    -1, "pdf14_clist_pop_color_model");
7881
20.8k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7882
20.8k
        }
7883
58.9k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7884
58.9k
    }
7885
58.9k
   pdf14_pop_group_color(dev, pgs);
7886
58.9k
    return 0;
7887
58.9k
}
7888
7889
/* When a transparency group is popped, the parent colorprocs must be restored.
7890
   Since the color mapping procs are all based upon the device, we must have a
7891
   nested list based upon the transparency group color space.  This nesting
7892
   must be outside the nested ctx structures to allow the nesting for the
7893
   clist writer */
7894
static void
7895
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7896
58.9k
{
7897
58.9k
    pdf14_device *pdev = (pdf14_device *)dev;
7898
58.9k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7899
7900
58.9k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7901
7902
    /* Update the link */
7903
58.9k
    pdev->color_model_stack = group_color->previous;
7904
7905
    /* Free the old one */
7906
58.9k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7907
58.9k
}
7908
7909
static  int
7910
pdf14_begin_transparency_mask(gx_device *dev,
7911
                              const gx_transparency_mask_params_t *ptmp,
7912
                              const gs_rect *pbbox,
7913
                              gs_gstate *pgs, gs_memory_t *mem)
7914
4.16M
{
7915
4.16M
    pdf14_device *pdev = (pdf14_device *)dev;
7916
4.16M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7917
4.16M
    byte *transfer_fn;
7918
4.16M
    gs_int_rect rect;
7919
4.16M
    int code;
7920
4.16M
    int group_color_numcomps;
7921
4.16M
    gs_transparency_color_t group_color_type;
7922
4.16M
    bool deep = device_is_deep(dev);
7923
4.16M
    pdf14_group_color_t* group_color_info;
7924
7925
4.16M
    code = pdf14_initialize_ctx(dev, pgs);
7926
4.16M
    if (code < 0)
7927
0
        return code;
7928
7929
4.16M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7930
3.74M
        pdf14_ctx *ctx = pdev->ctx;
7931
7932
        /* free up any maskbuf on the current tos */
7933
3.74M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7934
307k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7935
307k
            ctx->mask_stack->mask_buf = NULL;
7936
307k
        }
7937
3.74M
        return 0;
7938
3.74M
    }
7939
420k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7940
420k
                                         "pdf14_begin_transparency_mask");
7941
420k
    if (transfer_fn == NULL)
7942
0
        return_error(gs_error_VMerror);
7943
420k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7944
420k
    if (code < 0)
7945
0
        return code;
7946
    /* If we have background components the background alpha may be nonzero */
7947
420k
    if (ptmp->Background_components)
7948
65.2k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7949
420k
    if_debug1m('v', dev->memory,
7950
420k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7951
420k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7952
   /* If the group color is unknown, then we must use the previous group color
7953
       space or the device process color space */
7954
420k
    if (ptmp->group_color_type == UNKNOWN){
7955
0
        if (pdev->ctx->stack){
7956
            /* Use previous group color space */
7957
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7958
0
        } else {
7959
            /* Use process color space */
7960
0
            group_color_numcomps = pdev->color_info.num_components;
7961
0
        }
7962
0
        switch (group_color_numcomps) {
7963
0
            case 1:
7964
0
                group_color_type = GRAY_SCALE;
7965
0
                break;
7966
0
            case 3:
7967
0
                group_color_type = DEVICE_RGB;
7968
0
                break;
7969
0
            case 4:
7970
0
                group_color_type = DEVICE_CMYK;
7971
0
            break;
7972
0
            default:
7973
                /* We can end up here if we are in a deviceN color space and
7974
                   we have a sep output device */
7975
0
                group_color_type = DEVICEN;
7976
0
            break;
7977
0
         }
7978
420k
    } else {
7979
420k
        group_color_type = ptmp->group_color_type;
7980
420k
        group_color_numcomps = ptmp->group_color_numcomps;
7981
420k
    }
7982
7983
420k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7984
420k
                                               ptmp->iccprofile, true);
7985
420k
    if (group_color_info == NULL)
7986
0
        return gs_error_VMerror;
7987
7988
    /* Note that the soft mask always follows the group color requirements even
7989
       when we have a separable device */
7990
420k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7991
420k
                                        transfer_fn, ptmp->function_is_identity,
7992
420k
                                        ptmp->idle, ptmp->replacing,
7993
420k
                                        ptmp->mask_id, ptmp->subtype,
7994
420k
                                        group_color_numcomps,
7995
420k
                                        ptmp->Background_components,
7996
420k
                                        ptmp->Background,
7997
420k
                                        ptmp->Matte_components,
7998
420k
                                        ptmp->Matte,
7999
420k
                                        ptmp->GrayBackground,
8000
420k
                                        group_color_info);
8001
420k
    if (code < 0)
8002
0
        return code;
8003
8004
420k
    return 0;
8005
420k
}
8006
8007
static  int
8008
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8009
420k
{
8010
420k
    pdf14_device *pdev = (pdf14_device *)dev;
8011
420k
    pdf14_group_color_t *group_color;
8012
420k
    int ok;
8013
420k
    bool has_tags = device_encodes_tags(dev);
8014
8015
420k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8016
420k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8017
#ifdef DEBUG
8018
    pdf14_debug_mask_stack_state(pdev->ctx);
8019
#endif
8020
8021
    /* May need to reset some color stuff related
8022
     * to a mismatch between the Smask color space
8023
     * and the Smask blending space */
8024
420k
    if (pdev->ctx->stack != NULL ) {
8025
420k
        group_color = pdev->ctx->stack->group_color_info;
8026
420k
        if (!(group_color->group_color_mapping_procs == NULL &&
8027
420k
            group_color->group_color_comp_index == NULL)) {
8028
420k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8029
420k
            gx_set_cmap_procs(pgs, dev);
8030
420k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8031
420k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8032
420k
            pdev->color_info.polarity = group_color->polarity;
8033
420k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8034
420k
            if (pdev->num_planar_planes > 0)
8035
30.7k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8036
420k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8037
420k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8038
420k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8039
420k
            pdev->num_std_colorants = group_color->num_std_colorants;
8040
420k
            pdev->color_info.depth = group_color->depth;
8041
420k
            pdev->blend_procs = group_color->blend_procs;
8042
420k
            pdev->ctx->additive = group_color->isadditive;
8043
420k
            pdev->pdf14_procs = group_color->unpack_procs;
8044
420k
            pdev->color_info.max_color = group_color->max_color;
8045
420k
            pdev->color_info.max_gray = group_color->max_gray;
8046
420k
            set_dev_proc(pdev, encode_color, group_color->encode);
8047
420k
            set_dev_proc(pdev, decode_color, group_color->decode);
8048
420k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8049
420k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8050
420k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8051
420k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8052
            /* Take care of the ICC profile */
8053
420k
            if (group_color->icc_profile != NULL) {
8054
420k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8055
420k
                                        -1, "pdf14_end_transparency_mask");
8056
420k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8057
420k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8058
420k
                                         1, "pdf14_end_transparency_mask");
8059
420k
            }
8060
420k
        }
8061
420k
    }
8062
420k
    return ok;
8063
420k
}
8064
8065
static  int
8066
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8067
                                 gx_color_index color,
8068
                                 const gx_device_color *pdc, bool devn)
8069
2.41M
{
8070
2.41M
    pdf14_device *pdev = (pdf14_device *)dev;
8071
2.41M
    pdf14_buf *buf = pdev->ctx->stack;
8072
2.41M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8073
2.41M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8074
159k
        blend_mode == BLEND_MODE_Compatible ||
8075
159k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8076
2.41M
    int i, j, k;
8077
2.41M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8078
2.41M
    byte src[PDF14_MAX_PLANES];
8079
2.41M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8080
2.41M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8081
2.41M
    intptr_t rowstride = buf->rowstride;
8082
2.41M
    intptr_t planestride = buf->planestride;
8083
2.41M
    int num_chan = buf->n_chan;
8084
2.41M
    int num_comp = num_chan - 1;
8085
2.41M
    intptr_t shape_off = num_chan * planestride;
8086
2.41M
    bool has_shape = buf->has_shape;
8087
2.41M
    bool has_alpha_g = buf->has_alpha_g;
8088
2.41M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8089
2.41M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8090
2.41M
                                   (has_shape ? planestride : 0);
8091
2.41M
    bool has_tags = buf->has_tags;
8092
2.41M
    bool additive = pdev->ctx->additive;
8093
2.41M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8094
2.41M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8095
2.41M
    int shift = 8;
8096
2.41M
    byte shape = 0; /* Quiet compiler. */
8097
2.41M
    byte src_alpha;
8098
2.41M
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8099
2.41M
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8100
1.94M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8101
2.41M
    gx_color_index comps;
8102
2.41M
    bool has_backdrop = buf->backdrop != NULL;
8103
8104
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8105
       subtractive) and we are doing overprint with drawn_comps == 0
8106
       then this is a no-operation */
8107
2.41M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8108
0
        return 0;
8109
8110
2.41M
    if (buf->data == NULL)
8111
2
        return 0;
8112
#if 0
8113
    if (sizeof(color) <= sizeof(ulong))
8114
        if_debug6m('v', dev->memory,
8115
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8116
                   x, y, w, h, (ulong)color, num_chan);
8117
    else
8118
        if_debug7m('v', dev->memory,
8119
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8120
                   x, y, w, h,
8121
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8122
                   num_chan);
8123
#endif
8124
    /*
8125
     * Unpack the gx_color_index values.  Complement the components for subtractive
8126
     * color spaces.
8127
     */
8128
2.41M
    if (devn) {
8129
181k
        if (has_tags) {
8130
0
            curr_tag = pdc->tag;
8131
0
        }
8132
181k
        if (additive) {
8133
72.3k
            for (j = 0; j < num_comp; j++) {
8134
54.2k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8135
54.2k
            }
8136
163k
        } else {
8137
818k
            for (j = 0; j < num_comp; j++) {
8138
654k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8139
654k
            }
8140
163k
        }
8141
2.23M
    } else {
8142
2.23M
        if (has_tags) {
8143
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8144
0
        }
8145
2.23M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8146
2.23M
    }
8147
8148
2.41M
    if (!has_tags)
8149
2.41M
        tag_off = 0;
8150
8151
2.41M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8152
2.41M
    if (has_shape) {
8153
295
        shape = (byte)floor (255 * pdev->shape + 0.5);
8154
2.41M
    } else {
8155
2.41M
        shape_off = 0;
8156
2.41M
    }
8157
8158
2.41M
    if (!has_alpha_g)
8159
11
        alpha_g_off = 0;
8160
2.41M
    src_alpha = 255 - src_alpha;
8161
2.41M
    shape = 255 - shape;
8162
8163
    /* Fit the mark into the bounds of the buffer */
8164
2.41M
    if (x < buf->rect.p.x) {
8165
0
        w += x - buf->rect.p.x;
8166
0
        x = buf->rect.p.x;
8167
0
    }
8168
2.41M
    if (y < buf->rect.p.y) {
8169
12
      h += y - buf->rect.p.y;
8170
12
      y = buf->rect.p.y;
8171
12
    }
8172
2.41M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8173
2.41M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8174
    /* Update the dirty rectangle with the mark. */
8175
2.41M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8176
2.41M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8177
2.41M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8178
2.41M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8179
8180
    /* composite with backdrop only. */
8181
2.41M
    if (has_backdrop)
8182
2.41M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8183
11
    else
8184
11
        bline = NULL;
8185
8186
2.41M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8187
8188
5.05M
    for (j = 0; j < h; ++j) {
8189
2.63M
        bg_ptr = bline;
8190
2.63M
        dst_ptr = line;
8191
147M
        for (i = 0; i < w; ++i) {
8192
            /* Complement the components for subtractive color spaces */
8193
144M
            if (has_backdrop) {
8194
144M
                if (additive) {
8195
458M
                    for (k = 0; k < num_comp; ++k)
8196
315M
                        dst[k] = bg_ptr[k * planestride];
8197
143M
                } else {
8198
6.79M
                    for (k = 0; k < num_comp; ++k)
8199
5.43M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8200
1.35M
                }
8201
144M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8202
144M
            }
8203
144M
            if (buf->isolated || !has_backdrop) {
8204
311k
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8205
144M
            } else {
8206
144M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8207
144M
                                            blend_mode, pdev->blend_procs, pdev);
8208
144M
            }
8209
            /* Complement the results for subtractive color spaces */
8210
144M
            if (additive) {
8211
143M
                if (!overprint) {
8212
603M
                    for (k = 0; k < num_chan; ++k)
8213
459M
                        dst_ptr[k * planestride] = dst[k];
8214
143M
                } else {
8215
                    /* Hybrid additive with subtractive spots */
8216
                    /* We may have to do the compatible overprint blending */
8217
8.53k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8218
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8219
0
                            blend_mode, pdev->blend_procs, pdev);
8220
0
                    }
8221
34.1k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8222
25.6k
                        if ((comps & 0x1) != 0) {
8223
25.6k
                            dst_ptr[k * planestride] = dst[k];
8224
25.6k
                        } else {
8225
                            /* Compatible overprint blend result. */
8226
0
                            dst_ptr[k * planestride] = dst2[k];
8227
0
                        }
8228
25.6k
                    }
8229
8.53k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8230
8.53k
                }
8231
143M
            } else {
8232
1.35M
                if (overprint) {
8233
                    /* We may have to do the compatible overprint blending */
8234
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8235
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8236
0
                            blend_mode, pdev->blend_procs, pdev);
8237
0
                    }
8238
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8239
0
                        if ((comps & 0x1) != 0) {
8240
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8241
0
                        } else {
8242
                            /* Compatible overprint blend result. */
8243
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8244
0
                        }
8245
0
                    }
8246
1.35M
                } else {
8247
6.79M
                    for (k = 0; k < num_comp; ++k)
8248
5.43M
                        dst_ptr[k * planestride] = 255 - dst[k];
8249
1.35M
                }
8250
1.35M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8251
1.35M
            }
8252
144M
            if (tag_off) {
8253
                /* If src alpha is 100% then set to curr_tag, else or */
8254
                /* other than Normal BM, we always OR */
8255
0
                if (src[num_comp] == 255 && tag_blend) {
8256
0
                    dst_ptr[tag_off] = curr_tag;
8257
0
                } else {
8258
0
                    dst_ptr[tag_off] |= curr_tag;
8259
0
                }
8260
0
            }
8261
            /* Knockout group alpha and shape too */
8262
144M
            if (alpha_g_off)
8263
144M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8264
144M
            if (shape_off)
8265
62.8k
                dst_ptr[shape_off] = 255 - shape;
8266
144M
            ++dst_ptr;
8267
144M
            if (has_backdrop)
8268
144M
                ++bg_ptr;
8269
144M
        }
8270
2.63M
        bline += rowstride;
8271
2.63M
        line += rowstride;
8272
2.63M
    }
8273
#if 0
8274
/* #if RAW_DUMP */
8275
    /* Dump the current buffer to see what we have. */
8276
    dump_raw_buffer(pdev->ctx->memory,
8277
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8278
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8279
                    pdev->ctx->stack->n_planes,
8280
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8281
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8282
                    pdev->ctx->stack->deep);
8283
    global_index++;
8284
#endif
8285
2.41M
    return 0;
8286
2.41M
}
8287
8288
static  int
8289
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8290
                                   gx_color_index color,
8291
                                   const gx_device_color *pdc, bool devn)
8292
0
{
8293
0
    pdf14_device *pdev = (pdf14_device *)dev;
8294
0
    pdf14_buf *buf = pdev->ctx->stack;
8295
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8296
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8297
0
        blend_mode == BLEND_MODE_Compatible ||
8298
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8299
0
    int i, j, k;
8300
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8301
0
    uint16_t src[PDF14_MAX_PLANES];
8302
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8303
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8304
0
    intptr_t rowstride = buf->rowstride;
8305
0
    intptr_t planestride = buf->planestride;
8306
0
    int num_chan = buf->n_chan;
8307
0
    int num_comp = num_chan - 1;
8308
0
    intptr_t shape_off = num_chan * planestride;
8309
0
    bool has_shape = buf->has_shape;
8310
0
    bool has_alpha_g = buf->has_alpha_g;
8311
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8312
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8313
0
                                   (has_shape ? planestride : 0);
8314
0
    bool has_tags = buf->has_tags;
8315
0
    bool additive = pdev->ctx->additive;
8316
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8317
0
    uint16_t shape = 0; /* Quiet compiler. */
8318
0
    uint16_t src_alpha;
8319
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8320
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8321
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8322
0
    gx_color_index comps;
8323
0
    bool has_backdrop = buf->backdrop != NULL;
8324
8325
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8326
       subtractive) and we are doing overprint with drawn_comps == 0
8327
       then this is a no-operation */
8328
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8329
0
        return 0;
8330
8331
0
    if (buf->data == NULL)
8332
0
        return 0;
8333
#if 0
8334
    if (sizeof(color) <= sizeof(ulong))
8335
        if_debug6m('v', dev->memory,
8336
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8337
                   x, y, w, h, (ulong)color, num_chan);
8338
    else
8339
        if_debug7m('v', dev->memory,
8340
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8341
                   x, y, w, h,
8342
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8343
                   num_chan);
8344
#endif
8345
    /*
8346
     * Unpack the gx_color_index values.  Complement the components for subtractive
8347
     * color spaces.
8348
     */
8349
0
    if (devn) {
8350
0
        if (has_tags) {
8351
0
            curr_tag = pdc->tag;
8352
0
        }
8353
0
        if (additive) {
8354
0
            for (j = 0; j < num_comp; j++) {
8355
0
                src[j] = pdc->colors.devn.values[j];
8356
0
            }
8357
0
        } else {
8358
0
            for (j = 0; j < num_comp; j++) {
8359
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8360
0
            }
8361
0
        }
8362
0
    } else {
8363
0
        if (has_tags) {
8364
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8365
0
        }
8366
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8367
0
    }
8368
8369
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8370
0
    if (has_shape) {
8371
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8372
0
    } else {
8373
0
        shape_off = 0;
8374
0
    }
8375
8376
0
    if (!has_tags) {
8377
0
        tag_off = 0;
8378
0
    }
8379
8380
0
    if (!has_alpha_g)
8381
0
        alpha_g_off = 0;
8382
0
    src_alpha = 65535 - src_alpha;
8383
0
    shape = 65535 - shape;
8384
8385
    /* Fit the mark into the bounds of the buffer */
8386
0
    if (x < buf->rect.p.x) {
8387
0
        w += x - buf->rect.p.x;
8388
0
        x = buf->rect.p.x;
8389
0
    }
8390
0
    if (y < buf->rect.p.y) {
8391
0
      h += y - buf->rect.p.y;
8392
0
      y = buf->rect.p.y;
8393
0
    }
8394
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8395
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8396
    /* Update the dirty rectangle with the mark. */
8397
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8398
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8399
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8400
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8401
8402
8403
    /* composite with backdrop only. */
8404
0
    if (has_backdrop)
8405
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8406
0
    else
8407
0
        bline = NULL;
8408
8409
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8410
0
    planestride >>= 1;
8411
0
    rowstride >>= 1;
8412
0
    alpha_g_off >>= 1;
8413
0
    shape_off >>= 1;
8414
0
    tag_off >>= 1;
8415
8416
0
    for (j = 0; j < h; ++j) {
8417
0
        bg_ptr = bline;
8418
0
        dst_ptr = line;
8419
0
        for (i = 0; i < w; ++i) {
8420
            /* Complement the components for subtractive color spaces */
8421
0
            if (has_backdrop) {
8422
0
                if (additive) {
8423
0
                    for (k = 0; k < num_comp; ++k)
8424
0
                        dst[k] = bg_ptr[k * planestride];
8425
0
                } else {
8426
0
                    for (k = 0; k < num_comp; ++k)
8427
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8428
0
                }
8429
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8430
0
            }
8431
0
            if (buf->isolated || !has_backdrop) {
8432
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8433
0
            } else {
8434
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8435
0
                                              blend_mode, pdev->blend_procs, pdev);
8436
0
            }
8437
            /* Complement the results for subtractive color spaces */
8438
0
            if (additive) {
8439
0
                if (!overprint) {
8440
0
                    for (k = 0; k < num_chan; ++k)
8441
0
                        dst_ptr[k * planestride] = dst[k];
8442
0
                } else {
8443
                    /* Hybrid additive with subtractive spots */
8444
                    /* We may have to do the compatible overprint blending */
8445
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8446
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8447
0
                            blend_mode, pdev->blend_procs, pdev);
8448
0
                    }
8449
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8450
0
                        if ((comps & 0x1) != 0) {
8451
0
                            dst_ptr[k * planestride] = dst[k];
8452
0
                        } else {
8453
                            /* Compatible overprint blend result. */
8454
0
                            dst_ptr[k * planestride] = dst2[k];
8455
0
                        }
8456
0
                    }
8457
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8458
0
                }
8459
0
            } else {
8460
0
                if (overprint) {
8461
                    /* We may have to do the compatible overprint blending */
8462
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8463
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8464
0
                            blend_mode, pdev->blend_procs, pdev);
8465
0
                    }
8466
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8467
0
                        if ((comps & 0x1) != 0) {
8468
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8469
0
                        } else {
8470
                            /* Compatible overprint blend result. */
8471
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8472
0
                        }
8473
0
                    }
8474
0
                } else {
8475
0
                    for (k = 0; k < num_comp; ++k)
8476
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8477
0
                }
8478
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8479
0
            }
8480
0
            if (tag_off) {
8481
                /* FIXME: As we are knocking out, possibly, we should be
8482
                 * always overwriting tag values here? */
8483
                /* If src alpha is 100% then set to curr_tag, else or */
8484
                /* other than Normal BM, we always OR */
8485
0
                if (src[num_comp] == 65535 && tag_blend) {
8486
0
                    dst_ptr[tag_off] = curr_tag;
8487
0
                } else {
8488
0
                    dst_ptr[tag_off] |= curr_tag;
8489
0
                }
8490
0
            }
8491
            /* Knockout group alpha and shape too */
8492
0
            if (alpha_g_off)
8493
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8494
0
            if (shape_off)
8495
0
                dst_ptr[shape_off] = 65535 - shape;
8496
0
            ++dst_ptr;
8497
0
            if (has_backdrop)
8498
0
                ++bg_ptr;
8499
0
        }
8500
0
        bline += rowstride;
8501
0
        line += rowstride;
8502
0
    }
8503
#if 0
8504
/* #if RAW_DUMP */
8505
    /* Dump the current buffer to see what we have. */
8506
    dump_raw_buffer(pdev->ctx->memory,
8507
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8508
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8509
                    pdev->ctx->stack->n_planes,
8510
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8511
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8512
                    pdev->ctx->stack->deep);
8513
    global_index++;
8514
#endif
8515
0
    return 0;
8516
0
}
8517
8518
static  int
8519
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8520
                                    gx_color_index color,
8521
                                    const gx_device_color *pdc, bool devn)
8522
2.41M
{
8523
2.41M
    pdf14_device *pdev = (pdf14_device *)dev;
8524
2.41M
    pdf14_buf *buf = pdev->ctx->stack;
8525
8526
2.41M
    if (buf->deep)
8527
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8528
2.41M
    else
8529
2.41M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8530
2.41M
}
8531
8532
/**
8533
 * Here we have logic to override the cmap_procs with versions that
8534
 * do not apply the transfer function. These copies should track the
8535
 * versions in gxcmap.c.
8536
 **/
8537
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8538
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8539
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8540
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8541
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8542
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8543
8544
static  const gx_color_map_procs pdf14_cmap_many = {
8545
     pdf14_cmap_gray_direct,
8546
     pdf14_cmap_rgb_direct,
8547
     pdf14_cmap_cmyk_direct,
8548
     pdf14_cmap_separation_direct,
8549
     pdf14_cmap_devicen_direct,
8550
     pdf14_cmap_is_halftoned
8551
    };
8552
8553
/**
8554
 * Note: copied from gxcmap.c because it's inlined.
8555
 **/
8556
static  inline void
8557
map_components_to_colorants(const frac * pcc,
8558
                            const gs_devicen_color_map * pcolor_component_map,
8559
                            frac * plist,
8560
                            int num_additives)
8561
1.16M
{
8562
1.16M
    int i = pcolor_component_map->num_colorants - 1;
8563
1.16M
    int pos;
8564
8565
    /* Clear all output colorants first */
8566
5.83M
    for (; i >= num_additives; i--) {
8567
4.66M
        plist[i] = frac_0;
8568
4.66M
    }
8569
1.16M
    for (; i >= 0; i--) {
8570
2.90k
        plist[i] = frac_1;
8571
2.90k
    }
8572
    /* Map color components into output list */
8573
2.49M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8574
1.32M
        pos = pcolor_component_map->color_map[i];
8575
1.32M
        if (pos >= 0) {
8576
1.32M
            if (pos < num_additives)
8577
0
                plist[pos] = frac_1 - pcc[i];
8578
1.32M
            else
8579
1.32M
                plist[pos] = pcc[i];
8580
1.32M
        }
8581
1.32M
    }
8582
1.16M
}
8583
8584
/* See Section 7.6.4 of PDF 1.7 spec */
8585
static inline bool
8586
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8587
23.8M
{
8588
23.8M
    if (pgs->fillconstantalpha != 1.0 ||
8589
23.8M
        pgs->strokeconstantalpha != 1.0 ||
8590
23.8M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8591
159k
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8592
187k
        return 0;
8593
8594
    /* We can only be opaque if we're not in an SMask. */
8595
23.6M
    return dev_proc(pdev, dev_spec_op)(pdev,
8596
23.6M
                                       gxdso_in_smask,
8597
23.6M
                                       NULL, 0) != 1;
8598
23.8M
}
8599
8600
static  void
8601
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8602
                       gx_device * dev, gs_color_select_t select)
8603
9.10M
{
8604
9.10M
    int i, nc, ncomps;
8605
9.10M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8606
9.10M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8607
9.10M
    gx_color_index color;
8608
9.10M
    gx_device *trans_device;
8609
9.10M
    const gx_device *map_dev;
8610
9.10M
    const gx_cm_color_map_procs *procs;
8611
8612
    /* If trans device is set, we need to use its procs. */
8613
9.10M
    if (pgs->trans_device != NULL) {
8614
4.62M
        trans_device = pgs->trans_device;
8615
4.62M
    } else {
8616
4.47M
        trans_device = dev;
8617
4.47M
    }
8618
9.10M
    ncomps = trans_device->color_info.num_components;
8619
8620
    /* map to the color model */
8621
9.10M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8622
9.10M
    procs->map_gray(map_dev, gray, cm_comps);
8623
8624
9.10M
    nc = ncomps;
8625
9.10M
    if (device_encodes_tags(trans_device))
8626
0
        nc--;
8627
9.10M
    if (pdf14_state_opaque(trans_device, pgs)) {
8628
9.88M
        for (i = 0; i < nc; i++)
8629
4.94M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8630
4.93M
    } else {
8631
8.33M
        for (i = 0; i < nc; i++)
8632
4.16M
            cv[i] = frac2cv(cm_comps[i]);
8633
4.16M
    }
8634
    /* Copy tags untransformed. */
8635
9.10M
    if (nc < ncomps)
8636
0
        cv[nc] = dev->graphics_type_tag;
8637
8638
    /* If output device supports devn, we need to make sure we send it the
8639
       proper color type.  We now support Gray + spots as devn colors */
8640
9.10M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8641
389k
        for (i = 0; i < ncomps; i++)
8642
194k
            pdc->colors.devn.values[i] = cv[i];
8643
12.4M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8644
12.2M
            pdc->colors.devn.values[i] = 0;
8645
194k
        pdc->type = gx_dc_type_devn;
8646
8.91M
    } else {
8647
        /* encode as a color index */
8648
8.91M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8649
        /* check if the encoding was successful; we presume failure is rare */
8650
8.91M
        if (color != gx_no_color_index)
8651
8.91M
            color_set_pure(pdc, color);
8652
8.91M
    }
8653
9.10M
}
8654
8655
static  void
8656
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8657
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8658
3.47M
{
8659
3.47M
    int i, nc, ncomps;
8660
3.47M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8661
3.47M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8662
3.47M
    gx_color_index color;
8663
3.47M
    gx_device *trans_device;
8664
3.47M
    const gx_device *map_dev;
8665
3.47M
    const gx_cm_color_map_procs *procs;
8666
8667
    /* If trans device is set, we need to use its procs. */
8668
3.47M
    if (pgs->trans_device != NULL){
8669
133k
        trans_device = pgs->trans_device;
8670
3.34M
    } else {
8671
3.34M
        trans_device = dev;
8672
3.34M
    }
8673
3.47M
    ncomps = trans_device->color_info.num_components;
8674
    /* map to the color model */
8675
3.47M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8676
3.47M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8677
8678
3.47M
    nc = ncomps;
8679
3.47M
    if (device_encodes_tags(trans_device))
8680
0
        nc--;
8681
3.47M
    if (pdf14_state_opaque(trans_device, pgs)) {
8682
8.01M
        for (i = 0; i < nc; i++)
8683
6.01M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8684
2.00M
    } else {
8685
5.89M
        for (i = 0; i < nc; i++)
8686
4.41M
            cv[i] = frac2cv(cm_comps[i]);
8687
1.47M
    }
8688
    /* Copy tags untransformed. */
8689
3.47M
    if (nc < ncomps)
8690
0
        cv[nc] = dev->graphics_type_tag;
8691
8692
    /* If output device supports devn, we need to make sure we send it the
8693
       proper color type.  We now support RGB + spots as devn colors */
8694
3.47M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8695
11.6M
        for (i = 0; i < ncomps; i++)
8696
8.72M
            pdc->colors.devn.values[i] = cv[i];
8697
180M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8698
177M
            pdc->colors.devn.values[i] = 0;
8699
2.90M
        pdc->type = gx_dc_type_devn;
8700
2.90M
    } else {
8701
        /* encode as a color index */
8702
574k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8703
        /* check if the encoding was successful; we presume failure is rare */
8704
574k
        if (color != gx_no_color_index)
8705
574k
            color_set_pure(pdc, color);
8706
574k
    }
8707
3.47M
}
8708
8709
static  void
8710
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8711
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8712
     const gs_color_space *pcs)
8713
11.2M
{
8714
11.2M
    int i, nc, ncomps;
8715
11.2M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8716
11.2M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8717
11.2M
    gx_color_index color;
8718
11.2M
    gx_device *trans_device;
8719
11.2M
    const gx_device *map_dev;
8720
11.2M
    const gx_cm_color_map_procs *procs;
8721
8722
8723
    /* If trans device is set, we need to use its procs. */
8724
11.2M
    if (pgs->trans_device != NULL){
8725
8.76M
        trans_device = pgs->trans_device;
8726
8.76M
    } else {
8727
2.48M
        trans_device = dev;
8728
2.48M
    }
8729
11.2M
    ncomps = trans_device->color_info.num_components;
8730
8731
    /* Map to the color model. Transfer function is only used
8732
       if we are drawing with an opaque color. */
8733
11.2M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8734
11.2M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8735
8736
11.2M
    nc = ncomps;
8737
11.2M
    if (device_encodes_tags(trans_device))
8738
0
        nc--;
8739
11.2M
    if (pdf14_state_opaque(trans_device, pgs)) {
8740
49.9M
        for (i = 0; i < nc; i++)
8741
39.9M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8742
9.98M
    } else {
8743
6.35M
        for (i = 0; i < nc; i++)
8744
5.08M
            cv[i] = frac2cv(cm_comps[i]);
8745
1.27M
    }
8746
    /* Copy tags untransformed. */
8747
11.2M
    if (nc < ncomps)
8748
0
        cv[nc] = dev->graphics_type_tag;
8749
8750
    /* if output device supports devn, we need to make sure we send it the
8751
       proper color type */
8752
11.2M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8753
42.1M
        for (i = 0; i < ncomps; i++)
8754
33.7M
            pdc->colors.devn.values[i] = cv[i];
8755
514M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8756
505M
            pdc->colors.devn.values[i] = 0;
8757
8.42M
        pdc->type = gx_dc_type_devn;
8758
8.42M
    } else {
8759
        /* encode as a color index */
8760
2.82M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8761
        /* check if the encoding was successful; we presume failure is rare */
8762
2.82M
        if (color != gx_no_color_index)
8763
2.82M
            color_set_pure(pdc, color);
8764
2.82M
    }
8765
11.2M
}
8766
8767
static int
8768
pdf14_get_num_spots(gx_device * dev)
8769
1.16M
{
8770
1.16M
    cmm_dev_profile_t *dev_profile;
8771
1.16M
    cmm_profile_t *icc_profile;
8772
1.16M
    gsicc_rendering_param_t render_cond;
8773
8774
1.16M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8775
1.16M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8776
1.16M
        &render_cond);
8777
1.16M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8778
1.16M
}
8779
8780
static  void
8781
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8782
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8783
1.45k
{
8784
1.45k
    int i, nc, ncomps = dev->color_info.num_components;
8785
1.45k
    int num_spots = pdf14_get_num_spots(dev);
8786
1.45k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8787
1.45k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8788
1.45k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8789
1.45k
    gx_color_index color;
8790
1.45k
    int n = 0;
8791
8792
1.45k
    nc = ncomps;
8793
1.45k
    if (device_encodes_tags(dev))
8794
0
        nc--;
8795
8796
1.45k
    n = additive ? nc - num_spots : 0;
8797
1.45k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8798
0
        frac comp_value = all;
8799
8800
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8801
0
            cm_comps[i] = comp_value;
8802
        /*
8803
         * Invert the photometric interpretation for additive
8804
         * color spaces because separations are always subtractive.
8805
         */
8806
0
        if (additive)
8807
0
            comp_value = frac_1 - comp_value;
8808
        /* Use the "all" value for all components */
8809
0
        for (; i >= 0; i--)
8810
0
            cm_comps[i] = comp_value;
8811
1.45k
    } else {
8812
1.45k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8813
8814
1.45k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8815
0
            color_set_null(pdc);
8816
0
            return;
8817
0
        }
8818
8819
        /* map to the color model */
8820
2.90k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8821
1.45k
            comp_value[i] = all;
8822
1.45k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8823
1.45k
    }
8824
8825
    /* apply the transfer function(s); convert to color values */
8826
4.36k
    for (i = 0; i < n; i++)
8827
2.90k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8828
4.35k
    for (; i < nc; i++)
8829
2.90k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8830
8831
    /* Copy tags untransformed. */
8832
1.45k
    if (nc < ncomps)
8833
0
        cv[nc] = dev->graphics_type_tag;
8834
8835
    /* if output device supports devn, we need to make sure we send it the
8836
       proper color type */
8837
1.45k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8838
7.26k
        for (i = 0; i < ncomps; i++)
8839
5.81k
            pdc->colors.devn.values[i] = cv[i];
8840
88.6k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8841
87.1k
            pdc->colors.devn.values[i] = 0;
8842
1.45k
        pdc->type = gx_dc_type_devn;
8843
1.45k
    } else {
8844
        /* encode as a color index */
8845
0
        color = dev_proc(dev, encode_color)(dev, cv);
8846
        /* check if the encoding was successful; we presume failure is rare */
8847
0
        if (color != gx_no_color_index)
8848
0
            color_set_pure(pdc, color);
8849
0
    }
8850
1.45k
}
8851
8852
static  void
8853
pdf14_cmap_devicen_direct(const frac * pcc,
8854
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8855
    gs_color_select_t select, const gs_color_space *pcs)
8856
1.16M
{
8857
1.16M
    int i, nc, ncomps = dev->color_info.num_components;
8858
1.16M
    int num_spots = pdf14_get_num_spots(dev);
8859
1.16M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8860
1.16M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8861
1.16M
    gx_color_index color;
8862
1.16M
    gx_device *trans_device;
8863
1.16M
    int num_add_colorants = 0;
8864
8865
     /*  We may be coming from the clist writer which often forwards us the
8866
         target device. If this occurs we actually need to get to the color
8867
         space defined by the transparency group and we use the operators
8868
         defined by the transparency device to do the job.
8869
       */
8870
1.16M
    if (pgs->trans_device != NULL){
8871
1.16M
        trans_device = pgs->trans_device;
8872
1.16M
    } else {
8873
0
        trans_device = dev;
8874
0
    }
8875
1.16M
    ncomps = trans_device->color_info.num_components;
8876
1.16M
    nc = ncomps;
8877
1.16M
    if (device_encodes_tags(trans_device))
8878
0
        nc--;
8879
8880
1.16M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8881
0
        num_add_colorants = nc - num_spots;
8882
8883
    /* map to the color model */
8884
1.16M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8885
8886
    /* apply the transfer function(s); convert to color values */
8887
    /* The additive ones (if there are any) need to be inverted. */
8888
1.16M
    for (i = 0; i < num_add_colorants; i++)
8889
1.16M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8890
5.82M
    for (; i < nc; i++)
8891
4.66M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8892
    /* Copy tags untransformed. */
8893
1.16M
    if (nc < ncomps)
8894
0
        cv[nc] = dev->graphics_type_tag;
8895
8896
    /* if output device supports devn, we need to make sure we send it the
8897
       proper color type */
8898
1.16M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8899
517k
        for (i = 0; i < ncomps; i++)
8900
414k
            pdc->colors.devn.values[i] = cv[i];
8901
6.31M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8902
6.21M
            pdc->colors.devn.values[i] = 0;
8903
103k
        pdc->type = gx_dc_type_devn;
8904
1.06M
    } else {
8905
    /* encode as a color index */
8906
1.06M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8907
        /* check if the encoding was successful; we presume failure is rare */
8908
1.06M
        if (color != gx_no_color_index)
8909
1.06M
            color_set_pure(pdc, color);
8910
1.06M
    }
8911
1.16M
}
8912
8913
static  bool
8914
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8915
75.6k
{
8916
75.6k
    return false;
8917
75.6k
}
8918
8919
static  const gx_color_map_procs *
8920
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8921
1.74M
{
8922
    /* The pdf14 marking device itself is always continuous tone. */
8923
1.74M
    return &pdf14_cmap_many;
8924
1.74M
}
8925
8926
static int
8927
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8928
                  void *data, int size)
8929
101M
{
8930
101M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8931
8932
101M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8933
748k
        return 1;
8934
100M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8935
10.9k
        return 1;
8936
100M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8937
907
        if (data != NULL && size == sizeof(gx_device *))
8938
318
            *(gx_device **)data = pdev;
8939
907
        return 1;
8940
907
    }
8941
100M
    if (dev_spec_op == gxdso_device_child) {
8942
2.05k
        pdf14_device *dev = (pdf14_device *)pdev;
8943
2.05k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8944
2.05k
        if (d->target == pdev) {
8945
2.05k
            d->target = dev->target;
8946
2.05k
            return 1;
8947
2.05k
        }
8948
2.05k
    }
8949
100M
    if (dev_spec_op == gxdso_supports_devn
8950
51.3M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8951
51.3M
        cmm_dev_profile_t *dev_profile;
8952
51.3M
        int code;
8953
51.3M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8954
51.3M
        if (code == 0) {
8955
51.3M
            return dev_profile->supports_devn;
8956
51.3M
        } else {
8957
0
            return 0;
8958
0
        }
8959
51.3M
    }
8960
49.1M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8961
309k
        pdf14_device* dev = (pdf14_device*)pdev;
8962
8963
309k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8964
309k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8965
123k
            return 1;
8966
185k
        return 0;
8967
309k
    }
8968
48.8M
    if (dev_spec_op == gxdso_is_encoding_direct)
8969
1.42M
        return 1;
8970
8971
    /* We don't want to pass on these spec_ops either, because the child might respond
8972
     * with an inappropriate response when the PDF14 device is active. For example; the
8973
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8974
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8975
     */
8976
47.3M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8977
344k
        return 0;
8978
47.0M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8979
1.11M
        return 0;
8980
45.9M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8981
10.6k
        return 0;
8982
45.9M
    if(dev_spec_op == gxdso_supports_hlcolor)
8983
967
        return 0;
8984
45.9M
    if(dev_spec_op == gxdso_pattern_can_accum)
8985
84.2k
        return 0;
8986
45.8M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8987
1.67k
        return 0;
8988
45.8M
    if (dev_spec_op == gxdso_overprint_active) {
8989
3.41M
        if (p14dev->pclist_device != NULL) {
8990
3.40M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8991
3.40M
        } else {
8992
9.83k
            return p14dev->overprint || p14dev->stroke_overprint;
8993
9.83k
        }
8994
3.41M
    }
8995
8996
    /* These should be coming only from the abuf device
8997
       during fill-stroke operation. Any other use will
8998
       result in bad things. */
8999
42.4M
    if (dev_spec_op == gxdso_abuf_optrans)
9000
0
    {
9001
0
        int ret = p14dev->op_state;
9002
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
9003
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
9004
0
        const gs_gstate* cpgs = state_data->pgs;
9005
0
        union {
9006
0
            const gs_gstate* cpgs;
9007
0
            gs_gstate* pgs;
9008
0
        } const_breaker;
9009
0
        gs_gstate* pgs;
9010
0
        int code = 0;
9011
0
        int code1 = 0;
9012
9013
        /* A compile time assert to check our storage types are appropriately sized. */
9014
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9015
9016
        /* I don't really like this, but there is no easy way around it. The device
9017
           in the pgs needs to be the pdf14 device to ensure that the compositor
9018
           actions occur with the gs_transparency calls. We have to call at that
9019
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9020
           operations are invoked. We could change the gs_trans calls to take a
9021
           device to avoid this dance but that changes the device procs. */
9022
0
        gx_device *curr_dev;
9023
9024
0
        const_breaker.cpgs = cpgs;
9025
0
        pgs = const_breaker.pgs;
9026
0
        curr_dev = pgs->device;
9027
0
        pgs->device = pdev;
9028
9029
0
        switch (state_data->op_trans) {
9030
9031
0
            case OP_FS_TRANS_PREFILL:
9032
0
                pdf14_abuf->orig_state = p14dev->op_state;
9033
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9034
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9035
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9036
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9037
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9038
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9039
0
                    pdf14_abuf->group_needed = false;
9040
0
                else
9041
0
                    pdf14_abuf->group_needed = true;
9042
9043
0
                if (pdf14_abuf->group_needed) {
9044
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9045
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9046
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9047
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9048
0
                        state_data->alpha_buf_path_scale);
9049
0
                    if (code < 0)
9050
0
                        goto cleanup;
9051
0
                    if (pdf14_abuf->path_empty)
9052
0
                        pdf14_abuf->group_needed = 0;
9053
0
                }
9054
0
                code = gs_update_trans_marking_params(pgs);
9055
0
                break;
9056
9057
0
            case OP_FS_TRANS_PRESTROKE:
9058
0
                if (pdf14_abuf->group_needed) {
9059
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9060
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9061
0
                }
9062
0
                code = gs_update_trans_marking_params(pgs);
9063
0
                break;
9064
9065
0
            case OP_FS_TRANS_POSTSTROKE:
9066
0
                if (pdf14_abuf->group_needed) {
9067
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9068
0
                                                        pdf14_abuf->op_ca_eq_CA);
9069
0
                }
9070
0
                if (code >= 0)
9071
0
                    code = gs_update_trans_marking_params(pgs);
9072
9073
                /* fallthrough */
9074
9075
0
            case OP_FS_TRANS_CLEANUP:
9076
0
cleanup:
9077
0
                if (pdf14_abuf->group_needed) {
9078
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9079
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, pdf14_abuf->orig_state);
9080
0
                    if (code1 < 0)
9081
0
                        code = gs_note_error(gs_error_Fatal);
9082
0
                }
9083
0
                break;
9084
0
        }
9085
0
        pgs->device = curr_dev;
9086
9087
0
        return (code < 0) ? code : ret;
9088
0
    }
9089
9090
42.4M
    if (dev_spec_op == gxdso_in_smask_construction)
9091
3.55M
        return p14dev->in_smask_construction > 0;
9092
38.8M
    if (dev_spec_op == gxdso_in_smask)
9093
24.6M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9094
14.2M
    if (dev_spec_op == gxdso_replacecolor) {
9095
13.9M
        gx_device *tdev = p14dev->target;
9096
13.9M
        cmm_dev_profile_t *tdev_profile;
9097
13.9M
        int code;
9098
9099
         /* If in a softmask or softmask construction do not allow
9100
           replacement. */
9101
13.9M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9102
246k
            return 0;
9103
9104
        /* If the target CS is different than the pdf14 profile add this information
9105
           for the target device that will be handling the replacement. While not
9106
           perfect this at least lets you do the replacehment and have some information
9107
           about what the situation is. */
9108
13.7M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9109
13.7M
        if (code != 0)
9110
0
            return 0;
9111
9112
13.7M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9113
13.7M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9114
3.03M
            color_replace_t* replace_data = (color_replace_t*)data;
9115
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9116
               color remap operation. */
9117
3.03M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9118
3.03M
        }
9119
9120
        /* Pass on to target device */
9121
13.7M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9122
13.7M
    }
9123
214k
    if (dev_spec_op == gxdso_device_insert_child) {
9124
129
        gx_device *tdev = p14dev->target;
9125
129
        p14dev->target = (gx_device *)data;
9126
129
        rc_increment(p14dev->target);
9127
129
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9128
129
        return 0;
9129
129
    }
9130
213k
    if (dev_spec_op == gxdso_interpolate_threshold)
9131
5.14k
        return p14dev->interpolate_threshold;
9132
9133
208k
    if (dev_spec_op == gxdso_overprintsim_state) {
9134
5.12k
        unsigned char *data_uchar = (unsigned char *) data;
9135
5.12k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9136
5.12k
        if (p14dev->ctx != NULL)
9137
9
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9138
5.11k
        else
9139
5.11k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9140
5.12k
        return 1;
9141
5.12k
    }
9142
9143
203k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9144
208k
}
9145
9146
/* Needed to set color monitoring in the target device's profile */
9147
int
9148
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9149
0
{
9150
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9151
0
    gx_device *targ = p14dev->target;
9152
0
    cmm_dev_profile_t *dev_profile;
9153
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9154
9155
0
    if (code == 0)
9156
0
        dev_profile->pageneutralcolor = monitoring;
9157
0
    return code;
9158
0
}
9159
9160
static int
9161
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9162
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9163
1.10M
{
9164
1.10M
    pdf14_device dev_proto;
9165
1.10M
    pdf14_device * p14dev;
9166
1.10M
    int code;
9167
1.10M
    bool has_tags;
9168
1.10M
    cmm_profile_t *icc_profile;
9169
1.10M
    gsicc_rendering_param_t render_cond;
9170
1.10M
    cmm_dev_profile_t *dev_profile;
9171
1.10M
    uchar k;
9172
1.10M
    int max_bitmap;
9173
1.10M
    bool use_pdf14_accum = false;
9174
1.10M
    bool deep;
9175
9176
    /* Guard against later seg faults, this should not be possible */
9177
1.10M
    if (target == NULL)
9178
0
        return gs_throw_code(gs_error_Fatal);
9179
9180
1.10M
    has_tags = device_encodes_tags(target);
9181
1.10M
    deep = device_is_deep(target);
9182
1.10M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9183
1.10M
                                 target->space_params.MaxBitmap;
9184
    /* If the device is not a printer class device, it won't support saved-pages */
9185
    /* and so we may need to make a clist device in order to prevent very large  */
9186
    /* or high resolution pages from having allocation problems.                 */
9187
    /* We use MaxBitmap to decide when a clist is needed.*/
9188
1.10M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9189
5.79k
        gx_device_is_pattern_clist(target) == 0 &&
9190
5.79k
        gx_device_is_pattern_accum(target) == 0 &&
9191
3.55k
        gs_device_is_memory(target) == 0) {
9192
9193
3.55k
        uint32_t pdf14_trans_buffer_size =
9194
3.55k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9195
3.55k
                                         target->color_info.num_components,
9196
3.55k
                                         deep ? 16 : 8) >> 3);
9197
9198
3.55k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9199
3.55k
                pdf14_trans_buffer_size *= target->height;
9200
0
        else
9201
0
                max_bitmap = 0;     /* Force decision to clist */
9202
3.55k
        if (pdf14_trans_buffer_size > max_bitmap)
9203
3.30k
            use_pdf14_accum = true;
9204
3.55k
    }
9205
1.10M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9206
1.10M
    if (code < 0)
9207
0
        return code;
9208
1.10M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9209
1.10M
                          &render_cond);
9210
1.10M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9211
9212
    /* Get the proto from which to copy the device. This will always
9213
     * ignore tags! */
9214
1.10M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9215
1.10M
                                  pdf14pct, use_pdf14_accum);
9216
1.10M
    if (code < 0)
9217
0
        return code;
9218
1.10M
    code = gs_copydevice((gx_device **) &p14dev,
9219
1.10M
                         (const gx_device *) &dev_proto, mem);
9220
1.10M
    if (code < 0)
9221
0
        return code;
9222
9223
1.10M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9224
9225
    /* Copying the params across will add tags to the colorinfo as required. */
9226
1.10M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9227
1.10M
    if (code < 0)
9228
0
        return code;
9229
9230
1.10M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9231
1.10M
    p14dev->pad = target->pad;
9232
1.10M
    p14dev->log2_align_mod = target->log2_align_mod;
9233
1.10M
    if (target->num_planar_planes == 0)
9234
1.03M
        p14dev->num_planar_planes = 0;
9235
73.3k
    else
9236
73.3k
        p14dev->num_planar_planes = p14dev->color_info.num_components;
9237
1.10M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9238
9239
1.10M
    p14dev->alpha = 1.0;
9240
1.10M
    p14dev->shape = 1.0;
9241
1.10M
    p14dev->opacity = 1.0;
9242
1.10M
    p14dev->fillconstantalpha = 1.0;
9243
1.10M
    p14dev->strokeconstantalpha = 1.0;
9244
9245
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9246
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9247
       do the mapping to the NCLR profile when the put_image occurs */
9248
1.10M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9249
1.10M
        icc_profile->data_cs == gsNCHANNEL) {
9250
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9251
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9252
0
            -1, "gs_pdf14_device_push");
9253
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9254
1.10M
    } else {
9255
        /* If the target profile was CIELAB (and we are not using a blend CS),
9256
           then overide with default RGB for proper blending.  During put_image
9257
           we will convert from RGB to CIELAB.  Need to check that we have a
9258
           default profile, which will not be the case if we are coming from the clist reader */
9259
1.10M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9260
0
            && pgs->icc_manager->default_rgb != NULL &&
9261
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9262
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9263
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9264
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9265
0
                -1, "gs_pdf14_device_push");
9266
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9267
0
        }
9268
1.10M
    }
9269
9270
1.10M
    if (pdf14pct->params.overprint_sim_push &&
9271
0
        pdf14pct->params.num_spot_colors_int > 0) {
9272
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9273
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9274
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9275
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9276
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9277
0
    }
9278
9279
    /* The number of color planes should not exceed that of the target.
9280
       Unless we are using a blend CS */
9281
1.10M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9282
1.10M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev)) {
9283
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9284
0
            if (p14dev->num_planar_planes != 0)
9285
0
                p14dev->num_planar_planes = p14dev->color_info.num_components;
9286
0
        }
9287
1.10M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9288
73.2k
            p14dev->color_info.max_components = target->color_info.max_components;
9289
1.10M
    }
9290
1.10M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9291
    /* If we have a tag device then go ahead and do a special encoder
9292
       decoder for the pdf14 device to make sure we maintain this
9293
       information in the encoded color information.  We could use
9294
       the target device's methods but the PDF14 device has to maintain
9295
       8 bit color always and we could run into other issues if the number
9296
       of colorants became large.  If we need to do compressed color with
9297
       tags that will be a special project at that time */
9298
1.10M
    if (deep) {
9299
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9300
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9301
0
    }
9302
1.10M
    if (has_tags) {
9303
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9304
0
    }
9305
    /* if the device has separations already defined (by SeparationOrderNames) */
9306
    /* we need to copy them (allocating new names) so the colorants are in the */
9307
    /* same order as the target device.                                        */
9308
1.10M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9309
73.3k
        code = devn_copy_params(target, (gx_device *)p14dev);
9310
73.3k
        if (code < 0) {
9311
50
            *pdev = NULL;
9312
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9313
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9314
50
            return code;
9315
50
        }
9316
73.3k
    }
9317
    /* by definition pdf14_encode _is_ standard */
9318
1.10M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9319
1.10M
    gx_device_fill_in_procs((gx_device *)p14dev);
9320
1.10M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9321
1.10M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9322
1.10M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9323
9324
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9325
3.54M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9326
2.43M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9327
2.43M
        p14dev->color_info.comp_shift[k] =
9328
2.43M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9329
2.43M
    }
9330
1.10M
    if (use_pdf14_accum) {
9331
        /* we will disable this device later, but we don't want to allocate large buffers */
9332
3.30k
        p14dev->width = 1;
9333
3.30k
        p14dev->height = 1;
9334
3.30k
    }
9335
9336
1.10M
    p14dev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
9337
1.10M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9338
1.10M
    *pdev = (gx_device *) p14dev;
9339
1.10M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9340
1.10M
    p14dev->color_model_stack = NULL;
9341
9342
    /* In case we have alphabits set */
9343
1.10M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9344
9345
1.10M
    if (pdf14pct->params.is_pattern) {
9346
7.07k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9347
7.07k
        if (code < 0) {
9348
0
            *pdev = NULL;
9349
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9350
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9351
0
            return code;
9352
0
        }
9353
7.07k
    }
9354
9355
    /* We should never go into this when using a blend color space */
9356
1.10M
    if (use_pdf14_accum) {
9357
3.30k
        const gx_device_pdf14_accum *accum_proto = NULL;
9358
3.30k
        gx_device *new_target = NULL;
9359
3.30k
        gx_device_color pdcolor;
9360
3.30k
        frac pconc_white = frac_1;
9361
3.30k
        bool UsePlanarBuffer = false;
9362
9363
3.30k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9364
9365
        /* get the prototype for the accumulator device based on colorspace */
9366
3.30k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9367
660
            case 1:
9368
660
                accum_proto = &pdf14_accum_Gray;
9369
660
                break;
9370
2.64k
            case 3:
9371
2.64k
                accum_proto = &pdf14_accum_RGB;
9372
2.64k
                break;
9373
0
            case 4:
9374
0
                accum_proto = &pdf14_accum_CMYK;
9375
0
                break;
9376
0
            default:
9377
0
                accum_proto = &pdf14_accum_CMYKspot;
9378
0
                UsePlanarBuffer = true;
9379
3.30k
        }
9380
3.30k
        if (accum_proto == NULL ||
9381
3.30k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9382
0
            goto no_clist_accum;
9383
9384
3.30k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9385
        /* Fill in values from the target device before opening */
9386
3.30k
        new_target->color_info = p14dev->color_info;
9387
3.30k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9388
3.30k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9389
3.30k
        set_linear_color_bits_mask_shift(new_target);
9390
3.30k
        gs_pdf14_device_copy_params(new_target, target);
9391
3.30k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9392
3.30k
        gx_device_fill_in_procs(new_target);
9393
9394
3.30k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9395
3.30k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9396
3.30k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9397
9398
        /* This is used to mark the various internal subclass devices as having already
9399
         * been pushed, so that opening the device won't result in us trying to push
9400
         * them again, which leads to trouble.
9401
         */
9402
3.30k
        code = mark_internal_subclass_devices(new_target);
9403
3.30k
        if (code < 0)
9404
0
            return code;
9405
9406
        /* if the device has separations already defined (by SeparationOrderNames) */
9407
        /* we need to copy them (allocating new names) so the colorants are in the */
9408
        /* same order as the target device.                                        */
9409
3.30k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9410
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9411
0
            if (code < 0)
9412
0
                return code;
9413
0
        }
9414
        /* UsePlanarBuffer is true in case this is CMYKspot */
9415
3.30k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9416
3.30k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9417
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9418
0
            goto no_clist_accum;
9419
0
        }
9420
        /* Do the initial fillpage into the pdf14-accum device we just created */
9421
3.30k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9422
3.30k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9423
3.30k
                                            &pconc_white,
9424
3.30k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9425
3.30k
                                            dev_profile)) < 0)
9426
0
            goto no_clist_accum;
9427
9428
3.30k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9429
3.30k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9430
3.30k
        if (code < 0)
9431
0
            goto no_clist_accum;
9432
9433
3.30k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9434
3.30k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9435
3.30k
    }
9436
1.10M
    return code;
9437
9438
0
no_clist_accum:
9439
        /* FIXME: We allocated a really small p14dev, but that won't work */
9440
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9441
1.10M
}
9442
9443
/*
9444
 * In a modest violation of good coding practice, the gs_composite_common
9445
 * fields are "known" to be simple (contain no pointers to garbage
9446
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9447
 * to be simple, so we just create a trivial structure descriptor for the
9448
 * entire gs_pdf14trans_s structure.
9449
 */
9450
#define private_st_gs_pdf14trans_t()\
9451
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9452
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9453
9454
/* GC descriptor for gs_pdf14trans_t */
9455
private_st_gs_pdf14trans_t();
9456
9457
/*
9458
 * Check for equality of two PDF 1.4 transparency compositor objects.
9459
 *
9460
 * We are currently always indicating that PDF 1.4 transparency compositors are
9461
 * equal.  Two transparency compositors may have teh same data but still
9462
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9463
 * operations in a row mean that we are creating a group inside of a group.
9464
 */
9465
static  bool
9466
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9467
0
{
9468
0
    return false;
9469
0
}
9470
9471
#ifdef DEBUG
9472
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9473
#endif
9474
9475
#define put_value(dp, value)\
9476
6.50M
    BEGIN\
9477
6.50M
        memcpy(dp, &value, sizeof(value));\
9478
6.50M
        dp += sizeof(value);\
9479
6.50M
    END
9480
9481
static inline int
9482
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9483
800k
{
9484
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9485
       because clist writer may skip this command for some bands.
9486
       For a better result we need individual CTM for each band.
9487
     */
9488
800k
    byte *pbuf = *ppbuf;
9489
800k
    int len, code;
9490
9491
800k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9492
800k
    pbuf--; /* For cmd_write_ctm. */
9493
800k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9494
800k
    if (code < 0)
9495
0
        return code;
9496
800k
    pbuf += len + 1;
9497
800k
    *ppbuf = pbuf;
9498
800k
    return 0;
9499
800k
}
9500
9501
/*
9502
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9503
 * list device. This is also where we update the pdf14_needed. When set the clist
9504
 * painting procs will update the trans_bbox state for bands that are affected.
9505
*/
9506
static  int
9507
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9508
                   gx_device_clist_writer *cdev)
9509
1.84M
{
9510
1.84M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9511
1.84M
    int need, avail = *psize;
9512
1.84M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9513
        to fit the data written below. We don't implement a dynamic check for
9514
        the buffer owerflow, assuming that the consistency is verified in the
9515
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9516
1.84M
    byte * pbuf = buf;
9517
1.84M
    int opcode = pparams->pdf14_op;
9518
1.84M
    int mask_size = 0;
9519
1.84M
    uint mask_id = 0;
9520
1.84M
    int code;
9521
1.84M
    bool found_icc;
9522
1.84M
    int64_t hashcode = 0;
9523
1.84M
    cmm_profile_t *icc_profile;
9524
1.84M
    gsicc_rendering_param_t render_cond;
9525
1.84M
    cmm_dev_profile_t *dev_profile;
9526
    /* We maintain and update working copies until we actually write the clist */
9527
1.84M
    int pdf14_needed = cdev->pdf14_needed;
9528
1.84M
    int trans_group_level = cdev->pdf14_trans_group_level;
9529
1.84M
    int smask_level = cdev->pdf14_smask_level;
9530
1.84M
    bool deep = device_is_deep((gx_device *)cdev);
9531
9532
1.84M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9533
1.84M
                                                     &dev_profile);
9534
1.84M
    if (code < 0)
9535
0
        return code;
9536
1.84M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9537
1.84M
                          &render_cond);
9538
1.84M
    *pbuf++ = opcode;     /* 1 byte */
9539
1.84M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9540
0
        return_error(gs_error_unregistered);  /* prevent spurious transparency ops (Bug 702327) */
9541
9542
1.84M
    switch (opcode) {
9543
0
        default:      /* Should not occur. */
9544
0
            break;
9545
19.3k
        case PDF14_PUSH_DEVICE:
9546
19.3k
            trans_group_level = 0;
9547
19.3k
            cdev->pdf14_smask_level = 0;
9548
19.3k
            cdev->page_pdf14_needed = false;
9549
19.3k
            put_value(pbuf, pparams->num_spot_colors);
9550
19.3k
            put_value(pbuf, pparams->num_spot_colors_int);
9551
19.3k
            put_value(pbuf, pparams->overprint_sim_push);
9552
19.3k
            put_value(pbuf, pparams->is_pattern);
9553
9554
            /* If we happen to be going to a color space like CIELAB then
9555
               we are going to do our blending in default RGB and convert
9556
               to CIELAB at the end.  To do this, we need to store the
9557
               default RGB profile in the clist so that we can grab it
9558
               later on during the clist read back and put image command */
9559
19.3k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9560
                /* Get the default RGB profile.  Set the device hash code
9561
                   so that we can extract it during the put_image operation. */
9562
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9563
0
                found_icc =
9564
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9565
0
                if (!found_icc) {
9566
                    /* Add it to the table */
9567
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9568
0
                                       pparams->iccprofile);
9569
0
                }
9570
0
            }
9571
19.3k
            break;
9572
19.3k
        case PDF14_POP_DEVICE:
9573
19.3k
            pdf14_needed = false;   /* reset pdf14_needed */
9574
19.3k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9575
19.3k
            smask_level = 0;
9576
19.3k
            put_value(pbuf, pparams->is_pattern);
9577
19.3k
            break;
9578
432k
        case PDF14_END_TRANS_GROUP:
9579
438k
        case PDF14_END_TRANS_TEXT_GROUP:
9580
438k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9581
438k
            if (smask_level == 0 && trans_group_level == 0)
9582
27.2k
                pdf14_needed = cdev->page_pdf14_needed;
9583
438k
            break;      /* No data */
9584
7.28k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9585
438k
        case PDF14_BEGIN_TRANS_GROUP:
9586
438k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9587
438k
            trans_group_level++;
9588
438k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9589
438k
            if (code < 0)
9590
0
                return code;
9591
438k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9592
438k
            *pbuf++ = pparams->blend_mode;
9593
438k
            *pbuf++ = pparams->group_color_type;
9594
438k
            *pbuf++ = pparams->page_group;
9595
438k
            put_value(pbuf, pparams->group_color_numcomps);
9596
438k
            put_value(pbuf, pparams->opacity);
9597
438k
            put_value(pbuf, pparams->shape);
9598
438k
            put_value(pbuf, pparams->bbox);
9599
438k
            put_value(pbuf, pparams->shade_group);
9600
438k
            put_value(pbuf, pparams->text_group);
9601
438k
            mask_id = pparams->mask_id;
9602
438k
            put_value(pbuf, mask_id);
9603
            /* Color space information maybe ICC based
9604
               in this case we need to store the ICC
9605
               profile or the ID if it is cached already */
9606
438k
            if (pparams->group_color_type == ICC) {
9607
                /* Check if it is already in the ICC clist table */
9608
12.1k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9609
12.1k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9610
12.1k
                if (!found_icc) {
9611
                    /* Add it to the table */
9612
3.89k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9613
3.89k
                    put_value(pbuf, hashcode);
9614
8.25k
                } else {
9615
                    /* It will be in the clist. Just write out the hashcode */
9616
8.25k
                    put_value(pbuf, hashcode);
9617
8.25k
                }
9618
426k
            } else {
9619
426k
                put_value(pbuf, hashcode);
9620
426k
            }
9621
438k
            break;
9622
362k
        case PDF14_BEGIN_TRANS_MASK:
9623
362k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9624
307k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9625
307k
                smask_level++;
9626
307k
            }
9627
362k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9628
362k
            if (code < 0)
9629
0
                return code;
9630
362k
            put_value(pbuf, pparams->subtype);
9631
362k
            *pbuf++ = pparams->group_color_type;
9632
362k
            put_value(pbuf, pparams->group_color_numcomps);
9633
362k
            *pbuf++ = pparams->replacing;
9634
362k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9635
362k
            *pbuf++ = pparams->Background_components;
9636
362k
            *pbuf++ = pparams->Matte_components;
9637
362k
            put_value(pbuf, pparams->bbox);
9638
362k
            mask_id = pparams->mask_id;
9639
362k
            put_value(pbuf, mask_id);
9640
362k
            if (pparams->Background_components) {
9641
1.14k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9642
9643
1.14k
                memcpy(pbuf, pparams->Background, l);
9644
1.14k
                pbuf += l;
9645
1.14k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9646
1.14k
                pbuf += sizeof(pparams->GrayBackground);
9647
1.14k
            }
9648
362k
            if (pparams->Matte_components) {
9649
102
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9650
9651
102
                memcpy(pbuf, pparams->Matte, m);
9652
102
                pbuf += m;
9653
102
            }
9654
362k
            if (!pparams->function_is_identity)
9655
1.28k
                mask_size = (256+deep)<<deep;
9656
            /* Color space information may be ICC based
9657
               in this case we need to store the ICC
9658
               profile or the ID if it is cached already */
9659
362k
            if (pparams->group_color_type == ICC) {
9660
                /* Check if it is already in the ICC clist table */
9661
307k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9662
307k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9663
307k
                if (!found_icc) {
9664
                    /* Add it to the table */
9665
2.48k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9666
2.48k
                    put_value(pbuf, hashcode);
9667
305k
                } else {
9668
                    /* It will be in the clist. Just write out the hashcode */
9669
305k
                    put_value(pbuf, hashcode);
9670
305k
                }
9671
307k
            } else {
9672
54.8k
                put_value(pbuf, hashcode);
9673
54.8k
            }
9674
362k
            break;
9675
307k
        case PDF14_END_TRANS_MASK:
9676
307k
            smask_level--;
9677
307k
            if (smask_level == 0 && trans_group_level == 0)
9678
7.59k
                pdf14_needed = cdev->page_pdf14_needed;
9679
307k
            break;
9680
217k
        case PDF14_SET_BLEND_PARAMS:
9681
217k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9682
0
                pparams->shape != 1.0)
9683
217k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9684
0
            else if (smask_level == 0 && trans_group_level == 0)
9685
0
                pdf14_needed = false;   /* At page level, set back to false */
9686
217k
            if (smask_level == 0 && trans_group_level == 0)
9687
77.3k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9688
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9689
217k
            put_value(pbuf, pparams->changed);
9690
217k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9691
37.0k
                *pbuf++ = pparams->blend_mode;
9692
217k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9693
18.6k
                *pbuf++ = pparams->text_knockout;
9694
217k
            if (pparams->changed & PDF14_SET_AIS)
9695
217k
                put_value(pbuf, pparams->ais);
9696
217k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9697
217k
                put_value(pbuf, pparams->overprint);
9698
217k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9699
217k
                put_value(pbuf, pparams->stroke_overprint);
9700
217k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9701
217k
                put_value(pbuf, pparams->fillconstantalpha);
9702
217k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9703
217k
                put_value(pbuf, pparams->strokeconstantalpha);
9704
217k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9705
217k
                put_value(pbuf, pparams->op_fs_state);
9706
217k
            break;
9707
0
        case PDF14_PUSH_TRANS_STATE:
9708
0
            break;
9709
46.6k
        case PDF14_POP_TRANS_STATE:
9710
46.6k
            break;
9711
0
        case PDF14_PUSH_SMASK_COLOR:
9712
0
            return 0;   /* We really should never be here */
9713
0
            break;
9714
0
        case PDF14_POP_SMASK_COLOR:
9715
0
            return 0;   /* We really should never be here */
9716
0
            break;
9717
1.84M
    }
9718
9719
    /* check for fit */
9720
1.84M
    need = (pbuf - buf) + mask_size;
9721
1.84M
    *psize = need;
9722
1.84M
    if (need > avail) {
9723
286k
        if (avail)
9724
0
            return_error(gs_error_rangecheck);
9725
286k
        else
9726
286k
            return gs_error_rangecheck;
9727
286k
    }
9728
9729
    /* If we are writing more than the maximum ever expected,
9730
     * return a rangecheck error. Second check is for Coverity
9731
     */
9732
1.56M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9733
1.56M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9734
0
        return_error(gs_error_rangecheck);
9735
9736
    /* Copy our serialized data into the output buffer */
9737
1.56M
    memcpy(data, buf, need - mask_size);
9738
1.56M
    if (mask_size)  /* Include the transfer mask data if present */
9739
978
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9740
1.56M
    if_debug3m('v', cdev->memory,
9741
1.56M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9742
1.56M
               pdf14_opcode_names[opcode], mask_id, need);
9743
1.56M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9744
1.56M
    cdev->pdf14_trans_group_level = trans_group_level;
9745
1.56M
    cdev->pdf14_smask_level = smask_level;
9746
1.56M
    return 0;
9747
1.56M
}
9748
9749
#undef put_value
9750
9751
/* Function prototypes */
9752
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9753
                const gs_pdf14trans_params_t * pparams,
9754
                gs_memory_t * mem );
9755
9756
#define read_value(dp, value)\
9757
127M
    BEGIN\
9758
127M
        memcpy(&value, dp, sizeof(value));\
9759
127M
        dp += sizeof(value);\
9760
127M
    END
9761
9762
/*
9763
 * Convert the string representation of the PDF 1.4 transparency parameter
9764
 * into the full compositor.
9765
 */
9766
static  int
9767
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9768
                                uint size, gs_memory_t * mem )
9769
38.3M
{
9770
38.3M
    gs_pdf14trans_params_t params = {0};
9771
38.3M
    const byte * start = data;
9772
38.3M
    int used, code = 0;
9773
38.3M
    bool deep;
9774
9775
38.3M
    if (size < 1)
9776
0
        return_error(gs_error_rangecheck);
9777
9778
    /* Read PDF 1.4 compositor data from the clist */
9779
38.3M
    params.pdf14_op = *data++;
9780
38.3M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9781
38.3M
               pdf14_opcode_names[params.pdf14_op], size);
9782
38.3M
    memset(&params.ctm, 0, sizeof(params.ctm));
9783
38.3M
    switch (params.pdf14_op) {
9784
0
        default:      /* Should not occur. */
9785
0
            break;
9786
1.68M
        case PDF14_PUSH_DEVICE:
9787
1.68M
            read_value(data, params.num_spot_colors);
9788
1.68M
            read_value(data, params.num_spot_colors_int);
9789
1.68M
            read_value(data, params.overprint_sim_push);
9790
1.68M
            read_value(data, params.is_pattern);
9791
1.68M
            break;
9792
0
        case PDF14_ABORT_DEVICE:
9793
0
            break;
9794
1.68M
        case PDF14_POP_DEVICE:
9795
1.68M
            read_value(data, params.is_pattern);
9796
1.68M
            break;
9797
2.36M
        case PDF14_END_TRANS_GROUP:
9798
2.90M
        case PDF14_END_TRANS_TEXT_GROUP:
9799
#ifdef DEBUG
9800
            code += 0; /* A good place for a breakpoint. */
9801
#endif
9802
2.90M
            break;      /* No data */
9803
0
        case PDF14_PUSH_TRANS_STATE:
9804
0
            break;
9805
3.35M
        case PDF14_POP_TRANS_STATE:
9806
3.35M
            break;
9807
657k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9808
2.91M
        case PDF14_BEGIN_TRANS_GROUP:
9809
            /*
9810
             * We are currently not using the bbox or the colorspace so they were
9811
             * not placed in the clist
9812
             */
9813
2.91M
            data = cmd_read_matrix(&params.ctm, data);
9814
2.91M
            params.Isolated = (*data) & 1;
9815
2.91M
            params.Knockout = (*data++ >> 1) & 1;
9816
2.91M
            params.blend_mode = *data++;
9817
2.91M
            params.group_color_type = *data++;  /* Trans group color */
9818
2.91M
            params.page_group = *data++;
9819
2.91M
            read_value(data,params.group_color_numcomps);  /* color group size */
9820
2.91M
            read_value(data, params.opacity);
9821
2.91M
            read_value(data, params.shape);
9822
2.91M
            read_value(data, params.bbox);
9823
2.91M
            read_value(data, params.shade_group);
9824
2.91M
            read_value(data, params.text_group);
9825
2.91M
            read_value(data, params.mask_id);
9826
2.91M
            read_value(data, params.icc_hash);
9827
2.91M
            break;
9828
5.00M
        case PDF14_BEGIN_TRANS_MASK:
9829
                /* This is the largest transparency parameter at this time (potentially
9830
                 * 1531 bytes in size if Background_components =
9831
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9832
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9833
                 *
9834
                 * NOTE:
9835
                 * The clist reader must be able to handle this sized device.
9836
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9837
                 * may also need to be changed correspondingly (defined in gstparam.h)
9838
                 * Also... if another compositor param should exceed this size, this
9839
                 * same condition applies.
9840
                 */
9841
5.00M
            data = cmd_read_matrix(&params.ctm, data);
9842
5.00M
            read_value(data, params.subtype);
9843
5.00M
            params.group_color_type = *data++;
9844
5.00M
            read_value(data, params.group_color_numcomps);
9845
5.00M
            params.replacing = *data++;
9846
5.00M
            params.function_is_identity = *data & 1;
9847
5.00M
            deep = (*data++)>>1;
9848
5.00M
            params.Background_components = *data++;
9849
5.00M
            params.Matte_components = *data++;
9850
5.00M
            read_value(data, params.bbox);
9851
5.00M
            read_value(data, params.mask_id);
9852
5.00M
            if (params.Background_components) {
9853
89.0k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9854
9855
89.0k
                memcpy(params.Background, data, l);
9856
89.0k
                data += l;
9857
89.0k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9858
89.0k
                data += sizeof(params.GrayBackground);
9859
89.0k
            }
9860
5.00M
            if (params.Matte_components) {
9861
4.23k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9862
9863
4.23k
                memcpy(params.Matte, data, m);
9864
4.23k
                data += m;
9865
4.23k
            }
9866
5.00M
            read_value(data, params.icc_hash);
9867
5.00M
            if (params.function_is_identity) {
9868
4.97M
                int i;
9869
9870
4.97M
                if (deep) {
9871
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9872
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9873
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9874
4.97M
                } else {
9875
1.27G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9876
1.27G
                        params.transfer_fn[i] = (byte)floor(i *
9877
1.27G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9878
1.27G
                    }
9879
4.97M
                }
9880
4.97M
            } else {
9881
35.3k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9882
35.3k
                data += (256+deep)<<deep;
9883
35.3k
            }
9884
5.00M
            break;
9885
476k
        case PDF14_END_TRANS_MASK:
9886
476k
            break;
9887
0
        case PDF14_PUSH_SMASK_COLOR:
9888
0
            return 0;
9889
0
            break;
9890
0
        case PDF14_POP_SMASK_COLOR:
9891
0
            return 0;
9892
0
            break;
9893
20.2M
        case PDF14_SET_BLEND_PARAMS:
9894
20.2M
            read_value(data, params.changed);
9895
20.2M
            if (params.changed & PDF14_SET_BLEND_MODE)
9896
3.58M
                params.blend_mode = *data++;
9897
20.2M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9898
1.63M
                params.text_knockout = *data++;
9899
20.2M
            if (params.changed & PDF14_SET_AIS)
9900
20.2M
                read_value(data, params.ais);
9901
20.2M
            if (params.changed & PDF14_SET_OVERPRINT)
9902
20.2M
                read_value(data, params.overprint);
9903
20.2M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9904
20.2M
                read_value(data, params.stroke_overprint);
9905
20.2M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9906
20.2M
                read_value(data, params.fillconstantalpha);
9907
20.2M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9908
20.2M
                read_value(data, params.strokeconstantalpha);
9909
20.2M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9910
20.2M
                read_value(data, params.op_fs_state);
9911
20.2M
            break;
9912
38.3M
    }
9913
38.3M
    code = gs_create_pdf14trans(ppct, &params, mem);
9914
38.3M
    if (code < 0)
9915
0
        return code;
9916
38.3M
    used = data - start;
9917
38.3M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9918
9919
    /* If we read more than the maximum expected, return a rangecheck error */
9920
38.3M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9921
0
        return_error(gs_error_rangecheck);
9922
38.3M
    else
9923
38.3M
        return used;
9924
38.3M
}
9925
9926
/*
9927
 * Adjust the compositor's CTM.
9928
 */
9929
static int
9930
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9931
23.8M
{
9932
23.8M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9933
23.8M
    gs_matrix mat = pct->params.ctm;
9934
9935
23.8M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9936
23.8M
               mat.xx, mat.xy, mat.yx, mat.yy,
9937
23.8M
               mat.tx, mat.ty);
9938
23.8M
    mat.tx -= x0;
9939
23.8M
    mat.ty -= y0;
9940
23.8M
    gs_gstate_setmatrix(pgs, &mat);
9941
23.8M
    return 0;
9942
23.8M
}
9943
9944
/*
9945
 * Create a PDF 1.4 transparency compositor.
9946
 *
9947
 * Note that this routine will be called only if the device is not already
9948
 * a PDF 1.4 transparency compositor.
9949
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9950
 */
9951
static  int
9952
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9953
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9954
    gs_memory_t * mem)
9955
1.13M
{
9956
1.13M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9957
1.13M
    int code = 0;
9958
9959
    /*
9960
     * We only handle the push operation.  All other operations are ignored.
9961
     * The other operations will be handled by the composite routine
9962
     * for the PDF 1.4 compositing device.
9963
     */
9964
1.13M
    switch (pdf14pct->params.pdf14_op) {
9965
1.10M
        case PDF14_PUSH_DEVICE:
9966
1.10M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9967
            /* Change (non-error) code to 1 to indicate that we created
9968
             * a device. */
9969
1.10M
            if (code >= 0)
9970
1.10M
                code = 1;
9971
1.10M
            break;
9972
25.6k
        default:
9973
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9974
25.6k
            *pp14dev = NULL;
9975
25.6k
            return_error(gs_error_unregistered);
9976
1.13M
    }
9977
1.10M
    return code;
9978
1.13M
}
9979
9980
/*
9981
 * Find an opening compositor op.
9982
 */
9983
static gs_compositor_closing_state
9984
find_opening_op(int opening_op, gs_composite_t **ppcte,
9985
                gs_compositor_closing_state return_code)
9986
2.65M
{
9987
    /* Assuming a right *BEGIN* - *END* operation balance. */
9988
2.65M
    gs_composite_t *pcte = *ppcte;
9989
9990
6.40M
    for (;;) {
9991
6.40M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9992
6.01M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9993
6.01M
            int op = pct->params.pdf14_op;
9994
9995
6.01M
            *ppcte = pcte;
9996
6.01M
            if (op == opening_op)
9997
1.72M
                return return_code;
9998
4.28M
            if (op != PDF14_SET_BLEND_PARAMS) {
9999
2.58M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
10000
332
                    return COMP_ENQUEUE;
10001
2.58M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10002
269k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10003
250k
                        return COMP_ENQUEUE;
10004
269k
                }
10005
2.33M
                if (opening_op == PDF14_PUSH_DEVICE) {
10006
2.31M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10007
2.28M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10008
319k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10009
130k
                        return COMP_ENQUEUE;
10010
2.31M
                }
10011
2.33M
            }
10012
4.28M
        } else
10013
394k
            return COMP_ENQUEUE;
10014
3.90M
        pcte = pcte->prev;
10015
3.90M
        if (pcte == NULL)
10016
148k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10017
3.90M
    }
10018
2.65M
}
10019
10020
/*
10021
 * Find an opening compositor op.
10022
 */
10023
static gs_compositor_closing_state
10024
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10025
16.8M
{
10026
16.8M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10027
16.8M
    gs_composite_t *pct = *ppcte;
10028
10029
16.8M
    for (;;) {
10030
16.8M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10031
14.0M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10032
10033
14.0M
            *ppcte = pct;
10034
14.0M
            if (pct_pdf14->params.pdf14_op != my_op)
10035
4.34M
                return COMP_ENQUEUE;
10036
9.74M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10037
                /* If the new parameters completely replace the old ones
10038
                   then remove the old one from the queu */
10039
9.74M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10040
9.74M
                    pct_pdf14->params.changed) {
10041
8.89M
                    return COMP_REPLACE_CURR;
10042
8.89M
                } else {
10043
841k
                    return COMP_ENQUEUE;
10044
841k
                }
10045
9.74M
            }
10046
9.74M
        } else
10047
2.78M
            return COMP_ENQUEUE;
10048
0
        pct = pct->prev;
10049
0
        if (pct == NULL)
10050
0
            return COMP_ENQUEUE; /* Not in queue. */
10051
0
    }
10052
16.8M
}
10053
10054
/*
10055
 * Check for closing compositor.
10056
 */
10057
static gs_compositor_closing_state
10058
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10059
                        gx_device *dev)
10060
32.7M
{
10061
32.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10062
32.7M
    int op0 = pct0->params.pdf14_op;
10063
10064
32.7M
    switch (op0) {
10065
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10066
1.22M
        case PDF14_PUSH_DEVICE:
10067
1.22M
            return COMP_ENQUEUE;
10068
0
        case PDF14_ABORT_DEVICE:
10069
0
            return COMP_ENQUEUE;
10070
1.22M
        case PDF14_POP_DEVICE:
10071
1.22M
            if (*ppcte == NULL)
10072
816k
                return COMP_ENQUEUE;
10073
404k
            else {
10074
404k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10075
10076
404k
                if (state == COMP_EXEC_IDLE)
10077
111k
                    return COMP_DROP_QUEUE;
10078
292k
                return state;
10079
404k
            }
10080
493k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10081
2.52M
        case PDF14_BEGIN_TRANS_GROUP:
10082
2.52M
            return COMP_ENQUEUE;
10083
2.02M
        case PDF14_END_TRANS_GROUP:
10084
2.52M
        case PDF14_END_TRANS_TEXT_GROUP:
10085
2.52M
            if (*ppcte == NULL)
10086
433k
                return COMP_EXEC_QUEUE;
10087
2.09M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10088
4.16M
        case PDF14_BEGIN_TRANS_MASK:
10089
4.16M
            return COMP_ENQUEUE;
10090
0
        case PDF14_PUSH_TRANS_STATE:
10091
0
            return COMP_ENQUEUE;
10092
2.81M
        case PDF14_POP_TRANS_STATE:
10093
2.81M
            return COMP_ENQUEUE;
10094
0
        case PDF14_PUSH_SMASK_COLOR:
10095
0
            return COMP_ENQUEUE;
10096
0
            break;
10097
0
        case PDF14_POP_SMASK_COLOR:
10098
0
            return COMP_ENQUEUE;
10099
0
            break;
10100
416k
        case PDF14_END_TRANS_MASK:
10101
416k
            if (*ppcte == NULL)
10102
264k
                return COMP_EXEC_QUEUE;
10103
152k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10104
17.8M
        case PDF14_SET_BLEND_PARAMS:
10105
17.8M
            if (*ppcte == NULL)
10106
1.02M
                return COMP_ENQUEUE;
10107
            /* hack : ignore csel - here it is always zero : */
10108
16.8M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10109
32.7M
    }
10110
32.7M
}
10111
10112
/*
10113
 * Check whether a next operation is friendly to the compositor.
10114
 */
10115
static bool
10116
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10117
3.86M
{
10118
3.86M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10119
3.86M
    int op0 = pct0->params.pdf14_op;
10120
10121
3.86M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10122
2.45M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10123
        /* Halftone commands are always passed to the target printer device,
10124
           because transparency buffers are always contone.
10125
           So we're safe to execute them before queued transparency compositors. */
10126
1.42M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10127
400k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10128
669k
            return true;
10129
756k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10130
751k
            return true;
10131
756k
    }
10132
2.44M
    return false;
10133
3.86M
}
10134
10135
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10136
static composite_equal_proc(c_pdf14trans_equal);
10137
static composite_write_proc(c_pdf14trans_write);
10138
static composite_read_proc(c_pdf14trans_read);
10139
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10140
static composite_is_closing_proc(c_pdf14trans_is_closing);
10141
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10142
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10143
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10144
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10145
10146
/*
10147
 * Methods for the PDF 1.4 transparency compositor
10148
 *
10149
 * Note:  We have two set of methods.  They are the same except for the
10150
 * composite_clist_write_update method.  Once the clist write device is created,
10151
 * we use the second set of procedures.  This prevents the creation of multiple
10152
 * PDF 1.4 clist write compositor devices being chained together.
10153
 */
10154
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10155
    GX_COMPOSITOR_PDF14_TRANS,
10156
    {
10157
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10158
        c_pdf14trans_equal,                      /* procs.equal */
10159
        c_pdf14trans_write,                      /* procs.write */
10160
        c_pdf14trans_read,                       /* procs.read */
10161
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10162
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10163
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10164
                /* Create a PDF 1.4 clist write device */
10165
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10166
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10167
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10168
    }                                            /* procs */
10169
};
10170
10171
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10172
    GX_COMPOSITOR_PDF14_TRANS,
10173
    {
10174
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10175
        c_pdf14trans_equal,                      /* procs.equal */
10176
        c_pdf14trans_write,                      /* procs.write */
10177
        c_pdf14trans_read,                       /* procs.read */
10178
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10179
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10180
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10181
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10182
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10183
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10184
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10185
    }                                            /* procs */
10186
};
10187
10188
/*
10189
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10190
 */
10191
int
10192
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10193
272M
{
10194
272M
    return (pct->type == &gs_composite_pdf14trans_type
10195
210M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10196
272M
}
10197
10198
/*
10199
 * Create a PDF 1.4 transparency compositor data structure.
10200
 */
10201
static int
10202
gs_create_pdf14trans(
10203
    gs_composite_t **               ppct,
10204
    const gs_pdf14trans_params_t *  pparams,
10205
    gs_memory_t *                   mem )
10206
39.6M
{
10207
39.6M
    gs_pdf14trans_t *                pct;
10208
10209
39.6M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10210
39.6M
                             "gs_create_pdf14trans");
10211
39.6M
    if (pct == NULL)
10212
0
        return_error(gs_error_VMerror);
10213
39.6M
    pct->type = &gs_composite_pdf14trans_type;
10214
39.6M
    pct->id = gs_next_ids(mem, 1);
10215
39.6M
    pct->params = *pparams;
10216
39.6M
    pct->idle = false;
10217
39.6M
    *ppct = (gs_composite_t *)pct;
10218
39.6M
    return 0;
10219
39.6M
}
10220
10221
/*
10222
 * Send a PDF 1.4 transparency compositor action to the specified device.
10223
 */
10224
int
10225
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10226
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10227
1.17M
{
10228
1.17M
    gs_composite_t * pct = NULL;
10229
1.17M
    int code;
10230
10231
1.17M
    pparams->ctm = ctm_only(pgs);
10232
1.17M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10233
1.17M
    if (code < 0)
10234
0
        return code;
10235
1.17M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10236
1.17M
    if (code == gs_error_handled)
10237
0
        code = 0;
10238
10239
1.17M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10240
10241
1.17M
    return code;
10242
1.17M
}
10243
10244
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10245
10246
/*
10247
 * The PDF 1.4 transparency compositor device may have a different process
10248
 * color model than the output device.  If we are banding then we need to
10249
 * create two compositor devices.  The output side (clist reader) needs a
10250
 * compositor to actually composite the output.  We also need a compositor
10251
 * device before the clist writer.  This is needed to provide a process color
10252
 * model which matches the PDF 1.4 blending space.
10253
 *
10254
 * This section provides support for this device.
10255
 */
10256
10257
/*
10258
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10259
 * We actually use the same structure for both the clist writer and reader
10260
 * devices.  However we use separate names to identify the routines for each
10261
 * device.
10262
 */
10263
10264
static  dev_proc_composite(pdf14_clist_composite);
10265
static  dev_proc_composite(pdf14_clist_forward_composite);
10266
static  dev_proc_fill_path(pdf14_clist_fill_path);
10267
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10268
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10269
static  dev_proc_text_begin(pdf14_clist_text_begin);
10270
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10271
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10272
10273
static void
10274
pdf14_clist_init_procs(gx_device *dev,
10275
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10276
                       dev_proc_get_color_comp_index(get_color_comp_index))
10277
9.67k
{
10278
9.67k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10279
9.67k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10280
9.67k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10281
9.67k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10282
9.67k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10283
9.67k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10284
9.67k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10285
9.67k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10286
9.67k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10287
9.67k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10288
9.67k
    set_dev_proc(dev, put_params, pdf14_put_params);
10289
9.67k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10290
9.67k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10291
9.67k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10292
9.67k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10293
9.67k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10294
9.67k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10295
9.67k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10296
9.67k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10297
9.67k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10298
9.67k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10299
9.67k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10300
9.67k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10301
9.67k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10302
9.67k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10303
9.67k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10304
9.67k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10305
9.67k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10306
9.67k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10307
9.67k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10308
9.67k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10309
9.67k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10310
9.67k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10311
9.67k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10312
9.67k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10313
9.67k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10314
9.67k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10315
9.67k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10316
9.67k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10317
9.67k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10318
9.67k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10319
9.67k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10320
9.67k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10321
9.67k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10322
9.67k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10323
9.67k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10324
9.67k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10325
9.67k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10326
9.67k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10327
9.67k
}
10328
10329
static void
10330
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10331
3.67k
{
10332
3.67k
    pdf14_clist_init_procs(dev,
10333
3.67k
                           gx_default_DevGray_get_color_mapping_procs,
10334
3.67k
                           gx_default_DevGray_get_color_comp_index);
10335
3.67k
}
10336
10337
static void
10338
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10339
5.00k
{
10340
5.00k
    pdf14_clist_init_procs(dev,
10341
5.00k
                           gx_default_DevRGB_get_color_mapping_procs,
10342
5.00k
                           gx_default_DevRGB_get_color_comp_index);
10343
5.00k
}
10344
10345
static void
10346
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10347
15
{
10348
15
    pdf14_clist_init_procs(dev,
10349
15
                           gx_default_DevCMYK_get_color_mapping_procs,
10350
15
                           gx_default_DevCMYK_get_color_comp_index);
10351
15
}
10352
10353
static void
10354
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10355
988
{
10356
988
    pdf14_clist_init_procs(dev,
10357
988
                           pdf14_cmykspot_get_color_mapping_procs,
10358
988
                           pdf14_cmykspot_get_color_comp_index);
10359
988
}
10360
10361
static void
10362
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10363
0
{
10364
0
    pdf14_clist_init_procs(dev,
10365
0
                           pdf14_rgbspot_get_color_mapping_procs,
10366
0
                           pdf14_rgbspot_get_color_comp_index);
10367
0
}
10368
10369
#if 0 /* NOT USED */
10370
static int
10371
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10372
{
10373
    pdf14_clist_init_procs(dev,
10374
                           pdf14_grayspot_get_color_mapping_procs,
10375
                           pdf14_grayspot_get_color_comp_index);
10376
}
10377
#endif  /* NOT USED */
10378
10379
const pdf14_clist_device pdf14_clist_Gray_device = {
10380
    std_device_color_stype_body(pdf14_clist_device,
10381
                                pdf14_clist_Gray_initialize_device_procs,
10382
                                "pdf14clistgray",
10383
                                &st_pdf14_device,
10384
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10385
    { 0 },      /* Procs */
10386
    NULL,     /* target */
10387
    { 0 },      /* devn_params - not used */
10388
    &gray_pdf14_procs,
10389
    &gray_blending_procs
10390
};
10391
10392
const pdf14_clist_device pdf14_clist_RGB_device = {
10393
    std_device_color_stype_body(pdf14_clist_device,
10394
                                pdf14_clist_RGB_initialize_device_procs,
10395
                                "pdf14clistRGB",
10396
                                &st_pdf14_device,
10397
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10398
    { 0 },      /* Procs */
10399
    NULL,     /* target */
10400
    { 0 },      /* devn_params - not used */
10401
    &rgb_pdf14_procs,
10402
    &rgb_blending_procs
10403
};
10404
10405
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10406
    std_device_part1_(pdf14_device,
10407
                      pdf14_clist_RGBspot_initialize_device_procs,
10408
                      "pdf14clistrgbspot",
10409
                      &st_pdf14_device,
10410
                      open_init_closed),
10411
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10412
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10413
    offset_margin_values(0, 0, 0, 0, 0, 0),
10414
    std_device_part3_(),
10415
    { 0 },      /* Procs */
10416
    NULL,     /* target */
10417
    /* DeviceN parameters */
10418
    { 8,      /* Not used - Bits per color */
10419
      DeviceRGBComponents,  /* Names of color model colorants */
10420
      3,      /* Number colorants for CMYK */
10421
      0,      /* MaxSeparations has not been specified */
10422
      -1,     /* PageSpotColors has not been specified */
10423
      {0},      /* SeparationNames */
10424
      0,      /* SeparationOrder names */
10425
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10426
    },
10427
    &rgbspot_pdf14_procs,
10428
    &rgb_blending_procs
10429
};
10430
10431
const pdf14_clist_device pdf14_clist_CMYK_device = {
10432
    std_device_std_color_full_body_type(pdf14_clist_device,
10433
                                        pdf14_clist_CMYK_initialize_device_procs,
10434
                                        "pdf14clistcmyk",
10435
                                        &st_pdf14_device,
10436
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10437
                                        0, 0, 0, 0, 0, 0),
10438
    { 0 },      /* Procs */
10439
    NULL,     /* target */
10440
    { 0 },      /* devn_params - not used */
10441
    &cmyk_pdf14_procs,
10442
    &cmyk_blending_procs
10443
};
10444
10445
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10446
    std_device_part1_(pdf14_device,
10447
                      pdf14_clist_CMYKspot_initialize_device_procs,
10448
                      "pdf14clistcmykspot",
10449
                      &st_pdf14_device,
10450
                      open_init_closed),
10451
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10452
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10453
    offset_margin_values(0, 0, 0, 0, 0, 0),
10454
    std_device_part3_(),
10455
    { 0 },      /* Procs */
10456
    NULL,     /* target */
10457
    /* DeviceN parameters */
10458
    { 8,      /* Not used - Bits per color */
10459
      DeviceCMYKComponents, /* Names of color model colorants */
10460
      4,      /* Number colorants for CMYK */
10461
      0,      /* MaxSeparations has not been specified */
10462
      -1,     /* PageSpotColors has not been specified */
10463
      {0},      /* SeparationNames */
10464
      0,      /* SeparationOrder names */
10465
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10466
    },
10467
    &cmykspot_pdf14_procs,
10468
    &cmyk_blending_procs
10469
};
10470
10471
const pdf14_clist_device pdf14_clist_custom_device = {
10472
    std_device_part1_(pdf14_device,
10473
                      pdf14_clist_CMYKspot_initialize_device_procs,
10474
                      "pdf14clistcustom",
10475
                      &st_pdf14_device,
10476
                      open_init_closed),
10477
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10478
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10479
    offset_margin_values(0, 0, 0, 0, 0, 0),
10480
    std_device_part3_(),
10481
    { 0 },      /* Procs */
10482
    NULL,     /* target */
10483
    /* DeviceN parameters */
10484
    { 8,      /* Not used - Bits per color */
10485
      DeviceCMYKComponents, /* Names of color model colorants */
10486
      4,      /* Number colorants for CMYK */
10487
      0,      /* MaxSeparations has not been specified */
10488
      -1,     /* PageSpotColors has not been specified */
10489
      {0},      /* SeparationNames */
10490
      0,      /* SeparationOrder names */
10491
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10492
    },
10493
    &custom_pdf14_procs,
10494
    &custom_blending_procs
10495
};
10496
10497
/*
10498
 * the PDF 1.4 transparency spec says that color space for blending
10499
 * operations can be based upon either a color space specified in the
10500
 * group or a default value based upon the output device.  We are
10501
 * currently only using a color space based upon the device.
10502
 */
10503
static  int
10504
get_pdf14_clist_device_proto(gx_device          *dev,
10505
                             pdf14_clist_device *pdevproto,
10506
                             gs_gstate          *pgs,
10507
                       const gs_pdf14trans_t    *pdf14pct,
10508
                             bool                use_pdf14_accum)
10509
9.67k
{
10510
9.67k
    pdf14_blend_cs_t blend_cs_state;
10511
9.67k
    pdf14_default_colorspace_t dev_cs =
10512
9.67k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10513
9.67k
                                                 &blend_cs_state);
10514
9.67k
    bool deep = device_is_deep(dev);
10515
9.67k
    int num_spots = pdf14pct->params.num_spot_colors;
10516
10517
    /* overprint overide */
10518
9.67k
    if (pdf14pct->params.overprint_sim_push &&
10519
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10520
10521
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10522
0
            dev_cs = PDF14_DeviceCMYKspot;
10523
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10524
0
        } else
10525
0
            dev_cs = PDF14_DeviceCMYK;
10526
0
    }
10527
10528
9.67k
    switch (dev_cs) {
10529
3.67k
        case PDF14_DeviceGray:
10530
           /* We want gray to be single channel.  Low level
10531
               initialization of gray device prototype is
10532
               peculiar in that in dci_std_color_num_components
10533
               the comment is
10534
              "A device is monochrome only if it is bi-level"
10535
              Here we want monochrome anytime we have a gray device.
10536
              To avoid breaking things elsewhere, we will overide
10537
              the prototype intialization here */
10538
3.67k
            *pdevproto = pdf14_clist_Gray_device;
10539
3.67k
            pdevproto->color_info.max_components = 1;
10540
3.67k
            pdevproto->color_info.num_components =
10541
3.67k
                                    pdevproto->color_info.max_components;
10542
3.67k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10543
3.67k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10544
3.67k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10545
3.67k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10546
3.67k
            pdevproto->color_info.depth = deep ? 16 : 8;
10547
3.67k
            pdevproto->sep_device = false;
10548
3.67k
            break;
10549
5.00k
        case PDF14_DeviceRGB:
10550
5.00k
            *pdevproto = pdf14_clist_RGB_device;
10551
5.00k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10552
5.00k
            pdevproto->sep_device = false;
10553
5.00k
            if (deep) {
10554
0
                pdevproto->color_info.depth = 3*16;
10555
0
                pdevproto->color_info.max_color = 65535;
10556
0
                pdevproto->color_info.max_gray = 65535;
10557
0
                pdevproto->color_info.dither_colors = 65536;
10558
0
                pdevproto->color_info.dither_grays = 65536;
10559
0
            }
10560
5.00k
            break;
10561
15
        case PDF14_DeviceCMYK:
10562
15
            *pdevproto = pdf14_clist_CMYK_device;
10563
15
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10564
15
            pdevproto->sep_device = false;
10565
15
            if (deep) {
10566
0
                pdevproto->color_info.depth = 4*16;
10567
0
                pdevproto->color_info.max_color = 65535;
10568
0
                pdevproto->color_info.max_gray = 65535;
10569
0
                pdevproto->color_info.dither_colors = 65536;
10570
0
                pdevproto->color_info.dither_grays = 65536;
10571
0
            }
10572
15
            break;
10573
988
        case PDF14_DeviceCMYKspot:
10574
988
            *pdevproto = pdf14_clist_CMYKspot_device;
10575
            /*
10576
             * The number of components for the PDF14 device is the sum
10577
             * of the process components and the number of spot colors
10578
             * for the page. If we are using an NCLR ICC profile at
10579
             * the output device, those spot colors are skipped. They
10580
             * do not appear in the transparency buffer, but appear
10581
             * during put image transform of the page group to the target
10582
             * color space.
10583
             */
10584
988
            if (num_spots >= 0) {
10585
988
                pdevproto->devn_params.page_spot_colors = num_spots;
10586
988
                pdevproto->color_info.num_components =
10587
988
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10588
988
                if (pdevproto->color_info.num_components >
10589
988
                              pdevproto->color_info.max_components)
10590
0
                    pdevproto->color_info.num_components =
10591
0
                              pdevproto->color_info.max_components;
10592
988
                pdevproto->color_info.depth =
10593
988
                              pdevproto->color_info.num_components * (8<<deep);
10594
988
            }
10595
988
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10596
988
            pdevproto->sep_device = true;
10597
988
            break;
10598
0
        case PDF14_DeviceRGBspot:
10599
0
            *pdevproto = pdf14_clist_RGBspot_device;
10600
            /*
10601
             * The number of components for the PDF14 device is the sum
10602
             * of the process components and the number of spot colors
10603
             * for the page. If we are using an NCLR ICC profile at
10604
             * the output device, those spot colors are skipped. They
10605
             * do not appear in the transparency buffer, but appear
10606
             * during put image transform of the page group to the target
10607
             * color space.
10608
             */
10609
0
            if (num_spots >= 0) {
10610
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10611
0
                pdevproto->color_info.num_components =
10612
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10613
0
                if (pdevproto->color_info.num_components >
10614
0
                    pdevproto->color_info.max_components)
10615
0
                    pdevproto->color_info.num_components =
10616
0
                        pdevproto->color_info.max_components;
10617
0
                pdevproto->color_info.depth =
10618
0
                    pdevproto->color_info.num_components * (8 << deep);
10619
0
            }
10620
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10621
0
            pdevproto->sep_device = true;
10622
0
            break;
10623
0
        case PDF14_DeviceCustom:
10624
            /*
10625
             * We are using the output device's process color model.  The
10626
             * color_info for the PDF 1.4 compositing device needs to match
10627
             * the output device.
10628
             */
10629
0
            *pdevproto = pdf14_clist_custom_device;
10630
0
            pdevproto->color_info = dev->color_info;
10631
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10632
0
            pdevproto->color_info.depth =
10633
0
                pdevproto->color_info.num_components * (8<<deep);
10634
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10635
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10636
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10637
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10638
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10639
0
            break;
10640
0
        default:      /* Should not occur */
10641
0
            return_error(gs_error_rangecheck);
10642
9.67k
    }
10643
9.67k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10644
9.67k
    pdevproto->blend_cs_state = blend_cs_state;
10645
9.67k
    return 0;
10646
9.67k
}
10647
10648
static  int
10649
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10650
                                gx_device ** ppdev, gx_device * target,
10651
                                const gs_pdf14trans_t * pdf14pct)
10652
9.67k
{
10653
9.67k
    pdf14_clist_device dev_proto;
10654
9.67k
    pdf14_clist_device * pdev;
10655
9.67k
    int code;
10656
9.67k
    bool has_tags = device_encodes_tags(target);
10657
9.67k
    cmm_profile_t *target_profile;
10658
9.67k
    gsicc_rendering_param_t render_cond;
10659
9.67k
    cmm_dev_profile_t *dev_profile;
10660
9.67k
    uchar k;
10661
9.67k
    bool deep = device_is_deep(target);
10662
9.67k
    cmm_profile_t *icc_profile;
10663
9.67k
    int nc;
10664
10665
9.67k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10666
9.67k
    if (code < 0)
10667
0
        return code;
10668
9.67k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10669
9.67k
                          &render_cond);
10670
9.67k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10671
    /* Prototypes never include tags. We add those in later. */
10672
9.67k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10673
9.67k
                                        pgs, pdf14pct, false);
10674
9.67k
    if (code < 0)
10675
0
        return code;
10676
9.67k
    code = gs_copydevice((gx_device **) &pdev,
10677
9.67k
                         (const gx_device *) &dev_proto, mem);
10678
9.67k
    if (code < 0)
10679
0
        return code;
10680
10681
9.67k
    nc = pdev->color_info.num_components;
10682
    /* If we are not using a blending color space, the number of color planes
10683
       should not exceed that of the target */
10684
9.67k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10685
9.67k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10686
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10687
9.67k
        if (pdev->color_info.max_components > target->color_info.max_components)
10688
1.08k
            pdev->color_info.max_components = target->color_info.max_components;
10689
9.67k
    }
10690
10691
9.67k
    pdev->color_info.num_components = nc;
10692
9.67k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10693
9.67k
    pdev->pad = target->pad;
10694
9.67k
    pdev->log2_align_mod = target->log2_align_mod;
10695
10696
9.67k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10697
10698
9.67k
    pdev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
10699
10700
9.67k
    if (deep) {
10701
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10702
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10703
0
    }
10704
    /* If we have a tag device then go ahead and do a special encoder decoder
10705
       for the pdf14 device to make sure we maintain this information in the
10706
       encoded color information.  We could use the target device's methods but
10707
       the PDF14 device has to maintain 8 bit color always and we could run
10708
       into other issues if the number of colorants became large.  If we need to
10709
       do compressed color with tags that will be a special project at that time */
10710
9.67k
    if (has_tags) {
10711
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10712
0
    }
10713
9.67k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10714
9.67k
    gx_device_fill_in_procs((gx_device *)pdev);
10715
    /* Copying the params adds the tags to the color_info if required. */
10716
9.67k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10717
9.67k
    if (target->num_planar_planes > 0)
10718
1.07k
        pdev->num_planar_planes = pdev->color_info.num_components;
10719
9.67k
    gx_device_set_target((gx_device_forward *)pdev, target);
10720
10721
    /* Components shift, etc have to be based upon 8 bit */
10722
32.3k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10723
22.7k
        pdev->color_info.comp_bits[k] = 8<<deep;
10724
22.7k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10725
22.7k
    }
10726
9.67k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10727
9.67k
    if (code < 0)
10728
0
        return code;
10729
9.67k
    pdev->pclist_device = target;
10730
10731
9.67k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10732
9.67k
    if (code < 0)
10733
0
        return code;
10734
9.67k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10735
9.67k
        &render_cond);
10736
9.67k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10737
10738
    /* Simulated overprint case.  We have to use CMYK-based profile
10739
       Also if the target profile is NCLR, we are going to use a pdf14
10740
       device that is CMYK based and do the mapping to the NCLR profile
10741
       when the put_image occurs */
10742
9.67k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10743
9.67k
         icc_profile->data_cs == gsNCHANNEL) {
10744
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10745
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10746
0
            -1, "pdf14_create_clist_device");
10747
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10748
9.67k
    } else {
10749
        /* If the target profile was CIELAB, then overide with default RGB for
10750
           proper blending.  During put_image we will convert from RGB to
10751
           CIELAB */
10752
9.67k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10753
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10754
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10755
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10756
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10757
0
        }
10758
9.67k
    }
10759
10760
9.67k
    if (pdf14pct->params.overprint_sim_push &&
10761
0
        pdf14pct->params.num_spot_colors_int > 0) {
10762
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10763
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10764
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10765
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10766
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10767
0
    }
10768
    /* if the device has separations already defined (by SeparationOrderNames) */
10769
    /* we need to copy them (allocating new names) so the colorants are in the */
10770
    /* same order as the target device.                                        */
10771
9.67k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10772
1.07k
        code = devn_copy_params(target, (gx_device *)pdev);
10773
1.07k
        if (code < 0)
10774
0
            return code;
10775
1.07k
    }
10776
9.67k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10777
9.67k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10778
9.67k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10779
9.67k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10780
9.67k
    pdev->color_info.separable_and_linear =
10781
9.67k
        target->color_info.separable_and_linear;
10782
9.67k
    *ppdev = (gx_device *) pdev;
10783
9.67k
    return code;
10784
9.67k
}
10785
10786
/*
10787
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10788
 * compositor device is never removed.  (We do not have a remove compositor
10789
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10790
 * routine implements that action.
10791
 */
10792
static  int
10793
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10794
                                gx_device * dev)
10795
9.67k
{
10796
9.67k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10797
9.67k
    gx_device * target = pdev->target;
10798
10799
9.67k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10800
10801
    /*
10802
     * To disable the action of this device, we forward all device
10803
     * procedures to the target except the composite and copy
10804
     * the target's color_info.
10805
     */
10806
9.67k
    dev->color_info = target->color_info;
10807
9.67k
    pdf14_forward_device_procs(dev);
10808
9.67k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10809
9.67k
    return 0;
10810
9.67k
}
10811
10812
/*
10813
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10814
 * compositor device is never removed.  (We do not have a remove compositor
10815
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10816
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10817
 * again.
10818
 */
10819
static  int
10820
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10821
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10822
0
{
10823
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10824
0
    gx_device * target = pdev->target;
10825
0
    pdf14_clist_device dev_proto;
10826
0
    int code;
10827
10828
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10829
    /*
10830
     * We will not use the entire prototype device but we will set the
10831
     * color related info to match the prototype.
10832
     */
10833
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10834
0
                                        pgs, pdf14pct, false);
10835
0
    if (code < 0)
10836
0
        return code;
10837
0
    pdev->color_info = dev_proto.color_info;
10838
10839
0
    if (dev_proto.initialize_device_procs != NULL)
10840
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10841
10842
0
    pdev->procs = dev_proto.procs;
10843
0
    pdev->pad = target->pad;
10844
0
    pdev->log2_align_mod = target->log2_align_mod;
10845
10846
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10847
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10848
0
    else
10849
0
        pdev->num_planar_planes = target->num_planar_planes;
10850
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10851
10852
0
    copy_tag_setup(dev, target);
10853
10854
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10855
0
    gx_device_fill_in_procs((gx_device *)pdev);
10856
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10857
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10858
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10859
0
    check_device_separable((gx_device *)pdev);
10860
0
    return code;
10861
0
}
10862
10863
/*
10864
 * devicen params
10865
 */
10866
gs_devn_params *
10867
pdf14_ret_devn_params(gx_device *pdev)
10868
2.28M
{
10869
2.28M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10870
10871
2.28M
    return &(p14dev->devn_params);
10872
2.28M
}
10873
10874
/*
10875
 * devicen params
10876
 */
10877
gs_devn_params *
10878
pdf14_accum_ret_devn_params(gx_device *pdev)
10879
0
{
10880
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10881
10882
0
    return &(p14dev->devn_params);
10883
0
}
10884
10885
static int
10886
pdf14_accum_get_color_comp_index(gx_device * dev,
10887
    const char * pname, int name_size, int component_type)
10888
0
{
10889
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10890
0
    gx_device *target = p14dev->target;
10891
0
    int colorant_number = devn_get_color_comp_index(dev,
10892
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10893
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10894
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10895
10896
0
    if (target != NULL)
10897
        /* colorant_number returned here _should_ be the same as from above */
10898
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10899
0
                              (target, (const char *)pname, name_size, component_type);
10900
0
    return colorant_number;
10901
0
}
10902
10903
/*
10904
 * The following procedures are used to map the standard color spaces into
10905
 * the separation color components for the pdf14_accum device.
10906
 */
10907
static void
10908
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10909
0
{
10910
0
    int * map =
10911
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10912
10913
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10914
0
}
10915
10916
static void
10917
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10918
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10919
0
{
10920
0
    int * map =
10921
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10922
10923
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10924
0
}
10925
10926
static void
10927
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10928
    frac c, frac m, frac y, frac k, frac out[])
10929
0
{
10930
0
    const int * map =
10931
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10932
10933
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10934
0
}
10935
10936
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10937
    pdf14_accum_gray_cs_to_cmyk_cm,
10938
    pdf14_accum_rgb_cs_to_cmyk_cm,
10939
    pdf14_accum_cmyk_cs_to_cmyk_cm
10940
};
10941
10942
static const gx_cm_color_map_procs *
10943
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10944
0
{
10945
0
    *map_dev = dev;
10946
0
    return &pdf14_accum_cm_procs;
10947
0
}
10948
10949
/*
10950
 *  Device proc for updating the equivalent CMYK color for spot colors.
10951
 */
10952
static int
10953
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10954
0
{
10955
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10956
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10957
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10958
0
                                              &pdev->equiv_cmyk_colors);
10959
10960
0
    if (code >= 0 && tdev != NULL)
10961
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10962
0
    return code;
10963
0
}
10964
10965
/* Used when doing overprint simulation and have spot colors */
10966
static int
10967
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10968
0
{
10969
0
    pdf14_device *pdev = (pdf14_device *)dev;
10970
0
    int code;
10971
10972
    /* Make sure we are not All or None */
10973
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10974
0
        pcs->params.separation.sep_type != SEP_OTHER)
10975
0
            return 0;
10976
10977
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10978
0
        &pdev->op_pequiv_cmyk_colors);
10979
0
    return code;
10980
0
}
10981
10982
/*
10983
 * Retrieve a list of spot color names for the PDF14 device.
10984
 */
10985
int
10986
put_param_pdf14_spot_names(gx_device * pdev,
10987
                gs_separations * pseparations, gs_param_list * plist)
10988
84.0k
{
10989
84.0k
    int code, num_spot_colors, i;
10990
84.0k
    gs_param_string str;
10991
10992
    /* Check if the given keyname is present. */
10993
84.0k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10994
84.0k
                                                &num_spot_colors);
10995
84.0k
    switch (code) {
10996
0
        default:
10997
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10998
0
            break;
10999
84.0k
        case 1:
11000
84.0k
            return 0;
11001
0
        case 0:
11002
0
            if (num_spot_colors < 1 ||
11003
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11004
0
                return_error(gs_error_rangecheck);
11005
0
            for (i = 0; i < num_spot_colors; i++) {
11006
0
                char buff[20];
11007
0
                byte * sep_name;
11008
11009
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11010
0
                code = param_read_string(plist, buff, &str);
11011
0
                switch (code) {
11012
0
                    default:
11013
0
                        param_signal_error(plist, buff, code);
11014
0
                        break;
11015
0
                    case 0:
11016
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11017
0
                                str.size, "put_param_pdf14_spot_names");
11018
0
                        if (sep_name == NULL)
11019
0
                            return_error(gs_error_VMerror);
11020
11021
0
                        memcpy(sep_name, str.data, str.size);
11022
0
                        pseparations->names[i].size = str.size;
11023
0
                        pseparations->names[i].data = sep_name;
11024
0
                }
11025
0
            }
11026
0
            pseparations->num_separations = num_spot_colors;
11027
0
            break;
11028
84.0k
    }
11029
0
    return 0;;
11030
0
}
11031
11032
/*
11033
 * This procedure will have information from the PDF 1.4 clist writing
11034
 * clist compositior device.  This is information output the compressed
11035
 * color list info which is needed for the support of spot colors in
11036
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11037
 * clist reading compositor.  However this device is not created until
11038
 * the clist is read.  To get this info to that device, we have to
11039
 * temporarily store that info in the output device.  This routine saves
11040
 * that info in the output device.
11041
 */
11042
int
11043
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11044
                                        gs_param_list * plist)
11045
84.0k
{
11046
84.0k
    int code;
11047
84.0k
    code = put_param_pdf14_spot_names(pdev,
11048
84.0k
                       &pdevn_params->pdf14_separations, plist);
11049
84.0k
    return code;
11050
84.0k
}
11051
11052
/*
11053
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11054
 * when we are creating the clist.  The second is for imaging the data from
11055
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11056
 * This routine is only called once the PDF 1.4 clist write compositor already
11057
 * exists.
11058
 */
11059
static  int
11060
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11061
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11062
    gx_device *cdev)
11063
1.60M
{
11064
1.60M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11065
1.60M
    int code, is_pdf14_compositor;
11066
1.60M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11067
1.60M
    bool deep = device_is_deep(dev);
11068
11069
    /* We only handle a few PDF 1.4 transparency operations */
11070
1.60M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11071
987k
        switch (pdf14pct->params.pdf14_op) {
11072
0
            case PDF14_PUSH_DEVICE:
11073
                /* Re-activate the PDF 1.4 compositor */
11074
/*
11075
                We previously did:
11076
11077
                pdev->saved_target_color_info = pdev->target->color_info;
11078
11079
                Here, but since we already saved and modified the the color_info
11080
                of the target clist device in gs_pdf14_clist_device_push() this is
11081
                overwriting saved_target_color_info that we already saved with the
11082
                group color_info, meaning when we set it back again, it's incorrect.
11083
*/
11084
0
                pdev->target->color_info = pdev->color_info;
11085
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11086
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11087
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11088
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11089
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11090
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11091
0
                pdev->saved_target_get_color_mapping_procs =
11092
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11093
0
                pdev->saved_target_get_color_comp_index =
11094
0
                                        dev_proc(pdev->target, get_color_comp_index);
11095
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11096
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11097
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11098
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11099
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11100
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11101
0
                gx_set_cmap_procs(pgs, dev);
11102
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11103
0
                pdev->blend_mode = pdev->text_knockout = 0;
11104
0
                pdev->opacity = pdev->shape = 0.0;
11105
0
                if (code < 0)
11106
0
                    return code;
11107
                /*
11108
                 * This routine is part of the PDF 1.4 clist write device.
11109
                 * Change the compositor procs to not create another since we
11110
                 * do not need to create a chain of identical devices.
11111
                 */
11112
0
                {
11113
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11114
11115
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11116
0
                    code = dev_proc(pdev->target, composite)
11117
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11118
                    /* We should never have created a new device here. */
11119
0
                    assert(code != 1);
11120
0
                    return code;
11121
0
                }
11122
9.67k
            case PDF14_POP_DEVICE:
11123
9.67k
            {
11124
9.67k
                gx_device *clistdev = pdev->target;
11125
11126
                /* Find the clist device */
11127
9.67k
                while (1) {
11128
9.67k
                    gxdso_device_child_request req;
11129
                    /* Ignore any errors here, that's expected as non-clist
11130
                     * devices don't implement it. */
11131
9.67k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11132
9.67k
                    if (code == 1)
11133
9.67k
                        break;
11134
0
                    req.n = 0;
11135
0
                    req.target = clistdev;
11136
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11137
0
                    if (code < 0)
11138
0
                        return code;
11139
0
                    clistdev = req.target;
11140
0
                }
11141
11142
                /* If we have overprint simulation spot color information, store
11143
                   it in a pseudo-band of the clist */
11144
9.67k
                if (pdev->overprint_sim &&
11145
0
                    pdev->devn_params.page_spot_colors > 0) {
11146
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11147
0
                        &pdev->op_pequiv_cmyk_colors);
11148
0
                    if (code < 0)
11149
0
                        return code;
11150
0
                }
11151
11152
                /* If we hit an error during an SMask, we need to undo the color
11153
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11154
                 * for itself if it needs to take action.
11155
                 */
11156
9.67k
                pdf14_decrement_smask_color(pgs, dev);
11157
                /* Restore the color_info for the clist device */
11158
9.67k
                clistdev->color_info = pdev->saved_target_color_info;
11159
9.67k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11160
9.67k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11161
9.67k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11162
9.67k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11163
9.67k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11164
9.67k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11165
9.67k
                gx_set_cmap_procs(pgs, clistdev);
11166
9.67k
                gx_device_decache_colors(clistdev);
11167
                /* Disable the PDF 1.4 compositor */
11168
9.67k
                pdf14_disable_clist_device(mem, pgs, dev);
11169
                /*
11170
                 * Make sure that the transfer funtions, etc. are current.
11171
                 */
11172
9.67k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11173
9.67k
                if (code < 0)
11174
0
                    return code;
11175
9.67k
                break;
11176
9.67k
            }
11177
9.67k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11178
40.5k
            case PDF14_BEGIN_TRANS_GROUP:
11179
40.5k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11180
18.3k
                    pdev->depth_within_smask++;
11181
40.5k
                pdev->smask_constructed = 0;
11182
                /*
11183
                 * Keep track of any changes made in the blending parameters.
11184
                   These need to be written out in the same bands as the group
11185
                   information is written.  Hence the passing of the dimensions
11186
                   for the group. */
11187
40.5k
                code = pdf14_clist_update_params(pdev, pgs, true,
11188
40.5k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11189
40.5k
                if (code < 0)
11190
0
                    return code;
11191
40.5k
                if (pdf14pct->params.Background_components != 0 &&
11192
0
                    pdf14pct->params.Background_components !=
11193
0
                    pdev->color_info.num_components)
11194
0
                    return_error(gs_error_rangecheck);
11195
11196
                /* We need to update the clist writer device procs based upon the
11197
                   the group color space. This ensures the proper color data is
11198
                   written out to the device. For simplicity, the list item is
11199
                   created even if the color space did not change */
11200
40.5k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11201
40.5k
                if (code < 0)
11202
0
                    return code;
11203
11204
40.5k
                break;
11205
41.3k
            case PDF14_BEGIN_TRANS_MASK:
11206
                /* We need to update the clist writer device procs based upon the
11207
                   the group color space.  For simplicity, the list item is created
11208
                   even if the color space did not change */
11209
                /* First store the current ones */
11210
41.3k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11211
22.8k
                    break;
11212
11213
                /* Update the color settings of the clist writer.  Store information in stack */
11214
18.4k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11215
18.4k
                if (code < 0)
11216
0
                    return code;
11217
11218
                /* Also, if the BC is a value that may end up as something other
11219
                  than transparent. We must use the parent colors bounding box in
11220
                  determining the range of bands in which this mask can affect.
11221
                  So, if needed change the masks bounding box at this time */
11222
18.4k
                pdev->in_smask_construction++;
11223
18.4k
                break;
11224
390k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11225
390k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11226
16
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11227
16
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11228
16
                } else
11229
390k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11230
390k
                *pcdev = dev;
11231
390k
                return 0; /* Never put into clist. Only used during writing */
11232
394k
            case PDF14_END_TRANS_TEXT_GROUP:
11233
394k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11234
391k
                    *pcdev = dev;
11235
391k
                    return 0; /* Avoids spurious ET calls in interpreter */
11236
391k
                }
11237
2.73k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11238
2.73k
                code = pdf14_clist_pop_color_model(dev, pgs);
11239
2.73k
                if (code < 0)
11240
0
                    return code;
11241
2.73k
                break;
11242
18.4k
            case PDF14_END_TRANS_MASK:
11243
18.4k
                pdev->in_smask_construction--;
11244
18.4k
                if (pdev->in_smask_construction < 0)
11245
0
                    pdev->in_smask_construction = 0;
11246
18.4k
                if (pdev->in_smask_construction == 0)
11247
18.4k
                    pdev->smask_constructed = 1;
11248
                /* fallthrough */
11249
56.2k
            case PDF14_END_TRANS_GROUP:
11250
                /* We need to update the clist writer device procs based upon the
11251
                   the group color space. */
11252
56.2k
                code = pdf14_clist_pop_color_model(dev, pgs);
11253
56.2k
                if (pdev->depth_within_smask)
11254
18.3k
                    pdev->depth_within_smask--;
11255
56.2k
                if (code < 0)
11256
0
                    return code;
11257
56.2k
                break;
11258
56.2k
            case PDF14_PUSH_TRANS_STATE:
11259
0
                break;
11260
18.0k
            case PDF14_POP_TRANS_STATE:
11261
18.0k
                break;
11262
18.4k
            case PDF14_PUSH_SMASK_COLOR:
11263
18.4k
                code = pdf14_increment_smask_color(pgs,dev);
11264
18.4k
                *pcdev = dev;
11265
18.4k
                return code;  /* Note, this are NOT put in the clist */
11266
0
                break;
11267
18.4k
            case PDF14_POP_SMASK_COLOR:
11268
18.4k
                code = pdf14_decrement_smask_color(pgs,dev);
11269
18.4k
                *pcdev = dev;
11270
18.4k
                return code;  /* Note, this are NOT put in the clist */
11271
0
                break;
11272
0
            case PDF14_SET_BLEND_PARAMS:
11273
                /* If there is a change we go ahead and apply it to the target */
11274
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11275
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11276
0
                *pcdev = dev;
11277
0
                return code;
11278
0
                break;
11279
0
            case PDF14_ABORT_DEVICE:
11280
0
                code = gx_abort_trans_device(pgs, dev);
11281
0
                if (pdev->free_devicen) {
11282
0
                    devn_free_params(dev);
11283
0
                }
11284
0
                pdf14_disable_device(dev);
11285
0
                pdf14_close(dev);
11286
0
                *pcdev = dev;
11287
0
                return code;
11288
0
                break;
11289
0
            default:
11290
0
                break;   /* Pass remaining ops to target */
11291
987k
        }
11292
987k
    }
11293
787k
    code = dev_proc(pdev->target, composite)
11294
787k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11295
    /* If we were accumulating into a pdf14-clist-accum device, */
11296
    /* we now have to render the page into it's target device */
11297
787k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11298
9.67k
        pdev->target->stype == &st_gx_devn_accum_device) {
11299
11300
3.30k
        int i, y, rows_used;
11301
3.30k
        byte *linebuf;
11302
3.30k
        byte *actual_data;
11303
3.30k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11304
        /* get the target device we want to send the image to */
11305
3.30k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11306
3.30k
        gs_image1_t image;
11307
3.30k
        gs_color_space *pcs;
11308
3.30k
        gx_image_enum_common_t *info = NULL;
11309
3.30k
        gx_image_plane_t planes;
11310
3.30k
        gsicc_rendering_param_t render_cond;
11311
3.30k
        cmm_dev_profile_t *dev_profile;
11312
3.30k
        bool save_planar = pdev->num_planar_planes;
11313
3.30k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11314
3.30k
        int save_num_separations;
11315
3.30k
        gs_int_rect rect;
11316
11317
3.30k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11318
3.30k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11319
3.30k
        pdev->num_planar_planes = save_planar;
11320
11321
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11322
         * colors do require devn support
11323
         */
11324
3.30k
        if (tdev->color_info.num_components <= 4 ||
11325
3.30k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11326
            /*
11327
             * Set color space in preparation for sending an image.
11328
             */
11329
3.30k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11330
3.30k
            if (code < 0)
11331
0
                goto put_accum_error;
11332
11333
            /* Need to set this to avoid color management during the
11334
               image color render operation.  Exception is for the special case
11335
               when the destination was CIELAB.  Then we need to convert from
11336
               default RGB to CIELAB in the put image operation.  That will happen
11337
               here as we should have set the profile for the pdf14 device to RGB
11338
               and the target will be CIELAB */
11339
3.30k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11340
3.30k
            if (code < 0)
11341
0
                goto put_accum_error;
11342
3.30k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11343
3.30k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11344
            /* pcs takes a reference to the profile data it just retrieved. */
11345
3.30k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11346
3.30k
            if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS) {
11347
0
                code = gs_note_error(gs_error_rangecheck);
11348
0
                goto put_accum_error;
11349
0
            }
11350
3.30k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11351
3.30k
        } else {
11352
             /* DeviceN case -- need to handle spot colors */
11353
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11354
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11355
0
            if (code < 0)
11356
0
                goto put_accum_error;
11357
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11358
0
            pcs->params.device_n.use_alt_cspace = false;
11359
11360
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11361
0
                goto put_accum_error;
11362
0
            }
11363
            /* One last thing -- we need to fudge the pgs->color_component_map */
11364
0
            for (i=0; i < tdev->color_info.num_components; i++)
11365
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11366
            /* copy devn_params that were accumulated into the target device's devn_params */
11367
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11368
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11369
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11370
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11371
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11372
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11373
0
            target_devn_params->separations = tdev->devn_params.separations;
11374
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11375
0
                   sizeof(gs_separation_map));
11376
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11377
0
        }
11378
3.30k
        if (linebuf == NULL) {
11379
0
            code = gs_error_VMerror;
11380
0
            goto put_accum_error;
11381
0
        }
11382
3.30k
        gs_image_t_init_adjust(&image, pcs, false);
11383
3.30k
        image.ImageMatrix.xx = (float)pdev->width;
11384
3.30k
        image.ImageMatrix.yy = (float)pdev->height;
11385
3.30k
        image.Width = pdev->width;
11386
3.30k
        image.Height = pdev->height;
11387
3.30k
        image.BitsPerComponent = 8<<deep;
11388
3.30k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11389
3.30k
        ctm_only_writable(pgs).xy = 0;
11390
3.30k
        ctm_only_writable(pgs).yx = 0;
11391
3.30k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11392
3.30k
        ctm_only_writable(pgs).tx = 0.0;
11393
3.30k
        ctm_only_writable(pgs).ty = 0.0;
11394
3.30k
        code = dev_proc(target, begin_typed_image) (target,
11395
3.30k
                                                    pgs, NULL,
11396
3.30k
                                                    (gs_image_common_t *)&image,
11397
3.30k
                                                    NULL, NULL, NULL,
11398
3.30k
                                                    pgs->memory, &info);
11399
3.30k
        if (code < 0)
11400
0
            goto put_accum_error;
11401
3.30k
        rect.p.x = 0;
11402
3.30k
        rect.q.x = tdev->width;
11403
7.07M
        for (y=0; y < tdev->height; y++) {
11404
7.06M
            gs_get_bits_params_t params;
11405
11406
7.06M
            params.options = (GB_ALIGN_ANY |
11407
7.06M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11408
7.06M
                              GB_OFFSET_0 |
11409
7.06M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11410
7.06M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11411
7.06M
            params.x_offset = 0;
11412
7.06M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11413
7.06M
            params.data[0] = linebuf;
11414
7.06M
            rect.p.y = y;
11415
7.06M
            rect.q.y = y+1;
11416
7.06M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11417
7.06M
                                                      &rect, &params);
11418
7.06M
            if (code < 0)
11419
6
                goto put_accum_error;
11420
7.06M
            actual_data = params.data[0];
11421
7.06M
            planes.data = actual_data;
11422
7.06M
            planes.data_x = 0;
11423
7.06M
            planes.raster = tdev->width * tdev->color_info.num_components;
11424
7.06M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11425
0
                goto put_accum_error;
11426
7.06M
        }
11427
11428
3.30k
put_accum_error:
11429
3.30k
        if (info != NULL) {
11430
3.30k
            if (code < 0)
11431
6
                (void)info->procs->end_image(info, true);
11432
3.29k
            else
11433
3.29k
                code = info->procs->end_image(info, true);
11434
3.30k
        }
11435
11436
3.30k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11437
        /* This will also decrement the device profile */
11438
3.30k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11439
3.30k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11440
        /* Now unhook the clist device and hook to the original so we can clean up */
11441
3.30k
        gx_device_set_target((gx_device_forward *)pdev,
11442
3.30k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11443
3.30k
        pdev->pclist_device = pdev->target;
11444
3.30k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11445
3.30k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11446
3.30k
        if (target_devn_params != NULL) {
11447
            /* prevent devn_free_params from freeing names still in use by target device */
11448
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11449
0
            tdev->devn_params.separations.num_separations = 0;
11450
0
        }
11451
3.30k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11452
3.30k
        if (target_devn_params != NULL) {
11453
0
            target_devn_params->separations.num_separations = save_num_separations;
11454
0
        }
11455
3.30k
        return code;    /* DON'T perform set_target */
11456
3.30k
    }
11457
783k
    if (code == 1) {
11458
        /* We just wrapped pdev->target, so we need to update that.*/
11459
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11460
0
        code = 0; /* We did not wrap dev. */
11461
0
    }
11462
783k
    *pcdev = dev;
11463
783k
    return code;
11464
787k
}
11465
11466
/*
11467
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11468
 * compositor' method.  However the compositor is disabled when we are not
11469
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11470
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11471
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11472
 * to the targer.
11473
 */
11474
static  int
11475
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11476
        const gs_composite_t * pct, gs_gstate * pgs,
11477
        gs_memory_t * mem, gx_device *cdev)
11478
0
{
11479
0
    pdf14_device *pdev = (pdf14_device *)dev;
11480
0
    gx_device * tdev = pdev->target;
11481
0
    gx_device * ndev;
11482
0
    int code;
11483
11484
0
    *pcdev = dev;
11485
0
    if (gs_is_pdf14trans_compositor(pct)) {
11486
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11487
11488
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11489
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11490
0
        return 0;
11491
0
    }
11492
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11493
0
    if (code == 1) {
11494
        /* We just wrapped tdev, so update our target. */
11495
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11496
0
        code = 0; /* We did not wrap dev. */
11497
0
    }
11498
0
    return code;
11499
0
}
11500
11501
/*
11502
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11503
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11504
 */
11505
static  int
11506
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11507
                          bool crop_blend_params,
11508
                          gs_pdf14trans_params_t *group_params)
11509
3.64M
{
11510
3.64M
    gs_pdf14trans_params_t params = { 0 };
11511
3.64M
    gx_device * pcdev;
11512
3.64M
    int changed = 0;
11513
3.64M
    int code = 0;
11514
3.64M
    gs_composite_t *pct_new = NULL;
11515
11516
3.64M
    params.crop_blend_params = crop_blend_params;
11517
11518
3.64M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11519
3.64M
    if (pgs->blend_mode != pdev->blend_mode) {
11520
18.5k
        changed |= PDF14_SET_BLEND_MODE;
11521
18.5k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11522
18.5k
    }
11523
3.64M
    if (pgs->text_knockout != pdev->text_knockout) {
11524
9.33k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11525
9.33k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11526
9.33k
    }
11527
3.64M
    if (pgs->alphaisshape != pdev->ais) {
11528
1.66k
        changed |= PDF14_SET_AIS;
11529
1.66k
        params.ais = pdev->ais = pgs->alphaisshape;
11530
1.66k
    }
11531
3.64M
    if (pgs->overprint != pdev->overprint) {
11532
14.8k
        changed |= PDF14_SET_OVERPRINT;
11533
14.8k
        params.overprint = pdev->overprint = pgs->overprint;
11534
14.8k
    }
11535
3.64M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11536
14.7k
        changed |= PDF14_SET_STROKEOVERPRINT;
11537
14.7k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11538
14.7k
    }
11539
3.64M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11540
24.8k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11541
24.8k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11542
24.8k
    }
11543
3.64M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11544
17.0k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11545
17.0k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11546
17.0k
    }
11547
3.64M
    if ((pgs->is_fill_color && pdev->op_state != GS_OP_STATE_FILL)) {
11548
26.8k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11549
26.8k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_FILL;
11550
26.8k
        if_debug0m('v', pgs->memory,
11551
26.8k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_FILL \n");
11552
26.8k
    }
11553
3.64M
    if ((!pgs->is_fill_color && pdev->op_state != GS_OP_STATE_STROKE)) {
11554
27.9k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11555
27.9k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_STROKE;
11556
27.9k
        if_debug0m('v', pgs->memory,
11557
27.9k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_STROKE \n");
11558
27.9k
    }
11559
3.64M
    if (crop_blend_params) {
11560
40.5k
        params.ctm = group_params->ctm;
11561
40.5k
        params.bbox = group_params->bbox;
11562
40.5k
    }
11563
3.64M
    params.changed = changed;
11564
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11565
       now to the target.  Otherwise we send the compositor action
11566
       to the pdf14 device at this time.  This is due to the fact that we
11567
       need to often perform this operation when we are already starting to
11568
       do a compositor action */
11569
3.64M
    if (changed != 0) {
11570
108k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11571
108k
        if (code < 0)
11572
0
            return code;
11573
108k
        code = dev_proc(pdev->target, composite)
11574
108k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11575
108k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11576
108k
    }
11577
3.64M
    return code;
11578
3.64M
}
11579
11580
/*
11581
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11582
 * writing the clist.
11583
 */
11584
static  int
11585
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11586
                           gx_path *ppath, const gx_fill_params *params,
11587
                           const gx_drawing_color *pdcolor,
11588
                           const gx_clip_path *pcpath)
11589
922k
{
11590
922k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11591
922k
    gs_gstate new_pgs = *pgs;
11592
922k
    int code;
11593
922k
    gs_pattern2_instance_t *pinst = NULL;
11594
922k
    gx_device_forward * fdev = (gx_device_forward *)dev;
11595
922k
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11596
922k
    gsicc_rendering_param_t render_cond;
11597
922k
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11598
922k
    int push_group = 0;
11599
11600
922k
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11601
922k
    if (code < 0)
11602
0
        return code;
11603
922k
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11604
922k
    if (code < 0)
11605
0
        return code;
11606
11607
922k
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11608
1.41k
        check_device_separable(dev);
11609
11610
922k
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11611
922k
                          &render_cond);
11612
922k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11613
922k
                          &render_cond);
11614
11615
    /*
11616
     * Ensure that that the PDF 1.4 reading compositor will have the current
11617
     * blending parameters.  This is needed since the fill_rectangle routines
11618
     * do not have access to the gs_gstate.  Thus we have to pass any
11619
     * changes explictly.
11620
     */
11621
922k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11622
922k
    if (code < 0)
11623
0
        return code;
11624
    /* If we are doing a shading fill and we are in a transparency group of a
11625
       different color space, then we do not want to do the shading in the
11626
       device color space. It must occur in the source space.  To handle it in
11627
       the device space would require knowing all the nested transparency group
11628
       color space as well as the transparency.  Some of the shading code ignores
11629
       this, so we have to pass on the clist_writer device to enable proper
11630
       mapping to the transparency group color space. */
11631
11632
922k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11633
        /* Non-idempotent blends require a transparency
11634
         * group to be pushed because shadings might
11635
         * paint several pixels twice. */
11636
10.9k
        push_group = pgs->fillconstantalpha != 1.0 ||
11637
10.3k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11638
10.9k
        pinst =
11639
10.9k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11640
10.9k
           pinst->saved->has_transparency = true;
11641
           /* The transparency color space operations are driven by the pdf14
11642
              clist writer device.  */
11643
10.9k
           pinst->saved->trans_device = dev;
11644
10.9k
    }
11645
922k
    if (push_group) {
11646
574
        gs_fixed_rect box;
11647
574
        gs_fixed_rect dev_bbox;
11648
11649
574
        if (pcpath) {
11650
574
            gx_cpath_outer_box(pcpath, &box);
11651
574
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11652
574
            rect_intersect(box, dev_bbox);
11653
574
        } else
11654
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11655
11656
574
        if (ppath) {
11657
19
            gs_fixed_rect path_box;
11658
11659
19
            gx_path_bbox(ppath, &path_box);
11660
19
            if (box.p.x < path_box.p.x)
11661
19
                box.p.x = path_box.p.x;
11662
19
            if (box.p.y < path_box.p.y)
11663
19
                box.p.y = path_box.p.y;
11664
19
            if (box.q.x > path_box.q.x)
11665
19
                box.q.x = path_box.q.x;
11666
19
            if (box.q.y > path_box.q.y)
11667
19
                box.q.y = path_box.q.y;
11668
19
        }
11669
11670
574
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11671
            /* No need to do anything */
11672
239
            if (pinst != NULL) {
11673
239
                pinst->saved->trans_device = NULL;
11674
239
            }
11675
239
            return 0;
11676
239
        }
11677
11678
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11679
335
        code = push_shfill_group(pdev, &new_pgs, &box);
11680
335
    } else
11681
922k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11682
922k
    if (code >= 0) {
11683
922k
        new_pgs.trans_device = dev;
11684
922k
        new_pgs.has_transparency = true;
11685
922k
        if (gx_dc_is_pattern2_color(pdcolor))
11686
10.6k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11687
911k
        else
11688
911k
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11689
922k
        new_pgs.trans_device = NULL;
11690
922k
        new_pgs.has_transparency = false;
11691
922k
    }
11692
922k
    if (code >= 0 && push_group) {
11693
332
        code = pop_shfill_group(&new_pgs);
11694
332
        if (code >= 0)
11695
332
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11696
332
    }
11697
922k
    if (pinst != NULL){
11698
10.6k
        pinst->saved->trans_device = NULL;
11699
10.6k
    }
11700
922k
    return code;
11701
922k
}
11702
11703
/*
11704
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11705
 * writing the clist.
11706
 */
11707
static  int
11708
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11709
                             gx_path *ppath, const gx_stroke_params *params,
11710
                             const gx_drawing_color *pdcolor,
11711
                             const gx_clip_path *pcpath)
11712
349k
{
11713
349k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11714
349k
    gs_gstate new_pgs = *pgs;
11715
349k
    int code = 0;
11716
349k
    gs_pattern2_instance_t *pinst = NULL;
11717
349k
    int push_group = 0;
11718
11719
    /*
11720
     * Ensure that that the PDF 1.4 reading compositor will have the current
11721
     * blending parameters.  This is needed since the fill_rectangle routines
11722
     * do not have access to the gs_gstate.  Thus we have to pass any
11723
     * changes explictly.
11724
     */
11725
349k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11726
349k
    if (code < 0)
11727
0
        return code;
11728
    /* If we are doing a shading stroke and we are in a transparency group of a
11729
       different color space, then we need to get the proper device information
11730
       passed along so that we use the correct color procs and colorinfo about
11731
       the transparency device and not the final target device */
11732
349k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11733
        /* Non-idempotent blends require a transparency
11734
         * group to be pushed because shadings might
11735
         * paint several pixels twice. */
11736
84
        push_group = pgs->strokeconstantalpha != 1.0 ||
11737
84
               !blend_is_idempotent(gs_currentblendmode(pgs));
11738
84
        if (pdev->color_model_stack != NULL) {
11739
84
            pinst =
11740
84
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11741
84
            pinst->saved->has_transparency = true;
11742
            /* The transparency color space operations are driven
11743
              by the pdf14 clist writer device.  */
11744
84
            pinst->saved->trans_device = dev;
11745
84
        }
11746
84
    }
11747
349k
    if (push_group) {
11748
0
        gs_fixed_rect box;
11749
0
        if (pcpath)
11750
0
            gx_cpath_outer_box(pcpath, &box);
11751
0
        else
11752
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11753
0
        if (ppath) {
11754
0
            gs_fixed_rect path_box;
11755
0
            gs_fixed_point expansion;
11756
11757
0
            gx_path_bbox(ppath, &path_box);
11758
            /* Expand the path bounding box by the scaled line width. */
11759
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11760
                /* The expansion is so large it caused a limitcheck. */
11761
0
                path_box.p.x = path_box.p.y = min_fixed;
11762
0
                path_box.q.x = path_box.q.y = max_fixed;
11763
0
            } else {
11764
0
                expansion.x += pgs->fill_adjust.x;
11765
0
                expansion.y += pgs->fill_adjust.y;
11766
                /*
11767
                 * It's theoretically possible for the following computations to
11768
                 * overflow, so we need to check for this.
11769
                 */
11770
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11771
0
                                path_box.p.x - expansion.x);
11772
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11773
0
                                path_box.p.y - expansion.y);
11774
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11775
0
                                path_box.q.x + expansion.x);
11776
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11777
0
                                path_box.q.y + expansion.y);
11778
0
            }
11779
0
            if (box.p.x < path_box.p.x)
11780
0
                box.p.x = path_box.p.x;
11781
0
            if (box.p.y < path_box.p.y)
11782
0
                box.p.y = path_box.p.y;
11783
0
            if (box.q.x > path_box.q.x)
11784
0
                box.q.x = path_box.q.x;
11785
0
            if (box.q.y > path_box.q.y)
11786
0
                box.q.y = path_box.q.y;
11787
0
        }
11788
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11789
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11790
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11791
0
    } else
11792
349k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11793
11794
349k
    if (code >= 0) {
11795
349k
        new_pgs.trans_device = dev;
11796
349k
        new_pgs.has_transparency = true;
11797
349k
        if (gx_dc_is_pattern2_color(pdcolor))
11798
84
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11799
349k
        else
11800
349k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11801
349k
        new_pgs.trans_device = NULL;
11802
349k
        new_pgs.has_transparency = false;
11803
349k
    }
11804
349k
    if (code >= 0 && push_group) {
11805
0
        code = pop_shfill_group(&new_pgs);
11806
0
        if (code >= 0)
11807
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11808
0
    }
11809
349k
    if (pinst != NULL)
11810
84
        pinst->saved->trans_device = NULL;
11811
349k
    return code;
11812
349k
}
11813
11814
/* Set up work for doing shading patterns in fill stroke through
11815
   the clist.  We have to do all the dirty work now since we are
11816
   going through the default fill and stroke operations individually */
11817
static int
11818
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11819
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11820
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11821
    const gx_clip_path* pcpath)
11822
0
{
11823
0
    union {
11824
0
        const gs_gstate *cpgs;
11825
0
        gs_gstate *pgs;
11826
0
    } const_breaker;
11827
0
    gs_gstate *pgs;
11828
0
    int code, code2;
11829
0
    gs_transparency_group_params_t params = { 0 };
11830
0
    gs_fixed_rect clip_bbox;
11831
0
    gs_rect bbox, group_stroke_box;
11832
0
    float fill_alpha;
11833
0
    float stroke_alpha;
11834
0
    gs_blend_mode_t blend_mode;
11835
0
    gs_fixed_rect path_bbox;
11836
0
    int expansion_code;
11837
0
    gs_fixed_point expansion;
11838
11839
    /* Break const just once, neatly */
11840
0
    const_breaker.cpgs = cpgs;
11841
0
    pgs = const_breaker.pgs;
11842
11843
0
    fill_alpha = pgs->fillconstantalpha;
11844
0
    stroke_alpha = pgs->strokeconstantalpha;
11845
0
    blend_mode = pgs->blend_mode;
11846
11847
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11848
0
    if (code < 0 && code != gs_error_unknownerror)
11849
0
        return code;
11850
0
    if (code == gs_error_unknownerror) {
11851
        /* didn't get clip box from gx_curr_fixed_bbox */
11852
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11853
0
        clip_bbox.q.x = int2fixed(dev->width);
11854
0
        clip_bbox.q.y = int2fixed(dev->height);
11855
0
    }
11856
0
    if (pcpath)
11857
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11858
11859
    /* expand the ppath using stroke expansion rule, then intersect it */
11860
0
    code = gx_path_bbox(ppath, &path_bbox);
11861
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11862
0
        return 0;   /* ignore empty path */
11863
0
    if (code < 0)
11864
0
        return code;
11865
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11866
0
    if (expansion_code >= 0) {
11867
0
        path_bbox.p.x -= expansion.x;
11868
0
        path_bbox.p.y -= expansion.y;
11869
0
        path_bbox.q.x += expansion.x;
11870
0
        path_bbox.q.y += expansion.y;
11871
0
    }
11872
0
    rect_intersect(path_bbox, clip_bbox);
11873
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11874
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11875
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11876
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11877
11878
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11879
0
    if (code < 0)
11880
0
        return code;
11881
11882
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11883
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11884
0
        pgs->overprint && pgs->stroke_overprint &&
11885
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11886
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11887
11888
0
        params.Isolated = false;
11889
0
        params.group_color_type = UNKNOWN;
11890
0
        params.Knockout = false;
11891
0
        params.page_group = false;
11892
0
        params.group_opacity = fill_alpha;
11893
0
        params.group_shape = 1.0;
11894
11895
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11896
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11897
0
        if (code < 0)
11898
0
            return code;
11899
11900
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11901
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11902
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11903
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11904
11905
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11906
0
        if (code < 0)
11907
0
            goto cleanup;
11908
11909
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11910
0
        if (code < 0)
11911
0
            goto cleanup;
11912
11913
0
    } else {
11914
        /* Push a non-isolated knockout group. Do not change the alpha or
11915
           blend modes */
11916
0
        params.Isolated = false;
11917
0
        params.group_color_type = UNKNOWN;
11918
0
        params.Knockout = true;
11919
0
        params.page_group = false;
11920
0
        params.group_opacity = 1.0;
11921
0
        params.group_shape = 1.0;
11922
11923
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11924
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11925
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11926
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11927
11928
        /* restore blend mode for actual drawing in the group */
11929
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11930
11931
0
        if (fill_alpha > 0.0) {
11932
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11933
11934
            /* If we are in an overprint situation, set the blend mode to compatible
11935
               overprint */
11936
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11937
0
                pgs->overprint &&
11938
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11939
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11940
11941
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11942
0
            if (code < 0)
11943
0
                goto cleanup;
11944
11945
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11946
0
                pgs->overprint &&
11947
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11948
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11949
0
        }
11950
11951
0
        if (stroke_alpha > 0.0) {
11952
            /* Note that the stroke can end up looking like a fill here */
11953
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11954
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11955
11956
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11957
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11958
11959
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11960
0
            if (code < 0)
11961
0
                goto cleanup;
11962
11963
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11964
0
                pgs->overprint &&
11965
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11966
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11967
0
        }
11968
0
    }
11969
11970
0
cleanup:
11971
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11972
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11973
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11974
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11975
11976
    /* Restore where we were. If an error occured while in the group push
11977
       return that error code but try to do the cleanup */
11978
0
    code2 = gs_end_transparency_group(pgs);
11979
0
    if (code2 < 0) {
11980
        /* At this point things have gone very wrong. We should just shut down */
11981
0
        code = gs_abort_pdf14trans_device(pgs);
11982
0
        return code2;
11983
0
    }
11984
11985
    /* Restore if there were any changes */
11986
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11987
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11988
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11989
11990
0
    return code;
11991
0
}
11992
11993
/*
11994
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11995
 * writing the clist.
11996
 */
11997
static  int
11998
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11999
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
12000
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
12001
                             const gx_clip_path *pcpath)
12002
8.06k
{
12003
8.06k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12004
8.06k
    gs_gstate new_pgs = *pgs;
12005
8.06k
    int code;
12006
12007
8.06k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12008
7.99k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12009
89
        return 0;
12010
12011
    /*
12012
     * Ensure that that the PDF 1.4 reading compositor will have the current
12013
     * blending parameters.  This is needed since the fill_rectangle routines
12014
     * do not have access to the gs_gstate.  Thus we have to pass any
12015
     * changes explictly.
12016
     */
12017
7.98k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12018
7.98k
    if (code < 0)
12019
0
        return code;
12020
    /* If we are doing a shading fill or stroke, the clist can't
12021
       deal with this and end up in the pdf_fill_stroke operation.
12022
       We will need to break up the fill stroke now and do
12023
       the appropriate group pushes and set up. */
12024
12025
7.98k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12026
7.98k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12027
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12028
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12029
0
    }
12030
7.98k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12031
7.98k
    new_pgs.trans_device = dev;
12032
7.98k
    new_pgs.has_transparency = true;
12033
7.98k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12034
7.98k
                                       params_stroke, pdevc_stroke, pcpath);
12035
7.98k
    new_pgs.trans_device = NULL;
12036
7.98k
    new_pgs.has_transparency = false;
12037
7.98k
    return code;
12038
7.98k
}
12039
12040
/*
12041
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12042
 * writing the clist.
12043
 */
12044
static  int
12045
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12046
                 const gs_text_params_t * text, gs_font * font,
12047
                 const gx_clip_path * pcpath,
12048
                 gs_text_enum_t ** ppenum)
12049
2.27M
{
12050
2.27M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12051
2.27M
    gs_text_enum_t *penum;
12052
2.27M
    int code;
12053
2.27M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12054
2.27M
    float opacity = pgs->fillconstantalpha;
12055
2.27M
    float shape = 1.0;
12056
2.27M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12057
2.27M
    bool draw = !(text->operation & TEXT_DO_NONE);
12058
2.27M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12059
2.27M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12060
2.27M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12061
12062
2.27M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12063
    /*
12064
     * Ensure that that the PDF 1.4 reading compositor will have the current
12065
     * blending parameters.  This is needed since the fill_rectangle routines
12066
     * do not have access to the gs_gstate.  Thus we have to pass any
12067
     * changes explictly.
12068
     */
12069
2.27M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12070
2.27M
    if (code < 0)
12071
0
        return code;
12072
    /* Pass text_begin to the target */
12073
2.27M
    code = gx_forward_text_begin(dev, pgs, text, font,
12074
2.27M
                                 pcpath, &penum);
12075
2.27M
    if (code < 0)
12076
1.10k
        return code;
12077
12078
   /* Catch case where we already pushed a group and are trying to push another one.
12079
   In that case, we will pop the current one first, as we don't want to be left
12080
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12081
   will not be caught until we do the put_image and notice that the stack is not
12082
   empty. */
12083
2.27M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12084
0
        code = gs_end_transparency_group(pgs);
12085
0
        if (code < 0)
12086
0
            return code;
12087
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12088
0
    }
12089
12090
    /* We may need to push a non-isolated transparency group if the following
12091
    is true.
12092
    1) We are not currently in one that we pushed for text.  This is
12093
    is determined by looking at the pdf14 device.
12094
    2) The blend mode is not Normal or the opacity is not 1.0
12095
    3) Text knockout is set to true
12096
    4) And we are actually drawing text
12097
    */
12098
12099
2.27M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12100
2.27M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12101
2.26M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12102
12.5k
        text_mode != 3 && /* don't bother with invisible text */
12103
12.5k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12104
2.75k
        if (draw) {
12105
2.75k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12106
2.75k
            if (code == 0)
12107
2.75k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12108
2.75k
        }
12109
2.75k
    }
12110
2.27M
    *ppenum = (gs_text_enum_t *)penum;
12111
2.27M
    return code;
12112
2.27M
}
12113
12114
static  int
12115
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12116
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12117
                           const gs_int_rect * prect,
12118
                           const gx_drawing_color * pdcolor,
12119
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12120
                           gx_image_enum_common_t ** pinfo)
12121
41.4k
{
12122
41.4k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12123
41.4k
    int code;
12124
41.4k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12125
41.4k
    const gs_image_t *pim = (const gs_image_t *)pic;
12126
41.4k
    gx_image_enum *penum;
12127
41.4k
    gx_color_tile *ptile;
12128
41.4k
    gs_rect bbox_in, bbox_out;
12129
41.4k
    gs_transparency_group_params_t tgp;
12130
    /*
12131
     * Ensure that that the PDF 1.4 reading compositor will have the current
12132
     * blending parameters.  This is needed since the fill_rectangle routines
12133
     * do not have access to the gs_gstate.  Thus we have to pass any
12134
     * changes explictly.
12135
     */
12136
41.4k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12137
41.4k
    if (code < 0)
12138
0
        return code;
12139
    /* Pass image to the target */
12140
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12141
       case the clist writer cannot handle this image itself.  In such a case,
12142
       we want to make sure we dont use the target device.  I don't necc. like
12143
       doing it this way.  Probably need to go back and do something a bit
12144
       more elegant. */
12145
41.4k
    pgs_noconst->has_transparency = true;
12146
41.4k
    pgs_noconst->trans_device = dev;
12147
12148
    /* If we are filling an image mask with a pattern that has a transparency
12149
       then we need to do some special handling */
12150
41.4k
    if (pim->ImageMask) {
12151
78
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12152
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12153
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12154
0
                    ptile = pdcolor->colors.pattern.p_tile;
12155
                    /* Set up things in the ptile so that we get the proper
12156
                       blending etc */
12157
                    /* Set the blending procs and the is_additive setting based
12158
                       upon the number of channels */
12159
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12160
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12161
0
                        ptile->ttrans->is_additive = true;
12162
0
                    } else {
12163
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12164
0
                        ptile->ttrans->is_additive = false;
12165
0
                    }
12166
                    /* Set the blending mode in the ptile based upon the current
12167
                       setting in the gs_gstate */
12168
0
                    ptile->blending_mode = pgs->blend_mode;
12169
                    /* Set the procs so that we use the proper filling method. */
12170
                    /* Let the imaging stuff get set up */
12171
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12172
0
                                                        prect, pdcolor,
12173
0
                                                        pcpath, mem, pinfo);
12174
0
                    if (code < 0)
12175
0
                        return code;
12176
12177
0
                    penum = (gx_image_enum *) *pinfo;
12178
                    /* Apply inverse of the image matrix to our
12179
                       image size to get our bounding box. */
12180
0
                    bbox_in.p.x = 0;
12181
0
                    bbox_in.p.y = 0;
12182
0
                    bbox_in.q.x = pim->Width;
12183
0
                    bbox_in.q.y = pim->Height;
12184
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12185
0
                                                     &bbox_out);
12186
0
                    if (code < 0)
12187
0
                        return code;
12188
                    /* Set up a compositor action for pushing the group */
12189
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12190
0
                    tgp.Isolated = true;
12191
0
                    tgp.Knockout = false;
12192
0
                    tgp.page_group = false;
12193
0
                    tgp.mask_id = 0;
12194
0
                    tgp.image_with_SMask = false;
12195
0
                    tgp.idle = false;
12196
0
                    tgp.iccprofile = NULL;
12197
0
                    tgp.icc_hashcode = 0;
12198
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12199
0
                    tgp.ColorSpace = NULL;
12200
0
                    tgp.text_group = 0;
12201
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12202
0
                    tgp.group_shape = 1.0;
12203
                    /* This will handle the compositor command */
12204
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12205
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12206
0
                    ptile->ttrans->image_render = penum->render;
12207
0
                    penum->render = &pdf14_pattern_trans_render;
12208
0
                    ptile->trans_group_popped = false;
12209
0
                    pgs_noconst->has_transparency = false;
12210
0
                    pgs_noconst->trans_device = NULL;
12211
0
                    return code;
12212
0
                }
12213
0
            }
12214
21
        }
12215
78
    }
12216
    /* This basically tries high level images for clist. If that fails
12217
       then we do the default */
12218
41.4k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12219
41.4k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12220
41.4k
    if (code < 0){
12221
10.9k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12222
10.9k
                                        pdcolor, pcpath, mem, pinfo);
12223
10.9k
        pgs_noconst->has_transparency = false;
12224
10.9k
        pgs_noconst->trans_device = NULL;
12225
10.9k
        return code;
12226
30.5k
    } else {
12227
30.5k
        pgs_noconst->has_transparency = false;
12228
30.5k
        pgs_noconst->trans_device = NULL;
12229
30.5k
        return code;
12230
30.5k
    }
12231
41.4k
}
12232
12233
static int
12234
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12235
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12236
2.45k
{
12237
2.45k
    int code;
12238
12239
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12240
2.45k
                                  x, y, w, h, plane_height);
12241
2.45k
    return code;
12242
2.45k
}
12243
12244
static int
12245
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12246
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12247
9.67k
{
12248
9.67k
    int code;
12249
9.67k
    pdf14_clist_device *p14dev;
12250
9.67k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12251
12252
9.67k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12253
9.67k
    if (code < 0)
12254
0
        return code;
12255
    /*
12256
     * Set the color_info of the clist device to match the compositing
12257
     * device.  We will restore it when the compositor is popped.
12258
     * See pdf14_clist_composite for the restore.  Do the
12259
     * same with the gs_gstate's get_cmap_procs.  We do not want
12260
     * the gs_gstate to use transfer functions on our color values.
12261
     * The transfer functions will be applied at the end after we
12262
     * have done our PDF 1.4 blend operations.
12263
     */
12264
9.67k
    p14dev = (pdf14_clist_device *)(*pcdev);
12265
9.67k
    p14dev->saved_target_color_info = dev->color_info;
12266
9.67k
    dev->color_info = (*pcdev)->color_info;
12267
    /* Make sure that we keep the anti-alias information though */
12268
9.67k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12269
9.67k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12270
12271
    /* adjust the clist_color_info now */
12272
9.67k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12273
9.67k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12274
9.67k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12275
9.67k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12276
9.67k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12277
12278
9.67k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12279
9.67k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12280
9.67k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12281
9.67k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12282
9.67k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12283
9.67k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12284
9.67k
    p14dev->saved_target_get_color_mapping_procs =
12285
9.67k
                              dev_proc(dev, get_color_mapping_procs);
12286
9.67k
    p14dev->saved_target_get_color_comp_index =
12287
9.67k
                              dev_proc(dev, get_color_comp_index);
12288
9.67k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12289
9.67k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12290
9.67k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12291
9.67k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12292
9.67k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12293
9.67k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12294
9.67k
    gx_set_cmap_procs(pgs, dev);
12295
9.67k
    return code;
12296
9.67k
}
12297
/*
12298
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12299
 * to create a compositing device for clist writing.  The primary purpose of
12300
 * this device is to provide support for the process color model in which
12301
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12302
 * model of the output device.)  The actual work of compositing the image is
12303
 * done on the output (reader) side of the clist.
12304
 */
12305
static  int
12306
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12307
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12308
286k
{
12309
286k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12310
286k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12311
286k
    int code = 0;
12312
12313
    /* We only handle the push/pop operations */
12314
286k
    switch (pdf14pct->params.pdf14_op) {
12315
9.67k
        case PDF14_PUSH_DEVICE:
12316
9.67k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12317
            /* Change (non-error) code to 1 to indicate that we created
12318
             * a device. */
12319
9.67k
            if (code >= 0)
12320
9.67k
                code = 1;
12321
9.67k
            return code;
12322
12323
9.67k
        case PDF14_POP_DEVICE:
12324
9.67k
            code = clist_writer_check_empty_cropping_stack(cdev);
12325
9.67k
            break;
12326
12327
3.64k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12328
40.5k
        case PDF14_BEGIN_TRANS_GROUP:
12329
40.5k
            { /* HACK: store mask_id into our params for subsequent
12330
                   calls of c_pdf14trans_write. To do this we must
12331
                   break const. */
12332
40.5k
                gs_pdf14trans_t * pdf14pct_noconst;
12333
12334
40.5k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12335
                /* What ever the current mask ID is, that is the
12336
                   softmask group through which this transparency
12337
                   group must be rendered. Store it now. */
12338
40.5k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12339
40.5k
                if_debug1m('v', pgs->memory,
12340
40.5k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12341
40.5k
                           cdev->mask_id);
12342
40.5k
            }
12343
40.5k
            break;
12344
37.7k
        case PDF14_END_TRANS_GROUP:
12345
40.4k
        case PDF14_END_TRANS_TEXT_GROUP:
12346
40.4k
            code = 0; /* A place for breakpoint. */
12347
40.4k
            break;
12348
41.3k
        case PDF14_BEGIN_TRANS_MASK:
12349
            /* A new mask has been started */
12350
41.3k
            cdev->mask_id = ++cdev->mask_id_count;
12351
            /* replacing is set everytime that we
12352
               have a zpushtransparencymaskgroup */
12353
41.3k
            { /* HACK: store mask_id into our params for subsequent
12354
                   calls of c_pdf14trans_write. To do this we must
12355
                   break const. */
12356
41.3k
                gs_pdf14trans_t * pdf14pct_noconst;
12357
12358
41.3k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12359
41.3k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12360
41.3k
                if_debug1m('v', pgs->memory,
12361
41.3k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12362
41.3k
                           cdev->mask_id);
12363
41.3k
            }
12364
41.3k
            break;
12365
18.4k
        case PDF14_END_TRANS_MASK:
12366
18.4k
            code = 0; /* A place for breakpoint. */
12367
18.4k
            break;
12368
0
        case PDF14_PUSH_TRANS_STATE:
12369
0
            code = 0; /* A place for breakpoint. */
12370
0
            break;
12371
18.0k
        case PDF14_POP_TRANS_STATE:
12372
18.0k
            code = 0; /* A place for breakpoint. */
12373
18.0k
            break;
12374
0
        case PDF14_ABORT_DEVICE:
12375
0
            code = 0;
12376
0
            break;
12377
0
        case PDF14_PUSH_SMASK_COLOR:
12378
0
            *pcdev = dev;
12379
0
            return 0;
12380
0
            break;
12381
0
        case PDF14_POP_SMASK_COLOR:
12382
0
            *pcdev = dev;
12383
0
            return 0;
12384
0
            break;
12385
108k
        default:
12386
108k
            break;   /* do nothing for remaining ops */
12387
286k
    }
12388
277k
    *pcdev = dev;
12389
277k
    if (code < 0)
12390
0
        return code;
12391
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12392
       apply_composite. */
12393
277k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12394
    /* Wrote an extra ctm. */
12395
277k
    cmd_clear_known(cdev, ctm_known);
12396
12397
277k
    return code;
12398
277k
}
12399
12400
/*
12401
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12402
 * device color_info data match the compositing device.  We need to do this
12403
 * since the PDF 1.4 transparency compositing device may use a different
12404
 * process color model than the output device.  We do not need to modify the
12405
 * color related device procs since the compositing device has its own.  We
12406
 * restore the color_info data when the transparency device is popped.
12407
 */
12408
static  int
12409
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12410
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12411
23.2M
{
12412
23.2M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12413
23.2M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12414
23.2M
    gs_devn_params * pclist_devn_params;
12415
23.2M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12416
23.2M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12417
23.2M
    gsicc_rendering_param_t render_cond;
12418
23.2M
    cmm_dev_profile_t *dev_profile;
12419
12420
23.2M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12421
23.2M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12422
23.2M
                          &render_cond);
12423
12424
    /* If we are using the blending color space, then be sure to use that. */
12425
23.2M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12426
0
        dev_profile->blend_profile != NULL)
12427
0
        cl_icc_profile = dev_profile->blend_profile;
12428
23.2M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12429
0
        dev_profile->oi_profile != NULL)
12430
0
        cl_icc_profile = dev_profile->oi_profile;
12431
12432
23.2M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12433
23.2M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12434
23.2M
                          &render_cond);
12435
    /*
12436
     * We only handle the push/pop operations. Save and restore the color_info
12437
     * field for the clist device.  This is needed since the process color
12438
     * model of the clist device needs to match the PDF 1.4 compositing
12439
     * device.
12440
     */
12441
23.2M
    switch (pdf14pct->params.pdf14_op) {
12442
1.10M
    case PDF14_PUSH_DEVICE:
12443
        /* Overprint simulation sets the profile at prototype creation, as does
12444
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12445
1.10M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12446
1.10M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12447
1.10M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12448
1.10M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12449
1.10M
                -1, "c_pdf14trans_clist_read_update");
12450
1.10M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12451
1.10M
        }
12452
            /*
12453
             * If we are blending using spot colors (i.e. the output device
12454
             * supports spot colors) then we need to transfer
12455
             * color info from the clist PDF 1.4 compositing reader device
12456
             * to the clist writer PDF 1.4 compositing device.
12457
             * This info was transfered from that device to the output
12458
             * device as a set of device parameters.  However the clist
12459
             * reader PDF 1.4 compositing device did not exist when the
12460
             * device parameters were read from the clist.  So that info
12461
             * was buffered into the output device.
12462
             */
12463
1.10M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12464
1.10M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12465
837
                int num_comp = p14dev->color_info.num_components;
12466
837
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12467
                /*
12468
                 * The number of components for the PDF14 device is the sum
12469
                 * of the process components and the number of spot colors
12470
                 * for the page.  If the color capabilities of the parent
12471
                 * device (which coming into this are the same as the p14dev)
12472
                 * are smaller than the number of page spot colors then
12473
                 * use that for the number of components. Otherwise use
12474
                 * the page_spot_colors.  The exception is, if we had used
12475
                 * the sICCOutputColors setting, then just use that, which
12476
                 * should be already baked into num_comp. With clist patterns,
12477
                 * cdev->icc_struct may be null.
12478
                 */
12479
12480
837
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12481
837
                    p14dev->devn_params.page_spot_colors =
12482
837
                        pclist_devn_params->page_spot_colors;
12483
837
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12484
0
                        if (p14dev->num_planar_planes > 0)
12485
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12486
0
                        p14dev->color_info.num_components = num_comp;
12487
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12488
837
                    } else {
12489
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12490
837
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12491
837
                            int n = p14dev->num_std_colorants +
12492
837
                                    p14dev->devn_params.page_spot_colors + has_tags;
12493
837
                            if (p14dev->num_planar_planes > 0)
12494
837
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12495
837
                            p14dev->color_info.num_components = n;
12496
837
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12497
837
                        }
12498
837
                    }
12499
837
                }
12500
                /* limit the num_components to the max. */
12501
837
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12502
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12503
                /* Transfer the data for the spot color names
12504
                   But we have to free what may be there before we do this */
12505
837
                devn_free_params((gx_device*) p14dev);
12506
837
                p14dev->devn_params.separations =
12507
837
                    pclist_devn_params->pdf14_separations;
12508
837
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12509
837
                if (num_comp != p14dev->color_info.num_components) {
12510
                    /* Historically, there has been a comment here:
12511
                       "When the pdf14 device is opened it creates a context and some
12512
                       soft mask related objects.  The push device compositor action
12513
                       will have already created these but they are the wrong size.
12514
                       We must destroy them though before reopening the device."
12515
                       I can't see why this is the case, and testing in the cluster
12516
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12517
                       shows that this freeing/NULLing the ctx here causes problems
12518
                       when the freed ctx is reinserted at the end of clist pattern
12519
                       files. Accordingly, I'm removing the freeing/NULLing for now
12520
                       at least. */
12521
0
                    int code = dev_proc(tdev, open_device) (tdev);
12522
0
                    if (code < 0)
12523
0
                        return code;
12524
0
                }
12525
837
            }
12526
            /* Check if we need to swap out the ICC profile for the pdf14
12527
               device.  This will occur if our source profile for our device
12528
               happens to be something like CIELAB.  Then we will blend in
12529
               RGB (unless a trans group is specified) */
12530
1.10M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12531
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12532
0
                                        -1, "c_pdf14trans_clist_read_update");
12533
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12534
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12535
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12536
                /* Keep a pointer to the clist device */
12537
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12538
0
            }
12539
1.10M
            break;
12540
12541
1.10M
        case PDF14_POP_DEVICE:
12542
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12543
                    the clist playback. This code is not executed while clist
12544
                    writing. */
12545
            cdev->color_info = p14dev->saved_target_color_info;
12546
#     endif
12547
1.10M
           break;
12548
12549
21.0M
        default:
12550
21.0M
            break;   /* do nothing for remaining ops */
12551
23.2M
    }
12552
12553
23.2M
    return 0;
12554
23.2M
}
12555
12556
/*
12557
 * Get cropping for the compositor command.
12558
 */
12559
static  int
12560
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12561
                          int cropping_min, int cropping_max)
12562
286k
{
12563
286k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12564
286k
    switch (pdf14pct->params.pdf14_op) {
12565
9.67k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12566
9.67k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12567
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12568
3.64k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12569
40.5k
        case PDF14_BEGIN_TRANS_GROUP:
12570
40.5k
            { gs_int_rect rect;
12571
12572
                /* Text group always uses parents size*/
12573
40.5k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12574
2.75k
                    *ry = cropping_min;
12575
2.75k
                    *rheight = cropping_max - *ry;
12576
37.7k
                } else {
12577
37.7k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12578
37.7k
                        &pdf14pct->params.bbox, &rect);
12579
                    /* We have to crop this by the parent object.   */
12580
37.7k
                    *ry = max(rect.p.y, cropping_min);
12581
37.7k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12582
37.7k
                }
12583
40.5k
                return PUSHCROP; /* Push cropping. */
12584
3.64k
            }
12585
41.3k
        case PDF14_BEGIN_TRANS_MASK:
12586
41.3k
            { gs_int_rect rect;
12587
12588
41.3k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12589
41.3k
                                                    &pdf14pct->params.bbox, &rect);
12590
                /* We have to crop this by the parent object and worry about the BC outside
12591
                   the range, except for image SMask which don't affect areas outside the image.
12592
                   The presence of a transfer function opens the possibility of issues with this */
12593
41.3k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12594
17.2k
                      pdf14pct->params.function_is_identity)) {
12595
                    /* In this case there will not be a background effect to
12596
                       worry about.  The mask will not have any effect outside
12597
                       the bounding box.  This is NOT the default or common case. */
12598
17.2k
                    *ry = max(rect.p.y, cropping_min);
12599
17.2k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12600
17.2k
                    return PUSHCROP; /* Push cropping. */
12601
24.0k
                }  else {
12602
                    /* We need to make the soft mask range as large as the parent
12603
                       due to the fact that the background color can have an impact
12604
                       OUTSIDE the bounding box of the soft mask */
12605
24.0k
                    *ry = cropping_min;
12606
24.0k
                    *rheight = cropping_max - cropping_min;
12607
24.0k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12608
22.8k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12609
1.19k
                    else
12610
1.19k
                        return PUSHCROP; /* Push cropping. */
12611
24.0k
                }
12612
41.3k
            }
12613
37.7k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12614
2.73k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12615
18.4k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12616
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12617
18.0k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12618
108k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12619
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12620
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12621
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12622
286k
    }
12623
0
    return ALLBANDS;
12624
286k
}
12625
12626
/*
12627
 * This routine will check to see if the color component name matches those
12628
 * that are available amoung the current device's color components.  If the
12629
 * color name is known to the output device then we add it to the list of
12630
 * colorants for the PDF 1.4 transparency compositor.
12631
 *
12632
 * Notes:  There are currently three different versions of The PDF 1.4
12633
 * transparency compositor device.  The choice of which one is being used
12634
 * depends upon the process color model of the output device.  This procedure
12635
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12636
 * plus spot color process color model.
12637
 *
12638
 * Parameters:
12639
 *   dev - pointer to device data structure.
12640
 *   pname - pointer to name (zero termination not required)
12641
 *   nlength - length of the name
12642
 *   number of process colorants (either 1, 3, or 4)
12643
 *
12644
 * This routine returns a positive value (0 to n) which is the device colorant
12645
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12646
 * the colorant is not being used due to a SeparationOrder device parameter.
12647
 * It returns a negative value if not found.
12648
 */
12649
static int
12650
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12651
    int name_size, int component_type, int num_process_colors, int cmyk)
12652
7.36k
{
12653
7.36k
    pdf14_device *pdev = (pdf14_device *)dev;
12654
7.36k
    gx_device *tdev = pdev->target;
12655
7.36k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12656
7.36k
    gs_separations *pseparations;
12657
7.36k
    int comp_index;
12658
7.36k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12659
7.36k
    int offset;
12660
12661
7.36k
    while (tdev->child) {
12662
0
        tdev = tdev->child;
12663
0
    }
12664
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12665
    /* get the devn_params from the target to avoid accessing using the wrong  */
12666
    /* pointer. Bug 696372.                                                    */
12667
7.36k
    if (tdev == (gx_device *)pdev)
12668
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12669
7.36k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12670
7.36k
    pseparations = &pdevn_params->separations;
12671
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12672
     * where we are in a blend color space that is RGB or Gray based and we
12673
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12674
     * Yellow or Black, then we should use the alternate tint transform */
12675
7.36k
    if (num_process_colors < 4) {
12676
589
        int k;
12677
2.94k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12678
2.35k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12679
0
                return -1;
12680
2.35k
        }
12681
589
    }
12682
12683
7.36k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12684
12685
    /* The pdf14_clist_composite may have set the color procs.
12686
       We need the real target procs. */
12687
7.36k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12688
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12689
7.36k
        target_get_color_comp_index =
12690
7.36k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12691
    /*
12692
    * If this is not a separation name then simply forward it to the target
12693
    * device or return -1 if we are doing overprint simulation.
12694
    * The halftone setup expects this.
12695
    */
12696
7.36k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12697
7.36k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12698
6.39k
            if (target_get_color_comp_index != NULL)
12699
6.39k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12700
0
            else
12701
0
                return -1;
12702
6.39k
    }
12703
973
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12704
0
        return -1;
12705
0
    }
12706
12707
    /*
12708
    * Check if the component is in either the process color model list
12709
    * or in the SeparationNames list.
12710
    */
12711
973
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12712
973
        name_size, component_type);
12713
12714
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12715
     * This is a decision we take here to avoid problems with PDFI not
12716
     * counting such colorants as spots. */
12717
973
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12718
31
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12719
0
            return -1;
12720
31
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12721
0
            return -1;
12722
31
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12723
0
            return -1;
12724
31
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12725
0
            return -1;
12726
31
    }
12727
    /* A psdrgb device, with simulate overprint will have become a cmyk
12728
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12729
     * either, but we need to return real numbers for them as the underlying
12730
     * routine won't know about these. */
12731
973
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12732
1
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12733
0
            return 3;
12734
1
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12735
0
            return 0;
12736
1
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12737
0
            return 1;
12738
1
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12739
0
            return 2;
12740
1
    }
12741
12742
    /*
12743
    * Return the colorant number if we know this name.  Note adjustment for
12744
    * compensating of blend color space.
12745
    */
12746
973
    if (comp_index >= 0)
12747
941
        return comp_index - offset;
12748
12749
    /* Only worry about the target if we are not doing an overprint simulation */
12750
32
    if (!pdev->overprint_sim) {
12751
        /*
12752
        * If we do not know this color, check if the output (target) device does.
12753
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12754
        * the colorant so we will only get < 0 returned when we hit the max. for
12755
        * the target device.
12756
        */
12757
32
        if (target_get_color_comp_index != NULL)
12758
32
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12759
0
        else
12760
0
            return -1;
12761
        /*
12762
        * Ignore color if unknown to the output device or if color is not being
12763
        * imaged due to the SeparationOrder device parameter.
12764
        */
12765
32
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12766
0
            return comp_index - offset;
12767
32
    }
12768
12769
    /*
12770
    * This is a new colorant.  Add it to our list of colorants.
12771
    * The limit accounts for the number of process colors (at least 4).
12772
    */
12773
32
    if ((pseparations->num_separations + 1) <
12774
32
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12775
32
        int sep_num = pseparations->num_separations++;
12776
32
        int color_component_number;
12777
32
        byte * sep_name;
12778
12779
32
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12780
32
            name_size, "pdf14_spot_get_color_comp_index");
12781
32
        if (sep_name == NULL) {
12782
0
            pseparations->num_separations--;  /* we didn't add it */
12783
0
            return -1;
12784
0
        }
12785
32
        memcpy(sep_name, pname, name_size);
12786
32
        pseparations->names[sep_num].size = name_size;
12787
32
        pseparations->names[sep_num].data = sep_name;
12788
32
        color_component_number = sep_num + num_process_colors;
12789
32
        if (color_component_number >= dev->color_info.max_components)
12790
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12791
32
        else
12792
32
            pdevn_params->separation_order_map[color_component_number] =
12793
32
            color_component_number;
12794
12795
        /* Indicate that we need to find equivalent CMYK color. */
12796
32
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12797
32
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12798
12799
        /* If we're doing an overprint simulation, then the target device
12800
         * (for instance) might not know about this colorant. This is annoying
12801
         * as the target can't then output the correct names. Call the target
12802
         * get_color_comp_index routine and ignore the result to give it a
12803
         * chance to stash it. */
12804
32
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12805
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12806
12807
32
        return color_component_number;
12808
32
    }
12809
12810
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12811
32
}
12812
12813
12814
/* CMYK process + spots */
12815
static int
12816
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12817
    int name_size, int component_type)
12818
6.77k
{
12819
6.77k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12820
6.77k
}
12821
12822
/* RGB process + spots */
12823
static int
12824
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12825
    int name_size, int component_type)
12826
589
{
12827
589
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12828
589
}
12829
12830
/* Gray process + spots */
12831
static int
12832
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12833
    int name_size, int component_type)
12834
0
{
12835
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12836
0
}
12837
12838
/* These functions keep track of when we are dealing with soft masks.
12839
   In such a case, we set the default color profiles to ones that ensure
12840
   proper soft mask rendering. */
12841
static int
12842
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12843
22.7k
{
12844
22.7k
    pdf14_device * pdev = (pdf14_device *) dev;
12845
22.7k
    pdf14_smaskcolor_t *result;
12846
22.7k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12847
22.7k
    int k;
12848
12849
    /* See if we have profiles already in place.   Note we also have to
12850
       worry about a corner case where this device does not have a
12851
       smaskcolor stucture to store the profiles AND the profiles were
12852
       already swapped out in the icc_manager.  This can occur when we
12853
       pushed a transparency mask and then inside the mask we have a pattern
12854
       which also has a transparency mask.   The state of the icc_manager
12855
       is that it already has done the swap and there is no need to fool
12856
       with any of this while dealing with the soft mask within the pattern */
12857
22.7k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12858
22.6k
        pgs->icc_manager->smask_profiles->swapped) {
12859
0
            return 0;
12860
0
    }
12861
22.7k
    if (pdev->smaskcolor != NULL) {
12862
17
        pdev->smaskcolor->ref_count++;
12863
17
        if_debug1m(gs_debug_flag_icc, dev->memory,
12864
17
                   "[icc] Increment smask color now %d\n",
12865
17
                   pdev->smaskcolor->ref_count);
12866
22.6k
    } else {
12867
        /* Allocate and swap out the current profiles.  The softmask
12868
           profiles should already be in place */
12869
22.6k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12870
22.6k
                                &st_pdf14_smaskcolor,
12871
22.6k
                                "pdf14_increment_smask_color");
12872
22.6k
        if (result == NULL)
12873
0
            return gs_error_VMerror;
12874
12875
22.6k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12876
22.6k
        if (result->profiles == NULL)
12877
0
            return gs_error_VMerror;
12878
12879
22.6k
        pdev->smaskcolor = result;
12880
12881
22.6k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12882
22.6k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12883
22.6k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12884
22.6k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12885
22.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12886
22.6k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12887
22.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12888
22.6k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12889
22.6k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12890
22.6k
        pgs->icc_manager->smask_profiles->swapped = true;
12891
22.6k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12892
22.6k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12893
22.6k
        pdev->smaskcolor->ref_count = 1;
12894
        /* We also need to update the profile that is currently in the
12895
           color spaces of the graphic state.  Otherwise this can be
12896
           referenced, which will result in a mismatch.  What we want to do
12897
           is see if it was the original default and only swap in that case. */
12898
68.0k
        for (k = 0; k < 2; k++) {
12899
45.3k
            gs_color_space *pcs     = pgs->color[k].color_space;
12900
45.3k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12901
45.3k
            if (profile != NULL) {
12902
43.7k
                switch(profile->data_cs) {
12903
25.1k
                    case gsGRAY:
12904
25.1k
                        if (profile->hashcode ==
12905
25.1k
                            result->profiles->smask_gray->hashcode) {
12906
23.2k
                                profile = pgs->icc_manager->default_gray;
12907
23.2k
                        }
12908
25.1k
                        break;
12909
18.3k
                    case gsRGB:
12910
18.3k
                        if (profile->hashcode ==
12911
18.3k
                            result->profiles->smask_rgb->hashcode) {
12912
10.8k
                                profile = pgs->icc_manager->default_rgb;
12913
10.8k
                        }
12914
18.3k
                        break;
12915
249
                    case gsCMYK:
12916
249
                        if (profile->hashcode ==
12917
249
                            result->profiles->smask_cmyk->hashcode) {
12918
249
                                profile = pgs->icc_manager->default_cmyk;
12919
249
                        }
12920
249
                        break;
12921
0
                    default:
12922
12923
0
                        break;
12924
43.7k
                }
12925
43.7k
                if (pcs->cmm_icc_profile_data != profile) {
12926
34.3k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12927
34.3k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12928
34.3k
                    pcs->cmm_icc_profile_data = profile;
12929
34.3k
                }
12930
43.7k
            }
12931
45.3k
        }
12932
22.6k
    }
12933
22.7k
    return 0;
12934
22.7k
}
12935
12936
static int
12937
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12938
32.3k
{
12939
32.3k
    pdf14_device * pdev = (pdf14_device *) dev;
12940
32.3k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12941
32.3k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12942
32.3k
    int k;
12943
12944
    /* See comment in pdf14_increment_smask_color to understand this one */
12945
32.3k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12946
3.94k
        pgs->icc_manager->smask_profiles->swapped) {
12947
0
            return 0;
12948
0
    }
12949
32.3k
    if (smaskcolor != NULL) {
12950
22.7k
        smaskcolor->ref_count--;
12951
22.7k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12952
22.7k
                   "[icc] Decrement smask color.  Now %d\n",
12953
22.7k
                   smaskcolor->ref_count);
12954
22.7k
        if (smaskcolor->ref_count == 0) {
12955
22.6k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12956
            /* Lets return the profiles and clean up */
12957
            /* First see if we need to "reset" the profiles that are in
12958
               the graphic state */
12959
22.6k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12960
68.0k
            for (k = 0; k < 2; k++) {
12961
45.3k
                gs_color_space *pcs = pgs->color[k].color_space;
12962
45.3k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12963
45.3k
                if (profile != NULL) {
12964
43.7k
                    switch(profile->data_cs) {
12965
25.1k
                        case gsGRAY:
12966
25.1k
                            if (profile->hashcode ==
12967
25.1k
                                pgs->icc_manager->default_gray->hashcode) {
12968
23.2k
                                    profile =
12969
23.2k
                                        smaskcolor->profiles->smask_gray;
12970
23.2k
                            }
12971
25.1k
                            break;
12972
18.3k
                        case gsRGB:
12973
18.3k
                            if (profile->hashcode ==
12974
18.3k
                                pgs->icc_manager->default_rgb->hashcode) {
12975
10.8k
                                    profile =
12976
10.8k
                                        smaskcolor->profiles->smask_rgb;
12977
10.8k
                            }
12978
18.3k
                            break;
12979
249
                        case gsCMYK:
12980
249
                            if (profile->hashcode ==
12981
249
                                pgs->icc_manager->default_cmyk->hashcode) {
12982
249
                                    profile =
12983
249
                                        smaskcolor->profiles->smask_cmyk;
12984
249
                            }
12985
249
                            break;
12986
0
                        default:
12987
12988
0
                            break;
12989
43.7k
                    }
12990
43.7k
                    if (pcs->cmm_icc_profile_data != profile) {
12991
34.3k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12992
34.3k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12993
34.3k
                        pcs->cmm_icc_profile_data = profile;
12994
34.3k
                    }
12995
43.7k
                }
12996
45.3k
            }
12997
12998
22.6k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12999
22.6k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
13000
22.6k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
13001
22.6k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
13002
22.6k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13003
22.6k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13004
22.6k
            icc_manager->smask_profiles->swapped = false;
13005
            /* We didn't increment the reference count when we assigned these
13006
             * so NULL them to avoid decrementing when smaskcolor is freed
13007
             */
13008
22.6k
            smaskcolor->profiles->smask_gray =
13009
22.6k
              smaskcolor->profiles->smask_rgb =
13010
22.6k
              smaskcolor->profiles->smask_cmyk = NULL;
13011
13012
22.6k
            pdf14_free_smask_color(pdev);
13013
22.6k
        }
13014
22.7k
    }
13015
32.3k
    return 0;
13016
32.3k
}
13017
13018
static void
13019
pdf14_free_smask_color(pdf14_device * pdev)
13020
22.6k
{
13021
22.6k
    if (pdev->smaskcolor != NULL) {
13022
22.6k
        if ( pdev->smaskcolor->profiles != NULL) {
13023
            /* Do not decrement the profiles - the references were moved
13024
               here and moved back again, so the ref counts don't change
13025
             */
13026
22.6k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13027
22.6k
                        "pdf14_free_smask_color");
13028
22.6k
        }
13029
22.6k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13030
22.6k
        pdev->smaskcolor = NULL;
13031
22.6k
    }
13032
22.6k
}
13033
13034
static void
13035
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13036
1.11M
{
13037
1.11M
    gx_device * const dev = (gx_device *)vptr;
13038
1.11M
    pdf14_device * pdev = (pdf14_device *)dev;
13039
1.11M
    int k;
13040
13041
1.11M
    pdf14_cleanup_group_color_profiles (pdev);
13042
13043
1.11M
    if (pdev->ctx) {
13044
32
        pdf14_ctx_free(pdev->ctx);
13045
32
        pdev->ctx = NULL;
13046
32
    }
13047
13048
1.11M
    while (pdev->color_model_stack) {
13049
32
        pdf14_pop_group_color(dev, NULL);
13050
32
    }
13051
13052
1.11M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13053
32
        if (pdev->devn_params.separations.names[k].data) {
13054
32
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13055
32
            pdev->devn_params.separations.names[k].data = NULL;
13056
32
        }
13057
32
    }
13058
13059
1.11M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13060
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13061
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13062
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13063
0
        }
13064
0
    }
13065
13066
1.11M
    gx_device_finalize(cmem, vptr);
13067
1.11M
}
13068
13069
#if DUMP_MASK_STACK
13070
13071
static void
13072
dump_mask_stack(pdf14_mask_t *mask_stack)
13073
{
13074
    pdf14_mask_t *curr_mask = mask_stack;
13075
    int level = 0;
13076
13077
    while (curr_mask != NULL) {
13078
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13079
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13080
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13081
        level++;
13082
        curr_mask = curr_mask->previous;
13083
    }
13084
}
13085
13086
/* A function to display the current state of the mask stack */
13087
static void
13088
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13089
{
13090
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13091
    if (ctx->mask_stack != NULL) {
13092
        dump_mask_stack(ctx->mask_stack);
13093
    }
13094
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13095
    if (ctx->stack != NULL) {
13096
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13097
        if (ctx->stack->mask_stack != NULL) {
13098
            dump_mask_stack(ctx->stack->mask_stack);
13099
        }
13100
    }
13101
}
13102
13103
#else
13104
13105
#ifdef DEBUG
13106
static void
13107
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13108
{
13109
    return;
13110
}
13111
#endif
13112
13113
#endif /* DUMP_MASK_STACK */