Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/base/gdevp14.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
74
#if RAW_DUMP
75
unsigned int global_index = 0;
76
unsigned int clist_band_count = 0;
77
#endif
78
79
#define DUMP_MASK_STACK 0
80
81
/* Static prototypes */
82
/* Used for filling rects when we are doing a fill with a pattern that
83
   has transparency */
84
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
85
                                   gx_path * ppath, const gx_fill_params * params,
86
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
87
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
88
static void pdf14_free_smask_color(pdf14_device * pdev);
89
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
90
                                         const gs_rect *pbbox, gs_gstate *pgs);
91
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
92
                                     const gs_gstate * pgs,
93
                                     bool crop_blend_params,
94
                                     gs_pdf14trans_params_t *group_params);
95
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
96
                                               int w, int h, gx_color_index color,
97
                                               const gx_device_color *pdc,
98
                                               bool devn);
99
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
100
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
101
                                  gx_color_index color, const gx_device_color *pdc,
102
                                  int depth, bool devn);
103
104
/* Functions for dealing with soft mask color */
105
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
106
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
107
108
/*
109
 * We chose the blending color space based upon the process color model of the
110
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
111
 * usually simple.  For other devices or if the user is doing custom color
112
 * processing then the user may want to control this choice.
113
 */
114
#define AUTO_USE_CUSTOM_BLENDING 0
115
#define ALWAYS_USE_CUSTOM_BLENDING 1
116
#define DO_NOT_USE_CUSTOM_BLENDING 2
117
118
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
119
120
# define INCR(v) DO_NOTHING
121
122
/* Forward prototypes */
123
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
124
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
125
                                gx_device ** pdev, gx_device * target,
126
                                const gs_pdf14trans_t * pdf14pct);
127
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
128
                                      gx_device ** pdev, gx_device * target,
129
                                      const gs_pdf14trans_t * pdf14pct);
130
static int pdf14_tile_pattern_fill(gx_device * pdev,
131
                const gs_gstate * pgs, gx_path * ppath,
132
                const gx_fill_params * params,
133
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
134
static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    rc_mask, previous);
169
170
gs_private_st_ptrs1(st_pdf14_rcmask, pdf14_rcmask_t, "pdf_rcmask",
171
                    pdf14_rcmask_enum_ptrs, pdf14_rcmask_reloc_ptrs,
172
                    mask_buf);
173
174
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
175
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
176
                    profiles);
177
178
/* ------ The device descriptors ------ */
179
180
/*
181
 * Default X and Y resolution.
182
 */
183
#define X_DPI 72
184
#define Y_DPI 72
185
186
static int pdf14_initialize_device(gx_device *dev);
187
188
static  int pdf14_open(gx_device * pdev);
189
static  dev_proc_close_device(pdf14_close);
190
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
191
static  dev_proc_put_params(pdf14_put_params);
192
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
193
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
194
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
195
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
196
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
197
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
198
dev_proc_encode_color(pdf14_encode_color);
199
dev_proc_encode_color(pdf14_encode_color_tag);
200
dev_proc_decode_color(pdf14_decode_color);
201
dev_proc_encode_color(pdf14_encode_color16);
202
dev_proc_encode_color(pdf14_encode_color16_tag);
203
dev_proc_decode_color(pdf14_decode_color16);
204
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
205
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
206
static  dev_proc_fill_path(pdf14_fill_path);
207
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
208
static  dev_proc_copy_mono(pdf14_copy_mono);
209
static  dev_proc_fill_mask(pdf14_fill_mask);
210
static  dev_proc_stroke_path(pdf14_stroke_path);
211
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
212
static  dev_proc_text_begin(pdf14_text_begin);
213
static  dev_proc_composite(pdf14_composite);
214
static  dev_proc_composite(pdf14_forward_composite);
215
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
216
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
217
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
218
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
219
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
220
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
221
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
222
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
223
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
224
static  dev_proc_copy_alpha(pdf14_copy_alpha);
225
static  dev_proc_copy_planes(pdf14_copy_planes);
226
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
227
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
228
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
229
static  const gx_color_map_procs *
230
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
231
232
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
233
#define YSIZE (int)(11 * Y_DPI)
234
235
/* 24-bit color. */
236
237
static void
238
pdf14_procs_initialize(gx_device *dev,
239
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
240
                       dev_proc_get_color_comp_index(get_color_comp_index),
241
                       dev_proc_encode_color(encode_color),
242
                       dev_proc_decode_color(decode_color))
243
8.14M
{
244
8.14M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
245
8.14M
    set_dev_proc(dev, open_device, pdf14_open);
246
8.14M
    set_dev_proc(dev, output_page, pdf14_output_page);
247
8.14M
    set_dev_proc(dev, close_device, pdf14_close);
248
8.14M
    set_dev_proc(dev, map_rgb_color, encode_color);
249
8.14M
    set_dev_proc(dev, map_color_rgb, decode_color);
250
8.14M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
251
8.14M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
252
8.14M
    set_dev_proc(dev, get_params, gx_forward_get_params);
253
8.14M
    set_dev_proc(dev, put_params, pdf14_put_params);
254
8.14M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
255
8.14M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
256
8.14M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
257
8.14M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
258
8.14M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
259
8.14M
    set_dev_proc(dev, composite, pdf14_composite);
260
8.14M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
261
8.14M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
262
8.14M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
263
8.14M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
264
8.14M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
265
8.14M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
266
8.14M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
267
8.14M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
268
8.14M
    set_dev_proc(dev, encode_color, encode_color);
269
8.14M
    set_dev_proc(dev, decode_color, decode_color);
270
8.14M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
271
8.14M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
272
8.14M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
273
8.14M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
274
8.14M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
275
8.14M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
276
8.14M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
277
8.14M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
278
8.14M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
279
8.14M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
280
8.14M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
281
8.14M
}
282
283
static void
284
pdf14_Gray_initialize_device_procs(gx_device *dev)
285
1.93M
{
286
1.93M
    pdf14_procs_initialize(dev,
287
1.93M
                           gx_default_DevGray_get_color_mapping_procs,
288
1.93M
                           gx_default_DevGray_get_color_comp_index,
289
1.93M
                           pdf14_encode_color,
290
1.93M
                           pdf14_decode_color);
291
1.93M
}
292
293
static void
294
pdf14_RGB_initialize_device_procs(gx_device *dev)
295
4.64M
{
296
4.64M
    pdf14_procs_initialize(dev,
297
4.64M
                           gx_default_DevRGB_get_color_mapping_procs,
298
4.64M
                           gx_default_DevRGB_get_color_comp_index,
299
4.64M
                           pdf14_encode_color,
300
4.64M
                           pdf14_decode_color);
301
4.64M
}
302
303
static void
304
pdf14_CMYK_initialize_device_procs(gx_device *dev)
305
1.00M
{
306
1.00M
    pdf14_procs_initialize(dev,
307
1.00M
                           gx_default_DevCMYK_get_color_mapping_procs,
308
1.00M
                           gx_default_DevCMYK_get_color_comp_index,
309
1.00M
                           pdf14_encode_color,
310
1.00M
                           pdf14_decode_color);
311
1.00M
}
312
313
static void
314
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
315
436k
{
316
436k
    pdf14_procs_initialize(dev,
317
436k
                           pdf14_cmykspot_get_color_mapping_procs,
318
436k
                           pdf14_cmykspot_get_color_comp_index,
319
436k
                           pdf14_encode_color,
320
436k
                           pdf14_decode_color);
321
436k
}
322
323
static void
324
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
325
128k
{
326
128k
    pdf14_procs_initialize(dev,
327
128k
                           pdf14_rgbspot_get_color_mapping_procs,
328
128k
                           pdf14_rgbspot_get_color_comp_index,
329
128k
                           pdf14_encode_color,
330
128k
                           pdf14_decode_color);
331
128k
}
332
333
static void
334
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
335
29
{
336
29
    pdf14_procs_initialize(dev,
337
29
                           pdf14_grayspot_get_color_mapping_procs,
338
29
                           pdf14_grayspot_get_color_comp_index,
339
29
                           pdf14_encode_color,
340
29
                           pdf14_decode_color);
341
29
}
342
343
static void
344
pdf14_custom_initialize_device_procs(gx_device *dev)
345
0
{
346
0
    pdf14_procs_initialize(dev,
347
0
                           gx_forward_get_color_mapping_procs,
348
0
                           gx_forward_get_color_comp_index,
349
0
                           gx_forward_encode_color,
350
0
                           gx_forward_decode_color);
351
0
}
352
353
static struct_proc_finalize(pdf14_device_finalize);
354
355
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
356
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
357
                          pdf14_device_finalize);
358
359
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
362
                                                        gx_device * target);
363
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
364
                                                        gx_device * target);
365
366
/* Alter pdf14 device color model based upon group or softmask. This occurs
367
   post clist or in immediate rendering case. Data stored with buffer */
368
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
369
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
370
                              cmm_profile_t *iccprofile, bool is_mask);
371
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
372
373
/* Alter clist writer device color model based upon group or softmask. Data
374
   stored in the device color model stack */
375
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
376
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
377
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
378
379
/* Used for cleaning up the stack if things go wrong */
380
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
381
382
static const pdf14_procs_t gray_pdf14_procs = {
383
    pdf14_unpack_additive,
384
    pdf14_put_image,
385
    pdf14_unpack16_additive
386
};
387
388
static const pdf14_procs_t rgb_pdf14_procs = {
389
    pdf14_unpack_additive,
390
    pdf14_put_image,
391
    pdf14_unpack16_additive
392
};
393
394
static const pdf14_procs_t cmyk_pdf14_procs = {
395
    pdf14_unpack_subtractive,
396
    pdf14_put_image,
397
    pdf14_unpack16_subtractive
398
};
399
400
static const pdf14_procs_t cmykspot_pdf14_procs = {
401
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
402
    pdf14_cmykspot_put_image,
403
    pdf14_unpack16_custom /* should never be used since we will use devn values */
404
};
405
406
static const pdf14_procs_t rgbspot_pdf14_procs = {
407
    pdf14_unpack_rgb_mix,
408
    pdf14_cmykspot_put_image,
409
    pdf14_unpack16_rgb_mix
410
};
411
412
static const pdf14_procs_t grayspot_pdf14_procs = {
413
    pdf14_unpack_gray_mix,
414
    pdf14_cmykspot_put_image,
415
    pdf14_unpack16_gray_mix
416
};
417
418
static const pdf14_procs_t custom_pdf14_procs = {
419
    pdf14_unpack_custom,
420
    pdf14_custom_put_image,
421
    pdf14_unpack16_custom
422
};
423
424
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
425
    art_blend_luminosity_custom_8,
426
    art_blend_saturation_custom_8,
427
    art_blend_luminosity_custom_16,
428
    art_blend_saturation_custom_16
429
};
430
431
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
432
    art_blend_luminosity_rgb_8,
433
    art_blend_saturation_rgb_8,
434
    art_blend_luminosity_rgb_16,
435
    art_blend_saturation_rgb_16
436
};
437
438
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
439
    art_blend_luminosity_cmyk_8,
440
    art_blend_saturation_cmyk_8,
441
    art_blend_luminosity_cmyk_16,
442
    art_blend_saturation_cmyk_16
443
};
444
445
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
446
    art_blend_luminosity_rgb_8,
447
    art_blend_saturation_rgb_8,
448
    art_blend_luminosity_rgb_16,
449
    art_blend_saturation_rgb_16
450
};
451
452
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
453
    art_blend_luminosity_custom_8,
454
    art_blend_saturation_custom_8,
455
    art_blend_luminosity_custom_16,
456
    art_blend_saturation_custom_16
457
};
458
459
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
460
    art_blend_luminosity_custom_8,
461
    art_blend_saturation_custom_8,
462
    art_blend_luminosity_custom_16,
463
    art_blend_saturation_custom_16
464
};
465
466
const pdf14_device gs_pdf14_Gray_device = {
467
    std_device_std_color_full_body_type(pdf14_device,
468
                                        pdf14_Gray_initialize_device_procs,
469
                                        "pdf14gray",
470
                                        &st_pdf14_device,
471
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
472
                                        0, 0, 0, 0, 0, 0),
473
    { 0 },      /* Procs */
474
    NULL,     /* target */
475
    { 0 },      /* devn_params - not used */
476
    &gray_pdf14_procs,
477
    &gray_blending_procs,
478
    1
479
};
480
481
const pdf14_device gs_pdf14_RGB_device = {
482
    std_device_color_stype_body(pdf14_device,
483
                                pdf14_RGB_initialize_device_procs,
484
                                "pdf14RGB",
485
                                &st_pdf14_device,
486
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
487
    { 0 },      /* Procs */
488
    NULL,     /* target */
489
    { 0 },      /* devn_params - not used */
490
    &rgb_pdf14_procs,
491
    &rgb_blending_procs,
492
    3
493
};
494
495
const pdf14_device gs_pdf14_CMYK_device = {
496
    std_device_std_color_full_body_type(pdf14_device,
497
                                        pdf14_CMYK_initialize_device_procs,
498
                                        "pdf14cmyk",
499
                                        &st_pdf14_device,
500
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
501
                                        0, 0, 0, 0, 0, 0),
502
    { 0 },      /* Procs */
503
    NULL,     /* target */
504
    { 0 },      /* devn_params - not used */
505
    &cmyk_pdf14_procs,
506
    &cmyk_blending_procs,
507
    4
508
};
509
510
const pdf14_device gs_pdf14_CMYKspot_device = {
511
    std_device_part1_(pdf14_device,
512
                      pdf14_CMYKspot_initialize_device_procs,
513
                      "pdf14cmykspot",
514
                      &st_pdf14_device,
515
                      open_init_closed),
516
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
517
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
518
    offset_margin_values(0, 0, 0, 0, 0, 0),
519
    std_device_part3_(),
520
    { 0 },      /* Procs */
521
    NULL,     /* target */
522
    /* DeviceN parameters */
523
    { 8,      /* Not used - Bits per color */
524
      DeviceCMYKComponents, /* Names of color model colorants */
525
      4,      /* Number colorants for CMYK */
526
      0,      /* MaxSeparations has not been specified */
527
      -1,     /* PageSpotColors has not been specified */
528
      {0},      /* SeparationNames */
529
      0,      /* SeparationOrder names */
530
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
531
    },
532
    &cmykspot_pdf14_procs,
533
    &cmyk_blending_procs,
534
    4
535
};
536
537
const pdf14_device gs_pdf14_RGBspot_device = {
538
    std_device_part1_(pdf14_device,
539
                      pdf14_RGBspot_initialize_device_procs,
540
                      "pdf14rgbspot",
541
                      &st_pdf14_device,
542
                      open_init_closed),
543
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
544
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
545
    offset_margin_values(0, 0, 0, 0, 0, 0),
546
    std_device_part3_(),
547
    { 0 },      /* Procs */
548
    NULL,     /* target */
549
                    /* DeviceN parameters */
550
    { 8,      /* Not used - Bits per color */
551
    0,              /* Names of color model colorants */
552
    3,          /* Number colorants for RGB */
553
    0,          /* MaxSeparations has not been specified */
554
    -1,         /* PageSpotColors has not been specified */
555
    { 0 },      /* SeparationNames */
556
    0,          /* SeparationOrder names */
557
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
558
    },
559
    &rgbspot_pdf14_procs,
560
    &rgbspot_blending_procs,
561
    3
562
};
563
564
const pdf14_device gs_pdf14_Grayspot_device = {
565
    std_device_part1_(pdf14_device,
566
                      pdf14_Grayspot_initialize_device_procs,
567
                      "pdf14grayspot",
568
                      &st_pdf14_device,
569
                      open_init_closed),
570
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
571
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
572
    offset_margin_values(0, 0, 0, 0, 0, 0),
573
    std_device_part3_(),
574
    { 0 },      /* Procs */
575
    NULL,     /* target */
576
                    /* DeviceN parameters */
577
    { 8,      /* Not used - Bits per color */
578
    0,              /* Names of color model colorants */
579
    3,          /* Number colorants for RGB */
580
    0,          /* MaxSeparations has not been specified */
581
    -1,         /* PageSpotColors has not been specified */
582
    { 0 },      /* SeparationNames */
583
    0,          /* SeparationOrder names */
584
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
585
    },
586
    &grayspot_pdf14_procs,
587
    &grayspot_blending_procs,
588
    1
589
};
590
591
/*
592
 * The 'custom' PDF 1.4 compositor device is for working with those devices
593
 * which support spot colors but do not have a CMYK process color model.
594
 *
595
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
596
 * blending modes.  These blending modes are 'non separable' and depend upon
597
 * knowing the details of the blending color space.  However we use the
598
 * process color model of the output device for our blending color space.
599
 * With an unknown process color model, we have to fall back to some 'guesses'
600
 * about how to treat these blending modes.
601
 */
602
const pdf14_device gs_pdf14_custom_device = {
603
    std_device_part1_(pdf14_device,
604
                      pdf14_custom_initialize_device_procs,
605
                      "pdf14custom",
606
                      &st_pdf14_device,
607
                      open_init_closed),
608
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
609
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
610
    offset_margin_values(0, 0, 0, 0, 0, 0),
611
    std_device_part3_(),
612
    { 0 },      /* Procs */
613
    NULL,     /* target */
614
    /* DeviceN parameters */
615
    { 8,      /* Not used - Bits per color */
616
      DeviceCMYKComponents, /* Names of color model colorants */
617
      4,      /* Number colorants for CMYK */
618
      0,      /* MaxSeparations has not been specified */
619
      -1,     /* PageSpotColors has not been specified */
620
      {0},      /* SeparationNames */
621
      0,      /* SeparationOrder names */
622
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
623
    },
624
    &custom_pdf14_procs,
625
    &custom_blending_procs,
626
    4
627
};
628
629
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
630
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
631
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
632
633
static dev_proc_print_page(no_print_page);
634
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
635
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
636
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
637
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
638
639
static int
640
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
641
0
{
642
0
    return_error(gs_error_unknownerror);
643
0
}
644
645
struct gx_device_pdf14_accum_s {
646
    gx_devn_prn_device_common;
647
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
648
};
649
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
650
651
int
652
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
653
19.3M
{
654
19.3M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
655
656
19.3M
    if (dev_spec_op == gxdso_device_child) {
657
3.09k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
658
3.09k
        if (size < sizeof(*req))
659
0
            return gs_error_unknownerror;
660
3.09k
        req->target = adev->save_p14dev;
661
3.09k
        req->n = 0;
662
3.09k
        return 0;
663
3.09k
    }
664
665
19.3M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
666
19.3M
}
667
668
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
669
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
670
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
671
672
static void
673
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
674
1.01k
{
675
1.01k
    gdev_prn_initialize_device_procs_gray8(dev);
676
677
1.01k
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
678
1.01k
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
679
1.01k
}
680
681
const gx_device_pdf14_accum pdf14_accum_Gray = {
682
    prn_device_stype_body(gx_device_pdf14_accum,
683
                          pdf14_accum_Gray_initialize_device_procs,
684
                          "pdf14-accum-Gray",
685
                          &st_gx_devn_accum_device,
686
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
687
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
688
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
689
                          256/*dither_grays*/, 0/*dither_colors*/,
690
                          no_print_page),
691
    { 0 },      /* devn_params - not used */
692
    { 0 },      /* equivalent_cmyk_color_params - not used */
693
    0/*save_p14dev*/
694
};
695
696
static void
697
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
698
5.01k
{
699
5.01k
    gdev_prn_initialize_device_procs_rgb(dev);
700
5.01k
}
701
702
const gx_device_pdf14_accum pdf14_accum_RGB = {
703
    prn_device_stype_body(gx_device_pdf14_accum,
704
                          pdf14_accum_RGB_initialize_device_procs,
705
                          "pdf14-accum-RGB",
706
                          &st_gx_devn_accum_device,
707
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
708
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
709
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
710
                          1/*dither_grays*/, 256/*dither_colors*/,
711
                          no_print_page),
712
    { 0 },      /* devn_params - not used */
713
    { 0 },      /* equivalent_cmyk_color_params - not used */
714
    0/*save_p14dev*/
715
};
716
717
static void
718
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
719
0
{
720
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
721
722
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
723
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
724
0
}
725
726
const gx_device_pdf14_accum pdf14_accum_CMYK = {
727
    prn_device_stype_body(gx_device_pdf14_accum,
728
                          pdf14_accum_CMYK_initialize_device_procs,
729
                          "pdf14-accum-CMYK",
730
                          &st_gx_devn_accum_device,
731
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
732
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
733
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
734
                          256/*dither_grays*/, 256/*dither_colors*/,
735
                          no_print_page),
736
    { 0 },      /* devn_params - not used */
737
    { 0 },      /* equivalent_cmyk_color_params - not used */
738
    0/*save_p14dev*/
739
};
740
741
static void
742
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
743
0
{
744
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
745
746
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
747
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
748
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
749
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
750
0
}
751
752
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
753
    prn_device_stype_body(gx_device_pdf14_accum,
754
                          pdf14_accum_initialize_device_procs_cmykspot,
755
                          "pdf14-accum-CMYKspot",
756
                          &st_gx_devn_accum_device,
757
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
758
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
759
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
760
                          256/*dither_grays*/, 256/*dither_colors*/,
761
                          no_print_page),
762
    /* DeviceN parameters */
763
    { 8,      /* Not used - Bits per color */
764
      DeviceCMYKComponents, /* Names of color model colorants */
765
      4,      /* Number colorants for CMYK */
766
      0,      /* MaxSeparations has not been specified */
767
      -1,     /* PageSpotColors has not been specified */
768
      { 0 },      /* SeparationNames */
769
      0,      /* SeparationOrder names */
770
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
771
    },
772
    { true },     /* equivalent_cmyk_color_params */
773
    0/*save_p14dev*/
774
};
775
776
/* GC procedures */
777
static
778
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
779
0
{
780
0
    index -= 5;
781
0
    if (index < pdev->devn_params.separations.num_separations)
782
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
783
0
    index -= pdev->devn_params.separations.num_separations;
784
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
785
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
786
0
    return 0;
787
0
}
788
0
case 0: return ENUM_OBJ(pdev->ctx);
789
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
790
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
791
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
792
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
793
0
ENUM_PTRS_END
794
795
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
796
0
{
797
0
    {
798
0
        int i;
799
800
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
801
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
802
0
        }
803
0
    }
804
0
    RELOC_VAR(pdev->ctx);
805
0
    RELOC_VAR(pdev->smaskcolor);
806
0
    RELOC_VAR(pdev->color_model_stack);
807
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
808
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
809
0
}
810
0
RELOC_PTRS_END
811
812
/* ------ Private definitions ------ */
813
814
static void
815
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
816
              int width, int height, cmm_profile_t *src_profile, int deep)
817
1.19k
{
818
1.19k
    if (deep) {
819
0
        int x, y, i;
820
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
821
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
822
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
823
824
0
        src_planestride >>= 1;
825
0
        src_rowstride >>= 1;
826
827
0
        for (y = 0; y < height; y++) {
828
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
829
0
            uint16_t *src_curr_ptr = src_row_ptr;
830
0
            for (x = 0; x < width; x++) {
831
0
                uint16_t idx = *mask_curr_ptr;
832
0
                byte     top = idx>>8;
833
0
                uint16_t a   = mask_tr_fn[top];
834
0
                int      b   = mask_tr_fn[top+1]-a;
835
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
836
837
                /* matte's happen rarely enough that we allow ourselves to
838
                 * resort to 64bit here. */
839
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
840
0
                    for (i = 0; i < src_profile->num_comps; i++) {
841
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
842
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
843
844
                        /* clip */
845
0
                        if (temp > 0xffff)
846
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
847
0
                        else if (temp < 0)
848
0
                            src_curr_ptr[i * src_planestride] = 0;
849
0
                        else
850
0
                            src_curr_ptr[i * src_planestride] = temp;
851
0
                    }
852
0
                }
853
0
                mask_curr_ptr++;
854
0
                src_curr_ptr++;
855
0
            }
856
0
            src_row_ptr += src_rowstride;
857
0
            mask_row_ptr += (maskbuf->rowstride>>1);
858
0
        }
859
1.19k
    } else {
860
1.19k
        int x, y, i;
861
1.19k
        byte *mask_row_ptr  = maskbuf->data;
862
1.19k
        byte *src_row_ptr   = src_data;
863
1.19k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
864
865
15.3k
        for (y = 0; y < height; y++) {
866
14.1k
            byte *mask_curr_ptr = mask_row_ptr;
867
14.1k
            byte *src_curr_ptr = src_row_ptr;
868
17.9M
            for (x = 0; x < width; x++) {
869
17.8M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
870
17.8M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
871
7.89M
                    for (i = 0; i < src_profile->num_comps; i++) {
872
5.91M
                        byte matte = maskbuf->matte[i]>>8;
873
5.91M
                        int val = src_curr_ptr[i * src_planestride] - matte;
874
5.91M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
875
876
                        /* clip */
877
5.91M
                        if (temp > 0xff)
878
4.30M
                            src_curr_ptr[i * src_planestride] = 0xff;
879
1.61M
                        else if (temp < 0)
880
0
                            src_curr_ptr[i * src_planestride] = 0;
881
1.61M
                        else
882
1.61M
                            src_curr_ptr[i * src_planestride] = temp;
883
5.91M
                    }
884
1.97M
                }
885
17.8M
                mask_curr_ptr++;
886
17.8M
                src_curr_ptr++;
887
17.8M
            }
888
14.1k
            src_row_ptr += src_rowstride;
889
14.1k
            mask_row_ptr += maskbuf->rowstride;
890
14.1k
        }
891
1.19k
    }
892
1.19k
}
893
894
/* Transform of color data and copy noncolor data.  Used in
895
   group pop and during the pdf14 put image calls when the blend color space
896
   is different than the target device color space.  The function will try do
897
   in-place conversion if possible.  If not, it will do an allocation.  The
898
   put_image call needs to know if an allocation was made so that it can adjust
899
   for the fact that we likely don't have a full page any longer and we don't
900
   need to do the offset to our data in the buffer. Bug 700686: If we are in
901
   a softmask that includes a matte entry, then we need to undo the matte
902
   entry here at this time in the image's native color space not the parent
903
   color space.   The endian_swap term here is only set to true if the data
904
   has been baked as BE during the put_image blending operation and we are
905
   on a LE machine.  */
906
static forceinline pdf14_buf*
907
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
908
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
909
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
910
    bool has_matte, bool deep, bool endian_swap)
911
34.9k
{
912
34.9k
    gsicc_rendering_param_t rendering_params;
913
34.9k
    gsicc_link_t *icc_link;
914
34.9k
    gsicc_bufferdesc_t src_buff_desc;
915
34.9k
    gsicc_bufferdesc_t des_buff_desc;
916
34.9k
    intptr_t src_planestride = src_buf->planestride;
917
34.9k
    intptr_t src_rowstride = src_buf->rowstride;
918
34.9k
    int src_n_planes = src_buf->n_planes;
919
34.9k
    int src_n_chan = src_buf->n_chan;
920
34.9k
    intptr_t des_planestride = src_planestride;
921
34.9k
    intptr_t des_rowstride = src_rowstride;
922
34.9k
    int des_n_planes = src_n_planes;
923
34.9k
    int des_n_chan = src_n_chan;
924
34.9k
    int diff;
925
34.9k
    int k, j;
926
34.9k
    byte *des_data = NULL;
927
34.9k
    pdf14_buf *output = src_buf;
928
34.9k
    pdf14_mask_t *mask_stack;
929
34.9k
    pdf14_buf *maskbuf;
930
34.9k
    int code;
931
932
34.9k
    *did_alloc = false;
933
934
    /* Same profile */
935
34.9k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
936
0
        return src_buf;
937
938
    /* Define the rendering intent get the link */
939
34.9k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
940
34.9k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
941
34.9k
    rendering_params.override_icc = false;
942
34.9k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
943
34.9k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
944
34.9k
    rendering_params.cmm = gsCMM_DEFAULT;
945
34.9k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
946
34.9k
        &rendering_params, pgs->memory, false);
947
34.9k
    if (icc_link == NULL)
948
0
        return NULL;
949
950
    /* If different data sizes, we have to do an allocation */
951
34.9k
    diff = des_profile->num_comps - src_profile->num_comps;
952
34.9k
    if (diff != 0) {
953
34.4k
        byte *src_ptr;
954
34.4k
        byte *des_ptr;
955
956
34.4k
        *did_alloc = true;
957
34.4k
        des_rowstride = ((width + 3) & -4)<<deep;
958
34.4k
        des_planestride = height * des_rowstride;
959
34.4k
        des_n_planes = src_n_planes + diff;
960
34.4k
        des_n_chan = src_n_chan + diff;
961
34.4k
        des_data = gs_alloc_bytes(ctx->memory,
962
34.4k
                                  des_planestride * des_n_planes + CAL_SLOP,
963
34.4k
                                  "pdf14_transform_color_buffer");
964
34.4k
        if (des_data == NULL)
965
0
            return NULL;
966
967
        /* Copy over the noncolor planes. May only be a dirty part, so have
968
           to copy row by row */
969
34.4k
        src_ptr = src_data;
970
34.4k
        des_ptr = des_data;
971
374k
        for (j = 0; j < height; j++) {
972
700k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
973
360k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps),
974
360k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
975
360k
                       width<<deep);
976
360k
            }
977
339k
            src_ptr += src_rowstride;
978
339k
            des_ptr += des_rowstride;
979
339k
        }
980
34.4k
    } else
981
428
        des_data = src_data;
982
983
    /* Set up the buffer descriptors. */
984
34.9k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
985
34.9k
                      false, true, src_planestride, src_rowstride, height, width);
986
34.9k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
987
34.9k
                      false, true, des_planestride, des_rowstride, height, width);
988
989
34.9k
    src_buff_desc.endian_swap = endian_swap;
990
34.9k
    des_buff_desc.endian_swap = endian_swap;
991
992
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
993
       context to ensure that this is not done again during the group
994
       composition */
995
34.9k
    if (has_matte &&
996
        /* Should always happen, but check for safety */
997
34.9k
        ((mask_stack = ctx->mask_stack) != NULL) &&
998
34.9k
        ((maskbuf = mask_stack->rc_mask->mask_buf) != NULL) &&
999
34.9k
         (maskbuf->data != NULL))
1000
1.19k
    {
1001
1.19k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
1002
1.19k
    }
1003
1004
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1005
       Gray buffers, this transform does not need to worry about the cmap procs
1006
       of the target device. */
1007
34.9k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1008
34.9k
        src_data, des_data);
1009
34.9k
    gsicc_release_link(icc_link);
1010
34.9k
    if (code < 0)
1011
0
        return NULL;
1012
1013
34.9k
    output->planestride = des_planestride;
1014
34.9k
    output->rowstride = des_rowstride;
1015
34.9k
    output->n_planes = des_n_planes;
1016
34.9k
    output->n_chan = des_n_chan;
1017
    /* If not in-place conversion, then release. */
1018
34.9k
    if (des_data != src_data) {
1019
34.4k
        gs_free_object(ctx->memory, output->data,
1020
34.4k
            "pdf14_transform_color_buffer");
1021
34.4k
        output->data = des_data;
1022
        /* Note, this is needed for case where we did a put image, as the
1023
           resulting transformed buffer may not be a full page. */
1024
34.4k
        output->rect.p.x = x0;
1025
34.4k
        output->rect.p.y = y0;
1026
34.4k
        output->rect.q.x = x0 + width;
1027
34.4k
        output->rect.q.y = y0 + height;
1028
34.4k
    }
1029
34.9k
    return output;
1030
34.9k
}
1031
1032
/* This is a routine to do memset's but with 16 bit values.
1033
 * Note, that we still take bytes, NOT "num values to set".
1034
 * We assume dest is 16 bit aligned. We assume that bytes is
1035
 * a multiple of 2. */
1036
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1037
0
{
1038
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1039
0
    uint32_t v;
1040
0
    if (bytes < 0)
1041
0
        return;
1042
0
    if (((intptr_t)dest) & 2) {
1043
0
        *dest++ = value;
1044
0
        bytes--;
1045
0
        if (bytes == 0)
1046
0
            return;
1047
0
    }
1048
0
    v = value | (value<<16);
1049
0
    bytes -= 2;
1050
0
    while (bytes > 0) {
1051
0
        *(uint32_t *)dest = v;
1052
0
        dest += 2;
1053
0
        bytes -= 4;
1054
0
    }
1055
0
    bytes += 2;
1056
0
    if (bytes & 2) {
1057
0
        *dest = value;
1058
0
    }
1059
0
}
1060
1061
static pdf14_buf*
1062
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1063
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1064
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1065
    bool deep, bool endian_swap)
1066
33.3k
{
1067
33.3k
    if (deep)
1068
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1069
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap);
1070
33.3k
    else
1071
33.3k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1072
33.3k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap);
1073
33.3k
}
1074
1075
static pdf14_buf*
1076
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1077
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1078
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1079
    bool deep, bool endian_swap)
1080
1.51k
{
1081
1.51k
    if (deep)
1082
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1083
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap);
1084
1.51k
    else
1085
1.51k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1086
1.51k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap);
1087
1.51k
}
1088
1089
/**
1090
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1091
 * @n_chan: Number of pixel channels including alpha, but not including
1092
 * shape, group alpha, or tags.
1093
 *
1094
 * Return value: Newly allocated buffer, or NULL on failure.
1095
 **/
1096
static  pdf14_buf *
1097
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1098
              bool has_shape, bool idle, int n_chan, int num_spots,
1099
              gs_memory_t *memory, bool deep)
1100
5.50M
{
1101
1102
    /* Note that alpha_g is the alpha for the GROUP */
1103
    /* This is distinct from the alpha that may also exist */
1104
    /* for the objects within the group.  Hence it can introduce */
1105
    /* yet another plane */
1106
1107
5.50M
    pdf14_buf *result;
1108
5.50M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1109
5.50M
    int64_t height = (rect->q.y - rect->p.y);
1110
5.50M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1111
5.50M
                   (has_tags ? 1 : 0);
1112
5.50M
    size_t planestride;
1113
#if ARCH_SIZEOF_SIZE_T <= 4
1114
    int64_t dsize = rowstride * height * n_planes;
1115
1116
    if (dsize > max_size_t)
1117
        return NULL;
1118
#endif
1119
1120
5.50M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1121
5.50M
                             "pdf14_buf_new");
1122
5.50M
    if (result == NULL)
1123
0
        return result;
1124
1125
5.50M
    result->memory = memory;
1126
5.50M
    result->backdrop = NULL;
1127
5.50M
    result->saved = NULL;
1128
5.50M
    result->isolated = false;
1129
5.50M
    result->knockout = false;
1130
5.50M
    result->has_alpha_g = has_alpha_g;
1131
5.50M
    result->has_shape = has_shape;
1132
5.50M
    result->has_tags = has_tags;
1133
5.50M
    result->rect = *rect;
1134
5.50M
    result->n_chan = n_chan;
1135
5.50M
    result->n_planes = n_planes;
1136
5.50M
    result->rowstride = rowstride;
1137
5.50M
    result->transfer_fn = NULL;
1138
5.50M
    result->is_ident = true;
1139
5.50M
    result->matte_num_comps = 0;
1140
5.50M
    result->matte = NULL;
1141
5.50M
    result->mask_stack = NULL;
1142
5.50M
    result->idle = idle;
1143
5.50M
    result->mask_id = 0;
1144
5.50M
    result->num_spots = num_spots;
1145
5.50M
    result->deep = deep;
1146
5.50M
    result->page_group = false;
1147
5.50M
    result->group_color_info = NULL;
1148
5.50M
    result->group_popped = false;
1149
1150
5.50M
    if (idle || height <= 0) {
1151
        /* Empty clipping - will skip all drawings. */
1152
2.68M
        result->planestride = 0;
1153
2.68M
        result->data = 0;
1154
2.81M
    } else {
1155
2.81M
        planestride = rowstride * height;
1156
2.81M
        result->planestride = planestride;
1157
2.81M
        result->data = gs_alloc_bytes(memory,
1158
2.81M
                                      planestride * n_planes + CAL_SLOP,
1159
2.81M
                                      "pdf14_buf_new");
1160
2.81M
        if (result->data == NULL) {
1161
0
            gs_free_object(memory, result, "pdf14_buf_new");
1162
0
            return NULL;
1163
0
        }
1164
2.81M
        if (has_alpha_g) {
1165
517k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1166
            /* Memsetting by 0, so this copes with the deep case too */
1167
517k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1168
517k
        }
1169
2.81M
        if (has_tags) {
1170
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1171
            /* Memsetting by 0, so this copes with the deep case too */
1172
0
            memset (result->data + tags_plane * planestride,
1173
0
                    GS_UNTOUCHED_TAG, planestride);
1174
0
        }
1175
2.81M
    }
1176
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1177
     * Any future drawing will make it valid again, so we won't blend back
1178
     * more than we need. */
1179
5.50M
    result->dirty.p.x = rect->q.x;
1180
5.50M
    result->dirty.p.y = rect->q.y;
1181
5.50M
    result->dirty.q.x = rect->p.x;
1182
5.50M
    result->dirty.q.y = rect->p.y;
1183
5.50M
    return result;
1184
5.50M
}
1185
1186
static  void
1187
pdf14_buf_free(pdf14_buf *buf)
1188
5.50M
{
1189
5.50M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1190
5.50M
    gs_memory_t *memory = buf->memory;
1191
1192
5.50M
    if (buf->mask_stack && buf->mask_stack->rc_mask)
1193
5.50M
        rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free");
1194
1195
5.50M
    gs_free_object(memory, buf->mask_stack, "pdf14_buf_free");
1196
5.50M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1197
5.50M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1198
5.50M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1199
1200
11.0M
    while (group_color_info) {
1201
5.50M
       if (group_color_info->icc_profile != NULL) {
1202
5.50M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1203
5.50M
       }
1204
5.50M
       buf->group_color_info = group_color_info->previous;
1205
5.50M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1206
5.50M
       group_color_info = buf->group_color_info;
1207
5.50M
    }
1208
1209
5.50M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1210
5.50M
    gs_free_object(memory, buf, "pdf14_buf_free");
1211
5.50M
}
1212
1213
static void
1214
rc_pdf14_maskbuf_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1215
2.50M
{
1216
    /* Ending the mask buffer. */
1217
2.50M
    pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in;
1218
    /* free the pdf14 buffer. */
1219
2.50M
    if ( rcmask->mask_buf != NULL ){
1220
263k
        pdf14_buf_free(rcmask->mask_buf);
1221
263k
    }
1222
2.50M
    gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free");
1223
2.50M
}
1224
1225
static  pdf14_rcmask_t *
1226
pdf14_rcmask_new(gs_memory_t *memory)
1227
2.50M
{
1228
2.50M
    pdf14_rcmask_t *result;
1229
1230
2.50M
    result = gs_alloc_struct(memory, pdf14_rcmask_t, &st_pdf14_rcmask,
1231
2.50M
                             "pdf14_maskbuf_new");
1232
2.50M
    if (result == NULL)
1233
0
        return NULL;
1234
2.50M
    rc_init_free(result, memory, 1, rc_pdf14_maskbuf_free);
1235
2.50M
    result->mask_buf = NULL;
1236
2.50M
    result->memory = memory;
1237
2.50M
    return result;
1238
2.50M
}
1239
1240
static  pdf14_ctx *
1241
pdf14_ctx_new(gx_device *dev, bool deep)
1242
1.71M
{
1243
1.71M
    pdf14_ctx *result;
1244
1.71M
    gs_memory_t *memory = dev->memory->stable_memory;
1245
1246
1.71M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1247
1.71M
    if (result == NULL)
1248
0
        return result;
1249
1.71M
    result->stack = NULL;
1250
1.71M
    result->mask_stack = pdf14_mask_element_new(memory);
1251
1.71M
    result->mask_stack->rc_mask = pdf14_rcmask_new(memory);
1252
1.71M
    result->memory = memory;
1253
1.71M
    result->smask_depth = 0;
1254
1.71M
    result->smask_blend = false;
1255
1.71M
    result->deep = deep;
1256
1.71M
    result->base_color = NULL;
1257
1.71M
    return result;
1258
1.71M
}
1259
1260
static  void
1261
pdf14_ctx_free(pdf14_ctx *ctx)
1262
1.71M
{
1263
1.71M
    pdf14_buf *buf, *next;
1264
1265
1.71M
    if (ctx->base_color) {
1266
956k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1267
956k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1268
956k
    }
1269
1.71M
    if (ctx->mask_stack) {
1270
        /* A mask was created but was not used in this band. */
1271
729k
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_ctx_free");
1272
729k
        gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_ctx_free");
1273
729k
    }
1274
3.23M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1275
1.52M
        next = buf->saved;
1276
1.52M
        pdf14_buf_free(buf);
1277
1.52M
    }
1278
1.71M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1279
1.71M
}
1280
1281
/**
1282
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1283
 *
1284
 * Return value: Backdrop buffer for current group operation, or NULL
1285
 * if backdrop is fully transparent.
1286
 **/
1287
static  pdf14_buf *
1288
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1289
1.58M
{
1290
    /* Our new buffer is buf */
1291
1.58M
    pdf14_buf *buf = ctx->stack;
1292
1293
1.58M
    *is_backdrop = false;
1294
1295
1.58M
    if (buf != NULL) {
1296
        /* If the new buffer is isolated there is no backdrop */
1297
1.58M
        if (buf->isolated) return NULL;
1298
1299
        /* If the previous buffer is a knockout group
1300
           then we need to use its backdrop as the backdrop. If
1301
           it was isolated then that back drop was NULL */
1302
517k
        if (buf->saved != NULL && buf->saved->knockout) {
1303
            /* Per the spec, if we have a non-isolated group
1304
               in a knockout group the non-isolated group
1305
               uses the backdrop of its parent group (the knockout group)
1306
               as its own backdrop.  The non-isolated group must
1307
               go through the standard re-composition operation
1308
               to avoid the double application of the backdrop */
1309
28
            *is_backdrop = true;
1310
28
            return buf->saved;
1311
28
        }
1312
        /* This should be the non-isolated case where its parent is
1313
           not a knockout */
1314
517k
        if (buf->saved != NULL) {
1315
517k
            return buf->saved;
1316
517k
        }
1317
517k
    }
1318
0
    return NULL;
1319
1.58M
}
1320
1321
static pdf14_group_color_t*
1322
pdf14_make_base_group_color(gx_device* dev)
1323
956k
{
1324
956k
    pdf14_device* pdev = (pdf14_device*)dev;
1325
956k
    pdf14_group_color_t* group_color;
1326
956k
    bool deep = pdev->ctx->deep;
1327
956k
    bool has_tags = device_encodes_tags(dev);
1328
1329
956k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1330
1331
956k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1332
956k
        pdf14_group_color_t, &st_pdf14_clr,
1333
956k
        "pdf14_make_base_group_color");
1334
1335
956k
    if (group_color == NULL)
1336
0
        return NULL;
1337
956k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1338
1339
956k
    group_color->num_std_colorants = pdev->num_std_colorants;
1340
956k
    group_color->blend_procs = pdev->blend_procs;
1341
956k
    group_color->polarity = pdev->color_info.polarity;
1342
956k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1343
956k
    group_color->isadditive = pdev->ctx->additive;
1344
956k
    group_color->unpack_procs = pdev->pdf14_procs;
1345
956k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1346
956k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1347
956k
    group_color->depth = pdev->color_info.depth;
1348
956k
    group_color->decode = dev_proc(pdev, decode_color);
1349
956k
    group_color->encode = dev_proc(pdev, encode_color);
1350
956k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1351
956k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1352
956k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1353
956k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1354
956k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1355
956k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1356
956k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1357
956k
    group_color->icc_profile =
1358
956k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1359
956k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1360
1361
956k
    return group_color;
1362
956k
}
1363
1364
/* This wil create the first buffer when we have
1365
   either the first drawing operation or transparency
1366
   group push.  At that time, the color space in which
1367
   we are going to be doing the alpha blend will be known. */
1368
static int
1369
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1370
878M
{
1371
878M
    pdf14_device *pdev = (pdf14_device *)dev;
1372
878M
    bool has_tags = device_encodes_tags(dev);
1373
878M
    int n_chan = pdev->color_info.num_components - has_tags;
1374
878M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1375
878M
    int num_spots = pdev->ctx->num_spots;
1376
878M
    pdf14_buf* buf;
1377
878M
    gs_memory_t* memory = dev->memory->stable_memory;
1378
1379
    /* Check for a blank idle group as a base group */
1380
878M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1381
878M
        pdev->ctx->stack->idle) {
1382
0
        pdf14_buf_free(pdev->ctx->stack);
1383
0
        pdev->ctx->stack = NULL;
1384
0
    }
1385
1386
878M
    if (pdev->ctx->stack != NULL)
1387
877M
        return 0;
1388
1389
878M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1390
774k
        dev->width, dev->height);
1391
1392
774k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1393
774k
        num_spots, memory, pdev->ctx->deep);
1394
774k
    if (buf == NULL) {
1395
0
        return gs_error_VMerror;
1396
0
    }
1397
774k
    if_debug5m('v', memory,
1398
774k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1399
774k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1400
1401
774k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1402
774k
    buf->saved = NULL;
1403
774k
    pdev->ctx->stack = buf;
1404
774k
    pdev->ctx->additive = additive;
1405
1406
    /* Every buffer needs group color information including the base
1407
       one that is created for when we have no group */
1408
774k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1409
774k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1410
774k
    if (buf->group_color_info == NULL)
1411
0
        return gs_error_VMerror;
1412
1413
774k
    if (pgs != NULL)
1414
392k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1415
381k
    else
1416
381k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1417
1418
774k
    buf->group_color_info->group_color_mapping_procs =
1419
774k
        dev_proc(pdev, get_color_mapping_procs);
1420
774k
    buf->group_color_info->group_color_comp_index =
1421
774k
        dev_proc(pdev, get_color_comp_index);
1422
774k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1423
774k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1424
774k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1425
774k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1426
774k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1427
774k
    buf->group_color_info->depth = pdev->color_info.depth;
1428
774k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1429
774k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1430
774k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1431
774k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1432
774k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1433
774k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1434
774k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1435
774k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1436
774k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1437
774k
    buf->group_color_info->icc_profile =
1438
774k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1439
774k
    if (buf->group_color_info->icc_profile != NULL)
1440
774k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1441
1442
774k
    return 0;
1443
774k
}
1444
1445
static pdf14_group_color_t*
1446
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1447
43.1k
{
1448
43.1k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1449
43.1k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1450
43.1k
    if (des == NULL)
1451
0
        return NULL;
1452
1453
43.1k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1454
43.1k
    if (des->icc_profile != NULL)
1455
43.1k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1456
43.1k
    des->previous = NULL;  /* used during clist writing for state stack */
1457
1458
43.1k
    return des;
1459
43.1k
}
1460
1461
static  int
1462
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1463
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1464
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1465
                              int numcomps, bool cm_back_drop, bool shade_group,
1466
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1467
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1468
                              gx_device *dev)
1469
3.92M
{
1470
3.92M
    pdf14_buf *tos = ctx->stack;
1471
3.92M
    pdf14_buf *buf, * pdf14_backdrop;
1472
3.92M
    bool has_shape = false;
1473
3.92M
    bool is_backdrop;
1474
3.92M
    int num_spots;
1475
1476
3.92M
    if_debug1m('v', ctx->memory,
1477
3.92M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1478
1479
3.92M
    if (tos != NULL)
1480
3.18M
        has_shape = tos->has_shape || tos->knockout;
1481
1482
3.92M
    if (ctx->smask_depth > 0)
1483
4.91k
        num_spots = 0;
1484
3.92M
    else
1485
3.92M
        num_spots = ctx->num_spots;
1486
1487
1488
3.92M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1489
3.92M
                        num_spots, ctx->memory, ctx->deep);
1490
3.92M
    if (buf == NULL)
1491
0
        return_error(gs_error_VMerror);
1492
1493
3.92M
    if_debug4m('v', ctx->memory,
1494
3.92M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1495
3.92M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1496
3.92M
    buf->isolated = isolated;
1497
3.92M
    buf->knockout = knockout;
1498
3.92M
    buf->alpha = alpha;
1499
3.92M
    buf->shape = shape;
1500
3.92M
    buf->opacity = opacity;
1501
3.92M
    buf->blend_mode = blend_mode;
1502
3.92M
    buf->mask_id = mask_id;
1503
3.92M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1504
                                          set up another (nested) mask. */
1505
3.92M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1506
                            See pdf14_pop_transparency_group how to handle it. */
1507
3.92M
    buf->saved = tos;
1508
3.92M
    buf->group_color_info = group_color;
1509
1510
3.92M
    if (tos == NULL)
1511
747k
        buf->page_group = true;
1512
1513
3.92M
    ctx->stack = buf;
1514
3.92M
    if (buf->data == NULL)
1515
2.34M
        return 0;
1516
1.58M
    if (idle)
1517
0
        return 0;
1518
1.58M
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1519
1520
    /* Initializes buf->data with the backdrop or as opaque */
1521
1.58M
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1522
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1523
        /* Memsetting by 0, so this copes with the deep case too */
1524
1.07M
        memset(buf->data, 0, buf->planestride *
1525
1.07M
                                          (buf->n_chan +
1526
1.07M
                                           (buf->has_shape ? 1 : 0) +
1527
1.07M
                                           (buf->has_alpha_g ? 1 : 0)));
1528
1.07M
    } else {
1529
517k
        if (!cm_back_drop) {
1530
517k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1531
#if RAW_DUMP
1532
                                    , ctx->memory
1533
#endif
1534
517k
                                    );
1535
517k
        } else {
1536
            /* We must have an non-isolated group with a mismatch in color spaces.
1537
                In this case, we can't just copy the buffer but must CM it */
1538
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1539
0
                                        ctx->memory, pgs, dev, is_backdrop);
1540
0
        }
1541
517k
    }
1542
1543
    /* If our new group is a non-isolated knockout group, we have to maintain
1544
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1545
       knockout group. They have to always blend with the groups backdrop
1546
       not what is currently drawn in the group. Selection of the backdrop
1547
       depends upon the properties of the parent group. For example, if
1548
       the parent itself is a knockout group we actually
1549
       need to blend with its backdrop. This could be NULL if the parent was
1550
       an isolated knockout group. */
1551
1.58M
    if (buf->knockout && pdf14_backdrop != NULL) {
1552
55.1k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1553
55.1k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1554
55.1k
                                       "pdf14_push_transparency_group");
1555
55.1k
        if (buf->backdrop == NULL) {
1556
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1557
0
        }
1558
1559
55.1k
        memcpy(buf->backdrop, buf->data,
1560
55.1k
               buf->planestride * buf->n_planes);
1561
1562
#if RAW_DUMP
1563
        /* Dump the current buffer to see what we have. */
1564
        dump_raw_buffer(ctx->memory,
1565
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1566
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1567
            ctx->stack->planestride, ctx->stack->rowstride,
1568
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1569
        global_index++;
1570
#endif
1571
55.1k
    }
1572
#if RAW_DUMP
1573
    /* Dump the current buffer to see what we have. */
1574
    dump_raw_buffer(ctx->memory,
1575
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1576
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1577
                    ctx->stack->planestride, ctx->stack->rowstride,
1578
                    "TransGroupPush", ctx->stack->data, buf->deep);
1579
    global_index++;
1580
#endif
1581
1.58M
    return 0;
1582
1.58M
}
1583
1584
static  int
1585
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1586
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1587
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1588
3.92M
{
1589
3.92M
    pdf14_buf *tos = ctx->stack;
1590
3.92M
    pdf14_buf *nos = tos->saved;
1591
3.92M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1592
3.92M
    pdf14_buf *maskbuf;
1593
3.92M
    int x0, x1, y0, y1;
1594
3.92M
    int nos_num_color_comp;
1595
3.92M
    bool no_icc_match;
1596
3.92M
    pdf14_device *pdev = (pdf14_device *)dev;
1597
3.92M
    bool overprint = pdev->overprint;
1598
3.92M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1599
3.92M
    bool has_matte = false;
1600
3.92M
    int code = 0;
1601
1602
#ifdef DEBUG
1603
    pdf14_debug_mask_stack_state(ctx);
1604
#endif
1605
3.92M
    if (mask_stack == NULL) {
1606
2.04M
        maskbuf = NULL;
1607
2.04M
    }
1608
1.87M
    else {
1609
1.87M
        maskbuf = mask_stack->rc_mask->mask_buf;
1610
1.87M
    }
1611
1612
3.92M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1613
5.31k
        has_matte = true;
1614
1615
    /* Check if this is our last buffer, if yes, there is nothing to
1616
       compose to.  Keep this buffer until we have the put image.
1617
       If we have another group push, this group must be destroyed.
1618
       This only occurs sometimes when at clist creation time
1619
       push_shfill_group occured and nothing was drawn in this group.
1620
       There is also the complication if we have a softmask.  There
1621
       are two approaches to this problem.  Apply the softmask during
1622
       the put image or handle it now.  I choose the later as the
1623
       put_image code is already way to complicated. */
1624
3.92M
    if (nos == NULL && maskbuf == NULL) {
1625
745k
        tos->group_popped = true;
1626
745k
        return 0;
1627
745k
    }
1628
1629
    /* Here is the case with the soft mask.  Go ahead and create a new
1630
       target buffer (nos) with the same color information etc, but blank
1631
       and go ahead and do the blend with the softmask so that it gets applied. */
1632
3.18M
    if (nos == NULL && maskbuf != NULL) {
1633
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1634
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1635
0
        if (nos == NULL) {
1636
0
            code = gs_error_VMerror;
1637
0
            goto exit;
1638
0
        }
1639
1640
0
        if_debug4m('v', ctx->memory,
1641
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1642
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1643
1644
0
        nos->dirty = tos->dirty;
1645
0
        nos->isolated = tos->isolated;
1646
0
        nos->knockout = tos->knockout;
1647
0
        nos->alpha = 65535;
1648
0
        nos->shape = 65535;
1649
0
        nos->opacity = 65535;
1650
0
        nos->blend_mode = tos->blend_mode;
1651
0
        nos->mask_id = tos->mask_id;
1652
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1653
1654
0
        if (nos->data != NULL)
1655
0
            memset(nos->data, 0,
1656
0
                   nos->planestride * (nos->n_chan +
1657
0
                                       (nos->has_shape ? 1 : 0) +
1658
0
                                       (nos->has_alpha_g ? 1 : 0)));
1659
0
    }
1660
1661
    /* Before we get started, lets see if we have somehow gotten into
1662
       what should be an impossible situation where the group color
1663
       information does not match the buffer color information. This
1664
       can occur is there were memory issues that have perhaps blown
1665
       away information, or in the example of Bug 705197 the PDF interpreter
1666
       reuses a pattern during a circular reference causing an aliasing
1667
       of two nested patterns, one of which has a softmask. The change in
1668
       the buffer size of the inner one blows away the buffer of the
1669
       outer one leading to a mismatch of color spaces. Here
1670
       we can at least catch the case when the color space sizes have
1671
       changed and avoid buffer over-runs that would occur when we try
1672
       to do the group composition */
1673
3.18M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1674
3.18M
        tos->n_chan - 1 != tos_num_color_comp)
1675
0
        return_error(gs_error_Fatal);
1676
1677
3.18M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1678
3.18M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1679
1680
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1681
     * have made them overly large. */
1682
3.18M
    rect_intersect(tos->dirty, tos->rect);
1683
3.18M
    rect_intersect(nos->dirty, nos->rect);
1684
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1685
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1686
3.18M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1687
3.18M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1688
3.18M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1689
3.18M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1690
3.18M
    if (ctx->mask_stack) {
1691
        /* This can occur when we have a situation where we are ending out of
1692
           a group that has internal to it a soft mask and another group.
1693
           The soft mask left over from the previous trans group pop is put
1694
           into ctx->masbuf, since it is still active if another trans group
1695
           push occurs to use it.  If one does not occur, but instead we find
1696
           ourselves popping from a parent group, then this softmask is no
1697
           longer needed.  We will rc_decrement and set it to NULL. */
1698
99
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_pop_transparency_group");
1699
99
        if (ctx->mask_stack->rc_mask == NULL ){
1700
99
            gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_pop_transparency_group");
1701
99
        }
1702
99
        ctx->mask_stack = NULL;
1703
99
    }
1704
3.18M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1705
3.18M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1706
3.18M
    if (tos->idle)
1707
2.30M
        goto exit;
1708
880k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1709
0
        goto exit;
1710
1711
#if RAW_DUMP
1712
    /* Dump the current buffer to see what we have. */
1713
    dump_raw_buffer(ctx->memory,
1714
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1715
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1716
                    ctx->stack->planestride, ctx->stack->rowstride,
1717
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1718
    global_index++;
1719
#endif
1720
/* Note currently if a pattern space has transparency, the ICC profile is not used
1721
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1722
   This is partially due to the fact that pdf14_pop_transparency_group and
1723
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1724
   operations called in the tile transparency code.  Instead we may want to
1725
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1726
   is where all the ICC information is handled.  We will return to look at that later */
1727
880k
    if (nos->group_color_info->icc_profile != NULL) {
1728
880k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1729
880k
    } else {
1730
        /* Let the other tests make the decision if we need to transform */
1731
0
        no_icc_match = false;
1732
0
    }
1733
    /* If the color spaces are different and we actually did do a swap of
1734
       the procs for color */
1735
880k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1736
880k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1737
9.17k
        if (x0 < x1 && y0 < y1) {
1738
7.69k
            pdf14_buf *result;
1739
7.69k
            bool did_alloc; /* We don't care here */
1740
1741
7.69k
            if (has_matte) {
1742
1.51k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1743
1.51k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1744
1.51k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1745
1.51k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1746
1.51k
                has_matte = false;
1747
6.18k
            } else {
1748
6.18k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1749
6.18k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1750
6.18k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1751
6.18k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1752
6.18k
            }
1753
7.69k
            if (result == NULL) {
1754
                /* Clean up and return error code */
1755
0
                code = gs_error_unknownerror;
1756
0
                goto exit;
1757
0
            }
1758
1759
#if RAW_DUMP
1760
            /* Dump the current buffer to see what we have. */
1761
            dump_raw_buffer(ctx->memory,
1762
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1763
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1764
                            ctx->stack->planestride, ctx->stack->rowstride,
1765
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1766
                            ctx->stack->deep);
1767
#endif
1768
             /* compose. never do overprint in this case */
1769
7.69k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1770
7.69k
                 nos->group_color_info->isadditive,
1771
7.69k
                 nos->group_color_info->blend_procs,
1772
7.69k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1773
7.69k
        }
1774
871k
    } else {
1775
        /* Group color spaces are the same.  No color conversions needed */
1776
871k
        if (x0 < x1 && y0 < y1)
1777
556k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1778
556k
                                ctx->additive, pblend_procs, has_matte, overprint,
1779
556k
                                drawn_comps, ctx->memory, dev);
1780
871k
    }
1781
3.18M
exit:
1782
3.18M
    ctx->stack = nos;
1783
    /* We want to detect the cases where we have luminosity soft masks embedded
1784
       within one another.  The "alpha" channel really needs to be merged into
1785
       the luminosity channel in this case.  This will occur during the mask pop */
1786
3.18M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1787
        /* Set the trigger so that we will blend if not alpha. Since
1788
           we have softmasks embedded in softmasks */
1789
1.28k
        ctx->smask_blend = true;
1790
1.28k
    }
1791
3.18M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1792
3.18M
    pdf14_buf_free(tos);
1793
3.18M
    if (code < 0)
1794
0
        return_error(code);
1795
3.18M
    return 0;
1796
3.18M
}
1797
1798
/*
1799
 * Create a transparency mask that will be used as the mask for
1800
 * the next transparency group that is created afterwards.
1801
 * The sequence of calls is:
1802
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1803
 */
1804
static  int
1805
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1806
                             byte *transfer_fn, bool is_ident, bool idle,
1807
                             bool replacing, uint mask_id,
1808
                             gs_transparency_mask_subtype_t subtype,
1809
                             int numcomps, int Background_components,
1810
                             const float Background[], int Matte_components,
1811
                             const float Matte[], const float GrayBackground,
1812
                             pdf14_group_color_t* group_color)
1813
800k
{
1814
800k
    pdf14_buf *buf;
1815
800k
    int i;
1816
1817
800k
    if_debug2m('v', ctx->memory,
1818
800k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1819
800k
               idle, replacing);
1820
800k
    ctx->smask_depth += 1;
1821
1822
800k
    if (ctx->stack == NULL) {
1823
0
        return_error(gs_error_VMerror);
1824
0
    }
1825
1826
    /* An optimization to consider is that if the SubType is Alpha
1827
       then we really should only be allocating the alpha band and
1828
       only draw with that channel.  Current architecture makes that
1829
       a bit tricky.  We need to create this based upon the size of
1830
       the color space + an alpha channel. NOT the device size
1831
       or the previous ctx size */
1832
    /* A mask doesn't worry about tags */
1833
800k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1834
800k
                        ctx->memory, ctx->deep);
1835
800k
    if (buf == NULL)
1836
0
        return_error(gs_error_VMerror);
1837
800k
    buf->alpha = bg_alpha;
1838
800k
    buf->is_ident = is_ident;
1839
    /* fill in, but these values aren't really used */
1840
800k
    buf->isolated = true;
1841
800k
    buf->knockout = false;
1842
800k
    buf->shape = 0xffff;
1843
800k
    buf->blend_mode = BLEND_MODE_Normal;
1844
800k
    buf->transfer_fn = transfer_fn;
1845
800k
    buf->matte_num_comps = Matte_components;
1846
800k
    buf->group_color_info = group_color;
1847
1848
800k
    if (Matte_components) {
1849
5.31k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1850
5.31k
                                                "pdf14_push_transparency_mask");
1851
5.31k
        if (buf->matte == NULL)
1852
0
            return_error(gs_error_VMerror);
1853
21.2k
        for (i = 0; i < Matte_components; i++) {
1854
15.9k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1855
15.9k
        }
1856
5.31k
    }
1857
800k
    buf->mask_id = mask_id;
1858
    /* If replacing=false, we start the mask for an image with SMask.
1859
       In this case the image's SMask temporary replaces the
1860
       mask of the containing group. Save the containing droup's mask
1861
       in buf->mask_stack */
1862
800k
    buf->mask_stack = ctx->mask_stack;
1863
800k
    if (buf->mask_stack){
1864
179k
        rc_increment(buf->mask_stack->rc_mask);
1865
179k
    }
1866
#if RAW_DUMP
1867
    /* Dump the current buffer to see what we have. */
1868
    if (ctx->stack->planestride > 0 ){
1869
        dump_raw_buffer(ctx->memory,
1870
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1871
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1872
                        ctx->stack->planestride, ctx->stack->rowstride,
1873
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1874
        global_index++;
1875
    }
1876
#endif
1877
800k
    buf->saved = ctx->stack;
1878
800k
    ctx->stack = buf;
1879
    /* Soft Mask related information so we know how to
1880
       compute luminosity when we pop the soft mask */
1881
800k
    buf->SMask_SubType = subtype;
1882
800k
    if (buf->data != NULL) {
1883
        /* We need to initialize it to the BC if it existed */
1884
        /* According to the spec, the CS has to be the same */
1885
        /* If the back ground component is black, then don't bother
1886
           with this.  Since we are forcing the rendering to gray
1887
           earlier now, go ahead and just use the GrayBackGround color
1888
           directly. */
1889
454k
        if ( Background_components && GrayBackground != 0.0 ) {
1890
162
            if (buf->deep) {
1891
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1892
0
                gs_memset16(buf->data, gray, buf->planestride);
1893
                /* If we have a background component that was not black, then we
1894
                   need to set the alpha for this mask as if we had drawn in the
1895
                   entire soft mask buffer */
1896
0
                gs_memset16(buf->data + buf->planestride, 65535,
1897
0
                            buf->planestride *(buf->n_chan - 1));
1898
162
            } else {
1899
162
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1900
162
                memset(buf->data, gray, buf->planestride);
1901
                /* If we have a background component that was not black, then we
1902
                   need to set the alpha for this mask as if we had drawn in the
1903
                   entire soft mask buffer */
1904
162
                memset(buf->data + buf->planestride, 255,
1905
162
                       buf->planestride * (buf->n_chan - 1));
1906
162
            }
1907
453k
        } else {
1908
            /* Compose mask with opaque background */
1909
453k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1910
453k
        }
1911
454k
    }
1912
800k
    return 0;
1913
800k
}
1914
1915
static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory)
1916
179k
{
1917
179k
    pdf14_mask_t *mask_stack = ctx->mask_stack;
1918
1919
179k
    if (mask_stack->rc_mask != NULL) {
1920
1.09k
        pdf14_mask_t *curr_mask = mask_stack;
1921
1.09k
        pdf14_mask_t *old_mask;
1922
2.18k
        while (curr_mask != NULL) {
1923
            /* Force to decrement until free */
1924
2.31k
            while (curr_mask->rc_mask != NULL)
1925
1.22k
                rc_decrement(curr_mask->rc_mask, "pdf14_free_mask_stack");
1926
1.09k
            old_mask = curr_mask;
1927
1.09k
            curr_mask = curr_mask->previous;
1928
1.09k
            gs_free_object(old_mask->memory, old_mask, "pdf14_free_mask_stack");
1929
1.09k
        }
1930
178k
    } else {
1931
178k
        gs_free_object(memory, mask_stack, "pdf14_free_mask_stack");
1932
178k
    }
1933
179k
    ctx->mask_stack = NULL;
1934
179k
}
1935
1936
static  int
1937
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1938
800k
{
1939
800k
    pdf14_buf* tos = ctx->stack;
1940
800k
    pdf14_buf* nos = tos->saved;
1941
800k
    byte *new_data_buf;
1942
800k
    int icc_match;
1943
800k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1944
800k
    cmm_profile_t *src_profile;
1945
800k
    gsicc_rendering_param_t rendering_params;
1946
800k
    gsicc_link_t *icc_link;
1947
800k
    gsicc_rendering_param_t render_cond;
1948
800k
    cmm_dev_profile_t *dev_profile;
1949
800k
    int code = 0;
1950
1951
800k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1952
800k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1953
800k
                          &render_cond);
1954
800k
    ctx->smask_depth -= 1;
1955
    /* icc_match == -1 means old non-icc code.
1956
       icc_match == 0 means use icc code
1957
       icc_match == 1 mean no conversion needed */
1958
800k
    if (des_profile != NULL && src_profile != NULL ) {
1959
800k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1960
800k
    } else {
1961
0
        icc_match = -1;
1962
0
    }
1963
800k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1964
800k
               tos->idle);
1965
800k
    ctx->stack = tos->saved;
1966
800k
    tos->saved = NULL;  /* To avoid issues with GC */
1967
800k
    if (tos->mask_stack) {
1968
        /* During the soft mask push, the mask_stack was copied (not moved) from
1969
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1970
           just set to NULL.  However, before we do that we must perform
1971
           rc decrement to match the increment that occured was made.  Also,
1972
           if this is the last ref count of the rc_mask, we should free the
1973
           buffer now since no other groups need it. */
1974
178k
        rc_decrement(tos->mask_stack->rc_mask,
1975
178k
                     "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1976
178k
        if (tos->mask_stack->rc_mask) {
1977
178k
            if (tos->mask_stack->rc_mask->rc.ref_count == 1){
1978
178k
                rc_decrement(tos->mask_stack->rc_mask,
1979
178k
                            "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1980
178k
            }
1981
178k
        }
1982
178k
        tos->mask_stack = NULL;
1983
178k
    }
1984
800k
    if (tos->data == NULL ) {
1985
        /* This can occur in clist rendering if the soft mask does
1986
           not intersect the current band.  It would be nice to
1987
           catch this earlier and just avoid creating the structure
1988
           to begin with.  For now we need to delete the structure
1989
           that was created.  Only delete if the alpha value is 65535 */
1990
346k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1991
346k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1992
6.66k
            pdf14_buf_free(tos);
1993
6.66k
            if (ctx->mask_stack != NULL) {
1994
3.34k
                pdf14_free_mask_stack(ctx, ctx->memory);
1995
3.34k
            }
1996
340k
        } else {
1997
            /* Assign as mask buffer */
1998
340k
            if (ctx->mask_stack != NULL) {
1999
85.3k
                pdf14_free_mask_stack(ctx, ctx->memory);
2000
85.3k
            }
2001
340k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2002
340k
            ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2003
340k
            ctx->mask_stack->rc_mask->mask_buf = tos;
2004
340k
        }
2005
346k
        ctx->smask_blend = false;  /* just in case */
2006
454k
    } else {
2007
        /* If we are already in the source space then there is no reason
2008
           to do the transformation */
2009
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
2010
        /* This will reduce our memory.  We won't reuse the existing one, due */
2011
        /* Due to the fact that on certain systems we may have issues recovering */
2012
        /* the data after a resize */
2013
454k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
2014
454k
                                        "pdf14_pop_transparency_mask");
2015
454k
        if (new_data_buf == NULL)
2016
0
            return_error(gs_error_VMerror);
2017
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
2018
           we won't be filling everything during the remap if it had not been
2019
           written into by the PDF14 fill rect */
2020
454k
        memset(new_data_buf, 0, tos->planestride);
2021
        /* If the subtype was alpha, then just grab the alpha channel now
2022
           and we are all done */
2023
454k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
2024
38.0k
            ctx->smask_blend = false;  /* not used in this case */
2025
38.0k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
2026
38.0k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2027
38.0k
                       tos->rowstride,
2028
38.0k
                       (tos->data)+tos->planestride, new_data_buf);
2029
#if RAW_DUMP
2030
            /* Dump the current buffer to see what we have. */
2031
            dump_raw_buffer(ctx->memory,
2032
                            tos->rect.q.y-tos->rect.p.y,
2033
                            tos->rowstride>>tos->deep, 1,
2034
                            tos->planestride, tos->rowstride,
2035
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
2036
                            tos->deep);
2037
            global_index++;
2038
#endif
2039
415k
        } else {
2040
415k
            if (icc_match == 1 || tos->n_chan == 2) {
2041
#if RAW_DUMP
2042
                /* Dump the current buffer to see what we have. */
2043
                dump_raw_buffer(ctx->memory,
2044
                                tos->rect.q.y-tos->rect.p.y,
2045
                                tos->rowstride>>tos->deep, tos->n_planes,
2046
                                tos->planestride, tos->rowstride,
2047
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
2048
                                tos->deep);
2049
                global_index++;
2050
#endif
2051
                /* There is no need to color convert.  Data is already gray scale.
2052
                   We just need to copy the gray plane.  However it is
2053
                   possible that the soft mask could have a soft mask which
2054
                   would end us up with some alpha blending information
2055
                   (Bug691803). In fact, according to the spec, the alpha
2056
                   blending has to occur.  See FTS test fts_26_2601.pdf
2057
                   for an example of this.  Softmask buffer is intialized
2058
                   with BG values.  It would be nice to keep track if buffer
2059
                   ever has a alpha value not 1 so that we could detect and
2060
                   avoid this blend if not needed. */
2061
415k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
2062
415k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
2063
415k
                            tos->planestride, tos->deep);
2064
#if RAW_DUMP
2065
                /* Dump the current buffer to see what we have. */
2066
                dump_raw_buffer(ctx->memory,
2067
                                tos->rect.q.y-tos->rect.p.y,
2068
                                tos->rowstride>>tos->deep, 1,
2069
                                tos->planestride, tos->rowstride,
2070
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2071
                                tos->deep);
2072
                global_index++;
2073
#endif
2074
415k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2075
415k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2076
415k
                           tos->rowstride, tos->data, new_data_buf);
2077
415k
            } else {
2078
0
                if ( icc_match == -1 ) {
2079
                    /* The slow old fashioned way */
2080
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2081
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2082
0
                        tos->rowstride, tos->planestride,
2083
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2084
0
                        tos->deep
2085
#if RAW_DUMP
2086
                        , ctx->memory
2087
#endif
2088
0
                        );
2089
0
                } else {
2090
                    /* ICC case where we use the CMM */
2091
                    /* Request the ICC link for the transform that we will need to use */
2092
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2093
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2094
0
                    rendering_params.override_icc = false;
2095
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2096
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2097
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2098
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2099
0
                        src_profile, &rendering_params, pgs->memory, false);
2100
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2101
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2102
0
                              tos->rowstride, tos->planestride,
2103
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2104
                    /* Release the link */
2105
0
                    gsicc_release_link(icc_link);
2106
0
                }
2107
0
            }
2108
415k
        }
2109
        /* Free the old object, NULL test was above */
2110
454k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2111
454k
        tos->data = new_data_buf;
2112
        /* Data is single channel now */
2113
454k
        tos->n_chan = 1;
2114
454k
        tos->n_planes = 1;
2115
        /* Assign as reference counted mask buffer */
2116
454k
        if (ctx->mask_stack != NULL) {
2117
            /* In this case, the source file is wacky as it already had a
2118
               softmask and now is getting a replacement. We need to clean
2119
               up the softmask stack before doing this free and creating
2120
               a new stack. Bug 693312 */
2121
91.0k
            pdf14_free_mask_stack(ctx, ctx->memory);
2122
91.0k
        }
2123
454k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2124
454k
        if (ctx->mask_stack == NULL)
2125
0
            return gs_note_error(gs_error_VMerror);
2126
454k
        ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2127
454k
        if (ctx->mask_stack->rc_mask == NULL)
2128
0
            return gs_note_error(gs_error_VMerror);
2129
454k
        ctx->mask_stack->rc_mask->mask_buf = tos;
2130
454k
    }
2131
800k
    return code;
2132
800k
}
2133
2134
static pdf14_mask_t *
2135
pdf14_mask_element_new(gs_memory_t *memory)
2136
2.50M
{
2137
2.50M
    pdf14_mask_t *result;
2138
2139
2.50M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2140
2.50M
                             "pdf14_mask_element_new");
2141
2.50M
    if (result == NULL)
2142
0
        return NULL;
2143
    /* Get the reference counted mask */
2144
2.50M
    result->rc_mask = NULL;
2145
2.50M
    result->previous = NULL;
2146
2.50M
    result->memory = memory;
2147
2.50M
    return result;
2148
2.50M
}
2149
2150
static int
2151
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2152
0
{
2153
    /* We need to push the current soft mask.  We need to
2154
       be able to recover it if we draw a new one and
2155
       then obtain a Q operation ( a pop ) */
2156
2157
0
    pdf14_device *pdev = (pdf14_device *)dev;
2158
0
    pdf14_ctx *ctx = pdev->ctx;
2159
0
    pdf14_mask_t *new_mask;
2160
2161
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2162
    /* We need to push the current mask buffer   */
2163
    /* Allocate a new element for the stack.
2164
       Don't do anything if there is no mask present.*/
2165
0
    if (ctx->mask_stack != NULL) {
2166
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2167
        /* Duplicate and make the link */
2168
0
        new_mask->rc_mask = ctx->mask_stack->rc_mask;
2169
0
        rc_increment(new_mask->rc_mask);
2170
0
        new_mask->previous = ctx->mask_stack;
2171
0
        ctx->mask_stack = new_mask;
2172
0
    }
2173
#ifdef DEBUG
2174
    pdf14_debug_mask_stack_state(pdev->ctx);
2175
#endif
2176
0
    return 0;
2177
0
}
2178
2179
static int
2180
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2181
4.79M
{
2182
    /* Pop the soft mask.  It is no longer needed. Likely due to
2183
       a Q that has occurred. */
2184
4.79M
    pdf14_device *pdev = (pdf14_device *)dev;
2185
4.79M
    pdf14_ctx *ctx = pdev->ctx;
2186
4.79M
    pdf14_mask_t *old_mask;
2187
2188
4.79M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2189
    /* rc decrement the current link after we break it from
2190
       the list, then free the stack element.  Don't do
2191
       anything if there is no mask present. */
2192
4.79M
    if (ctx->mask_stack != NULL) {
2193
851k
        old_mask = ctx->mask_stack;
2194
851k
        ctx->mask_stack = ctx->mask_stack->previous;
2195
851k
        if (old_mask->rc_mask) {
2196
851k
            rc_decrement(old_mask->rc_mask, "pdf14_pop_transparency_state");
2197
851k
        }
2198
851k
        gs_free_object(old_mask->memory, old_mask, "pdf14_pop_transparency_state");
2199
        /* We need to have some special handling here for when we have nested
2200
           soft masks.  There may be a copy in the stack that we may need to
2201
           adjust. */
2202
851k
        if (ctx->smask_depth > 0) {
2203
332
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2204
189
                ctx->stack->mask_stack = ctx->mask_stack;
2205
189
            }
2206
332
        }
2207
851k
    }
2208
#ifdef DEBUG
2209
    pdf14_debug_mask_stack_state(pdev->ctx);
2210
#endif
2211
4.79M
    return 0;
2212
4.79M
}
2213
2214
static  int
2215
pdf14_open(gx_device *dev)
2216
1.71M
{
2217
1.71M
    pdf14_device *pdev = (pdf14_device *)dev;
2218
2219
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2220
1.71M
    if (pdev->ctx == NULL) {
2221
1.71M
        bool has_tags = device_encodes_tags(dev);
2222
1.71M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2223
1.71M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2224
1.71M
        if (pdev->ctx == NULL)
2225
0
            return_error(gs_error_VMerror);
2226
2227
1.71M
        pdev->ctx->rect.p.x = 0;
2228
1.71M
        pdev->ctx->rect.p.y = 0;
2229
1.71M
        pdev->ctx->rect.q.x = dev->width;
2230
1.71M
        pdev->ctx->rect.q.y = dev->height;
2231
1.71M
        pdev->ctx->has_tags = has_tags;
2232
1.71M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2233
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2234
         * is. I am not sure how to fix that. */
2235
1.71M
        if (pdev->ctx->num_spots < 0)
2236
0
            pdev->ctx->num_spots = 0;
2237
1.71M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2238
1.71M
    }
2239
1.71M
    pdev->free_devicen = true;
2240
1.71M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2241
1.71M
    return 0;
2242
1.71M
}
2243
2244
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2245
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2246
};
2247
2248
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2249
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2250
};
2251
2252
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2253
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2254
};
2255
2256
static const gx_cm_color_map_procs *
2257
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2258
7.34M
{
2259
7.34M
    *tdev = dev;
2260
7.34M
    return &pdf14_DeviceCMYKspot_procs;
2261
7.34M
}
2262
2263
static const gx_cm_color_map_procs *
2264
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2265
21.0M
{
2266
21.0M
    *tdev = dev;
2267
21.0M
    return &pdf14_DeviceRGBspot_procs;
2268
21.0M
}
2269
2270
static const gx_cm_color_map_procs *
2271
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2272
87
{
2273
87
    *tdev = dev;
2274
87
    return &pdf14_DeviceGrayspot_procs;
2275
87
}
2276
2277
static void
2278
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2279
0
{
2280
0
    for (; n != 0; n--) {
2281
0
        uint16_t in = *src++;
2282
0
        ((byte *)dst)[0] = in>>8;
2283
0
        ((byte *)dst)[1] = in;
2284
0
        dst++;
2285
0
    }
2286
0
}
2287
2288
/* Used to pass along information about the buffer created by the
2289
   pdf14 device.  This is used by the pattern accumulator when the
2290
   pattern contains transparency.  Note that if free_device is true then
2291
   we need to go ahead and get the buffer data copied and free up the
2292
   device.  This only occurs at the end of a pattern accumulation operation */
2293
int
2294
pdf14_get_buffer_information(const gx_device * dev,
2295
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2296
                             bool free_device)
2297
58.7k
{
2298
58.7k
    const pdf14_device * pdev = (pdf14_device *)dev;
2299
58.7k
    pdf14_buf *buf;
2300
58.7k
    gs_int_rect rect;
2301
58.7k
    int x1,y1,width,height;
2302
2303
58.7k
    if ( pdev->ctx == NULL){
2304
0
        return 0;  /* this can occur if the pattern is a clist */
2305
0
    }
2306
#ifdef DEBUG
2307
    pdf14_debug_mask_stack_state(pdev->ctx);
2308
#endif
2309
58.7k
    buf = pdev->ctx->stack;
2310
58.7k
    rect = buf->rect;
2311
58.7k
    transbuff->buf = (free_device ? NULL : buf);
2312
58.7k
    x1 = min(pdev->width, rect.q.x);
2313
58.7k
    y1 = min(pdev->height, rect.q.y);
2314
58.7k
    width = x1 - rect.p.x;
2315
58.7k
    height = y1 - rect.p.y;
2316
2317
58.7k
    transbuff->n_chan    = buf->n_chan;
2318
58.7k
    transbuff->has_tags  = buf->has_tags;
2319
58.7k
    transbuff->has_shape = buf->has_shape;
2320
58.7k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2321
58.7k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2322
58.7k
    transbuff->deep      = buf->deep;
2323
2324
58.7k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2325
12.4k
        transbuff->planestride = 0;
2326
12.4k
        transbuff->rowstride = 0;
2327
12.4k
        return 0;
2328
12.4k
    }
2329
2330
46.3k
    if (free_device) {
2331
15.5k
        transbuff->pdev14 = NULL;
2332
15.5k
        transbuff->rect = rect;
2333
15.5k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2334
            /* If the bbox is smaller than the whole buffer than go ahead and
2335
               create a new one to use.  This can occur if we drew in a smaller
2336
               area than was specified by the transparency group rect. */
2337
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2338
0
            intptr_t planestride = rowstride * height;
2339
0
            int k, j;
2340
0
            byte *buff_ptr_src, *buff_ptr_des;
2341
2342
0
            transbuff->planestride = planestride;
2343
0
            transbuff->rowstride = rowstride;
2344
0
            transbuff->transbytes =
2345
0
                         gs_alloc_bytes(mem,
2346
0
                                        planestride *
2347
0
                                                (buf->n_chan +
2348
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2349
0
                                        "pdf14_get_buffer_information");
2350
0
            if (transbuff->transbytes == NULL)
2351
0
                return gs_error_VMerror;
2352
2353
0
            transbuff->mem = mem;
2354
0
            if (transbuff->deep) {
2355
0
                for (j = 0; j < transbuff->n_chan; j++) {
2356
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2357
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2358
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2359
0
                    for (k = 0; k < height; k++) {
2360
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2361
0
                        buff_ptr_des += rowstride;
2362
0
                        buff_ptr_src += buf->rowstride;
2363
0
                    }
2364
0
                }
2365
0
            } else {
2366
0
                for (j = 0; j < transbuff->n_chan; j++) {
2367
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2368
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2369
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2370
0
                    for (k = 0; k < height; k++) {
2371
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2372
0
                        buff_ptr_des += rowstride;
2373
0
                        buff_ptr_src += buf->rowstride;
2374
0
                    }
2375
0
                }
2376
0
            }
2377
2378
15.5k
        } else {
2379
            /* The entire buffer is used.  Go ahead and grab the pointer and
2380
               clear the pointer in the pdf14 device data buffer so it is not
2381
               freed when we close the device */
2382
15.5k
            transbuff->planestride = buf->planestride;
2383
15.5k
            transbuff->rowstride = buf->rowstride;
2384
15.5k
            transbuff->transbytes = buf->data;
2385
15.5k
            transbuff->mem = buf->memory;
2386
15.5k
            buf->data = NULL;  /* So that the buffer is not freed */
2387
15.5k
            if (transbuff->deep) {
2388
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2389
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2390
0
                uint16_t *buff_ptr;
2391
0
                int j, k, z;
2392
0
                intptr_t rowstride = transbuff->rowstride>>1;
2393
0
                intptr_t planestride = transbuff->planestride;
2394
0
                for (j = 0; j < transbuff->n_chan; j++) {
2395
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2396
0
                    for (k = 0; k < height; k++) {
2397
0
                        for (z = 0; z < width; z++) {
2398
0
                            uint16_t in = buff_ptr[z];
2399
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2400
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2401
0
                        }
2402
0
                        buff_ptr += rowstride;
2403
0
                    }
2404
0
                }
2405
0
            }
2406
15.5k
        }
2407
#if RAW_DUMP
2408
        /* Dump the buffer that should be going into the pattern */;
2409
        dump_raw_buffer_be(buf->memory,
2410
                           height, width, transbuff->n_chan,
2411
                           transbuff->planestride, transbuff->rowstride,
2412
                           "pdf14_pattern_buff", transbuff->transbytes,
2413
                           transbuff->deep);
2414
        global_index++;
2415
#endif
2416
        /* Go ahead and free up the pdf14 device */
2417
15.5k
        dev_proc(dev, close_device)((gx_device *)dev);
2418
30.7k
    } else {
2419
        /* Here we are coming from one of the fill image / pattern / mask
2420
           operations */
2421
30.7k
        transbuff->pdev14 = dev;
2422
30.7k
        transbuff->planestride = buf->planestride;
2423
30.7k
        transbuff->rowstride = buf->rowstride;
2424
30.7k
        transbuff->transbytes = buf->data;
2425
30.7k
        transbuff->mem = buf->memory;
2426
30.7k
        transbuff->rect = rect;
2427
#if RAW_DUMP
2428
    /* Dump the buffer that should be going into the pattern */;
2429
        dump_raw_buffer(buf->memory,
2430
                        height, width, buf->n_chan,
2431
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2432
                        "pdf14_pattern_buff",
2433
                        buf->data,
2434
                        transbuff->deep);
2435
        global_index++;
2436
#endif
2437
30.7k
    }
2438
46.3k
    return 0;
2439
46.3k
}
2440
2441
typedef void(*blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2442
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2443
2444
2445
static int
2446
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2447
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2448
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height)
2449
27.2k
{
2450
27.2k
    pdf14_buf* cm_result = NULL;
2451
27.2k
    cmm_profile_t* des_profile;
2452
27.2k
    gsicc_rendering_param_t render_cond;
2453
27.2k
    bool did_alloc;
2454
27.2k
    bool endian_swap;
2455
2456
27.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2457
27.2k
        &render_cond);
2458
2459
#if RAW_DUMP
2460
#if !ARCH_IS_BIG_ENDIAN
2461
    if (was_blended && (*buf)->deep)
2462
      dump_raw_buffer_be(dev->ctx->memory,
2463
          height, width, (*buf)->n_planes, (*buf)->planestride,
2464
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2465
    else
2466
#endif
2467
      dump_raw_buffer(dev->ctx->memory,
2468
          height, width, (*buf)->n_planes, (*buf)->planestride,
2469
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2470
    global_index++;
2471
#endif
2472
2473
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2474
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2475
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2476
       will need to know if it is dealing with native or BE data. */
2477
27.2k
    if (was_blended && (*buf)->deep) {
2478
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2479
           color conversion */
2480
#if ARCH_IS_BIG_ENDIAN
2481
        endian_swap = false;
2482
#else
2483
0
        endian_swap = true;
2484
0
#endif
2485
27.2k
    } else {
2486
        /* Data is in native format. No swap needed for CMM */
2487
27.2k
        endian_swap = false;
2488
27.2k
    }
2489
2490
27.2k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2491
27.2k
        *buf_ptr, src_profile, des_profile, x, y, width,
2492
27.2k
        height, &did_alloc, (*buf)->deep, endian_swap);
2493
2494
27.2k
    if (cm_result == NULL)
2495
0
        return_error(gs_error_VMerror);
2496
2497
    /* Update */
2498
27.2k
    *buf = cm_result;
2499
2500
    /* Make sure our buf_ptr is pointing to the proper location */
2501
27.2k
    if (did_alloc)
2502
27.2k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2503
2504
#if RAW_DUMP
2505
    dump_raw_buffer(dev->ctx->memory,
2506
        height, width, (*buf)->n_planes, (*buf)->planestride,
2507
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2508
    global_index++;
2509
#endif
2510
27.2k
    return 0;
2511
27.2k
}
2512
2513
/**
2514
 * pdf14_put_image: Put rendered image to target device.
2515
 * @pdev: The PDF 1.4 rendering device.
2516
 * @pgs: State for image draw operation.
2517
 * @target: The target device.
2518
 *
2519
 * Puts the rendered image in @pdev's buffer to @target. This is called
2520
 * as part of the sequence of popping the PDF 1.4 device filter.
2521
 *
2522
 * Return code: negative on error.
2523
 **/
2524
static  int
2525
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2526
1.53M
{
2527
1.53M
    const pdf14_device * pdev = (pdf14_device *)dev;
2528
1.53M
    int code;
2529
1.53M
    gs_image1_t image;
2530
1.53M
    gx_image_enum_common_t *info;
2531
1.53M
    pdf14_buf *buf = pdev->ctx->stack;
2532
1.53M
    gs_int_rect rect;
2533
1.53M
    int y;
2534
1.53M
    int num_comp;
2535
1.53M
    byte *linebuf, *linebuf_unaligned;
2536
1.53M
    gs_color_space *pcs;
2537
1.53M
    int x1, y1, width, height;
2538
1.53M
    byte *buf_ptr;
2539
1.53M
    int num_rows_left;
2540
1.53M
    cmm_profile_t* src_profile = NULL;
2541
1.53M
    cmm_profile_t* des_profile = NULL;
2542
1.53M
    cmm_dev_profile_t *pdf14dev_profile;
2543
1.53M
    cmm_dev_profile_t *dev_target_profile;
2544
1.53M
    uint16_t bg;
2545
1.53M
    bool has_tags = device_encodes_tags(dev);
2546
1.53M
    bool deep = pdev->ctx->deep;
2547
1.53M
    intptr_t planestride;
2548
1.53M
    intptr_t rowstride;
2549
1.53M
    blend_image_row_proc_t blend_row;
2550
1.53M
    bool color_mismatch = false;
2551
1.53M
    bool supports_alpha = false;
2552
1.53M
    int i;
2553
1.53M
    int alpha_offset, tag_offset;
2554
1.53M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2555
1.53M
    int rendering_intent_saved;
2556
1.53M
    int additive;
2557
2558
    /* Nothing was ever drawn. */
2559
1.53M
    if (buf == NULL)
2560
146k
        return 0;
2561
2562
1.38M
    additive = buf->group_color_info->isadditive;
2563
2564
1.38M
    src_profile = buf->group_color_info->icc_profile;
2565
2566
1.38M
    num_comp = buf->n_chan - 1;
2567
1.38M
    rect = buf->rect;
2568
1.38M
    planestride = buf->planestride;
2569
1.38M
    rowstride = buf->rowstride;
2570
2571
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2572
       potential problem. Bug 694190 */
2573
1.38M
    if (buf->saved != NULL) {
2574
126
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2575
126
    }
2576
1.38M
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2577
1.38M
    rect_intersect(rect, buf->dirty);
2578
1.38M
    x1 = min(pdev->width, rect.q.x);
2579
1.38M
    y1 = min(pdev->height, rect.q.y);
2580
1.38M
    width = x1 - rect.p.x;
2581
1.38M
    height = y1 - rect.p.y;
2582
#ifdef DUMP_TO_PNG
2583
    dump_planar_rgba(pdev->memory, buf);
2584
#endif
2585
1.38M
    if (width <= 0 || height <= 0 || buf->data == NULL)
2586
264k
        return 0;
2587
1.12M
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2588
2589
    /* Check that target is OK.  From fuzzing results the target could have been
2590
       destroyed, for e.g if it were a pattern accumulator that was closed
2591
       prematurely (Bug 694154).  We should always be able to to get an ICC
2592
       profile from the target. */
2593
1.12M
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2594
1.12M
    if (code < 0)
2595
0
        return code;
2596
1.12M
    if (dev_target_profile == NULL)
2597
0
        return gs_throw_code(gs_error_Fatal);
2598
2599
1.12M
    if (src_profile == NULL) {
2600
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2601
0
        if (code < 0) {
2602
0
            return code;
2603
0
        }
2604
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2605
0
    }
2606
2607
    /* Check if we have a color conversion issue */
2608
1.12M
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2609
1.12M
    if (!gsicc_profiles_equal(des_profile, src_profile))
2610
173k
        color_mismatch = true;
2611
2612
    /* Check if target supports alpha */
2613
1.12M
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2614
1.12M
    code = 0;
2615
2616
#if RAW_DUMP
2617
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2618
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2619
        "pre_final_blend", buf_ptr, deep);
2620
#endif
2621
2622
    /* Note. The logic below will need a little rework if we ever
2623
       have a device that has tags and alpha support */
2624
1.12M
    if (supports_alpha) {
2625
0
        if (!color_mismatch) {
2626
0
            alpha_offset = num_comp;
2627
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2628
2629
0
            for (i = 0; i < buf->n_planes; i++)
2630
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2631
0
            for (; i < target->color_info.num_components; i++)
2632
0
                buf_ptrs[i] = 0;
2633
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2634
0
                rect.p.x, rect.p.y, width, height,
2635
0
                rowstride, alpha_offset,
2636
0
                tag_offset);
2637
            /* Right now code has number of rows written */
2638
0
        } else {
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,
2644
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2645
0
                width, height);
2646
0
            if (code < 0)
2647
0
                return code;
2648
2649
            /* reset */
2650
0
            rowstride = buf->rowstride;
2651
0
            planestride = buf->planestride;
2652
0
            num_comp = buf->n_chan - 1;
2653
0
            alpha_offset = num_comp;
2654
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2655
2656
            /* And then out */
2657
0
            for (i = 0; i < buf->n_planes; i++)
2658
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2659
0
            for (; i < target->color_info.num_components; i++)
2660
0
                buf_ptrs[i] = 0;
2661
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2662
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2663
0
                tag_offset);
2664
            /* Right now code has number of rows written */
2665
0
        }
2666
1.12M
    } else if (has_tags) {
2667
        /* We are going out to a device that supports tags */
2668
0
        if (deep) {
2669
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2670
0
                buf->planestride, num_comp, additive, false);
2671
0
        } else {
2672
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2673
0
                buf->planestride, num_comp, additive);
2674
0
        }
2675
2676
#if RAW_DUMP
2677
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2678
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2679
            "post_final_blend", buf_ptr, deep);
2680
#endif
2681
2682
        /* Take care of color issues */
2683
0
        if (color_mismatch) {
2684
            /* In this case, just color convert and maintain alpha.  This is a case
2685
               where we either either blend in the right color space and have no
2686
               alpha for the output device or hand back the wrong color space with
2687
               alpha data.  We choose the later. */
2688
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2689
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
2690
0
            if (code < 0)
2691
0
                return code;
2692
2693
#if RAW_DUMP
2694
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2695
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2696
                "final_color_manage", buf_ptr, deep);
2697
            global_index++;
2698
#endif
2699
0
        }
2700
2701
        /* reset */
2702
0
        rowstride = buf->rowstride;
2703
0
        planestride = buf->planestride;
2704
0
        num_comp = buf->n_chan - 1;
2705
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2706
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2707
2708
        /* And then out */
2709
0
        for (i = 0; i < buf->n_planes; i++)
2710
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2711
0
        for (; i < target->color_info.num_components; i++)
2712
0
            buf_ptrs[i] = 0;
2713
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2714
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2715
0
            tag_offset);
2716
        /* Right now code has number of rows written */
2717
2718
0
    }
2719
2720
    /* If code > 0 then put image worked.  Let it finish and then exit */
2721
1.12M
    if (code > 0) {
2722
        /* We processed some or all of the rows.  Continue until we are done */
2723
0
        num_rows_left = height - code;
2724
0
        while (num_rows_left > 0) {
2725
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2726
0
                                                rect.p.x, rect.p.y + code, width,
2727
0
                                                num_rows_left, rowstride,
2728
0
                                                alpha_offset, tag_offset);
2729
0
            num_rows_left = num_rows_left - code;
2730
0
        }
2731
0
        return 0;
2732
0
    }
2733
2734
    /* Target device did not support alpha or tags.
2735
     * Set color space in preparation for sending an image.
2736
     * color conversion will occur after blending with through
2737
     * the begin typed image work flow.
2738
     */
2739
2740
1.12M
    planestride = buf->planestride;
2741
1.12M
    rowstride = buf->rowstride;
2742
1.12M
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2743
1.12M
    if (code < 0)
2744
0
        return code;
2745
    /* Need to set this to avoid color management during the image color render
2746
       operation.  Exception is for the special case when the destination was
2747
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2748
       image operation.  That will happen here as we should have set the profile
2749
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2750
       the case when we have a blend color space that is different than the
2751
       target device color space */
2752
1.12M
    pcs->cmm_icc_profile_data = src_profile;
2753
2754
    /* pcs takes a reference to the profile data it just retrieved. */
2755
1.12M
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2756
1.12M
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2757
1.12M
    gs_image_t_init_adjust(&image, pcs, false);
2758
1.12M
    image.ImageMatrix.xx = (float)width;
2759
1.12M
    image.ImageMatrix.yy = (float)height;
2760
1.12M
    image.Width = width;
2761
1.12M
    image.Height = height;
2762
1.12M
    image.BitsPerComponent = deep ? 16 : 8;
2763
1.12M
    image.ColorSpace = pcs;
2764
1.12M
    ctm_only_writable(pgs).xx = (float)width;
2765
1.12M
    ctm_only_writable(pgs).xy = 0;
2766
1.12M
    ctm_only_writable(pgs).yx = 0;
2767
1.12M
    ctm_only_writable(pgs).yy = (float)height;
2768
1.12M
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2769
1.12M
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2770
    /* Make sure that the relative colorimetric rendering intent is
2771
       used for this image. */
2772
1.12M
    rendering_intent_saved = pgs->renderingintent;
2773
1.12M
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2774
1.12M
    code = dev_proc(target, begin_typed_image) (target,
2775
1.12M
                                                pgs, NULL,
2776
1.12M
                                                (gs_image_common_t *)&image,
2777
1.12M
                                                NULL, NULL, NULL,
2778
1.12M
                                                pgs->memory, &info);
2779
1.12M
    pgs->renderingintent = rendering_intent_saved;
2780
1.12M
    if (code < 0) {
2781
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2782
0
        return code;
2783
0
    }
2784
#if RAW_DUMP
2785
    /* Dump the current buffer to see what we have. */
2786
    dump_raw_buffer(pdev->ctx->memory,
2787
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2788
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2789
                    pdev->ctx->stack->n_planes,
2790
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2791
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2792
    dump_raw_buffer(pdev->ctx->memory,
2793
                    height, width, buf->n_planes,
2794
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2795
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2796
    global_index++;
2797
    clist_band_count++;
2798
#endif
2799
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2800
    /* 28 byte overflow for AVX CMYK case. */
2801
1.12M
#define SSE_ALIGN 32
2802
1.12M
#define SSE_OVERFLOW 28
2803
1.12M
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2804
1.12M
    if (linebuf_unaligned == NULL)
2805
0
        return gs_error_VMerror;
2806
1.12M
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2807
2808
1.12M
    blend_row = deep ? gx_build_blended_image_row16 :
2809
1.12M
                       gx_build_blended_image_row;
2810
#ifdef WITH_CAL
2811
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2812
                                  blend_row, num_comp, deep);
2813
#endif
2814
2815
1.12M
    bg = additive ? (deep ? 65535 : 255) : 0;
2816
12.5M
    for (y = 0; y < height; y++) {
2817
11.4M
        gx_image_plane_t planes;
2818
11.4M
        int rows_used;
2819
2820
11.4M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2821
11.4M
        planes.data = linebuf;
2822
11.4M
        planes.data_x = 0;
2823
11.4M
        planes.raster = width * num_comp;
2824
11.4M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2825
        /* todo: check return value */
2826
11.4M
        buf_ptr += buf->rowstride;
2827
11.4M
    }
2828
1.12M
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2829
1.12M
    info->procs->end_image(info, true);
2830
    /* This will also decrement the device profile */
2831
1.12M
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2832
1.12M
    return code;
2833
1.12M
}
2834
2835
/* Overprint simulation with spots.  Collapse to CMYK */
2836
static void
2837
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2838
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2839
    cmyk_composite_map *map, bool keep_alpha)
2840
0
{
2841
0
    int comp_num;
2842
0
    uint cyan, magenta, yellow, black;
2843
0
    cmyk_composite_map *cmyk_map_entry;
2844
0
    int x, y;
2845
0
    intptr_t position;
2846
0
    byte comp, a;
2847
2848
0
    for (y = 0; y < height; y++) {
2849
0
        position = y * rowstride;
2850
0
        for (x = 0; x < width; x++) {
2851
0
            a = buf_ptr[position + planestride * num_comp];
2852
0
            if (a != 0) {
2853
0
                cyan = buf_ptr[position] * frac_1;
2854
0
                magenta = buf_ptr[position + planestride] * frac_1;
2855
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2856
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2857
0
                cmyk_map_entry = &(map[4]);
2858
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2859
0
                    comp = buf_ptr[position + planestride * comp_num];
2860
0
                    cyan += cmyk_map_entry->c * comp;
2861
0
                    magenta += cmyk_map_entry->m * comp;
2862
0
                    yellow += cmyk_map_entry->y * comp;
2863
0
                    black += cmyk_map_entry->k * comp;
2864
0
                    cmyk_map_entry++;
2865
0
                }
2866
0
                cyan /= frac_1;
2867
0
                magenta /= frac_1;
2868
0
                yellow /= frac_1;
2869
0
                black /= frac_1;
2870
2871
0
                if (cyan > 255)
2872
0
                    cyan = 255;
2873
0
                if (magenta > 255)
2874
0
                    magenta = 255;
2875
0
                if (yellow > 255)
2876
0
                    yellow = 255;
2877
0
                if (black > 255)
2878
0
                    black = 255;
2879
2880
0
                buf_ptr[position] = cyan;
2881
0
                buf_ptr[position + planestride] = magenta;
2882
0
                buf_ptr[position + planestride * 2] = yellow;
2883
0
                buf_ptr[position + planestride * 3] = black;
2884
0
            }
2885
0
            if (keep_alpha) {
2886
                /* Move the alpha and tag data */
2887
0
                buf_ptr[position + planestride * 4] = a;
2888
0
                if (tag_offset > 0) {
2889
0
                    buf_ptr[position + planestride * 5] =
2890
0
                        buf_ptr[position + planestride * tag_offset];
2891
0
                }
2892
0
            } else {
2893
                /* Remove alpha but keep tags */
2894
0
                if (tag_offset > 0) {
2895
0
                    buf_ptr[position + planestride * 4] =
2896
0
                        buf_ptr[position + planestride * tag_offset];
2897
0
                }
2898
2899
0
            }
2900
0
            position += 1;
2901
0
        }
2902
0
    }
2903
0
}
2904
2905
static void
2906
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2907
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2908
    cmyk_composite_map *map, bool keep_alpha)
2909
0
{
2910
0
    int comp_num;
2911
0
    ulong cyan, magenta, yellow, black;
2912
0
    cmyk_composite_map *cmyk_map_entry;
2913
0
    int x, y;
2914
0
    intptr_t position;
2915
0
    ulong comp, a;
2916
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2917
2918
    /* planestride and rowstride are in bytes, and we want them in shorts */
2919
0
    planestride >>= 1;
2920
0
    rowstride >>= 1;
2921
2922
0
    for (y = 0; y < height; y++) {
2923
0
        position = y * rowstride;
2924
0
        for (x = 0; x < width; x++) {
2925
0
            a = buf_ptr[position + planestride * num_comp];
2926
0
            if (a != 0) {
2927
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2928
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2929
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2930
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2931
0
                cmyk_map_entry = &(map[4]);
2932
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2933
0
                    comp = buf_ptr[position + planestride * comp_num];
2934
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2935
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2936
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2937
0
                    black += (ulong)cmyk_map_entry->k * comp;
2938
0
                    cmyk_map_entry++;
2939
0
                }
2940
0
                cyan /= frac_1_long;
2941
0
                magenta /= frac_1_long;
2942
0
                yellow /= frac_1_long;
2943
0
                black /= frac_1_long;
2944
2945
0
                if (cyan > 65535)
2946
0
                    cyan = 65535;
2947
0
                if (magenta > 65535)
2948
0
                    magenta = 65535;
2949
0
                if (yellow > 65535)
2950
0
                    yellow = 65535;
2951
0
                if (black > 65535)
2952
0
                    black = 65535;
2953
2954
#if ARCH_IS_BIG_ENDIAN
2955
                buf_ptr[position] = cyan;
2956
                buf_ptr[position + planestride] = magenta;
2957
                buf_ptr[position + planestride * 2] = yellow;
2958
                buf_ptr[position + planestride * 3] = black;
2959
#else
2960
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2961
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2962
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2963
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2964
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2965
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2966
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2967
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2968
0
#endif
2969
0
            }
2970
            /* Move the alpha and tag data */
2971
#if ARCH_IS_BIG_ENDIAN
2972
            if (keep_alpha) {
2973
                buf_ptr[position + planestride * 4] = a;
2974
                if (tag_offset > 0) {
2975
                    buf_ptr[position + planestride * 5] =
2976
                        buf_ptr[position + planestride * tag_offset];
2977
                }
2978
            } else {
2979
                if (tag_offset > 0) {
2980
                    buf_ptr[position + planestride * 4] =
2981
                        buf_ptr[position + planestride * tag_offset];
2982
                }
2983
            }
2984
#else
2985
0
            if (keep_alpha) {
2986
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2987
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2988
0
                if (tag_offset > 0) {
2989
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2990
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2991
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2992
0
                        buf_ptr[position + planestride * tag_offset];
2993
0
                }
2994
0
            } else {
2995
0
                if (tag_offset > 0) {
2996
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2997
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2998
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2999
0
                        buf_ptr[position + planestride * tag_offset];
3000
0
                }
3001
0
            }
3002
0
#endif
3003
0
            position += 1;
3004
0
        }
3005
0
    }
3006
0
}
3007
3008
static void
3009
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
3010
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
3011
    cmyk_composite_map *map, bool keep_alpha, bool deep)
3012
0
{
3013
0
    if (deep) {
3014
0
        if (keep_alpha) {
3015
0
            if (tag_offset > 0) {
3016
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3017
0
                    planestride, num_comp, spot_start, tag_offset,
3018
0
                    map, true);
3019
0
            } else {
3020
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3021
0
                    planestride, num_comp, spot_start, 0,
3022
0
                    map, true);
3023
0
            }
3024
0
        } else {
3025
0
            if (tag_offset > 0) {
3026
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3027
0
                    planestride, num_comp, spot_start, tag_offset,
3028
0
                    map, false);
3029
0
            } else {
3030
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3031
0
                    planestride, num_comp, spot_start, 0,
3032
0
                    map, false);
3033
0
            }
3034
0
        }
3035
0
    } else {
3036
0
        if (keep_alpha) {
3037
0
            if (tag_offset > 0) {
3038
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3039
0
                    planestride, num_comp, spot_start, tag_offset,
3040
0
                    map, true);
3041
0
            } else {
3042
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3043
0
                    planestride, num_comp, spot_start, 0,
3044
0
                    map, true);
3045
0
            }
3046
0
        } else {
3047
0
            if (tag_offset > 0) {
3048
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3049
0
                    planestride, num_comp, spot_start, tag_offset,
3050
0
                    map, false);
3051
0
            } else {
3052
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3053
0
                    planestride, num_comp, spot_start, 0,
3054
0
                    map, false);
3055
0
            }
3056
0
        }
3057
0
    }
3058
0
}
3059
3060
/* This is for the case where we have mixture of spots and additive color.
3061
   For example, RGB + spots or Gray + spots */
3062
static void
3063
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3064
    intptr_t planestride, int num_comp, int spot_start)
3065
27.2k
{
3066
27.2k
    int x, y;
3067
27.2k
    intptr_t position;
3068
27.2k
    byte comp, a;
3069
27.2k
    int tmp, comp_num;
3070
3071
289k
    for (y = 0; y < height; y++) {
3072
262k
        position = y * rowstride;
3073
267M
        for (x = 0; x < width; x++) {
3074
267M
            a = buf_ptr[position + planestride * num_comp];
3075
267M
            if ((a + 1) & 0xfe) {
3076
12.7M
                a ^= 0xff;
3077
51.0M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3078
38.2M
                    comp = buf_ptr[position + planestride * comp_num];
3079
38.2M
                    tmp = ((0xff - comp) * a) + 0x80;
3080
38.2M
                    comp += (tmp + (tmp >> 8)) >> 8;
3081
38.2M
                    buf_ptr[position + planestride * comp_num] = comp;
3082
38.2M
                }
3083
12.7M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3084
0
                    comp = buf_ptr[position + planestride * comp_num];
3085
0
                    tmp = ((-comp) * a) + 0x80;
3086
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3087
0
                    buf_ptr[position + planestride * comp_num] = comp;
3088
0
                }
3089
254M
            } else if (a == 0) {
3090
233M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3091
175M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3092
175M
                }
3093
71.3M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3094
12.9M
                    buf_ptr[position + planestride * comp_num] = 0;
3095
12.9M
                }
3096
58.3M
            }
3097
267M
            position += 1;
3098
267M
        }
3099
262k
    }
3100
27.2k
}
3101
3102
static void
3103
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3104
    intptr_t planestride, int num_comp, int spot_start)
3105
0
{
3106
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3107
0
    int x, y;
3108
0
    intptr_t position;
3109
0
    int comp, a;
3110
0
    int tmp, comp_num;
3111
3112
    /* planestride and rowstride are in bytes, and we want them in shorts */
3113
0
    planestride >>= 1;
3114
0
    rowstride >>= 1;
3115
3116
    /* Note that the input here is native endian, and the output must be in big endian! */
3117
0
    for (y = 0; y < height; y++) {
3118
0
        position = y * rowstride;
3119
0
        for (x = 0; x < width; x++) {
3120
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3121
0
            a = buf_ptr[position + planestride * num_comp];
3122
0
            if (a == 0) {
3123
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3124
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3125
0
                }
3126
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3127
0
                    buf_ptr[position + planestride * comp_num] = 0;
3128
0
                }
3129
0
            } else if (a == 0xffff) {
3130
#if ARCH_IS_BIG_ENDIAN
3131
#else
3132
                /* Convert from native -> big endian */
3133
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3134
0
                    comp = buf_ptr[position + planestride * comp_num];
3135
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3136
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3137
0
                }
3138
0
#endif
3139
0
            } else {
3140
0
                a ^= 0xffff;
3141
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3142
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3143
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3144
0
                    comp = buf_ptr[position + planestride * comp_num];
3145
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3146
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3147
                    /* Store as big endian */
3148
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3149
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3150
0
                }
3151
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3152
0
                    comp = buf_ptr[position + planestride * comp_num];
3153
0
                    tmp = ((0 - comp) * a) + 0x4000;
3154
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3155
                    /* Store as big endian */
3156
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3157
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3158
0
                }
3159
0
            }
3160
0
            position += 1;
3161
0
        }
3162
0
    }
3163
0
}
3164
3165
static int
3166
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3167
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3168
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3169
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3170
    gs_separations* pseparations, bool deep)
3171
76.4k
{
3172
76.4k
    pdf14_device* pdev = (pdf14_device*)dev;
3173
76.4k
    int code = 0;
3174
76.4k
    int y;
3175
76.4k
    int num_rows_left;
3176
76.4k
    int i;
3177
76.4k
    gs_int_rect rect = rect_in;
3178
76.4k
    intptr_t planestride = planestride_in;
3179
76.4k
    intptr_t rowstride = rowstride_in;
3180
76.4k
    byte* buf_ptr = NULL;
3181
76.4k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3182
76.4k
    cmm_profile_t* des_profile = NULL;
3183
76.4k
    cmm_dev_profile_t* dev_target_profile;
3184
76.4k
    cmm_dev_profile_t* pdf14dev_profile;
3185
76.4k
    bool color_mismatch = false;
3186
76.4k
    bool supports_alpha = false;
3187
76.4k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3188
76.4k
    int alpha_offset = num_comp;
3189
76.4k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3190
76.4k
    gs_color_space *pcs;
3191
76.4k
    gs_image1_t image;
3192
76.4k
    gx_image_enum_common_t *info;
3193
76.4k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3194
76.4k
    pdf14_buf *cm_result = NULL;
3195
76.4k
    bool did_alloc;
3196
76.4k
    bool target_sep_device = dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0);
3197
76.4k
    bool has_spots = pdev->ctx->num_spots > 0;
3198
76.4k
    bool blend_spots = !target_sep_device && has_spots;
3199
3200
    /* Check if group color space is CMYK based */
3201
76.4k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3202
76.4k
    if (code < 0)
3203
0
        return code;
3204
76.4k
    if (dev_target_profile == NULL)
3205
0
        return gs_throw_code(gs_error_Fatal);
3206
3207
76.4k
    if (src_profile == NULL) {
3208
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3209
0
        if (code < 0) {
3210
0
            return code;
3211
0
        }
3212
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3213
0
    }
3214
3215
    /* If the target device does not support spot colors and we have spot colors
3216
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3217
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3218
76.4k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3219
3220
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3221
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3222
0
            buf->rect.q.y, &did_alloc, buf->deep, false);
3223
0
        if (cm_result == NULL)
3224
0
            return_error(gs_error_VMerror);
3225
3226
        /* Update */
3227
0
        buf = cm_result;
3228
0
        src_profile = pgs->icc_manager->default_cmyk;
3229
0
        num_comp = buf->n_chan - 1;
3230
0
        additive = 0;
3231
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3232
0
        alpha_offset = num_comp;
3233
3234
#if RAW_DUMP
3235
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3236
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3237
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3238
        global_index++;
3239
#endif
3240
0
    }
3241
3242
    /* Fix order map if needed */
3243
358k
    for (i = 0; i < num_comp; i++) {
3244
281k
        pdev->devn_params.separation_order_map[i] = i;
3245
281k
    }
3246
3247
    /* Check if we have a color conversion issue */
3248
76.4k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3249
76.4k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3250
27.2k
        color_mismatch = true;
3251
3252
    /* Check if target supports alpha */
3253
76.4k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
3254
76.4k
    code = 0;
3255
3256
76.4k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3257
3258
    /* Note. The logic below will need a little rework if we ever
3259
       have a device that has tags and alpha support */
3260
76.4k
    if (supports_alpha) {
3261
3262
        /* If doing simulated overprint, Bring the spot color channels into
3263
           CMYK. Data is planar and 16 bit data in native format. */
3264
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3265
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3266
3267
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3268
0
            if (pdev->pclist_device != NULL) {
3269
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3270
3271
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3272
0
                if (code < 0)
3273
0
                    return code;
3274
0
            }
3275
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3276
3277
            /* Now we go to big endian */
3278
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3279
0
                planestride, num_comp, src_profile->num_comps,
3280
0
                tag_offset, cmyk_map, true, deep);
3281
3282
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3283
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3284
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3285
0
            buf->num_spots = 0;
3286
0
            num_comp = buf->n_chan - 1;
3287
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3288
0
        }
3289
3290
0
        if (!color_mismatch) {
3291
0
            for (i = 0; i < buf->n_planes; i++)
3292
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3293
0
            for (; i < target->color_info.num_components; i++)
3294
0
                buf_ptrs[i] = 0;
3295
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3296
0
                rect.p.x, rect.p.y, width, height,
3297
0
                rowstride, alpha_offset, tag_offset);
3298
            /* Right now code has number of rows written */
3299
0
        } else {
3300
            /* In this case, just color convert and maintain alpha.
3301
               This is a case where we either either blend in the
3302
               right color space and have no alpha for the output
3303
               device or hand back the wrong color space with
3304
               alpha data.  We choose the later. */
3305
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3306
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3307
0
                        rect.p.y, width, height);
3308
0
            if (code < 0)
3309
0
                return code;
3310
3311
            /* reset */
3312
0
            rowstride = buf->rowstride;
3313
0
            planestride = buf->planestride;
3314
0
            num_comp = buf->n_chan - 1;
3315
0
            alpha_offset = num_comp;
3316
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3317
3318
            /* And then out */
3319
0
            for (i = 0; i < buf->n_planes; i++)
3320
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3321
0
            for (; i < target->color_info.num_components; i++)
3322
0
                buf_ptrs[i] = 0;
3323
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3324
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3325
0
                tag_offset);
3326
            /* Right now code has number of rows written.  Writing continues below */
3327
0
        }
3328
76.4k
    } else {
3329
        /* Device could not handle the alpha data (we actually don't have
3330
           a device that does spot colorants and has an alpha channel so
3331
           the above code is untested.  Go ahead and preblend now and then
3332
           color convert if needed */
3333
#if RAW_DUMP
3334
           /* Dump before and after the blend to make sure we are doing that ok */
3335
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3336
            "pre_put_image_blend_image", buf_ptr, deep);
3337
        global_index++;
3338
#endif
3339
3340
76.4k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3341
27.2k
            if (deep) {
3342
            /* In this case, we are NOT going to bring the spots into the CMYK
3343
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3344
               16 bit data will be converted now from native endian to big endian during
3345
               the blending process */
3346
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3347
0
                    planestride, num_comp, src_profile->num_comps);
3348
27.2k
            } else {
3349
27.2k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3350
27.2k
                    planestride, num_comp, src_profile->num_comps);
3351
27.2k
            }
3352
49.2k
        } else {
3353
49.2k
            if (deep) {
3354
            /* In this case, if blend_spots == true, we will shortly be bringing
3355
               the spot colors to CMYK equivalent colors. It is at that time that
3356
               we will convert from native endian to big endian. In all other
3357
               cases this blending will due to conversion from native to BE */
3358
0
                bool keep_native = (blend_spots == true);
3359
3360
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3361
0
                    planestride, num_comp, additive, keep_native);
3362
49.2k
            } else {
3363
49.2k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3364
49.2k
                    planestride, num_comp, additive);
3365
49.2k
            }
3366
49.2k
        }
3367
3368
76.4k
        if (deep && has_tags)
3369
0
        {
3370
            /* We still need to convert the tags from Native to BE */
3371
#if ARCH_IS_BIG_ENDIAN
3372
#else
3373
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3374
0
            int i, j;
3375
0
            for (j = 0; j < height; j++)
3376
0
            {
3377
0
                for (i = 0; i < width; i++)
3378
0
                {
3379
0
                    uint16_t tag = *tags++;
3380
0
                    ((byte *)tags)[-2] = tag >> 8;
3381
0
                    ((byte *)tags)[-1] = tag;
3382
0
                }
3383
0
                tags += (buf->rowstride>>1) - width;
3384
0
            }
3385
0
#endif
3386
0
        }
3387
3388
#if RAW_DUMP
3389
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3390
            "post_put_image_blend_image", buf_ptr, deep);
3391
        global_index++;
3392
#endif
3393
3394
        /* If doing simulated overprint and we are not going to a sep device and
3395
           we have spot colors, then bring the spot color channels into CMYK
3396
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3397
           At this point, data is planar and 16 bit data is still in native format. It is
3398
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3399
           above during the alpha blend operation. */
3400
76.4k
        if (blend_spots) {
3401
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3402
3403
            /* In the clist case, we need to get equiv spots out of the
3404
               pseudo-band. */
3405
0
            if (pdev->pclist_device != NULL) {
3406
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3407
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3408
0
                if (code < 0)
3409
0
                    return code;
3410
0
            }
3411
3412
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3413
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3414
0
                planestride, num_comp, src_profile->num_comps,
3415
0
                tag_offset, cmyk_map, false, deep);
3416
3417
            /* Reset buffer information. We have CMYK and maybe tags */
3418
0
            num_comp = 4;
3419
0
            alpha_offset = 0;
3420
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3421
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3422
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3423
0
            buf->num_spots = 0;
3424
3425
#if RAW_DUMP
3426
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3427
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3428
            global_index++;
3429
#endif
3430
0
        }
3431
3432
        /* Map to the destination color space */
3433
76.4k
        if (color_mismatch) {
3434
27.2k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3435
27.2k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
3436
27.2k
            if (code < 0)
3437
0
                return code;
3438
3439
            /* reset */
3440
27.2k
            rowstride = buf->rowstride;
3441
27.2k
            planestride = buf->planestride;
3442
27.2k
            num_comp = buf->n_chan;
3443
27.2k
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3444
27.2k
        }
3445
3446
#if RAW_DUMP
3447
        /* Dump after the CS transform */
3448
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3449
            "post_put_image_color_convert", buf_ptr, deep);
3450
        global_index++;
3451
        /* clist_band_count++; */
3452
#endif
3453
3454
        /* Try put_image again. This can occur if the
3455
           target, like psdcmyk and tiffsep, support put_image */
3456
76.4k
        alpha_offset = 0;
3457
462k
        for (i = 0; i < buf->n_planes; i++)
3458
385k
            buf_ptrs[i] = buf_ptr + i * planestride;
3459
76.4k
        for (; i < target->color_info.num_components; i++)
3460
0
            buf_ptrs[i] = 0;
3461
76.4k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3462
76.4k
            rect.p.x, rect.p.y, width, height,
3463
76.4k
            rowstride, alpha_offset, tag_offset);
3464
76.4k
    }
3465
3466
    /* Put image was succesful.  We processed some or all of the rows.
3467
       Continue until we are done */
3468
76.4k
    if (code > 0) {
3469
173
        num_rows_left = height - code;
3470
173
        while (num_rows_left > 0) {
3471
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3472
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3473
0
                alpha_offset, tag_offset);
3474
0
            if (code < 0) {
3475
0
                return code;
3476
0
            }
3477
0
            num_rows_left = num_rows_left - code;
3478
0
        }
3479
173
        return 0;
3480
173
    }
3481
3482
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3483
       as well as those devices that support alpha (pngalpha,
3484
       png16malpha). If we are here, then we are doing an
3485
       overprint simulation on some other device. Image data
3486
       is aleady blended and in device color space. */
3487
76.3k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3488
76.3k
    if (code < 0)
3489
0
        return code;
3490
3491
    /* Already in destination CS */
3492
76.3k
    pcs->cmm_icc_profile_data = des_profile;
3493
3494
    /* pcs takes a reference to the profile data it just retrieved. */
3495
76.3k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3496
76.3k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3497
3498
    /* If we have more components to write out than are in the des_profile,
3499
     * then just using a PCS based on des_profile, will result in us dropping
3500
     * the spot colors.
3501
     * So, if our target supports devn colors, we instead construct a
3502
     * DevN device space with colors names taken from the devn_params, and
3503
     * use that instead. */
3504
76.3k
    if (des_profile->num_comps != target->color_info.num_components &&
3505
76.3k
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0))
3506
3.18k
    {
3507
3.18k
        int num_std;
3508
3.18k
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3509
3.18k
        gs_color_space *pcs2 = pcs;
3510
3.18k
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3511
3.18k
                                     pcs2, pgs->memory->non_gc_memory);
3512
3.18k
        if (code < 0)
3513
0
            return code;
3514
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3515
3.18k
        pcs->params.device_n.use_alt_cspace = false;
3516
3.18k
        num_std = devn_params->num_std_colorant_names;
3517
15.9k
        for (i = 0; i < num_std; i++) {
3518
12.7k
            const char *name = devn_params->std_colorant_names[i];
3519
12.7k
            size_t len = strlen(name);
3520
12.7k
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3521
12.7k
            if (pcs->params.device_n.names[i] == NULL) {
3522
0
                int j = 0;
3523
0
                for (j = 0;j < i; j++) {
3524
0
                    if (pcs->params.device_n.names[j] != NULL)
3525
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3526
0
                    pcs->params.device_n.names[j] = NULL;
3527
0
                }
3528
0
                return_error(gs_error_VMerror);
3529
0
            }
3530
12.7k
            strcpy(pcs->params.device_n.names[i], name);
3531
12.7k
        }
3532
3.18k
        for (; i < devn_params->separations.num_separations; i++) {
3533
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3534
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");
3535
0
            if (pcs->params.device_n.names[i] == NULL) {
3536
0
                int j = 0;
3537
0
                for (j = 0;j < i; j++) {
3538
0
                    if (pcs->params.device_n.names[j] != NULL)
3539
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3540
0
                    pcs->params.device_n.names[j] = NULL;
3541
0
                }
3542
0
                return_error(gs_error_VMerror);
3543
0
            }
3544
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3545
0
            pcs->params.device_n.names[i][name->size] = 0;
3546
0
        }
3547
3.18k
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3548
0
            return code;
3549
0
        }
3550
        /* One last thing -- we need to fudge the pgs->color_component_map */
3551
19.1k
        for (i=0; i < dev->color_info.num_components; i++)
3552
15.9k
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3553
3.18k
    }
3554
3555
76.3k
    gs_image_t_init_adjust(&image, pcs, false);
3556
76.3k
    image.ImageMatrix.xx = (float)width;
3557
76.3k
    image.ImageMatrix.yy = (float)height;
3558
76.3k
    image.Width = width;
3559
76.3k
    image.Height = height;
3560
76.3k
    image.BitsPerComponent = deep ? 16 : 8;
3561
76.3k
    image.ColorSpace = pcs;
3562
76.3k
    image.format = gs_image_format_component_planar;
3563
3564
76.3k
    ctm_only_writable(pgs).xx = (float)width;
3565
76.3k
    ctm_only_writable(pgs).xy = 0;
3566
76.3k
    ctm_only_writable(pgs).yx = 0;
3567
76.3k
    ctm_only_writable(pgs).yy = (float)height;
3568
76.3k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3569
76.3k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3570
76.3k
    code = dev_proc(target, begin_typed_image) (target,
3571
76.3k
        pgs, NULL, (gs_image_common_t *)&image,
3572
76.3k
        NULL, NULL, NULL, pgs->memory, &info);
3573
76.3k
    if (code < 0) {
3574
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3575
0
        return code;
3576
0
    }
3577
#if RAW_DUMP
3578
    /* Dump the current buffer to see what we have. */
3579
    dump_raw_buffer(pdev->ctx->memory,
3580
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3581
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3582
        pdev->ctx->stack->n_planes,
3583
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3584
        "put_image_final_big", pdev->ctx->stack->data, deep);
3585
    dump_raw_buffer(pdev->ctx->memory,
3586
        height, width, buf->n_planes,
3587
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3588
        "put_image_final_small", buf_ptr, deep);
3589
    global_index++;
3590
    clist_band_count++;
3591
#endif
3592
3593
411k
    for (i = 0; i < num_comp; i++) {
3594
335k
        planes[i].data = buf_ptr + i * planestride;
3595
335k
        planes[i].data_x = 0;
3596
335k
        planes[i].raster = buf->rowstride;
3597
335k
    }
3598
3599
846k
    for (y = 0; y < height; y++) {
3600
770k
        int rows_used;
3601
3602
770k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3603
3604
4.13M
        for (i = 0; i < num_comp; i++) {
3605
3.36M
            planes[i].data += buf->rowstride;
3606
3.36M
        }
3607
770k
    }
3608
76.3k
    info->procs->end_image(info, true);
3609
3610
    /* This will also decrement the profile */
3611
76.3k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3612
76.3k
    return code;
3613
76.3k
}
3614
3615
/**
3616
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3617
 * @pdev: The PDF 1.4 rendering device.
3618
 * @pgs: State for image draw operation.
3619
 * @target: The target device.
3620
 *
3621
 * Puts the rendered image in @pdev's buffer to @target. This is called
3622
 * as part of the sequence of popping the PDF 1.4 device filter.
3623
 *
3624
 * Return code: negative on error.
3625
 **/
3626
static  int
3627
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3628
156k
{
3629
156k
    pdf14_device *pdev = (pdf14_device *)dev;
3630
156k
    pdf14_buf *buf = pdev->ctx->stack;
3631
156k
    gs_int_rect rect;
3632
156k
    int x1, y1, width, height;
3633
156k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3634
156k
    gs_separations *pseparations = &pdevn_params->separations;
3635
156k
    intptr_t planestride;
3636
156k
    intptr_t rowstride;
3637
156k
    bool deep = pdev->ctx->deep;
3638
156k
    int num_comp;
3639
3640
    /* Nothing was ever drawn. */
3641
156k
    if (buf == NULL)
3642
40.4k
        return 0;
3643
3644
115k
    num_comp = buf->n_chan - 1;
3645
115k
    rect = buf->rect;
3646
115k
    planestride = buf->planestride;
3647
115k
    rowstride = buf->rowstride;
3648
3649
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3650
       potential problem. Bug 694190 */
3651
115k
    if (buf->saved != NULL) {
3652
1
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3653
1
    }
3654
115k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3655
115k
    rect_intersect(rect, buf->dirty);
3656
115k
    x1 = min(pdev->width, rect.q.x);
3657
115k
    y1 = min(pdev->height, rect.q.y);
3658
115k
    width = x1 - rect.p.x;
3659
115k
    height = y1 - rect.p.y;
3660
115k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3661
39.4k
        return 0;
3662
3663
#if RAW_DUMP
3664
    /* Dump the current buffer to see what we have. */
3665
    dump_raw_buffer(pdev->ctx->memory,
3666
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3667
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3668
                    pdev->ctx->stack->n_planes,
3669
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3670
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3671
                    pdev->ctx->stack->deep);
3672
3673
    global_index++;
3674
    clist_band_count++;
3675
#endif
3676
3677
76.4k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3678
76.4k
                      buf, planestride, rowstride,
3679
76.4k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3680
76.4k
                      buf->has_tags, rect, pseparations, deep);
3681
115k
}
3682
3683
/**
3684
 * pdf14_custom_put_image: Put rendered image to target device.
3685
 * @pdev: The PDF 1.4 rendering device.
3686
 * @pgs: State for image draw operation.
3687
 * @target: The target device.
3688
 *
3689
 * Puts the rendered image in @pdev's buffer to @target. This is called
3690
 * as part of the sequence of popping the PDF 1.4 device filter.
3691
 *
3692
 * Return code: negative on error.
3693
 **/
3694
static  int
3695
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3696
0
{
3697
0
    pdf14_device * pdev = (pdf14_device *)dev;
3698
0
    pdf14_buf *buf = pdev->ctx->stack;
3699
0
    bool deep = pdev->ctx->deep;
3700
0
    gs_int_rect rect;
3701
0
    int x0, y0;
3702
0
    intptr_t planestride;
3703
0
    intptr_t rowstride;
3704
0
    int num_comp;
3705
0
    uint16_t bg;
3706
0
    int x1, y1, width, height;
3707
0
    byte *buf_ptr;
3708
3709
    /* Nothing was ever drawn. */
3710
0
    if (buf == NULL)
3711
0
        return 0;
3712
3713
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3714
0
    num_comp = buf->n_chan - 1;
3715
0
    rect = buf->rect;
3716
0
    x0 = rect.p.x;
3717
0
    y0 = rect.p.y;
3718
0
    planestride = buf->planestride;
3719
0
    rowstride = buf->rowstride;
3720
3721
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3722
       potential problem. Bug 694190 */
3723
0
    if (buf->saved != NULL) {
3724
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3725
0
    }
3726
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3727
0
    rect_intersect(rect, buf->dirty);
3728
0
    x1 = min(pdev->width, rect.q.x);
3729
0
    y1 = min(pdev->height, rect.q.y);
3730
0
    width = x1 - rect.p.x;
3731
0
    height = y1 - rect.p.y;
3732
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3733
0
        return 0;
3734
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3735
3736
0
    return gx_put_blended_image_custom(target, buf_ptr,
3737
0
                      planestride, rowstride,
3738
0
                      x0, y0, width, height, num_comp, bg, deep);
3739
0
}
3740
3741
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3742
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3743
 * putting everything back how it was, and cleaning up the reference counts.
3744
 */
3745
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3746
3.46M
{
3747
3.46M
    if (pdev->ctx && pdev->ctx->stack) {
3748
1.52M
        pdf14_buf *buf, *next;
3749
3750
1.52M
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3751
127
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3752
127
            next = buf->saved;
3753
254
            while (group_color_info) {
3754
127
               if (group_color_info->icc_profile != NULL) {
3755
127
                   cmm_profile_t *group_profile;
3756
127
                   gsicc_rendering_param_t render_cond;
3757
127
                   cmm_dev_profile_t *dev_profile;
3758
127
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3759
3760
127
                   if (code >= 0) {
3761
127
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3762
127
                                             &render_cond);
3763
3764
127
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3765
127
                                               -1, "pdf14_end_transparency_group");
3766
127
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3767
127
                           group_color_info->icc_profile;
3768
127
                       group_color_info->icc_profile = NULL;
3769
127
                   }
3770
127
               }
3771
3772
127
               group_color_info = group_color_info->previous;
3773
127
            }
3774
127
        }
3775
1.52M
    }
3776
3.46M
}
3777
3778
static  int
3779
pdf14_close(gx_device *dev)
3780
1.73M
{
3781
1.73M
    pdf14_device *pdev = (pdf14_device *)dev;
3782
3783
1.73M
    pdf14_cleanup_group_color_profiles(pdev);
3784
3785
1.73M
    if (pdev->ctx) {
3786
1.71M
        pdf14_ctx_free(pdev->ctx);
3787
1.71M
        pdev->ctx = NULL;
3788
1.71M
    }
3789
1.73M
    return 0;
3790
1.73M
}
3791
3792
/* This is called when something has gone wrong and the interpreter received a
3793
   stop while in the middle of doing something with the PDF14 device.  We need
3794
   to clean up and end this in a graceful manner */
3795
static int
3796
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3797
0
{
3798
0
    pdf14_device *pdev = (pdf14_device *)dev;
3799
    /* The things that need to be cleaned up */
3800
0
    pdf14_ctx *ctx = pdev->ctx;
3801
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3802
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3803
3804
    /* Free up the smask color */
3805
0
    if (smaskcolor != NULL) {
3806
0
        smaskcolor->ref_count = 1;
3807
0
        pdf14_decrement_smask_color(pgs, dev);
3808
0
        pdev->smaskcolor = NULL;
3809
0
    }
3810
3811
    /* Free up the nested color procs and decrement the profiles */
3812
0
    if (group_color != NULL) {
3813
0
        while (group_color->previous != NULL)
3814
0
            pdf14_pop_group_color(dev, pgs);
3815
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3816
0
        pdev->color_model_stack = NULL;
3817
0
    }
3818
3819
    /* Start the context clean up */
3820
0
    if (ctx != NULL) {
3821
0
        pdf14_buf *buf, *next;
3822
0
        pdf14_group_color_t *procs, *prev_procs;
3823
3824
0
        if (ctx->mask_stack != NULL) {
3825
0
            pdf14_free_mask_stack(ctx, ctx->memory);
3826
0
        }
3827
3828
        /* Now the stack of buffers */
3829
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3830
0
            next = buf->saved;
3831
3832
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3833
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3834
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3835
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3836
            /* During the soft mask push, the mask_stack was copied (not moved) from
3837
               the ctx to the tos mask_stack. We are done with this now so it is safe
3838
               to free this one object */
3839
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3840
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3841
0
                prev_procs = procs->previous;
3842
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3843
0
            }
3844
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3845
0
        }
3846
        /* Finally the context itself */
3847
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3848
0
        pdev->ctx = NULL;
3849
0
    }
3850
0
    return 0;
3851
0
}
3852
3853
static  int
3854
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3855
0
{
3856
0
    pdf14_device * pdev = (pdf14_device *)dev;
3857
3858
0
    if (pdev->target != NULL)
3859
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3860
0
    return 0;
3861
0
}
3862
3863
13.8M
#define COPY_PARAM(p) dev->p = target->p
3864
8.67M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3865
3866
static void
3867
copy_tag_setup(gx_device *dev, const gx_device *target)
3868
1.73M
{
3869
1.73M
    bool deep = device_is_deep(target);
3870
1.73M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3871
1.73M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3872
1.73M
    COPY_PARAM(graphics_type_tag);
3873
1.73M
    if (had_tags && !has_tags)
3874
0
    {
3875
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3876
0
        dev->color_info.num_components--;
3877
0
        dev->color_info.depth -= deep ? 16 : 8;
3878
0
    }
3879
1.73M
    else if (!had_tags && has_tags)
3880
0
    {
3881
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3882
0
        dev->color_info.num_components++;
3883
0
        dev->color_info.depth += deep ? 16 : 8;
3884
0
    }
3885
1.73M
}
3886
3887
/*
3888
 * Copy device parameters back from a target.  This copies all standard
3889
 * parameters related to page size and resolution, but not any of the
3890
 * color-related parameters, as the pdf14 device retains its own color
3891
 * handling. This routine is parallel to gx_device_copy_params().
3892
 * Note that it DOES copy the devn_params since these are required to
3893
 * keep agreement with colorant name->number mapping, and don't change
3894
 * with the pdf14 color handling.
3895
 */
3896
static  int
3897
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3898
1.73M
{
3899
1.73M
    cmm_dev_profile_t *profile_targ;
3900
1.73M
    cmm_dev_profile_t *profile_dev14;
3901
1.73M
    pdf14_device *pdev = (pdf14_device*) dev;
3902
1.73M
    cmm_profile_t *blend_profile = NULL;
3903
1.73M
    int k;
3904
3905
1.73M
    COPY_PARAM(width);
3906
1.73M
    COPY_PARAM(height);
3907
1.73M
    COPY_ARRAY_PARAM(MediaSize);
3908
1.73M
    COPY_ARRAY_PARAM(ImagingBBox);
3909
1.73M
    COPY_PARAM(ImagingBBox_set);
3910
1.73M
    COPY_ARRAY_PARAM(HWResolution);
3911
1.73M
    COPY_ARRAY_PARAM(Margins);
3912
1.73M
    COPY_ARRAY_PARAM(HWMargins);
3913
1.73M
    COPY_PARAM(PageCount);
3914
1.73M
    COPY_PARAM(MaxPatternBitmap);
3915
3916
3917
    /* Supposedly this function isn't supposed to change the color setup of dev.
3918
     * BUT... if we change the tags value, we have to change the color setup to
3919
     * keep it valid. This is because num_components and depth include tags. */
3920
1.73M
    copy_tag_setup(dev, target);
3921
1.73M
    COPY_PARAM(interpolate_control);
3922
1.73M
    COPY_PARAM(non_strict_bounds);
3923
1.73M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3924
3925
1.73M
    if (dev->icc_struct == NULL) {
3926
1.73M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3927
1.73M
        if (dev->icc_struct == NULL)
3928
0
            return_error(gs_error_VMerror);
3929
1.73M
        profile_dev14 = dev->icc_struct;
3930
1.73M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3931
1.73M
                                          &(profile_targ));
3932
3933
8.67M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3934
6.93M
            if (profile_targ->device_profile[k] != NULL) {
3935
1.73M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3936
1.73M
            }
3937
6.93M
            if (profile_dev14->device_profile[k] != NULL) {
3938
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3939
0
            }
3940
6.93M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3941
6.93M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3942
6.93M
        }
3943
3944
1.73M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3945
1.73M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3946
1.73M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3947
1.73M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3948
1.73M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3949
1.73M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3950
1.73M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3951
1.73M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3952
1.73M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3953
3954
1.73M
        switch (pdev->blend_cs_state) {
3955
1.73M
            case PDF14_BLEND_CS_UNSPECIFIED:
3956
1.73M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3957
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3958
                   during the device push, when we have
3959
                   access to the pgs */
3960
1.73M
                break;
3961
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3962
0
                blend_profile = profile_targ->oi_profile;
3963
0
                break;
3964
0
            case PDF14_BLEND_CS_SPECIFIED:
3965
0
                blend_profile = profile_targ->blend_profile;
3966
0
                break;
3967
0
            default:
3968
0
                break;
3969
1.73M
        }
3970
3971
1.73M
        if (blend_profile != NULL) {
3972
            /* Set the device profile to the blend profile. Note only default profile is set */
3973
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3974
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3975
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3976
0
        }
3977
3978
1.73M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3979
1.73M
    }
3980
1.73M
#undef COPY_ARRAY_PARAM
3981
1.73M
#undef COPY_PARAM
3982
1.73M
    return 0;
3983
1.73M
}
3984
3985
/*
3986
 * This is a forwarding version of the put_params device proc.  It is only
3987
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3988
 * check if the target device has closed and, if so, close itself.  The routine
3989
 * also sync the device parameters.
3990
 */
3991
static  int
3992
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3993
0
{
3994
0
    pdf14_device * pdev = (pdf14_device *)dev;
3995
0
    gx_device * tdev = pdev->target;
3996
0
    bool was_open = tdev->is_open;
3997
0
    int code = 0;
3998
3999
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4000
0
        gx_device_decache_colors(dev);
4001
0
        if (!tdev->is_open) {
4002
0
            code = gs_closedevice(dev);
4003
0
            if (code == 0)
4004
0
                code = was_open ? 1 : 0;   /* target device closed */
4005
0
        }
4006
0
        gx_device_copy_params(dev, tdev);
4007
0
    }
4008
0
    return code;
4009
0
}
4010
4011
/* Function prototypes */
4012
int put_param_pdf14_spot_names(gx_device * pdev,
4013
                gs_separations * pseparations, gs_param_list * plist);
4014
119k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
4015
4016
/*
4017
 * The put_params method for the PDF 1.4 device will check if the
4018
 * target device has closed and, if so, close itself.  Note:  This routine is
4019
 * currently being used by both the pdf14_clist_device and the pdf_device.
4020
 * Please make sure that any changes are either applicable to both devices
4021
 * or clone the routine for each device.
4022
 */
4023
static  int
4024
pdf14_put_params(gx_device * dev, gs_param_list * plist)
4025
0
{
4026
0
    pdf14_device * pdev = (pdf14_device *)dev;
4027
0
    gx_device * tdev = pdev->target;
4028
0
    bool was_open = tdev->is_open;
4029
0
    int code = 0, code2 = 0;
4030
4031
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4032
0
        gx_device_decache_colors(dev);
4033
0
        if (!tdev->is_open) {
4034
0
            code = gs_closedevice(dev);
4035
0
            if (code == 0)
4036
0
                code = was_open ? 1 : 0;   /* target device closed */
4037
0
        }
4038
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4039
0
        if (code2 < 0)
4040
0
            code = code2;
4041
0
    }
4042
0
    return code;
4043
0
}
4044
4045
/*
4046
 * Copy marking related parameters into the PDF 1.4 device structure for use
4047
 * by pdf14_fill_rectangle.
4048
 */
4049
static  void
4050
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4051
56.1M
{
4052
56.1M
    pdf14_device * pdev = (pdf14_device *)dev;
4053
4054
56.1M
    if (pgs->alphaisshape) {
4055
1.04M
        pdev->opacity = 1.0;
4056
1.04M
        if (pgs->is_fill_color) {
4057
989k
            pdev->shape = pgs->fillconstantalpha;
4058
989k
        } else {
4059
50.5k
            pdev->shape = pgs->strokeconstantalpha;
4060
50.5k
        }
4061
55.0M
    } else {
4062
55.0M
        pdev->shape = 1.0;
4063
55.0M
        if (pgs->is_fill_color) {
4064
23.5M
            pdev->opacity = pgs->fillconstantalpha;
4065
31.5M
        } else {
4066
31.5M
            pdev->opacity = pgs->strokeconstantalpha;
4067
31.5M
        }
4068
55.0M
    }
4069
56.1M
    pdev->alpha = pdev->opacity * pdev->shape;
4070
56.1M
    pdev->blend_mode = pgs->blend_mode;
4071
56.1M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4072
56.1M
        pdev->overprint = pgs->overprint;
4073
56.1M
        pdev->stroke_overprint = pgs->stroke_overprint;
4074
56.1M
    } else {
4075
0
        pdev->overprint = false;
4076
0
        pdev->stroke_overprint = false;
4077
0
    }
4078
4079
56.1M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4080
56.1M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4081
4082
56.1M
    if (pgs->is_fill_color)
4083
24.5M
        pdev->op_state = PDF14_OP_STATE_FILL;
4084
31.5M
    else
4085
31.5M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4086
4087
56.1M
    if_debug6m('v', dev->memory,
4088
56.1M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4089
56.1M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4090
56.1M
               pdev->stroke_effective_op_mode);
4091
56.1M
}
4092
4093
static  void
4094
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4095
40.0M
{
4096
40.0M
    bool hastrans = false;
4097
4098
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4099
     * makes other operations much slower. We have no option however, if the
4100
     * current colour involves transparency, or if it's anything other than
4101
     * a completely solid (or transparent) operation in the normal blend mode.
4102
     */
4103
40.0M
    if (pdcolor != NULL)
4104
40.0M
    {
4105
40.0M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4106
40.0M
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4107
15.7k
            hastrans = true;
4108
40.0M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4109
            /* FIXME: Here we assume that ALL type 2 patterns are
4110
             * transparent - this test could be better. */
4111
57.5k
            hastrans = true;
4112
57.5k
        }
4113
40.0M
    }
4114
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4115
       This appears to be the only place where this test is done so
4116
       not adding a is_idempotent method */
4117
40.0M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4118
40.0M
        pgs->blend_mode != BLEND_MODE_Darken &&
4119
40.0M
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4120
40.0M
        (pgs->fillconstantalpha != 1.0) ||
4121
40.0M
        (pgs->strokeconstantalpha != 1.0) ||
4122
40.0M
        (hastrans))
4123
1.16M
    {
4124
        /*
4125
         * The blend operations are not idempotent.  Force non-idempotent
4126
         * filling and stroking operations.
4127
         */
4128
1.16M
        pgs->log_op |= lop_pdf14;
4129
1.16M
    }
4130
40.0M
}
4131
4132
static int
4133
push_shfill_group(pdf14_clist_device *pdev,
4134
                  gs_gstate *pgs,
4135
                  gs_fixed_rect *box)
4136
2.30k
{
4137
2.30k
    gs_transparency_group_params_t params = { 0 };
4138
2.30k
    int code;
4139
2.30k
    gs_rect cb;
4140
2.30k
    gs_gstate fudged_pgs = *pgs;
4141
4142
2.30k
    params.shade_group = true;
4143
4144
    /* gs_begin_transparency_group takes a bbox that it then
4145
     * transforms by ctm. Our bbox has already been transformed,
4146
     * so clear out the ctm. */
4147
2.30k
    fudged_pgs.ctm.xx = 1.0;
4148
2.30k
    fudged_pgs.ctm.xy = 0;
4149
2.30k
    fudged_pgs.ctm.yx = 0;
4150
2.30k
    fudged_pgs.ctm.yy = 1.0;
4151
2.30k
    fudged_pgs.ctm.tx = 0;
4152
2.30k
    fudged_pgs.ctm.ty = 0;
4153
2.30k
    cb.p.x = fixed2int_pixround(box->p.x);
4154
2.30k
    cb.p.y = fixed2int_pixround(box->p.y);
4155
2.30k
    cb.q.x = fixed2int_pixround(box->q.x);
4156
2.30k
    cb.q.y = fixed2int_pixround(box->q.y);
4157
4158
2.30k
    params.Isolated = false;
4159
2.30k
    params.Knockout = true;
4160
2.30k
    params.page_group = false;
4161
2.30k
    params.group_opacity = fudged_pgs.fillconstantalpha;
4162
2.30k
    params.group_shape = 1.0;
4163
2.30k
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4164
4165
    /* We have the group handle the blendmode and the opacity,
4166
     * and continue with the existing graphics state reset
4167
     * to normal, opaque operation. We could do it the other
4168
     * way around, but this way means that if we push a knockout
4169
     * group for a stroke, and then the code calls back into
4170
     * the fill operation as part of doing the stroking, we don't
4171
     * push another one. */
4172
2.30k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4173
2.30k
    gs_setfillconstantalpha(pgs, 1.0);
4174
2.30k
    gs_setstrokeconstantalpha(pgs, 1.0);
4175
2.30k
    if (pdev) {
4176
2.30k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4177
2.30k
        if (code < 0)
4178
0
            return code;
4179
2.30k
    }
4180
4181
2.30k
    return code;
4182
2.30k
}
4183
4184
static int
4185
pop_shfill_group(gs_gstate *pgs)
4186
2.29k
{
4187
2.29k
     return gs_end_transparency_group(pgs);
4188
2.29k
}
4189
4190
static int
4191
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4192
                           gx_path *ppath, const gx_fill_params *params,
4193
                           const gx_drawing_color *pdcolor,
4194
                           const gx_clip_path *pcpath)
4195
32.4M
{
4196
32.4M
    gs_gstate new_pgs = *pgs;
4197
32.4M
    int code = 0;
4198
32.4M
    gs_pattern2_instance_t *pinst = NULL;
4199
32.4M
    int push_group = 0;
4200
4201
32.4M
    code = pdf14_initialize_ctx(dev, pgs);
4202
32.4M
    if (code < 0)
4203
0
        return code;
4204
4205
32.4M
    if (pdcolor == NULL)
4206
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4207
32.4M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4208
32.4M
    if (gx_dc_is_pattern1_color(pdcolor)){
4209
898k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4210
898k
            gx_pattern1_clist_has_trans(pdcolor) ){
4211
            /* In this case, we need to push a transparency group
4212
               and tile the pattern color, which is stored in
4213
               a pdf14 device buffer in the ctile object memember
4214
               variable ttrans */
4215
#if RAW_DUMP
4216
            /* Since we do not get a put_image to view what
4217
               we have do it now */
4218
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4219
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4220
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4221
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4222
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4223
                        ppatdev14->ctx->stack->rect.p.y *
4224
                        ppatdev14->ctx->stack->rowstride +
4225
                        ppatdev14->ctx->stack->rect.p.x;
4226
                    dump_raw_buffer(ppatdev14->ctx->memory,
4227
                                    (ppatdev14->ctx->stack->rect.q.y -
4228
                                     ppatdev14->ctx->stack->rect.p.y),
4229
                                    (ppatdev14->ctx->stack->rect.q.x -
4230
                                     ppatdev14->ctx->stack->rect.p.x),
4231
                                    ppatdev14->ctx->stack->n_planes,
4232
                                    ppatdev14->ctx->stack->planestride,
4233
                                    ppatdev14->ctx->stack->rowstride,
4234
                                    "Pattern_Fill", buf_ptr,
4235
                                    ppatdev14->ctx->stack->deep);
4236
                    global_index++;
4237
                } else {
4238
                     gx_pattern_trans_t *patt_trans =
4239
                                        pdcolor->colors.pattern.p_tile->ttrans;
4240
                     dump_raw_buffer(patt_trans->mem,
4241
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4242
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4243
                                     patt_trans->n_chan,
4244
                                     patt_trans->planestride, patt_trans->rowstride,
4245
                                     "Pattern_Fill_clist",
4246
                                     patt_trans->transbytes +
4247
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4248
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4249
                                     patt_trans->deep);
4250
                    global_index++;
4251
                }
4252
            }
4253
#endif
4254
113k
            pdf14_set_marking_params(dev, &new_pgs);
4255
113k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4256
113k
                params, pdcolor, pcpath);
4257
113k
            new_pgs.trans_device = NULL;
4258
113k
            new_pgs.has_transparency = false;
4259
113k
            return code;
4260
113k
        }
4261
898k
    }
4262
32.3M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4263
32.3M
        pdcolor->type == &gx_dc_devn_masked) {
4264
        /* Non-idempotent blends require a transparency
4265
         * group to be pushed because shadings might
4266
         * paint several pixels twice. */
4267
54
        push_group = pgs->fillconstantalpha != 1.0 ||
4268
54
               !blend_is_idempotent(gs_currentblendmode(pgs));
4269
54
        pinst =
4270
54
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4271
54
        pinst->saved->has_transparency = true;
4272
        /* The transparency color space operations are driven
4273
           by the pdf14 clist writer device.  */
4274
54
        pinst->saved->trans_device = dev;
4275
54
    }
4276
32.3M
    if (push_group) {
4277
0
        gs_fixed_rect box;
4278
0
        if (pcpath)
4279
0
            gx_cpath_outer_box(pcpath, &box);
4280
0
        else
4281
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4282
0
        if (ppath) {
4283
0
            gs_fixed_rect path_box;
4284
4285
0
            gx_path_bbox(ppath, &path_box);
4286
0
            if (box.p.x < path_box.p.x)
4287
0
                box.p.x = path_box.p.x;
4288
0
            if (box.p.y < path_box.p.y)
4289
0
                box.p.y = path_box.p.y;
4290
0
            if (box.q.x > path_box.q.x)
4291
0
                box.q.x = path_box.q.x;
4292
0
            if (box.q.y > path_box.q.y)
4293
0
                box.q.y = path_box.q.y;
4294
0
        }
4295
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4296
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4297
0
    } else
4298
32.3M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4299
32.3M
    pdf14_set_marking_params(dev, &new_pgs);
4300
32.3M
    if (code >= 0) {
4301
32.3M
        new_pgs.trans_device = dev;
4302
32.3M
        new_pgs.has_transparency = true;
4303
        /* ppath can permissibly be NULL here, if we want to have a
4304
         * shading or a pattern fill the clipping path. This upsets
4305
         * coverity, which is not smart enough to realise that the
4306
         * validity of a NULL ppath depends on the type of pdcolor.
4307
         * We'll mark it as a false positive. */
4308
32.3M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4309
32.3M
        new_pgs.trans_device = NULL;
4310
32.3M
        new_pgs.has_transparency = false;
4311
32.3M
    }
4312
32.3M
    if (code >= 0 && push_group) {
4313
0
        code = pop_shfill_group(&new_pgs);
4314
0
        pdf14_set_marking_params(dev, pgs);
4315
0
    }
4316
32.3M
    if (pinst != NULL){
4317
54
        pinst->saved->trans_device = NULL;
4318
54
    }
4319
32.3M
    return code;
4320
32.4M
}
4321
4322
static  int
4323
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4324
                             gx_path *ppath, const gx_stroke_params *params,
4325
                             const gx_drawing_color *pdcolor,
4326
                             const gx_clip_path *pcpath)
4327
4.47M
{
4328
4.47M
    gs_gstate new_pgs = *pgs;
4329
4.47M
    int push_group = 0;
4330
4.47M
    int code = 0;
4331
4332
4.47M
    if (pdcolor == NULL)
4333
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4334
4335
4.47M
    code = pdf14_initialize_ctx(dev, pgs);
4336
4.47M
    if (code < 0)
4337
0
        return code;
4338
4339
4.47M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4340
        /* Non-idempotent blends require a transparency
4341
         * group to be pushed because shadings might
4342
         * paint several pixels twice. */
4343
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4344
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4345
0
    }
4346
4.47M
    if (push_group) {
4347
0
        gs_fixed_rect box;
4348
0
        if (pcpath)
4349
0
            gx_cpath_outer_box(pcpath, &box);
4350
0
        else
4351
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4352
4353
        /* For fill_path, we accept ppath == NULL to mean
4354
         * fill the entire clipping region. That makes no
4355
         * sense for stroke_path, hence ppath is always non
4356
         * NULL here. */
4357
0
        {
4358
0
            gs_fixed_rect path_box;
4359
0
            gs_fixed_point expansion;
4360
4361
0
            gx_path_bbox(ppath, &path_box);
4362
            /* Expand the path bounding box by the scaled line width. */
4363
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4364
                /* The expansion is so large it caused a limitcheck. */
4365
0
                path_box.p.x = path_box.p.y = min_fixed;
4366
0
                path_box.q.x = path_box.q.y = max_fixed;
4367
0
            } else {
4368
0
                expansion.x += pgs->fill_adjust.x;
4369
0
                expansion.y += pgs->fill_adjust.y;
4370
                /*
4371
                 * It's theoretically possible for the following computations to
4372
                 * overflow, so we need to check for this.
4373
                 */
4374
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4375
0
                                path_box.p.x - expansion.x);
4376
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4377
0
                                path_box.p.y - expansion.y);
4378
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4379
0
                                path_box.q.x + expansion.x);
4380
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4381
0
                                path_box.q.y + expansion.y);
4382
0
            }
4383
0
            if (box.p.x < path_box.p.x)
4384
0
                box.p.x = path_box.p.x;
4385
0
            if (box.p.y < path_box.p.y)
4386
0
                box.p.y = path_box.p.y;
4387
0
            if (box.q.x > path_box.q.x)
4388
0
                box.q.x = path_box.q.x;
4389
0
            if (box.q.y > path_box.q.y)
4390
0
                box.q.y = path_box.q.y;
4391
0
        }
4392
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4393
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4394
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4395
0
    } else
4396
4.47M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4397
4.47M
    pdf14_set_marking_params(dev, &new_pgs);
4398
4.47M
    if (code >= 0) {
4399
4.47M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4400
4401
4.47M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4402
4.47M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4403
4.47M
        ((pdf14_device*)dev)->op_state = save_op_state;
4404
4.47M
    }
4405
4.47M
    if (code >= 0 && push_group) {
4406
0
        code = pop_shfill_group(&new_pgs);
4407
0
        pdf14_set_marking_params(dev, pgs);
4408
0
    }
4409
4410
4.47M
    return code;
4411
4.47M
}
4412
4413
/* Pull out steps of transparency updates for fill/stroke
4414
   so that they can be invoked elsewhere (e.g.
4415
   when the abuf device is handling the stroke/fill */
4416
4417
/* Set-up prior to fill operation in fill-stroke */
4418
static int
4419
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4420
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4421
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4422
90.2k
{
4423
90.2k
    int code = 0;
4424
90.2k
    gs_transparency_group_params_t params = { 0 };
4425
90.2k
    gs_fixed_rect clip_bbox;
4426
90.2k
    gs_rect bbox, group_stroke_box;
4427
90.2k
    gs_fixed_rect path_bbox;
4428
90.2k
    int expansion_code;
4429
90.2k
    gs_fixed_point expansion;
4430
90.2k
    pdf14_device* p14dev = (pdf14_device*)dev;
4431
4432
90.2k
    *path_empty = false;
4433
4434
90.2k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4435
90.2k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4436
67
        return 0;
4437
4438
    /* The clip box returned here is scaled up by path_log2scale, so we need
4439
     * to scale down by this later. */
4440
90.1k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4441
90.1k
    if (code < 0 && code != gs_error_unknownerror)
4442
0
        return code;
4443
4444
90.1k
    if (code == gs_error_unknownerror) {
4445
        /* didn't get clip box from gx_curr_fixed_bbox */
4446
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4447
         * scaling down by this in a moment. */
4448
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4449
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4450
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4451
0
    }
4452
    /* pcpath->outer_box is scaled by path_log2scale too. */
4453
90.1k
    if (pcpath)
4454
90.1k
        rect_intersect(clip_bbox, pcpath->outer_box);
4455
4456
    /* expand the ppath using stroke expansion rule, then intersect it */
4457
90.1k
    code = gx_path_bbox(ppath, &path_bbox);
4458
4459
    /* If we are coming from the abuf device, the path has been scaled
4460
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4461
       on the path_bbox so that we get the proper bounding box for our group. */
4462
90.1k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4463
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4464
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4465
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4466
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4467
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4468
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4469
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4470
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4471
0
    }
4472
4473
90.1k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4474
60.8k
        *path_empty = true;
4475
60.8k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4476
                     there are simply too many return cases that I can't account for. */
4477
60.8k
    }
4478
29.3k
    if (code < 0)
4479
0
        return code;
4480
4481
29.3k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4482
29.3k
    if (expansion_code >= 0) {
4483
26.4k
        path_bbox.p.x -= expansion.x;
4484
26.4k
        path_bbox.p.y -= expansion.y;
4485
26.4k
        path_bbox.q.x += expansion.x;
4486
26.4k
        path_bbox.q.y += expansion.y;
4487
26.4k
    }
4488
29.3k
    rect_intersect(path_bbox, clip_bbox);
4489
29.3k
    bbox.p.x = fixed2float(path_bbox.p.x);
4490
29.3k
    bbox.p.y = fixed2float(path_bbox.p.y);
4491
29.3k
    bbox.q.x = fixed2float(path_bbox.q.x);
4492
29.3k
    bbox.q.y = fixed2float(path_bbox.q.y);
4493
4494
29.3k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4495
29.3k
    if (code < 0)
4496
3
        return code;
4497
4498
29.3k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4499
0
        p14dev->overprint = pgs->overprint;
4500
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4501
0
    }
4502
4503
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4504
29.3k
    if (fill_alpha == stroke_alpha &&
4505
29.3k
        p14dev->overprint && p14dev->stroke_overprint &&
4506
29.3k
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4507
4508
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4509
           compatible overprint mode.  Group will be composited with
4510
           original alpha and blend mode */
4511
0
        *op_ca_eq_CA = true;
4512
0
        params.Isolated = false;
4513
0
        params.group_color_type = UNKNOWN;
4514
0
        params.Knockout = false;
4515
0
        params.page_group = false;
4516
0
        params.group_opacity = 1.0;
4517
0
        params.group_shape = fill_alpha;
4518
4519
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4520
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4521
0
        if (code < 0)
4522
0
            return code;
4523
4524
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4525
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4526
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4527
4528
29.3k
    } else {
4529
        /* Push a non-isolated knockout group. Do not change the alpha or
4530
            blend modes. Note: we need to draw those that have alpha = 0 */
4531
29.3k
        *op_ca_eq_CA = false;
4532
29.3k
        params.Isolated = false;
4533
29.3k
        params.group_color_type = UNKNOWN;
4534
29.3k
        params.Knockout = true;
4535
29.3k
        params.page_group = false;
4536
29.3k
        params.group_shape = 1.0;
4537
29.3k
        params.group_opacity = 1.0;
4538
4539
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4540
29.3k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4541
29.3k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4542
29.3k
        if (code < 0)
4543
0
            return code;
4544
4545
        /* restore blend mode for actual drawing in the group */
4546
29.3k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4547
4548
        /* If we are in an overprint situation, set the blend mode to compatible
4549
            overprint */
4550
29.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4551
29.3k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4552
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4553
29.3k
    }
4554
29.3k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4555
29.3k
    return code;
4556
29.3k
}
4557
4558
/* Set-up prior to stroke operation in fill-stroke */
4559
static void
4560
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4561
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4562
29.4k
{
4563
29.4k
    pdf14_device* p14dev = (pdf14_device*)dev;
4564
4565
29.4k
    if (op_ca_eq_CA) {
4566
67
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4567
29.3k
    } else {
4568
29.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4569
29.3k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4570
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4571
4572
        /* Note that the stroke can end up doing fill methods */
4573
29.3k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4574
4575
29.3k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4576
29.3k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4577
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4578
29.3k
    }
4579
29.4k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4580
29.4k
}
4581
4582
/* Cleanup after the stroke in fill-stroke  */
4583
static int
4584
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4585
29.4k
{
4586
29.4k
    int code;
4587
4588
29.4k
    if (!op_ca_eq_CA) {
4589
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4590
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4591
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4592
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4593
          * We therefore need to make sure it is set according to the current fill state.
4594
          */
4595
29.3k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4596
29.3k
        code = gs_update_trans_marking_params(pgs);
4597
29.3k
        if (code < 0)
4598
0
            return code;
4599
29.3k
        pdf14_set_marking_params(dev, pgs);
4600
29.3k
    }
4601
4602
29.4k
    return 0;
4603
29.4k
}
4604
4605
/* cleanup in fill-stroke  */
4606
static int
4607
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4608
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4609
29.4k
{
4610
29.4k
    pdf14_device* p14dev = (pdf14_device*)dev;
4611
29.4k
    int code2;
4612
29.4k
    int code = 0;
4613
4614
    /* Restore the state */
4615
29.4k
    p14dev->op_state = save_op_state;
4616
29.4k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4617
29.4k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4618
29.4k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4619
4620
29.4k
    code2 = gs_end_transparency_group(pgs);
4621
29.4k
    if (code2 < 0) {
4622
        /* At this point things have gone very wrong. We should just shut down */
4623
0
        code = gs_abort_pdf14trans_device(pgs);
4624
0
        return code2;
4625
0
    }
4626
29.4k
    return code;
4627
29.4k
}
4628
4629
static int
4630
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4631
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4632
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4633
    const gx_clip_path *pcpath)
4634
311k
{
4635
311k
    bool op_ca_eq_CA;
4636
311k
    bool path_empty;
4637
311k
    int code;
4638
311k
    float stroke_alpha = cpgs->strokeconstantalpha;
4639
311k
    float fill_alpha = cpgs->fillconstantalpha;
4640
311k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4641
311k
    pdf14_device* p14dev = (pdf14_device*)dev;
4642
311k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4643
311k
    gs_log2_scale_point path_log2scale;
4644
311k
    bool group_needed = true;
4645
311k
    gx_device* curr_pgs_dev = cpgs->device;
4646
4647
311k
    union {
4648
311k
        const gs_gstate* cpgs;
4649
311k
        gs_gstate* pgs;
4650
311k
    } const_breaker;
4651
311k
    gs_gstate* pgs;
4652
4653
    /* Break const just once, neatly */
4654
311k
    const_breaker.cpgs = cpgs;
4655
311k
    pgs = const_breaker.pgs;
4656
311k
    path_log2scale.x = 0;
4657
311k
    path_log2scale.y = 0;
4658
4659
311k
    code = pdf14_initialize_ctx(dev, pgs);
4660
311k
    if (code < 0)
4661
0
        return code;
4662
4663
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4664
     * blend is normal we don't do a group push. Just do the stroke
4665
     * and the fill, even with overprint */
4666
311k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4667
220k
        group_needed = false;
4668
4669
311k
    if (group_needed) {
4670
90.2k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4671
                              can be called on the clist writer side when dealing
4672
                              with the abuf/pdf14 interaction. Those calls have to
4673
                              go through the gs_trans API not the gx_trans or pdf14
4674
                              methods.  Perhaps these methods should have a different
4675
                              suffix, but they are static methods here in the pdf14
4676
                              file. */
4677
90.2k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4678
90.2k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4679
90.2k
        pgs->device = curr_pgs_dev;
4680
90.2k
        if (code < 0)
4681
3
            goto cleanup;
4682
90.2k
        if (path_empty)
4683
60.8k
            return 0;
4684
90.2k
    }
4685
4686
250k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4687
250k
    if (code < 0)
4688
0
        goto cleanup;
4689
4690
250k
    if (group_needed)
4691
29.4k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4692
250k
    gs_swapcolors_quick(pgs);
4693
4694
4695
#if RAW_DUMP
4696
    /* Dump the current buffer to see what we have. */
4697
    dump_raw_buffer(p14dev->ctx->memory,
4698
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4699
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4700
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4701
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4702
    global_index++;
4703
#endif
4704
4705
250k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4706
250k
    gs_swapcolors_quick(pgs);
4707
250k
    if (code < 0) {
4708
0
        goto cleanup;
4709
0
    }
4710
4711
#if RAW_DUMP
4712
    /* Dump the current buffer to see what we have. */
4713
    dump_raw_buffer(p14dev->ctx->memory,
4714
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4715
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4716
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4717
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4718
    global_index++;
4719
#endif
4720
250k
    if (group_needed)
4721
29.4k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4722
4723
250k
cleanup:
4724
250k
    if (group_needed) {
4725
29.4k
        int code1;
4726
29.4k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4727
29.4k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4728
29.4k
            save_op_state);
4729
29.4k
        if (code1 < 0)
4730
0
            code = code1;
4731
29.4k
        pgs->device = curr_pgs_dev;
4732
29.4k
    }
4733
250k
    return code;
4734
250k
}
4735
4736
static int
4737
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4738
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4739
                      gx_color_index color, int depth)
4740
0
{
4741
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4742
0
                                  color, NULL, depth, false);
4743
0
}
4744
4745
static int
4746
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4747
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4748
                      const gx_drawing_color *pdcolor, int depth)
4749
0
{
4750
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4751
0
                                  0, pdcolor, depth, true);
4752
0
}
4753
4754
static int
4755
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4756
                          int aa_raster, gx_bitmap_id id, int x, int y,
4757
                          int w, int h, gx_color_index color,
4758
                          const gx_device_color *pdc, int depth, bool devn)
4759
0
{
4760
0
    const byte *aa_row;
4761
0
    pdf14_device *pdev = (pdf14_device *)dev;
4762
0
    pdf14_buf *buf = pdev->ctx->stack;
4763
0
    int i, j, k;
4764
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4765
0
    byte src[PDF14_MAX_PLANES];
4766
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4767
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4768
0
    bool additive = pdev->ctx->additive;
4769
0
    intptr_t rowstride = buf->rowstride;
4770
0
    intptr_t planestride = buf->planestride;
4771
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4772
0
    bool has_alpha_g = buf->has_alpha_g;
4773
0
    bool has_shape = buf->has_shape;
4774
0
    bool has_tags = buf->has_tags;
4775
0
    bool knockout = buf->knockout;
4776
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4777
0
        blend_mode == BLEND_MODE_Compatible ||
4778
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4779
0
    int num_chan = buf->n_chan;
4780
0
    int num_comp = num_chan - 1;
4781
0
    intptr_t shape_off = num_chan * planestride;
4782
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4783
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4784
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4785
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4786
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4787
0
    gx_color_index comps;
4788
0
    byte shape = 0; /* Quiet compiler. */
4789
0
    byte src_alpha;
4790
0
    int alpha2_aa, alpha_aa, sx;
4791
0
    int alpha_aa_act;
4792
0
    int xoff;
4793
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4794
0
    int shift = 8;
4795
0
    bool has_backdrop = buf->backdrop != NULL;
4796
4797
0
    if (buf->data == NULL)
4798
0
        return 0;
4799
0
    aa_row = data;
4800
0
    if (has_tags) {
4801
0
        if (devn)
4802
0
            curr_tag = pdc->tag;
4803
0
        else
4804
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4805
0
    }
4806
4807
0
    if (devn) {
4808
0
        if (additive) {
4809
0
            for (j = 0; j < num_comp; j++) {
4810
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4811
0
            }
4812
0
        } else {
4813
0
            for (j = 0; j < num_comp; j++) {
4814
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4815
0
            }
4816
0
        }
4817
0
    } else
4818
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4819
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4820
0
    if (has_shape)
4821
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4822
    /* Limit the area we write to the bounding rectangle for this buffer */
4823
0
    if (x < buf->rect.p.x) {
4824
0
        xoff = data_x + buf->rect.p.x - x;
4825
0
        w += x - buf->rect.p.x;
4826
0
        x = buf->rect.p.x;
4827
0
    } else {
4828
0
        xoff = data_x;
4829
0
    }
4830
0
    if (y < buf->rect.p.y) {
4831
0
      h += y - buf->rect.p.y;
4832
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4833
0
      y = buf->rect.p.y;
4834
0
    }
4835
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4836
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4837
    /* Update the dirty rectangle. */
4838
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4839
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4840
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4841
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4842
4843
    /* composite with backdrop only. */
4844
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4845
0
    if (knockout && has_backdrop)
4846
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4847
0
    else
4848
0
        bline = line;
4849
4850
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4851
0
        back_ptr = bline;
4852
0
        dst_ptr = line;
4853
0
        sx = xoff;
4854
0
        for (i = 0; i < w; ++i, ++sx) {
4855
            /* Complement the components for subtractive color spaces */
4856
0
            if (additive) {
4857
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4858
0
                    dst[k] = back_ptr[k * planestride];
4859
0
            } else { /* Complement the components for subtractive color spaces */
4860
0
                for (k = 0; k < num_comp; ++k)
4861
0
                    dst[k] = 255 - back_ptr[k * planestride];
4862
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4863
0
            }
4864
            /* Get the aa alpha from the buffer */
4865
0
            switch(depth)
4866
0
            {
4867
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4868
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4869
0
                break;
4870
0
            case 4:
4871
0
                alpha2_aa = aa_row[sx >> 1];
4872
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4873
0
                break;
4874
0
            case 8:
4875
0
                alpha_aa = aa_row[sx];
4876
0
                break;
4877
0
            default:
4878
0
                return_error(gs_error_rangecheck);
4879
0
            }
4880
0
            if (alpha_aa != 0) {  /* This does happen */
4881
0
                if (alpha_aa != 255) {
4882
                    /* We have an alpha value from aa */
4883
0
                    alpha_aa_act = alpha_aa;
4884
0
                    if (src_alpha != 255) {
4885
                        /* Need to combine it with the existing alpha */
4886
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4887
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4888
0
                    }
4889
                    /* Set our source alpha value appropriately */
4890
0
                    src[num_comp] = alpha_aa_act;
4891
0
                } else {
4892
                    /* We may have to reset this is it was changed as we
4893
                       moved across the row */
4894
0
                    src[num_comp] = src_alpha;
4895
0
                }
4896
0
                if (knockout) {
4897
0
                    if (buf->isolated) {
4898
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4899
0
                    } else {
4900
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4901
0
                            blend_mode, pdev->blend_procs, pdev);
4902
0
                    }
4903
0
                } else {
4904
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4905
0
                                                    pdev->blend_procs, pdev);
4906
0
                }
4907
                /* Complement the results for subtractive color spaces */
4908
0
                if (additive) {
4909
0
                    for (k = 0; k < num_chan; ++k)
4910
0
                        dst_ptr[k * planestride] = dst[k];
4911
0
                } else {
4912
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4913
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4914
0
                                ++k, comps >>= 1) {
4915
0
                            if ((comps & 0x1) != 0) {
4916
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4917
0
                            }
4918
0
                        }
4919
                        /* The alpha channel */
4920
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4921
0
                    } else {
4922
0
                        for (k = 0; k < num_comp; ++k)
4923
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4924
                        /* The alpha channel */
4925
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4926
0
                    }
4927
0
                }
4928
0
                if (has_alpha_g) {
4929
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4930
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4931
0
                }
4932
0
                if (has_shape) {
4933
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4934
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4935
0
                }
4936
0
                if (has_tags) {
4937
                    /* If alpha is 100% then set to curr_tag, else or */
4938
                    /* other than Normal BM, we always OR */
4939
0
                    if (src[num_comp] == 255 && tag_blend) {
4940
0
                        dst_ptr[tag_off] = curr_tag;
4941
0
                    } else {
4942
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4943
0
                    }
4944
0
                }
4945
0
            }
4946
0
            ++dst_ptr;
4947
0
            ++back_ptr;
4948
0
        }
4949
0
        line += rowstride;
4950
0
        bline += rowstride;
4951
0
    }
4952
0
    return 0;
4953
0
}
4954
4955
static int
4956
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4957
                             int aa_raster, gx_bitmap_id id, int x, int y,
4958
                             int w, int h, gx_color_index color,
4959
                             const gx_device_color *pdc, int depth, bool devn)
4960
0
{
4961
0
    const byte *aa_row;
4962
0
    pdf14_device *pdev = (pdf14_device *)dev;
4963
0
    pdf14_buf *buf = pdev->ctx->stack;
4964
0
    int i, j, k;
4965
0
    byte *bline, *line;
4966
0
    uint16_t *dst_ptr, *back_ptr;
4967
0
    uint16_t src[PDF14_MAX_PLANES];
4968
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4969
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4970
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4971
0
        blend_mode == BLEND_MODE_Compatible ||
4972
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4973
0
    bool additive = pdev->ctx->additive;
4974
0
    intptr_t rowstride = buf->rowstride;
4975
0
    int planestride = buf->planestride;
4976
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4977
0
    bool has_alpha_g = buf->has_alpha_g;
4978
0
    bool has_shape = buf->has_shape;
4979
0
    bool has_tags = buf->has_tags;
4980
0
    bool knockout = buf->knockout;
4981
0
    int num_chan = buf->n_chan;
4982
0
    int num_comp = num_chan - 1;
4983
0
    intptr_t shape_off = num_chan * planestride;
4984
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4985
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4986
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4987
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4988
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4989
0
    gx_color_index comps;
4990
0
    uint16_t shape = 0; /* Quiet compiler. */
4991
0
    uint16_t src_alpha;
4992
0
    int alpha2_aa, alpha_aa, sx;
4993
0
    int alpha_aa_act;
4994
0
    int xoff;
4995
0
    bool has_backdrop = buf->backdrop != NULL;
4996
4997
0
    if (buf->data == NULL)
4998
0
        return 0;
4999
0
    aa_row = data;
5000
0
    if (has_tags) {
5001
0
        if (devn)
5002
0
            curr_tag = pdc->tag;
5003
0
        else
5004
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
5005
0
    }
5006
5007
0
    if (devn) {
5008
0
        if (additive) {
5009
0
            for (j = 0; j < num_comp; j++) {
5010
0
                src[j] = pdc->colors.devn.values[j];
5011
0
            }
5012
0
        } else {
5013
0
            for (j = 0; j < num_comp; j++) {
5014
0
                src[j] = 65535 - pdc->colors.devn.values[j];
5015
0
            }
5016
0
        }
5017
0
    } else
5018
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
5019
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
5020
0
    if (has_shape)
5021
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
5022
    /* Limit the area we write to the bounding rectangle for this buffer */
5023
0
    if (x < buf->rect.p.x) {
5024
0
        xoff = data_x + buf->rect.p.x - x;
5025
0
        w += x - buf->rect.p.x;
5026
0
        x = buf->rect.p.x;
5027
0
    } else {
5028
0
        xoff = data_x;
5029
0
    }
5030
0
    if (y < buf->rect.p.y) {
5031
0
      h += y - buf->rect.p.y;
5032
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5033
0
      y = buf->rect.p.y;
5034
0
    }
5035
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5036
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5037
    /* Update the dirty rectangle. */
5038
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5039
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5040
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5041
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5042
5043
    /* composite with backdrop only. */
5044
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5045
0
    if (knockout && has_backdrop)
5046
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5047
0
    else
5048
0
        bline = line;
5049
5050
0
    planestride >>= 1;
5051
0
    rowstride   >>= 1;
5052
0
    alpha_g_off >>= 1;
5053
0
    shape_off   >>= 1;
5054
0
    tag_off     >>= 1;
5055
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5056
0
        back_ptr = (uint16_t *)(void *)bline;
5057
0
        dst_ptr = (uint16_t *)(void *)line;
5058
0
        sx = xoff;
5059
0
        for (i = 0; i < w; ++i, ++sx) {
5060
            /* Complement the components for subtractive color spaces */
5061
0
            if (additive) {
5062
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5063
0
                    dst[k] = back_ptr[k * planestride];
5064
0
            } else { /* Complement the components for subtractive color spaces */
5065
0
                for (k = 0; k < num_comp; ++k)
5066
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5067
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5068
0
            }
5069
            /* Get the aa alpha from the buffer */
5070
0
            switch(depth)
5071
0
            {
5072
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5073
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5074
0
                break;
5075
0
            case 4:
5076
0
                alpha2_aa = aa_row[sx >> 1];
5077
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5078
0
                break;
5079
0
            case 8:
5080
0
                alpha_aa = aa_row[sx];
5081
0
                break;
5082
0
            default:
5083
0
                return_error(gs_error_rangecheck);
5084
0
            }
5085
0
            if (alpha_aa != 0) {  /* This does happen */
5086
0
                if (alpha_aa != 255) {
5087
                    /* We have an alpha value from aa */
5088
0
                    alpha_aa_act = alpha_aa * 0x101;
5089
0
                    if (src_alpha != 65535) {
5090
                        /* Need to combine it with the existing alpha */
5091
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5092
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5093
0
                    }
5094
                    /* Set our source alpha value appropriately */
5095
0
                    src[num_comp] = alpha_aa_act;
5096
0
                } else {
5097
                    /* We may have to reset this is it was changed as we
5098
                       moved across the row */
5099
0
                    src[num_comp] = src_alpha;
5100
0
                }
5101
0
                if (knockout) {
5102
0
                    if (buf->isolated) {
5103
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5104
0
                    } else {
5105
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5106
0
                            blend_mode, pdev->blend_procs, pdev);
5107
0
                    }
5108
0
                } else {
5109
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5110
0
                                                     pdev->blend_procs, pdev);
5111
0
                }
5112
                /* Complement the results for subtractive color spaces */
5113
0
                if (additive) {
5114
0
                    for (k = 0; k < num_chan; ++k)
5115
0
                        dst_ptr[k * planestride] = dst[k];
5116
0
                } else {
5117
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5118
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5119
0
                                ++k, comps >>= 1) {
5120
0
                            if ((comps & 0x1) != 0) {
5121
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5122
0
                            }
5123
0
                        }
5124
                        /* The alpha channel */
5125
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5126
0
                    } else {
5127
0
                        for (k = 0; k < num_comp; ++k)
5128
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5129
                        /* The alpha channel */
5130
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5131
0
                    }
5132
0
                }
5133
0
                if (has_alpha_g) {
5134
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5135
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5136
0
                }
5137
0
                if (has_shape) {
5138
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5139
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5140
0
                }
5141
0
                if (has_tags) {
5142
                    /* If alpha is 100% then set to curr_tag, else or */
5143
                    /* other than Normal BM, we always OR */
5144
0
                    if (src[num_comp] == 65535 && tag_blend) {
5145
0
                        dst_ptr[tag_off] = curr_tag;
5146
0
                    } else {
5147
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5148
0
                    }
5149
0
                }
5150
0
            }
5151
0
            ++dst_ptr;
5152
0
            ++back_ptr;
5153
0
        }
5154
0
        line += rowstride;
5155
0
        bline += rowstride;
5156
0
    }
5157
0
    return 0;
5158
0
}
5159
5160
static int
5161
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5162
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5163
                      gx_color_index color, const gx_device_color *pdc,
5164
                      int depth, bool devn)
5165
0
{
5166
0
    bool deep = device_is_deep(dev);
5167
0
    int code;
5168
5169
0
    code = pdf14_initialize_ctx(dev, NULL);
5170
0
    if (code < 0)
5171
0
        return code;
5172
5173
0
    if (deep)
5174
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5175
0
                                            id, x, y, w, h,
5176
0
                                            color, pdc, depth, devn);
5177
0
    else
5178
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5179
0
                                         id, x, y, w, h,
5180
0
                                         color, pdc, depth, devn);
5181
0
}
5182
5183
static  int
5184
pdf14_fill_mask(gx_device * orig_dev,
5185
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5186
                     int x, int y, int w, int h,
5187
                     const gx_drawing_color * pdcolor, int depth,
5188
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5189
25.8M
{
5190
25.8M
    gx_device *dev;
5191
25.8M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5192
25.8M
    gx_device_clip cdev;
5193
25.8M
    gx_color_tile *ptile = NULL;
5194
25.8M
    int code = 0;
5195
25.8M
    gs_int_rect group_rect;
5196
25.8M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5197
25.8M
    bool has_pattern_trans = false;
5198
25.8M
    cmm_dev_profile_t *dev_profile;
5199
5200
25.8M
    if (pdcolor == NULL)
5201
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5202
5203
25.8M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5204
25.8M
    if (code < 0)
5205
0
        return code;
5206
5207
    /* If we are doing a fill with a pattern that has a transparency then
5208
       go ahead and do a push and a pop of the transparency group */
5209
25.8M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5210
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5211
0
            ptile = pdcolor->colors.pattern.p_tile;
5212
            /* Set up things in the ptile so that we get the proper
5213
               blending etc */
5214
            /* Set the blending procs and the is_additive setting based
5215
               upon the number of channels */
5216
0
            if (ptile->ttrans->n_chan-1 < 4) {
5217
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5218
0
                ptile->ttrans->is_additive = true;
5219
0
            } else {
5220
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5221
0
                ptile->ttrans->is_additive = false;
5222
0
            }
5223
            /* Set the procs so that we use the proper filling method. */
5224
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5225
            /* Based upon if the tiles overlap pick the type of rect
5226
               fill that we will want to use */
5227
0
            if (ptile->has_overlap) {
5228
                /* This one does blending since there is tile overlap */
5229
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5230
0
            } else {
5231
                /* This one does no blending since there is no tile overlap */
5232
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5233
0
            }
5234
            /* Push the group */
5235
0
            group_rect.p.x = x;
5236
0
            group_rect.p.y = max(0,y);
5237
0
            group_rect.q.x = x + w;
5238
0
            group_rect.q.y = y + h;
5239
0
            if (!(w <= 0 || h <= 0)) {
5240
5241
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5242
0
                if (group_color_info == NULL)
5243
0
                    return_error(gs_error_VMerror);
5244
5245
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5246
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5247
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5248
0
                     group_color_info, NULL, NULL);
5249
0
                if (code < 0)
5250
0
                    return code;
5251
                /* Set up the output buffer information now that we have
5252
                   pushed the group */
5253
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5254
0
                if (fill_trans_buffer == NULL)
5255
0
                    return_error(gs_error_VMerror);
5256
5257
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5258
0
                                              fill_trans_buffer, NULL, false);
5259
                /* Store this in the appropriate place in pdcolor.  This
5260
                   is released later after the mask fill */
5261
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5262
0
                has_pattern_trans = true;
5263
0
            }
5264
0
        }
5265
0
    }
5266
25.8M
    if (pcpath != 0) {
5267
3.41M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5268
3.41M
        dev = (gx_device *) & cdev;
5269
3.41M
    } else
5270
22.4M
        dev = orig_dev;
5271
25.8M
    if (depth > 1) {
5272
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5273
0
        code = (*dev_proc(dev, copy_alpha))
5274
0
            (dev, data, dx, raster, id, x, y, w, h,
5275
0
             gx_dc_pure_color(pdcolor), depth);
5276
25.8M
    } else {
5277
25.8M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5278
25.8M
                                          x, y, w, h, dev, lop, false);
5279
25.8M
    }
5280
25.8M
    if (has_pattern_trans) {
5281
0
        bool has_tags = device_encodes_tags(dev);
5282
0
        if (code >= 0)
5283
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5284
0
        if (code >= 0)
5285
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5286
0
                                                p14dev->blend_procs,
5287
0
                                                p14dev->color_info.num_components - has_tags,
5288
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5289
0
                                                orig_dev);
5290
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5291
0
                       "pdf14_fill_mask");
5292
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5293
0
    }
5294
25.8M
    if (pcpath != 0)
5295
3.41M
        gx_destroy_clip_device_on_stack(&cdev);
5296
25.8M
    return code;
5297
25.8M
}
5298
5299
5300
5301
/* Used for filling rects when we are doing a fill with a pattern that
5302
   has transparency */
5303
static  int
5304
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5305
                        gx_path * ppath, const gx_fill_params * params,
5306
                        const gx_device_color * pdevc,
5307
                        const gx_clip_path * pcpath)
5308
113k
{
5309
113k
    int code;
5310
113k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5311
113k
    gs_fixed_rect clip_box;
5312
113k
    gs_fixed_rect outer_box;
5313
113k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5314
113k
    gs_int_rect rect;
5315
113k
    gx_clip_rect *curr_clip_rect;
5316
113k
    gx_color_tile *ptile = NULL;
5317
113k
    int k;
5318
113k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5319
113k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5320
113k
    int n_chan_tile;
5321
113k
    gx_clip_path cpath_intersection;
5322
113k
    gx_path path_ttrans;
5323
113k
    pdf14_group_color_t *group_color_info;
5324
113k
    bool has_tags = device_encodes_tags(pdev);
5325
5326
113k
    if (ppath == NULL)
5327
0
        return_error(gs_error_unknownerror);  /* should not happen */
5328
113k
    if (pcpath != NULL) {
5329
107k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5330
107k
    } else {
5331
5.56k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5332
5.56k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5333
5.56k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5334
5.56k
    }
5335
113k
    if (code < 0)
5336
0
        return code;
5337
113k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5338
113k
                                          params->rule, pgs_noconst, params);
5339
113k
    if (code < 0)
5340
0
        return code;
5341
    /* One (common) case worth optimising for is where we have a pattern that
5342
     * is positioned such that only one repeat of the tile is actually
5343
     * visible. In this case, we can restrict the size of the blending group
5344
     * we need to produce to be that of the actual area of the tile that is
5345
     * used. */
5346
113k
    ptile = pdevc->colors.pattern.p_tile;
5347
113k
    if (ptile->ttrans != NULL)
5348
43.1k
    {
5349
43.1k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5350
43.1k
            (cpath_intersection.outer_box.p.y < 0) ||
5351
43.1k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5352
43.1k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5353
27.2k
        {
5354
            /* More than one repeat of the tile would be visible, so we can't
5355
             * use the optimisation here. (Actually, this test isn't quite
5356
             * right - it actually tests whether more than the '0th' repeat
5357
             * of the tile is visible. A better test would test if just one
5358
             * repeat of the tile was visible, irrespective of which one.
5359
             * This is (hopefully) relatively rare, and would make the code
5360
             * below more complex too, so we're ignoring that for now. If it
5361
             * becomes evident that it's a case that matters we can revisit
5362
             * it.) */
5363
27.2k
        } else {
5364
            /* Only the 0th repeat is visible. Restrict the size further to
5365
             * just the used area of that patch. */
5366
15.9k
            gx_path_init_local(&path_ttrans, ppath->memory);
5367
15.9k
            code = gx_path_add_rectangle(&path_ttrans,
5368
15.9k
                                         int2fixed(ptile->ttrans->rect.p.x),
5369
15.9k
                                         int2fixed(ptile->ttrans->rect.p.y),
5370
15.9k
                                         int2fixed(ptile->ttrans->rect.q.x),
5371
15.9k
                                         int2fixed(ptile->ttrans->rect.q.y));
5372
15.9k
            if (code < 0)
5373
0
                return code;
5374
15.9k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5375
15.9k
                                      params->rule, pgs_noconst);
5376
15.9k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5377
15.9k
            if (code < 0)
5378
0
                return code;
5379
15.9k
        }
5380
43.1k
    }
5381
    /* Now let us push a transparency group into which we are
5382
     * going to tile the pattern.  */
5383
113k
    if (ppath != NULL) {
5384
113k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5385
5386
113k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5387
113k
        rect.p.x = fixed2int(outer_box.p.x);
5388
113k
        rect.p.y = fixed2int(outer_box.p.y);
5389
113k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5390
113k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5391
5392
        /* The color space of this group must be the same as that of the
5393
           tile.  Then when we pop the group, if there is a mismatch between
5394
           the tile color space and the current context we will do the proper
5395
           conversion.  In this way, we ensure that if the tile has any overlapping
5396
           occuring it will be blended in the proper manner i.e in the tile
5397
           underlying color space. */
5398
113k
        if (ptile->cdev == NULL) {
5399
43.1k
            if (ptile->ttrans == NULL)
5400
0
                return_error(gs_error_unknownerror);  /* should not happen */
5401
43.1k
            n_chan_tile = ptile->ttrans->n_chan;
5402
69.8k
        } else {
5403
69.8k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5404
69.8k
        }
5405
113k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5406
5407
        /* Transparency handling with patterns confuses me, so some notes...
5408
         *
5409
         * For simple, non-transparent patterns, like you'd get in PS, we've
5410
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5411
         * times. To cope with unmarked pixels, we have a "transparency" plane
5412
         * (simple on/off) that says whether a pixel is marked or not.
5413
         *
5414
         * For patterns with transparency (but not blending), we can create an
5415
         * isolated transparency group, tile all the bitmap tiles into that, and
5416
         * then blend that back with the required alpha at the end. This works
5417
         * because the alpha values of the individual objects within the tile are
5418
         * recorded in that group.
5419
         *
5420
         * We can't do that for groups that use blending though, as each object
5421
         * in the pattern might use a different blend, and we don't (can't) record
5422
         * the blending mode. An isolated group doesn't even allow us to actually
5423
         * do the blending at all. So, for such patterns (any patterns that sets (or
5424
         * just has a resource that mentions) a non-normal blend mode), we use
5425
         * a pattern clist.
5426
         */
5427
113k
        if (ptile->cdev == NULL) {
5428
43.1k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5429
43.1k
            if (group_color_info == NULL)
5430
0
                return gs_error_VMerror;
5431
5432
43.1k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5433
43.1k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5434
43.1k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5435
43.1k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5436
43.1k
            if (code < 0)
5437
0
                return code;
5438
43.1k
        }
5439
5440
        /* Set the blending procs and the is_additive setting based
5441
           upon the number of channels */
5442
113k
        if (ptile->cdev == NULL) {
5443
43.1k
            if (n_chan_tile-1 < 4) {
5444
41.2k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5445
41.2k
                ptile->ttrans->is_additive = true;
5446
41.2k
            } else {
5447
1.90k
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5448
1.90k
                ptile->ttrans->is_additive = false;
5449
1.90k
            }
5450
43.1k
        }
5451
        /* Now lets go through the rect list and fill with the pattern */
5452
        /* First get the buffer that we will be filling */
5453
113k
        if (ptile->cdev == NULL) {
5454
43.1k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5455
43.1k
            if (fill_trans_buffer == NULL) {
5456
0
                p14dev->pclist_device = NULL;
5457
0
                return_error(gs_error_VMerror);
5458
0
            }
5459
43.1k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5460
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5461
               want to use */
5462
43.1k
            if (ptile->has_overlap) {
5463
                /* This one does blending since there is tile overlap */
5464
2.13k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5465
41.0k
            } else {
5466
                /* This one does no blending since there is no tile overlap */
5467
41.0k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5468
41.0k
            }
5469
            /* fill the rectangles */
5470
43.1k
            phase.x = pdevc->phase.x;
5471
43.1k
            phase.y = pdevc->phase.y;
5472
43.1k
            if (cpath_intersection.rect_list->list.head != NULL){
5473
1.21k
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5474
20.0k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5475
18.8k
                    if_debug5m('v', pgs->memory,
5476
18.8k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5477
18.8k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5478
18.8k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5479
18.8k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5480
18.8k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5481
18.8k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5482
18.8k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5483
18.8k
                    curr_clip_rect = curr_clip_rect->next;
5484
18.8k
                }
5485
41.9k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5486
                /* The case when there is just a single rect */
5487
41.0k
                if_debug5m('v', pgs->memory,
5488
41.0k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5489
41.0k
                           cpath_intersection.rect_list->list.single.xmin,
5490
41.0k
                           cpath_intersection.rect_list->list.single.ymin,
5491
41.0k
                           cpath_intersection.rect_list->list.single.xmax-
5492
41.0k
                              cpath_intersection.rect_list->list.single.xmin,
5493
41.0k
                           cpath_intersection.rect_list->list.single.ymax-
5494
41.0k
                              cpath_intersection.rect_list->list.single.ymin,
5495
41.0k
                           (int)ptile->id);
5496
41.0k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5497
41.0k
                                                  cpath_intersection.rect_list->list.single.ymin,
5498
41.0k
                                                  cpath_intersection.rect_list->list.single.xmax,
5499
41.0k
                                                  cpath_intersection.rect_list->list.single.ymax,
5500
41.0k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5501
41.0k
            }
5502
69.8k
        } else {
5503
            /* Clist pattern with transparency.  Create a clip device from our
5504
               cpath_intersection.  The above non-clist case could probably be
5505
               done this way too, which will reduce the amount of code here.
5506
               That is for another day though due to time constraints*/
5507
69.8k
            gx_device *dev;
5508
69.8k
            gx_device_clip clipdev;
5509
5510
69.8k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5511
69.8k
            dev = (gx_device *)&clipdev;
5512
69.8k
            phase.x = pdevc->phase.x;
5513
69.8k
            phase.y = pdevc->phase.y;
5514
69.8k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5515
69.8k
                                              ptile, fill_trans_buffer, phase,
5516
69.8k
                                              dev, pdevc, 1);
5517
69.8k
            gx_destroy_clip_device_on_stack(&clipdev);
5518
69.8k
        }
5519
        /* We're done drawing with the pattern, remove the reference to the
5520
         * pattern device
5521
         */
5522
113k
        p14dev->pclist_device = NULL;
5523
113k
        if (code < 0)
5524
0
            return code;
5525
5526
        /* free our buffer object */
5527
113k
        if (fill_trans_buffer != NULL) {
5528
43.1k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5529
43.1k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5530
43.1k
        }
5531
113k
        if (ptile->cdev == NULL) {
5532
            /* pop our transparency group which will force the blending.
5533
               This was all needed for Bug 693498 */
5534
43.1k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5535
43.1k
                                                p14dev->blend_procs,
5536
43.1k
                                                p14dev->color_info.num_components - has_tags,
5537
43.1k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5538
43.1k
                                                pdev);
5539
43.1k
        }
5540
113k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5541
113k
        p14dev->pclist_device = NULL;
5542
113k
    }
5543
113k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5544
113k
    return code;
5545
113k
}
5546
5547
/* Useful function that should probably go elsewhere.
5548
 * Call this function to find the topmost pdf14 device in the device chain,
5549
 * or NULL if there is not one.
5550
 */
5551
static pdf14_device *find_pdf14_device(gx_device *dev)
5552
0
{
5553
0
    pdf14_device *pdev;
5554
5555
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5556
0
        return NULL;
5557
0
    return pdev;
5558
0
}
5559
5560
/* Imager render for pattern transparency filling.  This is just here to catch
5561
   the final flush, at which time we will pop the group and reset a few items */
5562
static  int
5563
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5564
                    uint w, int h, gx_device * dev)
5565
0
{
5566
0
    int code;
5567
0
    pdf14_device * p14dev;
5568
0
    const gs_gstate * pgs = penum->pgs;
5569
0
    gx_device_color * pdcolor = (penum->icolor1);
5570
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5571
0
    bool has_tags = device_encodes_tags(dev);
5572
5573
    /* Pass along to the original renderer */
5574
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5575
0
    if (code < 0)
5576
0
        return code;
5577
    /* On our final time through here, go ahead and pop the transparency
5578
       group and reset the procs in the device color. And free the fill
5579
       trans buffer object */
5580
0
    if (h == 0 && ptile->trans_group_popped == false) {
5581
0
        p14dev = find_pdf14_device(dev);
5582
5583
0
        if (p14dev->pclist_device == NULL) {
5584
            /* Used if we are on clist writing phase.  Would only
5585
               occur if we somehow failed in high level clist
5586
               image writing */
5587
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5588
0
        } else {
5589
            /* Used if we are on clist reading phase.  If we had high level
5590
               image in clist */
5591
0
            cmm_dev_profile_t *dev_profile;
5592
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5593
0
            if (code < 0)
5594
0
                return code;
5595
5596
0
            if_debug2m('v', p14dev->ctx->memory,
5597
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5598
0
                       ptile->uid.id, ptile->id);
5599
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5600
0
                    p14dev->color_info.num_components - has_tags,
5601
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5602
0
                    (gx_device *) p14dev);
5603
0
        }
5604
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5605
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5606
0
                       "pdf14_pattern_trans_render");
5607
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5608
0
    }
5609
0
    return code;
5610
0
}
5611
5612
/* This function is used to get things in place for filling a mask image
5613
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5614
   and pdf14_clist_begin_type_image */
5615
static int
5616
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5617
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5618
                           const gs_int_rect * prect,
5619
                           const gx_drawing_color * pdcolor,
5620
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5621
                           gx_image_enum_common_t ** pinfo)
5622
0
{
5623
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5624
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5625
0
    gx_color_tile *ptile;
5626
0
    int code;
5627
0
    gs_int_rect group_rect;
5628
0
    gx_image_enum *penum;
5629
0
    gs_rect bbox_in, bbox_out;
5630
0
    gx_pattern_trans_t *fill_trans_buffer;
5631
5632
0
    ptile = pdcolor->colors.pattern.p_tile;
5633
    /* Set up things in the ptile so that we get the proper
5634
       blending etc */
5635
    /* Set the blending procs and the is_additive setting based
5636
       upon the number of channels */
5637
0
    if (ptile->ttrans->n_chan-1 < 4) {
5638
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5639
0
        ptile->ttrans->is_additive = true;
5640
0
    } else {
5641
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5642
0
        ptile->ttrans->is_additive = false;
5643
0
    }
5644
    /* Set the blending mode in the ptile based upon the current
5645
       setting in the gs_gstate */
5646
0
    ptile->blending_mode = pgs->blend_mode;
5647
    /* Based upon if the tiles overlap pick the type of rect
5648
       fill that we will want to use */
5649
0
    if (ptile->has_overlap) {
5650
        /* This one does blending since there is tile overlap */
5651
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5652
0
    } else {
5653
        /* This one does no blending since there is no tile overlap */
5654
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5655
0
    }
5656
    /* Set the procs so that we use the proper filling method. */
5657
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5658
    /* Let the imaging stuff get set up */
5659
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5660
0
                            prect, pdcolor,pcpath, mem, pinfo);
5661
0
    if (code < 0)
5662
0
        return code;
5663
    /* Now Push the group */
5664
    /* First apply the inverse of the image matrix to our
5665
       image size to get our bounding box. */
5666
0
    bbox_in.p.x = 0;
5667
0
    bbox_in.p.y = 0;
5668
0
    bbox_in.q.x = pim->Width;
5669
0
    bbox_in.q.y = pim->Height;
5670
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5671
0
                                &bbox_out);
5672
0
    if (code < 0)
5673
0
        return code;
5674
    /* That in turn will get hit by the matrix in the gs_gstate */
5675
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5676
0
                                            &bbox_out, (gs_gstate *)pgs);
5677
0
    if (code < 0)
5678
0
        return code;
5679
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5680
0
        if_debug2m('v', p14dev->ctx->memory,
5681
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5682
0
                   ptile->uid.id, ptile->id);
5683
5684
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5685
0
                                             65535, pgs->blend_mode, 0, 0,
5686
0
                                             ptile->ttrans->n_chan-1, false, false,
5687
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5688
5689
        /* Set up the output buffer information now that we have
5690
           pushed the group */
5691
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5692
0
        if (fill_trans_buffer == NULL)
5693
0
            return_error(gs_error_VMerror);
5694
5695
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5696
5697
        /* Store this in the appropriate place in pdcolor.  This
5698
           is released later in pdf14_pattern_trans_render when
5699
           we are all done with the mask fill */
5700
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5701
5702
        /* Change the renderer to handle this case so we can catch the
5703
           end.  We will then pop the group and reset the pdcolor proc.
5704
           Keep the base renderer also. */
5705
0
        penum = (gx_image_enum *) *pinfo;
5706
0
        ptile->ttrans->image_render = penum->render;
5707
0
        penum->render = &pdf14_pattern_trans_render;
5708
0
        ptile->trans_group_popped = false;
5709
0
    }
5710
0
    return code;
5711
0
}
5712
5713
static  int
5714
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5715
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5716
                           const gs_int_rect * prect,
5717
                           const gx_drawing_color * pdcolor,
5718
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5719
                           gx_image_enum_common_t ** pinfo)
5720
668k
{
5721
668k
    const gs_image_t *pim = (const gs_image_t *)pic;
5722
668k
    int code;
5723
5724
668k
    code = pdf14_initialize_ctx(dev, pgs);
5725
668k
    if (code < 0)
5726
0
        return code;
5727
5728
    /* If we are filling an image mask with a pattern that has a transparency
5729
       then we need to do some special handling */
5730
668k
    if (pim->ImageMask) {
5731
81
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5732
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5733
                /* If we are in a final run through here for this case then
5734
                   go ahead and push the transparency group.   Also, update
5735
                   the proc for the pattern color so that we used the
5736
                   appropriate fill operation.  Note that the group
5737
                   is popped and the proc will be reset when we flush the
5738
                   image data.  This is handled in a special pdf14 image
5739
                   renderer which will end up installed for this case.
5740
                   Detect setting of begin_image to gx_no_begin_image.
5741
                   (final recursive call) */
5742
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5743
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5744
0
                                                prect, pdcolor, pcpath, mem,
5745
0
                                                pinfo);
5746
0
                    return code;
5747
0
                }
5748
0
            }
5749
0
        }
5750
81
    }
5751
668k
    pdf14_set_marking_params(dev, pgs);
5752
668k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5753
668k
                                        pcpath, mem, pinfo);
5754
668k
}
5755
5756
static  void
5757
pdf14_set_params(gs_gstate * pgs,
5758
                 gx_device * dev,
5759
                 const gs_pdf14trans_params_t * pparams)
5760
16.7M
{
5761
16.7M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5762
16.7M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5763
3.18M
        pgs->blend_mode = pparams->blend_mode;
5764
16.7M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5765
1.70M
        pgs->text_knockout = pparams->text_knockout;
5766
16.7M
    if (pparams->changed & PDF14_SET_AIS)
5767
778k
        pgs->alphaisshape = pparams->ais;
5768
16.7M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5769
4.38M
        pgs->overprint = pparams->overprint;
5770
16.7M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5771
4.37M
        pgs->stroke_overprint = pparams->stroke_overprint;
5772
16.7M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5773
5.57M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5774
16.7M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5775
4.45M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5776
16.7M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5777
4.81M
        gs_swapcolors_quick(pgs);
5778
4.81M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5779
1.65M
            pgs->is_fill_color = false;
5780
3.15M
        else
5781
3.15M
            pgs->is_fill_color = true;
5782
4.81M
    }
5783
16.7M
    pdf14_set_marking_params(dev, pgs);
5784
16.7M
}
5785
5786
/*
5787
 * This open_device method for the PDF 1.4 compositor devices is only used
5788
 * when these devices are disabled.  This routine is about as close to
5789
 * a pure "forwarding" open_device operation as is possible. Its only
5790
 * significant function is to ensure that the is_open field of the
5791
 * PDF 1.4 compositor devices matches that of the target device.
5792
 *
5793
 * We assume this procedure is called only if the device is not already
5794
 * open, and that gs_opendevice will take care of the is_open flag.
5795
 */
5796
static  int
5797
pdf14_forward_open_device(gx_device * dev)
5798
0
{
5799
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5800
0
    gx_device * tdev = pdev->target;
5801
0
    int code;
5802
5803
    /* The PDF 1.4 compositing devices must have a target */
5804
0
    if (tdev == 0)
5805
0
        return_error(gs_error_unknownerror);
5806
0
    if ((code = gs_opendevice(tdev)) >= 0)
5807
0
        gx_device_copy_params(dev, tdev);
5808
0
    return code;
5809
0
}
5810
5811
/*
5812
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5813
 * for setting any device procs that should not be forwarded.
5814
 */
5815
static  void
5816
pdf14_forward_device_procs(gx_device * dev)
5817
1.71M
{
5818
1.71M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5819
1.71M
    pdf14_device *p14dev = (pdf14_device*)dev;
5820
5821
    /* If doing simulated overprint with spot colors
5822
       then makes sure to reset devn setting */
5823
1.71M
    if (p14dev->overprint_sim &&
5824
1.71M
        p14dev->color_info.num_components > 4)
5825
0
        p14dev->icc_struct->supports_devn =
5826
0
            p14dev->target_support_devn;
5827
5828
    /*
5829
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5830
     * This will ensure that any new device procs are also set.  However that
5831
     * routine only changes procs which are NULL.  Thus we start by setting all
5832
     * procs to NULL.
5833
     */
5834
1.71M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5835
1.71M
    gx_device_forward_fill_in_procs(pdev);
5836
    /*
5837
     * gx_device_forward_fill_in_procs does not forward all procs.
5838
     * Set the remainding procs to also forward.
5839
     */
5840
1.71M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5841
1.71M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5842
1.71M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5843
1.71M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5844
1.71M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5845
1.71M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5846
1.71M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5847
1.71M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5848
1.71M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5849
1.71M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5850
    /* These are forwarding devices with minor tweaks. */
5851
1.71M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5852
1.71M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5853
1.71M
}
5854
5855
/*
5856
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5857
 * compositor device is never removed.  (We do not have a remove compositor
5858
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5859
 * routine implements that action.
5860
 */
5861
int
5862
pdf14_disable_device(gx_device * dev)
5863
1.69M
{
5864
1.69M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5865
5866
1.69M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5867
1.69M
    dev->color_info = pdev->target->color_info;
5868
1.69M
    pdf14_forward_device_procs(dev);
5869
1.69M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5870
1.69M
    return 0;
5871
1.69M
}
5872
5873
/*
5874
 * The default color space for PDF 1.4 blend modes is based upon the process
5875
 * color model of the output device.
5876
 */
5877
static  pdf14_default_colorspace_t
5878
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5879
                                 pdf14_blend_cs_t *blend_cs_state)
5880
4.78M
{
5881
    /* If a blend color space was specified, then go ahead and use that to
5882
       define the default color space for the blend modes.  Only Gray, RGB
5883
       or CMYK blend color spaces are allowed.  Note we do not allow this
5884
       setting if we are dealing with a separation device. */
5885
4.78M
    cmm_dev_profile_t *dev_profile;
5886
4.78M
    cmm_profile_t *blend_profile = NULL;
5887
4.78M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5888
4.78M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5889
4.78M
    bool valid_blend_cs = false;
5890
4.78M
    int has_tags = device_encodes_tags(pdev);
5891
5892
4.78M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5893
5894
    /* Are we using a blend color space or the output intent color space? Also
5895
       is there a conflict in the settings. i.e. has someone set a blend color
5896
       space and tried to use the output intent with simulate overprint setting.
5897
    */
5898
4.78M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5899
4.78M
        dev_profile->oi_profile != NULL &&
5900
4.78M
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5901
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5902
           possible conflicting command line settings and we will err on using the blend profile
5903
           if one was specified. */
5904
0
        if (dev_profile->blend_profile != NULL &&
5905
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5906
0
            blend_profile = dev_profile->blend_profile;
5907
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5908
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5909
0
        } else {
5910
            /* All good, use the output intent profile as we have one
5911
               and are doing simulate overprint with a different device
5912
               profile set. */
5913
0
            blend_profile = dev_profile->oi_profile;
5914
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5915
0
        }
5916
4.78M
    } else if (dev_profile->blend_profile != NULL &&
5917
4.78M
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5918
        /* Blend profile is different than device profile */
5919
0
        blend_profile = dev_profile->blend_profile;
5920
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5921
0
    }
5922
5923
    /* Make sure any blend color space is valid along with other cond */
5924
4.78M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5925
0
        if (!blend_profile->isdevlink &&
5926
0
            !blend_profile->islab &&
5927
0
            (blend_profile->data_cs == gsGRAY ||
5928
0
             blend_profile->data_cs == gsRGB ||
5929
0
             blend_profile->data_cs == gsCMYK)) {
5930
            /* Also, do not allow the use of the blend space when we are pushing
5931
               a pattern pdf14 device.  Those should inherit from the parent */
5932
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5933
0
                  gx_device_is_pattern_accum(pdev))) {
5934
0
                valid_blend_cs = true;
5935
0
            }
5936
0
        }
5937
0
    }
5938
5939
    /* If num components is one, just go ahead and use gray.  This avoids
5940
       issues with additive/subtractive mono color devices  */
5941
4.78M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5942
4.78M
        pdev->color_info.num_components == 1) {
5943
        /*
5944
        * Note:  We do not allow the SeparationOrder device parameter for
5945
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5946
        * and 3 colorants for DeviceRGB.
5947
        */
5948
4.35M
        if (valid_blend_cs) {
5949
0
            *blend_cs_state = temp_cs_state;
5950
0
            switch (blend_profile->num_comps) {
5951
0
            case 1:
5952
0
                return PDF14_DeviceGray;
5953
0
            case 3:
5954
0
                return PDF14_DeviceRGB;
5955
0
            case 4:
5956
0
                return PDF14_DeviceCMYK;
5957
0
            }
5958
0
        }
5959
4.35M
        if (pdev->color_info.num_components - has_tags == 1)
5960
1.25M
            return PDF14_DeviceGray;
5961
3.09M
        else if (pdev->color_info.num_components - has_tags == 3)
5962
3.09M
            return PDF14_DeviceRGB;
5963
0
        else
5964
0
            return PDF14_DeviceRGBspot;
5965
4.35M
    } else {
5966
        /*
5967
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5968
         * the CMYK plus spot colors will not support the blend color space
5969
         */
5970
432k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5971
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5972
        return PDF14_DeviceCustom;
5973
#endif
5974
        /*
5975
         * Count the number of CMYK process components supported by the output
5976
         * device.
5977
         */
5978
2.16M
        for (i = 0; i < 4; i++) {
5979
1.72M
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5980
5981
1.72M
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5982
1.72M
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5983
1.72M
            if (output_comp_num >= 0) {
5984
1.72M
                num_cmyk++;
5985
1.72M
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5986
1.72M
                    num_cmyk_used++;
5987
1.72M
            }
5988
1.72M
        }
5989
        /*
5990
         * Check if the device supports only CMYK.  Otherewise we assume that
5991
         * the output device supports spot colors.  Note:  This algorithm can
5992
         * be fooled if the SeparationOrder device parameter is being used by
5993
         * the output device device to only select CMYK.
5994
         */
5995
432k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5996
432k
            && pdev->color_info.max_components == 4) {
5997
51.0k
            if (valid_blend_cs) {
5998
0
                *blend_cs_state = temp_cs_state;
5999
0
                switch (blend_profile->num_comps) {
6000
0
                case 1:
6001
0
                    return PDF14_DeviceGray;
6002
0
                case 3:
6003
0
                    return PDF14_DeviceRGB;
6004
0
                case 4:
6005
0
                    return PDF14_DeviceCMYK;
6006
0
                }
6007
0
            }
6008
51.0k
            return PDF14_DeviceCMYK;
6009
51.0k
        }
6010
        /*
6011
         * Check if we should use the 'custom' PDF 1.4 compositor device.
6012
         * This device is only needed for those devices which do not support
6013
         * a basic CMYK process color model.
6014
         */
6015
381k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
6016
381k
        if (num_cmyk != 4)
6017
0
            return PDF14_DeviceCustom;
6018
381k
#endif
6019
        /*
6020
         * Otherewise we use a CMYK plus spot colors for blending.
6021
         */
6022
381k
        if (valid_blend_cs)
6023
0
            *blend_cs_state = temp_cs_state;
6024
381k
        return PDF14_DeviceCMYKspot;
6025
381k
    }
6026
4.78M
}
6027
6028
/*
6029
 * the PDF 1.4 transparency spec says that color space for blending
6030
 * operations can be based upon either a color space specified in the
6031
 * group or a default value based upon the output device.  We are
6032
 * currently only using a color space based upon the device.
6033
 */
6034
static  int
6035
get_pdf14_device_proto(gx_device       *dev,
6036
                       pdf14_device    *pdevproto,
6037
                       gs_gstate       *pgs,
6038
                 const gs_pdf14trans_t *pdf14pct,
6039
                       bool             use_pdf14_accum)
6040
1.71M
{
6041
1.71M
    pdf14_blend_cs_t blend_cs_state;
6042
1.71M
    pdf14_default_colorspace_t dev_cs =
6043
1.71M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6044
1.71M
                                                 &blend_cs_state);
6045
1.71M
    bool deep = device_is_deep(dev);
6046
1.71M
    int num_spots = pdf14pct->params.num_spot_colors;
6047
6048
    /* overprint overide */
6049
1.71M
    if (pdf14pct->params.overprint_sim_push &&
6050
1.71M
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6051
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6052
0
            dev_cs = PDF14_DeviceCMYKspot;
6053
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6054
0
        } else
6055
0
            dev_cs = PDF14_DeviceCMYK;
6056
0
    }
6057
6058
1.71M
    switch (dev_cs) {
6059
465k
        case PDF14_DeviceGray:
6060
465k
            *pdevproto = gs_pdf14_Gray_device;
6061
465k
            pdevproto->color_info.max_components = 1;
6062
465k
            pdevproto->color_info.num_components =
6063
465k
                                    pdevproto->color_info.max_components;
6064
465k
            pdevproto->color_info.depth = 8<<deep;
6065
465k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6066
465k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6067
465k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6068
465k
            pdevproto->sep_device = false;
6069
465k
            break;
6070
1.08M
        case PDF14_DeviceRGB:
6071
1.08M
            *pdevproto = gs_pdf14_RGB_device;
6072
1.08M
            pdevproto->color_info.depth = 24<<deep;
6073
1.08M
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6074
1.08M
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6075
1.08M
            pdevproto->sep_device = false;
6076
1.08M
            break;
6077
2.39k
        case PDF14_DeviceCMYK:
6078
2.39k
            *pdevproto = gs_pdf14_CMYK_device;
6079
2.39k
            pdevproto->color_info.depth = 32<<deep;
6080
2.39k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6081
2.39k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6082
2.39k
            pdevproto->sep_device = false;
6083
2.39k
            break;
6084
159k
        case PDF14_DeviceCMYKspot:
6085
159k
            *pdevproto = gs_pdf14_CMYKspot_device;
6086
            /* Need to figure out how we want to handle the device profile
6087
               for this case */
6088
            /*
6089
             * The number of components for the PDF14 device is the sum
6090
             * of the process components and the number of spot colors
6091
             * for the page.
6092
             */
6093
159k
            if (num_spots >= 0) {
6094
159k
                pdevproto->color_info.num_components =
6095
159k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
6096
159k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6097
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6098
159k
                pdevproto->color_info.depth =
6099
159k
                                    pdevproto->color_info.num_components * (8<<deep);
6100
159k
                pdevproto->sep_device = true;
6101
159k
            }
6102
159k
            break;
6103
0
        case PDF14_DeviceRGBspot:
6104
0
            *pdevproto = gs_pdf14_RGBspot_device;
6105
            /* Need to figure out how we want to handle the device profile
6106
               for this case */
6107
            /*
6108
             * The number of components for the PDF14 device is the sum
6109
             * of the process components and the number of spot colors
6110
             * for the page.
6111
             */
6112
0
            if (num_spots >= 0) {
6113
0
                pdevproto->color_info.num_components =
6114
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
6115
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6116
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6117
0
                pdevproto->color_info.depth =
6118
0
                    pdevproto->color_info.num_components * (8 << deep);
6119
0
                pdevproto->sep_device = true;
6120
0
            }
6121
0
            break;
6122
0
        case PDF14_DeviceCustom:
6123
            /*
6124
             * We are using the output device's process color model.  The
6125
             * color_info for the PDF 1.4 compositing device needs to match
6126
             * the output device.
6127
             */
6128
0
            *pdevproto = gs_pdf14_custom_device;
6129
0
            pdevproto->color_info = dev->color_info;
6130
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6131
0
            pdevproto->color_info.depth =
6132
0
                       pdevproto->color_info.num_components * (8<<deep);
6133
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6134
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6135
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6136
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6137
0
            break;
6138
0
        default:      /* Should not occur */
6139
0
            return_error(gs_error_rangecheck);
6140
1.71M
    }
6141
1.71M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6142
1.71M
    pdevproto->blend_cs_state = blend_cs_state;
6143
1.71M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6144
1.71M
    return 0;
6145
1.71M
}
6146
6147
/* When playing back the clist, we need to know if the buffer device is compatible */
6148
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6149
/* depth are critical since these must match when reading back colors.             */
6150
bool
6151
pdf14_ok_to_optimize(gx_device *dev)
6152
3.05M
{
6153
3.05M
    pdf14_blend_cs_t blend_cs_state;
6154
3.05M
    pdf14_default_colorspace_t pdf14_cs =
6155
3.05M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6156
3.05M
    gsicc_colorbuffer_t dev_icc_cs;
6157
3.05M
    bool ok = false;
6158
3.05M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6159
3.05M
    cmm_dev_profile_t *dev_profile;
6160
3.05M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6161
3.05M
    bool deep = device_is_deep(dev);
6162
6163
3.05M
    if (code < 0)
6164
0
        return false;
6165
6166
3.05M
    check_device_compatible_encoding(dev);
6167
6168
3.05M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6169
1.10M
        return false;
6170
6171
1.95M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6172
    /* If the outputprofile is not "standard" then colors converted to device color */
6173
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6174
1.95M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6175
0
        return false;                           /* can't handle funky output profiles */
6176
6177
1.95M
    switch (pdf14_cs) {
6178
442k
        case PDF14_DeviceGray:
6179
442k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6180
442k
            break;
6181
1.29M
        case PDF14_DeviceRGB:
6182
1.29M
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6183
1.29M
            break;
6184
0
        case PDF14_DeviceCMYK:
6185
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6186
0
            break;
6187
219k
        case PDF14_DeviceCMYKspot:
6188
219k
            ok = false;     /* punt for this case */
6189
219k
            break;
6190
0
        case PDF14_DeviceRGBspot:
6191
0
            ok = false;     /* punt for this case */
6192
0
            break;
6193
0
        case PDF14_DeviceCustom:
6194
            /*
6195
             * We are using the output device's process color model.  The
6196
             * color_info for the PDF 1.4 compositing device needs to match
6197
             * the output device, but it may not have been contone.
6198
             */
6199
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6200
0
            break;
6201
0
        default:      /* Should not occur */
6202
0
            ok = false;
6203
1.95M
    }
6204
1.95M
    return ok;
6205
1.95M
}
6206
6207
/*
6208
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6209
 * compositor device is never removed.  (We do not have a remove compositor
6210
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6211
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6212
 * again.
6213
 */
6214
static  int
6215
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6216
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6217
0
{
6218
0
    pdf14_device * pdev = (pdf14_device *)dev;
6219
0
    gx_device * target = pdev->target;
6220
0
    pdf14_device dev_proto;
6221
0
    bool has_tags = device_encodes_tags(dev);
6222
0
    int code;
6223
0
    bool deep = device_is_deep(dev);
6224
6225
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6226
6227
    /*
6228
     * We will not use the entire prototype device but we will set the
6229
     * color related info and the device procs to match the prototype.
6230
     */
6231
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6232
0
                                  pdf14pct, false);
6233
0
    if (code < 0)
6234
0
        return code;
6235
0
    pdev->color_info = dev_proto.color_info;
6236
0
    pdev->pad = target->pad;
6237
0
    pdev->log2_align_mod = target->log2_align_mod;
6238
6239
    /* The prototype has the color setup without tags. If we are
6240
     * using tags, then we need to extend num_components and depth.
6241
     */
6242
0
    if (has_tags) {
6243
0
        pdev->color_info.num_components++;
6244
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6245
0
    }
6246
6247
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6248
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6249
0
    else
6250
0
        pdev->num_planar_planes = target->num_planar_planes;
6251
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6252
6253
0
    pdev->procs = dev_proto.procs;
6254
0
    if (deep) {
6255
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6256
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6257
0
    }
6258
0
    if (has_tags) {
6259
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6260
0
    }
6261
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6262
0
    gx_device_fill_in_procs((gx_device *)pdev);
6263
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6264
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6265
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6266
0
    check_device_separable(dev);
6267
0
    return dev_proc(pdev, open_device)(dev);
6268
0
}
6269
6270
/*
6271
 * Implement the various operations that can be specified via the PDF 1.4
6272
 * create compositor request.
6273
 */
6274
static  int
6275
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6276
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6277
39.0M
{
6278
39.0M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6279
39.0M
    gs_pdf14trans_params_t params = pdf14pct->params;
6280
39.0M
    int code = 0;
6281
6282
39.0M
    params.idle = pdf14pct->idle;
6283
39.0M
    switch (params.pdf14_op) {
6284
0
        default:      /* Should not occur. */
6285
0
            break;
6286
17.9k
        case PDF14_PUSH_DEVICE:
6287
17.9k
            if (!(params.is_pattern)) {
6288
0
                p14dev->blend_mode = 0;
6289
0
                p14dev->opacity = p14dev->shape = 0.0;
6290
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6291
0
            }
6292
17.9k
            break;
6293
0
        case PDF14_ABORT_DEVICE:
6294
            /* Something has gone very wrong.  Let transparency device clean up
6295
               what ever it has allocated and then we are shutting it down */
6296
0
            code = gx_abort_trans_device(pgs, pdev);
6297
0
            if (p14dev->free_devicen) {
6298
0
                devn_free_params(pdev);
6299
0
            }
6300
0
            pdf14_disable_device(pdev);
6301
0
            pdf14_close(pdev);
6302
0
            break;
6303
1.70M
        case PDF14_POP_DEVICE:
6304
1.70M
            if (!(params.is_pattern)) {
6305
1.68M
                if_debug0m('v', pdev->memory,
6306
1.68M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6307
1.68M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6308
1.68M
                gx_set_cmap_procs(pgs, p14dev->target);
6309
                /* Send image out raster data to output device */
6310
1.68M
                {
6311
                    /* Make a copy so we can change the ROP */
6312
1.68M
                    gs_gstate new_pgs = *pgs;
6313
6314
                    /* We don't use the gs_gstate log_op since this is for the */
6315
                    /* clist playback. Putting the image (band in the case of the */
6316
                    /* clist) only needs to use the default ROP to copy the data  */
6317
1.68M
                    new_pgs.log_op = rop3_default;
6318
1.68M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6319
1.68M
                }
6320
                /* Before we disable the device release any deviceN structures.
6321
                    free_devicen is set if the pdf14 device had inherited its
6322
                    deviceN parameters from the target clist device.  In this
6323
                    case they should not be freed */
6324
1.68M
                if (p14dev->free_devicen) {
6325
1.68M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6326
1.68M
                    if (devn_params) {
6327
1.68M
                        gxdso_spot_info si;
6328
1.68M
                        si.params = devn_params;
6329
1.68M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6330
1.68M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6331
1.68M
                    }
6332
1.68M
                    devn_free_params(pdev);
6333
1.68M
                }
6334
1.68M
                pdf14_disable_device(pdev);
6335
1.68M
                pdf14_close(pdev);
6336
1.68M
            }
6337
1.70M
            break;
6338
747k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6339
3.88M
        case PDF14_BEGIN_TRANS_GROUP:
6340
3.88M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6341
580k
                p14dev->depth_within_smask++;
6342
3.88M
            p14dev->smask_constructed = 0;
6343
3.88M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6344
3.88M
            break;
6345
3.26M
        case PDF14_END_TRANS_GROUP:
6346
3.26M
            code = gx_end_transparency_group(pgs, pdev);
6347
3.26M
            if (p14dev->depth_within_smask)
6348
580k
                p14dev->depth_within_smask--;
6349
3.26M
            break;
6350
138
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6351
138
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6352
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6353
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6354
0
            } else
6355
138
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6356
138
            break;
6357
619k
        case PDF14_END_TRANS_TEXT_GROUP:
6358
619k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6359
618k
                code = gx_end_transparency_group(pgs, pdev);
6360
619k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6361
619k
            break;
6362
7.17M
        case PDF14_BEGIN_TRANS_MASK:
6363
7.17M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6364
7.17M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6365
800k
                p14dev->in_smask_construction++;
6366
7.17M
            break;
6367
800k
        case PDF14_END_TRANS_MASK:
6368
800k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6369
800k
            if (code >= 0) {
6370
800k
                p14dev->in_smask_construction--;
6371
800k
                if (p14dev->in_smask_construction < 0)
6372
0
                    p14dev->in_smask_construction = 0;
6373
800k
                if (p14dev->in_smask_construction == 0)
6374
799k
                    p14dev->smask_constructed = 1;
6375
800k
            }
6376
800k
            break;
6377
16.7M
        case PDF14_SET_BLEND_PARAMS:
6378
16.7M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6379
16.7M
            break;
6380
0
        case PDF14_PUSH_TRANS_STATE:
6381
0
            code = gx_push_transparency_state(pgs, pdev);
6382
0
            break;
6383
4.79M
        case PDF14_POP_TRANS_STATE:
6384
4.79M
            code = gx_pop_transparency_state(pgs, pdev);
6385
4.79M
            break;
6386
14.0k
        case PDF14_PUSH_SMASK_COLOR:
6387
14.0k
            code = pdf14_increment_smask_color(pgs, pdev);
6388
14.0k
            break;
6389
14.0k
        case PDF14_POP_SMASK_COLOR:
6390
14.0k
            code = pdf14_decrement_smask_color(pgs, pdev);
6391
14.0k
            break;
6392
39.0M
    }
6393
39.0M
    return code;
6394
39.0M
}
6395
6396
/*
6397
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6398
 * compositor' method.  However the compositor is disabled when we are not
6399
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6400
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6401
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6402
 * to the target.
6403
 */
6404
static  int
6405
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6406
        const gs_composite_t * pct, gs_gstate * pgs,
6407
        gs_memory_t * mem, gx_device *cdev)
6408
2.97k
{
6409
2.97k
    pdf14_device *pdev = (pdf14_device *)dev;
6410
2.97k
    gx_device * tdev = pdev->target;
6411
2.97k
    int code;
6412
6413
2.97k
    *pcdev = dev;
6414
2.97k
    if (gs_is_pdf14trans_compositor(pct)) {
6415
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6416
6417
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6418
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6419
0
        return 0;
6420
0
    }
6421
2.97k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6422
2.97k
    if (code == 1) {
6423
        /* We have created a new compositor that wrapped tdev. This means
6424
         * that our target should be updated to point to that. */
6425
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6426
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6427
0
    }
6428
2.97k
    return code;
6429
2.97k
}
6430
6431
/*
6432
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6433
 * and return. Since the gs_pdf14_device only supports the high-level routines
6434
 * of the interface, don't bother trying to handle any other compositor.
6435
 */
6436
static int
6437
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6438
        const gs_composite_t * pct, gs_gstate * pgs,
6439
        gs_memory_t * mem, gx_device *cdev)
6440
241M
{
6441
241M
    pdf14_device *p14dev = (pdf14_device *)dev;
6442
241M
    if (gs_is_pdf14trans_compositor(pct)) {
6443
39.0M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6444
39.0M
        *pcdev = dev;
6445
        /* cdev, may be the clist reader device which may contain information that
6446
           we will need related to the ICC color spaces that define transparency
6447
           groups.  We want this propogated through all the pdf14 functions.  Store
6448
           a pointer to it in the pdf14 device */
6449
39.0M
        p14dev->pclist_device = cdev;
6450
39.0M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6451
202M
    } else if (gs_is_overprint_compositor(pct)) {
6452
                /* If we had an overprint compositer action, then the
6453
                   color components that were drawn should be updated.
6454
                   The overprint compositor logic and its interactions
6455
                   with the clist is a little odd as it passes uninitialized
6456
                   values around a fair amount.  Hence the forced assignement here.
6457
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6458
202M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6459
202M
                gx_color_index drawn_comps;
6460
202M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6461
6462
202M
                p14dev->op_state = op_pct->params.op_state;
6463
202M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6464
101M
                    if (op_pct->params.retain_any_comps) {
6465
1.11M
                        drawn_comps = op_pct->params.drawn_comps;
6466
100M
                    } else {
6467
                        /* Draw everything. If this parameter was not set, clist does
6468
                           not fill it in.  */
6469
100M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6470
100M
                    }
6471
6472
101M
                    if (op_pct->params.is_fill_color) {
6473
62.0M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6474
62.0M
                        p14dev->drawn_comps_fill = drawn_comps;
6475
62.0M
                    } else {
6476
39.1M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6477
39.1M
                        p14dev->drawn_comps_stroke = drawn_comps;
6478
39.1M
                    }
6479
                    /* We restore the NONE states as that is used just to force
6480
                       overprint settings in the overprint compositor communication */
6481
101M
                    p14dev->op_state = curr_state;
6482
101M
                }
6483
202M
                *pcdev = dev;
6484
202M
                return 0;
6485
202M
    } else
6486
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6487
241M
}
6488
6489
static int
6490
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6491
                      gs_blend_mode_t blend_mode, float opacity,
6492
                      float shape, bool is_clist)
6493
3.45k
{
6494
3.45k
    int code;
6495
3.45k
    gs_transparency_group_params_t params = { 0 };
6496
3.45k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6497
3.45k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6498
3.45k
    float alpha = pgs->fillconstantalpha;
6499
6500
    /* Push a non-isolated knock-out group making sure the opacity and blend
6501
       mode are correct */
6502
3.45k
    params.Isolated = false;
6503
3.45k
    params.Knockout = true;
6504
3.45k
    params.page_group = false;
6505
3.45k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6506
3.45k
    params.group_opacity = 1.0;
6507
3.45k
    params.group_shape = 1.0;
6508
6509
3.45k
    gs_setfillconstantalpha(pgs, 1.0);
6510
3.45k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6511
6512
3.45k
    if (is_clist) {
6513
3.45k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6514
3.45k
        if (code < 0)
6515
0
            return code;
6516
3.45k
    }
6517
6518
3.45k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6519
3.45k
    gs_setfillconstantalpha(pgs, alpha);
6520
3.45k
    gs_setblendmode(pgs, blend_mode);
6521
3.45k
    if (code < 0)
6522
0
        return code;
6523
6524
3.45k
    if (is_clist) {
6525
3.45k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6526
3.45k
    }
6527
3.45k
    return code;
6528
3.45k
}
6529
6530
static  int
6531
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6532
                 const gs_text_params_t * text, gs_font * font,
6533
                 const gx_clip_path * pcpath,
6534
                 gs_text_enum_t ** ppenum)
6535
346
{
6536
346
    int code;
6537
346
    gs_text_enum_t *penum;
6538
346
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6539
346
    float opacity = pgs->fillconstantalpha;
6540
346
    float shape = 1.0;
6541
346
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6542
346
    pdf14_device *pdev = (pdf14_device*)dev;
6543
346
    bool draw = !(text->operation & TEXT_DO_NONE);
6544
346
    uint text_mode = gs_currenttextrenderingmode(pgs);
6545
346
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6546
346
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6547
6548
346
    code = pdf14_initialize_ctx(dev, pgs);
6549
346
    if (code < 0)
6550
0
        return code;
6551
6552
346
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6553
346
    pdf14_set_marking_params(dev, pgs);
6554
346
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6555
346
    if (code < 0)
6556
0
        return code;
6557
6558
    /* We may need to push a non-isolated transparency group if the following
6559
       is true.
6560
       1) We are not currently in one that we pushed for text and we are in
6561
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6562
       2) The blend mode is not Normal or the opacity is not 1.0
6563
       3) Text knockout is set to true
6564
       4) We are actually doing a text drawing
6565
6566
       Special note:  If text-knockout is set to false while we are within a
6567
       BT ET pair, we should pop the group.  I need to create a test file for
6568
       this case.  */
6569
6570
       /* Catch case where we already pushed a group and are trying to push another one.
6571
       In that case, we will pop the current one first, as we don't want to be left
6572
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6573
       will not be caught until we do the put_image and notice that the stack is not
6574
       empty. */
6575
346
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6576
0
        code = gs_end_transparency_group(pgs);
6577
0
        if (code < 0)
6578
0
            return code;
6579
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6580
0
    }
6581
6582
346
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6583
346
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6584
346
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6585
346
         text_mode != 3 && /* don't bother with invisible text */
6586
346
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6587
1
        if (draw) {
6588
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6589
1
                false);
6590
1
        }
6591
346
    *ppenum = (gs_text_enum_t *)penum;
6592
346
    return code;
6593
346
}
6594
6595
static  int
6596
pdf14_initialize_device(gx_device *new_dev)
6597
1.71M
{
6598
1.71M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6599
6600
1.71M
    pdev->ctx = NULL;
6601
1.71M
    pdev->color_model_stack = NULL;
6602
1.71M
    pdev->smaskcolor = NULL;
6603
6604
1.71M
    return 0;
6605
1.71M
}
6606
6607
/*
6608
 * Implement copy_mono by filling lots of small rectangles.
6609
 */
6610
static int
6611
pdf14_copy_mono(gx_device * dev,
6612
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6613
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6614
26.0M
{
6615
26.0M
    const byte *sptr;
6616
26.0M
    const byte *line;
6617
26.0M
    int sbit, first_bit;
6618
26.0M
    int code, sbyte, bit, count;
6619
26.0M
    int run_length, startx, current_bit, bit_value;
6620
26.0M
    gx_color_index current_color;
6621
6622
26.0M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6623
26.0M
    line = base + (sourcex >> 3);
6624
26.0M
    sbit = sourcex & 7;
6625
26.0M
    first_bit = 7 - sbit;
6626
6627
    /* Loop through the height of the specified area. */
6628
196M
    while (h-- > 0) {
6629
        /* Set up for the start of each line of the area. */
6630
170M
        sptr = line;
6631
170M
        sbyte = *sptr++;
6632
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6633
         * the loop below so adding 1 means that we don't fall into the bit == 0
6634
         * case and incorrectly read a new byte from the source. This weirdness is because
6635
         * the original code wouold read off the end of the buffer if the number of bits in
6636
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6637
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6638
         * of the loop to the beginning meant we would not read past the end of the buffer
6639
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6640
         * reading another byte.
6641
         */
6642
170M
        bit = first_bit + 1;
6643
170M
        count = w;
6644
170M
        run_length = 0;
6645
170M
        startx = x;
6646
170M
        current_bit = 0;
6647
170M
        current_color = zero;
6648
6649
        /* Loop across each pixel of a line. */
6650
2.29G
        do {
6651
            /* Move to the next input bit. */
6652
2.29G
            if (bit == 0) {
6653
196M
                bit = 7;
6654
196M
                sbyte = *sptr++;
6655
196M
            }
6656
2.09G
            else
6657
2.09G
                bit--;
6658
2.29G
            bit_value = (sbyte >> bit) & 1;
6659
2.29G
            if (bit_value == current_bit) {
6660
                /* The value did not change, simply increment our run length */
6661
1.87G
                run_length++;
6662
1.87G
            } else {
6663
                /* The value changed, fill the current rectangle. */
6664
419M
                if (run_length != 0) {
6665
400M
                    if (current_color != gx_no_color_index) {
6666
172M
                        code = (*dev_proc(dev, fill_rectangle))
6667
172M
                                (dev, startx, y, run_length, 1, current_color);
6668
172M
                        if (code < 0)
6669
0
                            return code;
6670
172M
                    }
6671
400M
                    startx += run_length;
6672
400M
                }
6673
419M
                run_length = 1;
6674
419M
                current_color = bit_value ? one : zero;
6675
419M
                current_bit = bit_value;
6676
419M
            }
6677
2.29G
        } while (--count > 0);
6678
        /* Fill the last rectangle in the line. */
6679
170M
        if (run_length != 0 && current_color != gx_no_color_index) {
6680
75.3M
            code = (*dev_proc(dev, fill_rectangle))
6681
75.3M
                        (dev, startx, y, run_length, 1, current_color);
6682
75.3M
            if (code < 0)
6683
0
                return code;
6684
75.3M
        }
6685
        /* Move to the next line */
6686
170M
        line += sraster;
6687
170M
        y++;
6688
170M
    }
6689
26.0M
    return 0;
6690
26.0M
}
6691
6692
/* Added to avoid having to go back and forth between fixed and int
6693
   in some of the internal methods used for dealing with tiling
6694
   and devn colors */
6695
static int
6696
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6697
    const gx_drawing_color *pdcolor)
6698
2.44k
{
6699
2.44k
    pdf14_device *pdev = (pdf14_device *)dev;
6700
2.44k
    pdf14_buf *buf;
6701
2.44k
    int code;
6702
6703
2.44k
    fit_fill_xywh(dev, x, y, w, h);
6704
2.44k
    if (w <= 0 || h <= 0)
6705
0
        return 0;
6706
6707
2.44k
    code = pdf14_initialize_ctx(dev, NULL);
6708
2.44k
    if (code < 0)
6709
0
        return code;
6710
2.44k
    buf = pdev->ctx->stack;
6711
6712
2.44k
    if (buf->knockout)
6713
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6714
0
            true);
6715
2.44k
    else
6716
2.44k
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6717
2.44k
}
6718
6719
/* Step through and do rect fills with the devn colors as
6720
   we hit each transition in the bitmap. It is possible
6721
   that one of the colors is not devn, but is pure and
6722
   is set to gx_no_color_index. This type of mix happens
6723
   for example from tile_clip_fill_rectangle_hl_color */
6724
static int
6725
pdf14_copy_mono_devn(gx_device *dev,
6726
    const byte *base, int sourcex, int sraster,
6727
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6728
    const gx_drawing_color *pdcolor1)
6729
668
{
6730
668
    const byte *sptr;
6731
668
    const byte *line;
6732
668
    int sbit, first_bit;
6733
668
    int code, sbyte, bit, count;
6734
668
    int run_length, startx, current_bit, bit_value;
6735
668
    const gx_drawing_color *current_color;
6736
6737
668
    if ((x | y) < 0) {
6738
0
        if (x < 0) {
6739
0
            w += x;
6740
0
            sourcex -= x;
6741
0
            x = 0;
6742
0
        }
6743
0
        if (y < 0) {
6744
0
            h += y;
6745
0
            base -= (int)(y * sraster);
6746
0
            y = 0;
6747
0
        }
6748
0
    }
6749
668
    if (w > (dev)->width - x)
6750
0
        w = (dev)->width - x;
6751
668
    if (h > (dev)->height - y)
6752
0
        h = (dev)->height - y;
6753
668
    if (w <= 0 || h <= 0)
6754
0
        return 0;
6755
6756
668
    line = base + (sourcex >> 3);
6757
668
    sbit = sourcex & 7;
6758
668
    first_bit = 7 - sbit;
6759
6760
    /* Loop through the height of the specified area. */
6761
2.10k
    while (h-- > 0) {
6762
        /* Set up for the start of each line of the area. */
6763
1.43k
        sptr = line;
6764
1.43k
        sbyte = *sptr++;
6765
1.43k
        bit = first_bit;
6766
1.43k
        count = w;
6767
1.43k
        run_length = 0;
6768
1.43k
        startx = x;
6769
1.43k
        current_bit = 0;
6770
1.43k
        current_color = pdcolor0;
6771
6772
        /* Loop across each pixel of a line. */
6773
15.6k
        do {
6774
15.6k
            bit_value = (sbyte >> bit) & 1;
6775
15.6k
            if (bit_value == current_bit) {
6776
                /* The value did not change, simply increment our run length */
6777
11.3k
                run_length++;
6778
11.3k
            } else {
6779
                /* The value changed, fill the current rectangle. */
6780
4.26k
                if (run_length != 0) {
6781
3.85k
                    if (current_color->type != gx_dc_type_pure &&
6782
3.85k
                        current_color->colors.pure != gx_no_color_index) {
6783
1.82k
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6784
1.82k
                            run_length, 1, current_color);
6785
1.82k
                        if (code < 0)
6786
0
                            return code;
6787
1.82k
                    }
6788
3.85k
                    startx += run_length;
6789
3.85k
                }
6790
4.26k
                run_length = 1;
6791
4.26k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6792
4.26k
                current_bit = bit_value;
6793
4.26k
            }
6794
6795
            /* Move to the next input bit. */
6796
15.6k
            if (bit == 0) {
6797
1.40k
                bit = 7;
6798
1.40k
                sbyte = *sptr++;
6799
1.40k
            } else
6800
14.2k
                bit--;
6801
15.6k
        } while (--count > 0);
6802
6803
        /* Fill the last rectangle in the line. */
6804
1.43k
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6805
1.43k
            current_color->colors.pure != gx_no_color_index) {
6806
619
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6807
619
                run_length, 1, current_color);
6808
619
            if (code < 0)
6809
0
                return code;
6810
619
        }
6811
        /* Move to the next line */
6812
1.43k
        line += sraster;
6813
1.43k
        y++;
6814
1.43k
    }
6815
668
    return 0;
6816
668
}
6817
6818
/* Step through the tiles doing essentially copy_mono but with devn colors */
6819
static int
6820
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6821
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6822
    const gx_drawing_color *pdcolor1, int px, int py)
6823
668
{   /* Fill the rectangle in chunks. */
6824
668
    int width = tiles->size.x;
6825
668
    int height = tiles->size.y;
6826
668
    int raster = tiles->raster;
6827
668
    int rwidth = tiles->rep_width;
6828
668
    int rheight = tiles->rep_height;
6829
668
    int shift = tiles->shift;
6830
6831
668
    if (rwidth == 0 || rheight == 0)
6832
0
        return_error(gs_error_unregistered);
6833
668
    fit_fill_xy(dev, x, y, w, h);
6834
6835
668
     {
6836
668
        int xoff = (shift == 0 ? px :
6837
668
                px + (y + py) / rheight * tiles->rep_shift);
6838
668
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6839
0
            (x + xoff) & (rwidth - 1) :
6840
668
            (x + xoff) % rwidth);
6841
668
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6842
0
            (y + py) & (rheight - 1) :
6843
668
            (y + py) % rheight);
6844
668
        int icw = width - irx;
6845
668
        int ch = height - ry;
6846
668
        byte *row = tiles->data + ry * raster;
6847
668
        int code = 0;
6848
6849
668
        if (ch >= h) {      /* Shallow operation */
6850
668
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6851
668
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6852
668
                    w, h, pdcolor0, pdcolor1);
6853
668
                if (code < 0)
6854
0
                    return_error(code);
6855
668
            } else {
6856
0
                int ex = x + w;
6857
0
                int fex = ex - width;
6858
0
                int cx = x + icw;
6859
6860
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6861
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6862
0
                if (code < 0)
6863
0
                    return_error(code);
6864
6865
0
                while (cx <= fex) {
6866
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6867
0
                        width, h, pdcolor0, pdcolor1);
6868
0
                    if (code < 0)
6869
0
                        return_error(code);
6870
0
                    cx += width;
6871
0
                }
6872
0
                if (cx < ex) {
6873
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6874
0
                        ex - cx, h, pdcolor0, pdcolor1);
6875
0
                    if (code < 0)
6876
0
                        return_error(code);
6877
0
                }
6878
0
            }
6879
668
        } else if (icw >= w && shift == 0) {
6880
            /* Narrow operation, no shift */
6881
0
            int ey = y + h;
6882
0
            int fey = ey - height;
6883
0
            int cy = y + ch;
6884
6885
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6886
0
                x, y, w, ch, pdcolor0, pdcolor1);
6887
0
            if (code < 0)
6888
0
                return_error(code);
6889
0
            row = tiles->data;
6890
0
            do {
6891
0
                ch = (cy > fey ? ey - cy : height);
6892
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6893
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6894
0
                if (code < 0)
6895
0
                    return_error(code);
6896
0
            } while ((cy += ch) < ey);
6897
0
        } else {
6898
            /* Full operation.  If shift != 0, some scan lines */
6899
            /* may be narrow.  We could test shift == 0 in advance */
6900
            /* and use a slightly faster loop, but right now */
6901
            /* we don't bother. */
6902
0
            int ex = x + w, ey = y + h;
6903
0
            int fex = ex - width, fey = ey - height;
6904
0
            int cx, cy;
6905
6906
0
            for (cy = y;;) {
6907
0
                if (icw >= w) {
6908
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6909
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6910
0
                    if (code < 0)
6911
0
                        return_error(code);
6912
0
                } else {
6913
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6914
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6915
0
                    if (code < 0)
6916
0
                        return_error(code);
6917
0
                    cx = x + icw;
6918
0
                    while (cx <= fex) {
6919
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6920
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6921
0
                        if (code < 0)
6922
0
                            return_error(code);
6923
0
                        cx += width;
6924
0
                    }
6925
0
                    if (cx < ex) {
6926
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6927
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6928
0
                        if (code < 0)
6929
0
                            return_error(code);
6930
0
                    }
6931
0
                }
6932
0
                if ((cy += ch) >= ey)
6933
0
                    break;
6934
0
                ch = (cy > fey ? ey - cy : height);
6935
0
                if ((irx += shift) >= rwidth)
6936
0
                    irx -= rwidth;
6937
0
                icw = width - irx;
6938
0
                row = tiles->data;
6939
0
            }
6940
0
        }
6941
668
    }
6942
668
    return 0;
6943
668
}
6944
6945
/* pdf14 device supports devn */
6946
static int
6947
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6948
    int x, int y, int w, int h,
6949
    const gx_drawing_color *pdcolor0,
6950
    const gx_drawing_color *pdcolor1, int px, int py)
6951
668
{
6952
668
    pdf14_device *pdev = (pdf14_device *)dev;
6953
668
    pdf14_buf *buf;
6954
668
    int num_comp;
6955
668
    int k;
6956
668
    bool same = false;
6957
668
    int code;
6958
6959
668
    code = pdf14_initialize_ctx(dev, NULL);
6960
668
    if (code < 0)
6961
0
        return code;
6962
668
    buf = pdev->ctx->stack;
6963
668
    num_comp = buf->n_chan - 1;
6964
6965
    /* if color0 is identical to color1, do rect fill */
6966
668
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6967
0
        same = true;
6968
0
        for (k = 0; k < num_comp; k++) {
6969
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6970
0
                same = false;
6971
0
                break;
6972
0
            }
6973
0
        }
6974
0
    }
6975
6976
668
    if (same) {
6977
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6978
668
    } else {
6979
        /* Go through the tile stepping using code stolen from
6980
           gx_default_strip_tile_rectangle and call the rect fills
6981
           using code stolen from pdf14_copy_mono but using devn
6982
           colors */
6983
668
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6984
668
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6985
668
    }
6986
668
    return code;
6987
668
}
6988
6989
/* Used in a few odd cases where the target device is planar and we have
6990
   a planar tile (pattern) and we are copying it into place here */
6991
static int
6992
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6993
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6994
4.62k
{
6995
4.62k
    pdf14_device *pdev = (pdf14_device *)dev;
6996
4.62k
    pdf14_ctx *ctx;
6997
4.62k
    pdf14_buf *buf;
6998
4.62k
    int xo = x;
6999
4.62k
    int yo = y;
7000
4.62k
    pdf14_buf fake_tos;
7001
4.62k
    int deep;
7002
7003
4.62k
    int code = pdf14_initialize_ctx(dev, NULL);
7004
4.62k
    if (code < 0)
7005
0
        return code;
7006
7007
4.62k
    fit_fill_xywh(dev, x, y, w, h);
7008
4.62k
    if (w <= 0 || h <= 0)
7009
0
        return 0;
7010
7011
4.62k
    ctx = pdev->ctx;
7012
4.62k
    buf = ctx->stack;
7013
4.62k
    deep = ctx->deep;
7014
7015
4.62k
    fake_tos.deep = deep;
7016
4.62k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7017
4.62k
    fake_tos.backdrop = NULL;
7018
4.62k
    fake_tos.blend_mode = pdev->blend_mode;
7019
4.62k
    fake_tos.color_space = buf->color_space;
7020
4.62k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7021
4.62k
    fake_tos.dirty.p.x = x;
7022
4.62k
    fake_tos.dirty.p.y = y;
7023
4.62k
    fake_tos.dirty.q.x = x + w;
7024
4.62k
    fake_tos.dirty.q.y = y + h;
7025
4.62k
    fake_tos.has_alpha_g = 0;
7026
4.62k
    fake_tos.has_shape = 0;
7027
4.62k
    fake_tos.has_tags = 0;
7028
4.62k
    fake_tos.idle = false;
7029
4.62k
    fake_tos.isolated = false;
7030
4.62k
    fake_tos.knockout = false;
7031
4.62k
    fake_tos.mask_id = 0;
7032
4.62k
    fake_tos.mask_stack = NULL;
7033
4.62k
    fake_tos.matte = NULL;
7034
4.62k
    fake_tos.matte_num_comps = 0;
7035
4.62k
    fake_tos.memory = dev->memory;
7036
4.62k
    fake_tos.n_chan = dev->color_info.num_components;
7037
4.62k
    fake_tos.n_planes = dev->color_info.num_components;
7038
4.62k
    fake_tos.num_spots = 0;
7039
4.62k
    fake_tos.group_color_info = NULL;
7040
4.62k
    fake_tos.planestride = raster * (size_t)plane_height;
7041
4.62k
    fake_tos.rect.p.x = x;
7042
4.62k
    fake_tos.rect.p.y = y;
7043
4.62k
    fake_tos.rect.q.x = x + w;
7044
4.62k
    fake_tos.rect.q.y = y + h;
7045
4.62k
    fake_tos.rowstride = raster;
7046
4.62k
    fake_tos.saved = NULL;
7047
4.62k
    fake_tos.shape = 0xffff;
7048
4.62k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7049
4.62k
    fake_tos.transfer_fn = NULL;
7050
4.62k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7051
4.62k
                                  pdev->ctx->memory, dev);
7052
4.62k
    return 0;
7053
4.62k
}
7054
7055
static int
7056
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7057
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7058
    const gx_clip_path *pcpath)
7059
50.7M
{
7060
50.7M
    pdf14_device *pdev = (pdf14_device *)dev;
7061
50.7M
    pdf14_buf* buf;
7062
50.7M
    int code;
7063
50.7M
    int x = fixed2int(rect->p.x);
7064
50.7M
    int y = fixed2int(rect->p.y);
7065
50.7M
    int w = fixed2int(rect->q.x) - x;
7066
50.7M
    int h = fixed2int(rect->q.y) - y;
7067
7068
50.7M
    fit_fill_xywh(dev, x, y, w, h);
7069
50.7M
    if (w <= 0 || h <= 0)
7070
1.57M
        return 0;
7071
7072
49.1M
    code = pdf14_initialize_ctx(dev, pgs);
7073
49.1M
    if (code < 0)
7074
0
        return code;
7075
49.1M
    buf = pdev->ctx->stack;
7076
7077
49.1M
    if (buf->knockout)
7078
708k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7079
708k
                                                   true);
7080
48.4M
    else
7081
48.4M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7082
49.1M
}
7083
7084
static  int
7085
pdf14_fill_rectangle(gx_device * dev,
7086
                    int x, int y, int w, int h, gx_color_index color)
7087
786M
{
7088
786M
    pdf14_device *pdev = (pdf14_device *)dev;
7089
786M
    pdf14_buf *buf;
7090
786M
    int code;
7091
7092
786M
    fit_fill_xywh(dev, x, y, w, h);
7093
786M
    if (w <= 0 || h <= 0)
7094
28.3M
        return 0;
7095
7096
758M
    code = pdf14_initialize_ctx(dev, NULL);
7097
758M
    if (code < 0)
7098
0
        return code;
7099
7100
758M
    buf = pdev->ctx->stack;
7101
7102
758M
    if (buf->knockout)
7103
4.54M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7104
4.54M
                                                   false);
7105
753M
    else
7106
753M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7107
758M
}
7108
7109
static int
7110
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7111
                                    const gs_rect *pbbox, gs_int_rect *rect)
7112
4.20M
{
7113
4.20M
    gs_rect dev_bbox;
7114
4.20M
    int code;
7115
7116
4.20M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7117
4.20M
    if (code < 0)
7118
0
        return code;
7119
4.20M
    rect->p.x = (int)floor(dev_bbox.p.x);
7120
4.20M
    rect->p.y = (int)floor(dev_bbox.p.y);
7121
4.20M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7122
4.20M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7123
    /* Sanity check rect for insane ctms */
7124
4.20M
    if (rect->p.x < 0)
7125
1.00M
        rect->p.x = 0;
7126
4.20M
    if (rect->q.x < rect->p.x)
7127
4.59k
        rect->q.x = rect->p.x;
7128
4.20M
    if (rect->p.y < 0)
7129
3.82M
        rect->p.y = 0;
7130
4.20M
    if (rect->q.y < rect->p.y)
7131
106k
        rect->q.y = rect->p.y;
7132
4.20M
    return 0;
7133
4.20M
}
7134
7135
static  int
7136
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7137
                              const gs_rect *pbbox, gs_gstate *pgs)
7138
4.06M
{
7139
4.06M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7140
7141
4.06M
    if (code < 0)
7142
0
        return code;
7143
4.06M
    rect_intersect(*rect, pdev->ctx->rect);
7144
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7145
4.06M
    if (rect->q.x < rect->p.x)
7146
18.1k
        rect->q.x = rect->p.x;
7147
4.06M
    if (rect->q.y < rect->p.y)
7148
117k
        rect->q.y = rect->p.y;
7149
4.06M
    return 0;
7150
4.06M
}
7151
7152
static  int
7153
pdf14_begin_transparency_group(gx_device* dev,
7154
    const gs_transparency_group_params_t* ptgp,
7155
    const gs_rect* pbbox,
7156
    gs_gstate* pgs, gs_memory_t* mem)
7157
3.88M
{
7158
3.88M
    pdf14_device* pdev = (pdf14_device*)dev;
7159
3.88M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7160
3.88M
    gs_int_rect rect;
7161
3.88M
    int code;
7162
3.88M
    bool isolated = ptgp->Isolated;
7163
3.88M
    gs_transparency_color_t group_color_type;
7164
3.88M
    cmm_profile_t* group_profile;
7165
3.88M
    cmm_profile_t* tos_profile;
7166
3.88M
    gsicc_rendering_param_t render_cond;
7167
3.88M
    cmm_dev_profile_t* dev_profile;
7168
3.88M
    bool cm_back_drop = false;
7169
3.88M
    bool new_icc = false;
7170
3.88M
    pdf14_group_color_t* group_color_info;
7171
3.88M
    bool has_tags = device_encodes_tags(dev);
7172
7173
3.88M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7174
3.88M
    if (code < 0)
7175
0
        return code;
7176
3.88M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7177
7178
3.88M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7179
619k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7180
619k
    }
7181
7182
3.88M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7183
619k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7184
3.26M
    else
7185
3.26M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7186
7187
3.88M
    if (code < 0)
7188
0
        return code;
7189
3.88M
    if_debug5m('v', pdev->memory,
7190
3.88M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7191
3.88M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7192
7193
    /* If the group color is unknown then use the current device profile. */
7194
3.88M
    if (ptgp->group_color_type == UNKNOWN) {
7195
3.11M
        group_color_type = ICC;
7196
3.11M
        group_profile = tos_profile;
7197
3.11M
    }
7198
772k
    else {
7199
772k
        group_color_type = ptgp->group_color_type;
7200
772k
        group_profile = ptgp->iccprofile;
7201
772k
    }
7202
7203
    /* We have to handle case where the profile is in the clist */
7204
3.88M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7205
        /* Get the serialized data from the clist. */
7206
772k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7207
772k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7208
772k
        if (group_profile == NULL)
7209
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7210
        /* Keep a pointer to the clist device */
7211
772k
        group_profile->dev = (gx_device*)pcrdev;
7212
772k
        new_icc = true;
7213
772k
    }
7214
3.88M
    if (group_profile != NULL) {
7215
        /* If we have a non-isolated group and the color space is different,
7216
            we will need to CM the backdrop. */
7217
3.88M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7218
296k
            cm_back_drop = true;
7219
296k
        }
7220
3.88M
    }
7221
7222
    /* Always create the base color group information as it is only through
7223
       groups that we can have a color space change.  This will survive
7224
       the life of the context. */
7225
3.88M
    if (pdev->ctx->base_color == NULL) {
7226
956k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7227
956k
    }
7228
7229
    /* If this is not the page group and we don't yet have a group, we need
7230
       to create a buffer for the whole page so that we can handle stuff drawn
7231
       outside this current group (e.g. two non inclusive groups drawn independently) */
7232
3.88M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7233
82.1k
        code = pdf14_initialize_ctx(dev, NULL);
7234
82.1k
        if (code < 0)
7235
0
            return code;
7236
82.1k
        pdev->ctx->stack->isolated = true;
7237
82.1k
    }
7238
7239
3.88M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7240
3.88M
        group_profile, false);
7241
3.88M
    if (group_color_info == NULL)
7242
0
        return gs_error_VMerror;
7243
3.88M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7244
7245
3.88M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7246
3.88M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7247
3.88M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7248
3.88M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7249
3.88M
                                        pgs->blend_mode, ptgp->idle,
7250
3.88M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7251
3.88M
                                         cm_back_drop, ptgp->shade_group,
7252
3.88M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7253
3.88M
    if (new_icc)
7254
772k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7255
3.88M
    return code;
7256
3.88M
}
7257
7258
static void
7259
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7260
3.88M
{
7261
3.88M
    pdf14_device* pdev = (pdf14_device*)dev;
7262
7263
3.88M
    if (group_color != NULL &&
7264
3.88M
        !(group_color->group_color_mapping_procs == NULL &&
7265
3.88M
            group_color->group_color_comp_index == NULL)) {
7266
3.88M
        bool has_tags = device_encodes_tags(dev);
7267
3.88M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7268
3.88M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7269
3.88M
        pdev->color_info.polarity = group_color->polarity;
7270
3.88M
        if (pdev->num_planar_planes > 0)
7271
244k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7272
3.88M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7273
3.88M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7274
3.88M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7275
3.88M
        pdev->blend_procs = group_color->blend_procs;
7276
3.88M
        pdev->ctx->additive = group_color->isadditive;
7277
3.88M
        pdev->pdf14_procs = group_color->unpack_procs;
7278
3.88M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7279
3.88M
        pdev->color_info.depth = group_color->depth;
7280
3.88M
        pdev->color_info.max_color = group_color->max_color;
7281
3.88M
        pdev->color_info.max_gray = group_color->max_gray;
7282
3.88M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7283
3.88M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7284
3.88M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7285
3.88M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7286
3.88M
        if (group_color->icc_profile != NULL) {
7287
            /* make sure to decrement the device profile.  If it was allocated
7288
               with the push then it will be freed. */
7289
3.88M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7290
3.88M
                                    -1, "pdf14_pop_color_model");
7291
3.88M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7292
3.88M
                                    group_color->icc_profile;
7293
7294
3.88M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7295
3.88M
                                    1, "pdf14_pop_color_model");
7296
3.88M
        }
7297
3.88M
        pdev->num_std_colorants = group_color->num_std_colorants;
7298
3.88M
    }
7299
3.88M
}
7300
7301
static  int
7302
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7303
3.88M
{
7304
3.88M
    pdf14_device* pdev = (pdf14_device*)dev;
7305
3.88M
    int code;
7306
3.88M
    cmm_profile_t* group_profile;
7307
3.88M
    gsicc_rendering_param_t render_cond;
7308
3.88M
    cmm_dev_profile_t* dev_profile;
7309
3.88M
    int has_tags = device_encodes_tags(dev);
7310
7311
3.88M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7312
3.88M
    if (code < 0)
7313
0
        return code;
7314
7315
3.88M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7316
3.88M
        &render_cond);
7317
3.88M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7318
7319
3.88M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7320
3.88M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7321
3.88M
    if (code < 0)
7322
0
        return code;
7323
#ifdef DEBUG
7324
    pdf14_debug_mask_stack_state(pdev->ctx);
7325
#endif
7326
    /* If this group is the base group, then restore the color model
7327
       of the device at this time.  Note that during the actual device pop
7328
       we will need to use the profile of the buffer not the pdf14 device
7329
       as the source color space */
7330
3.88M
    if (pdev->ctx->stack->group_popped) {
7331
745k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7332
3.13M
    } else {
7333
3.13M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7334
3.13M
    }
7335
7336
3.88M
    return code;
7337
3.88M
}
7338
7339
static pdf14_group_color_t*
7340
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7341
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7342
                        bool is_mask)
7343
4.68M
{
7344
4.68M
    pdf14_device *pdevproto = NULL;
7345
4.68M
    pdf14_device *pdev = (pdf14_device *)dev;
7346
4.68M
    const pdf14_procs_t *new_14procs = NULL;
7347
4.68M
    pdf14_group_color_t *group_color;
7348
4.68M
    gx_color_polarity_t new_polarity;
7349
4.68M
    uchar new_num_comps;
7350
4.68M
    bool new_additive;
7351
4.68M
    gx_device_clist_reader *pcrdev;
7352
4.68M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7353
4.68M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7354
4.68M
    int k;
7355
4.68M
    bool has_tags = device_encodes_tags(dev);
7356
4.68M
    bool deep = pdev->ctx->deep;
7357
7358
4.68M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7359
7360
4.68M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7361
4.68M
                               pdf14_group_color_t, &st_pdf14_clr,
7362
4.68M
                               "pdf14_push_color_model");
7363
4.68M
    if (group_color == NULL)
7364
0
        return NULL;
7365
7366
4.68M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7367
7368
4.68M
    switch (group_color_type) {
7369
0
        case GRAY_SCALE:
7370
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7371
0
            new_num_comps = 1;
7372
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7373
0
            new_additive = true;
7374
0
            new_14procs = &gray_pdf14_procs;
7375
0
            break;
7376
0
        case DEVICE_RGB:
7377
0
        case CIE_XYZ:
7378
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7379
0
            new_num_comps = 3;
7380
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7381
0
            new_additive = true;
7382
0
            new_14procs = &rgb_pdf14_procs;
7383
0
            break;
7384
0
        case DEVICE_CMYK:
7385
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7386
0
            new_num_comps = 4;
7387
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7388
0
            new_additive = false;
7389
            /* This is needed due to the mismatched compressed encode decode
7390
                between the device procs and the pdf14 procs */
7391
0
            if (dev->color_info.num_components > 4){
7392
0
                new_14procs = &cmykspot_pdf14_procs;
7393
0
            } else {
7394
0
                new_14procs = &cmyk_pdf14_procs;
7395
0
            }
7396
0
            break;
7397
4.68M
        case ICC:
7398
            /* If we are coming from the clist reader, then we need to get
7399
                the ICC data now  */
7400
4.68M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7401
                /* Get the serialized data from the clist.  Not the whole
7402
                    profile. */
7403
786k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7404
786k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7405
786k
                                                    icc_hashcode);
7406
786k
                if (iccprofile == NULL)
7407
0
                    return NULL;
7408
                /* Keep a pointer to the clist device */
7409
786k
                iccprofile->dev = (gx_device *) pcrdev;
7410
3.89M
            } else {
7411
                /* Go ahead and rc increment right now.  This way when
7412
                    we pop, we will make sure to decrement and avoid a
7413
                    leak for the above profile that we just created.  This
7414
                    goes with the assignment to the device's profile.
7415
                    Note that we still do the increment for the group_color
7416
                    assignment below. */
7417
3.89M
                if (iccprofile == NULL)
7418
0
                    return NULL;
7419
3.89M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7420
3.89M
            }
7421
4.68M
            new_num_comps = iccprofile->num_comps;
7422
4.68M
            if (new_num_comps == 4) {
7423
1.11M
                new_additive = false;
7424
1.11M
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7425
3.57M
            } else {
7426
3.57M
                new_additive = true;
7427
3.57M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7428
3.57M
            }
7429
4.68M
            switch (new_num_comps) {
7430
971k
                case 1:
7431
971k
                    if (pdev->sep_device && !is_mask) {
7432
29
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7433
29
                        new_14procs = &grayspot_pdf14_procs;
7434
971k
                    } else {
7435
971k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7436
971k
                        new_14procs = &gray_pdf14_procs;
7437
971k
                    }
7438
971k
                    break;
7439
2.60M
                case 3:
7440
2.60M
                    if (pdev->sep_device) {
7441
128k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7442
128k
                        new_14procs = &rgbspot_pdf14_procs;
7443
128k
                    }
7444
2.47M
                    else {
7445
2.47M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7446
2.47M
                        new_14procs = &rgb_pdf14_procs;
7447
2.47M
                    }
7448
2.60M
                    break;
7449
1.11M
                case 4:
7450
1.11M
                    if (pdev->sep_device) {
7451
116k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7452
116k
                        new_14procs = &cmykspot_pdf14_procs;
7453
996k
                    } else {
7454
996k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7455
996k
                        new_14procs = &cmyk_pdf14_procs;
7456
996k
                    }
7457
1.11M
                    break;
7458
0
                default:
7459
0
                    return NULL;
7460
0
                    break;
7461
4.68M
            }
7462
4.68M
            break;
7463
4.68M
        default:
7464
0
            return NULL;
7465
0
            break;
7466
4.68M
    }
7467
7468
    /* We might just have changed the colorspace of the device, which means
7469
     * the number of colorants have changed. */
7470
4.68M
    group_color->num_std_colorants = new_num_comps;
7471
4.68M
    pdev->num_std_colorants = new_num_comps;
7472
7473
4.68M
    if (has_tags)
7474
0
        new_num_comps++;
7475
7476
4.68M
    if (group_color_type == ICC && iccprofile != NULL) {
7477
4.68M
        group_color->icc_profile = iccprofile;
7478
4.68M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7479
4.68M
    }
7480
7481
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7482
       spot colorants and know how to index into them */
7483
4.68M
    if (pdev->sep_device && !is_mask) {
7484
244k
        int num_spots = dev->color_info.num_components - has_tags -
7485
244k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7486
7487
244k
        if (num_spots > 0)
7488
7.65k
            new_num_comps += num_spots;
7489
244k
    }
7490
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7491
17.9M
    for (k = 0; k < new_num_comps; k++) {
7492
13.2M
        comp_bits[k] = 8<<deep;
7493
13.2M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7494
13.2M
    }
7495
7496
    /* Set device values now and store settings in group_color.  Then they
7497
       are available when we pop the previous group */
7498
4.68M
    if_debug2m('v', pdev->memory,
7499
4.68M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7500
4.68M
                pdev->color_info.num_components,new_num_comps);
7501
4.68M
    {
7502
4.68M
        gx_device local_device;
7503
7504
4.68M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7505
4.68M
        local_device.initialize_device_procs((gx_device *)&local_device);
7506
4.68M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7507
4.68M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7508
4.68M
    }
7509
4.68M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7510
4.68M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7511
4.68M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7512
4.68M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7513
4.68M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7514
4.68M
    if (pdev->num_planar_planes > 0)
7515
311k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7516
4.68M
    group_color->num_components = new_num_comps - has_tags;
7517
4.68M
    pdev->color_info.num_components = new_num_comps;
7518
4.68M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7519
4.68M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7520
4.68M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7521
4.68M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7522
4.68M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7523
4.68M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7524
4.68M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7525
4.68M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7526
4.68M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7527
4.68M
    group_color->depth = pdev->color_info.depth;
7528
4.68M
    group_color->decode = dev_proc(pdev, decode_color);
7529
4.68M
    group_color->encode = dev_proc(pdev, encode_color);
7530
4.68M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7531
4.68M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7532
4.68M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7533
4.68M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7534
4.68M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7535
4.68M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7536
4.68M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7537
7538
    /* If the CS was ICC based, we need to update the device ICC profile
7539
        in the ICC manager, since that is the profile that is used for the
7540
        PDF14 device */
7541
4.68M
    if (group_color_type == ICC && iccprofile != NULL) {
7542
        /* iccprofile was incremented above if we had not just created it.
7543
           When we do the pop we will decrement and if we just created it, it
7544
           will be destroyed */
7545
4.68M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7546
4.68M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7547
4.68M
    }
7548
4.68M
    return group_color;
7549
4.68M
}
7550
7551
static int
7552
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7553
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7554
                             bool is_mask)
7555
101k
{
7556
101k
    pdf14_device* pdev = (pdf14_device*)dev;
7557
101k
    pdf14_group_color_t* new_group_color;
7558
101k
    gsicc_rendering_param_t render_cond;
7559
101k
    cmm_dev_profile_t* dev_profile;
7560
101k
    pdf14_device* pdevproto;
7561
101k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7562
101k
    const pdf14_procs_t* new_14procs;
7563
101k
    bool update_color_info;
7564
101k
    gx_color_polarity_t new_polarity;
7565
101k
    int new_num_comps;
7566
101k
    bool new_additive = false;
7567
101k
    byte new_depth;
7568
101k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7569
101k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7570
101k
    int k;
7571
101k
    bool has_tags = device_encodes_tags(dev);
7572
101k
    bool deep = device_is_deep(dev);
7573
101k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7574
101k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7575
101k
    cmm_profile_t *old_profile = NULL;
7576
7577
101k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7578
101k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7579
101k
        &render_cond);
7580
101k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7581
7582
    /* Allocate a new one */
7583
101k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7584
101k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7585
7586
101k
    if (new_group_color == NULL)
7587
0
        return_error(gs_error_VMerror);
7588
7589
    /* Link to old one */
7590
101k
    new_group_color->previous = pdev->color_model_stack;
7591
7592
    /* Reassign new one to dev */
7593
101k
    pdev->color_model_stack = new_group_color;
7594
7595
    /* Initialize with values */
7596
101k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7597
101k
    new_group_color->group_color_mapping_procs =
7598
101k
        dev_proc(pdev, get_color_mapping_procs);
7599
101k
    new_group_color->group_color_comp_index =
7600
101k
        dev_proc(pdev, get_color_comp_index);
7601
101k
    new_group_color->blend_procs = pdev->blend_procs;
7602
101k
    new_group_color->polarity = pdev->color_info.polarity;
7603
101k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7604
101k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7605
101k
    new_group_color->depth = pdev->color_info.depth;
7606
101k
    new_group_color->max_color = pdev->color_info.max_color;
7607
101k
    new_group_color->max_gray = pdev->color_info.max_gray;
7608
101k
    new_group_color->decode = dev_proc(pdev, decode_color);
7609
101k
    new_group_color->encode = dev_proc(pdev, encode_color);
7610
101k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7611
101k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7612
101k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7613
101k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7614
7615
101k
    if (new_profile == NULL)
7616
62.2k
        new_group_color->icc_profile = NULL;
7617
7618
    /* isadditive is only used in ctx */
7619
101k
    if (pdev->ctx) {
7620
0
        new_group_color->isadditive = pdev->ctx->additive;
7621
0
    }
7622
7623
101k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7624
101k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7625
7626
101k
    if (group_color_type == ICC && new_profile == NULL)
7627
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7628
101k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7629
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7630
       are based upon the color space of the device.  We want to remain in the
7631
       color space defined by the color space of the soft mask or transparency
7632
       group as opposed to the device color space. Later, when we pop the softmask
7633
       we will collapse it to a single band and then compose with it to the device
7634
       color space (or the parent layer space).  In the case where we pop an
7635
       isolated transparency group, we will do the blending in the proper color
7636
       space and then transform the data when we pop the group.  Remember that only
7637
       isolated groups can have color spaces that are different than their parent. */
7638
101k
    update_color_info = false;
7639
101k
    switch (group_color_type) {
7640
0
    case GRAY_SCALE:
7641
0
        if (pdev->color_info.num_components != 1) {
7642
0
            update_color_info = true;
7643
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7644
0
            new_num_comps = 1;
7645
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7646
0
            new_additive = true;
7647
0
            new_14procs = &gray_pdf14_procs;
7648
0
            new_depth = 8 << deep;
7649
0
        }
7650
0
        break;
7651
0
    case DEVICE_RGB:
7652
0
    case CIE_XYZ:
7653
0
        if (pdev->color_info.num_components != 3) {
7654
0
            update_color_info = true;
7655
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7656
0
            new_num_comps = 3;
7657
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7658
0
            new_additive = true;
7659
0
            new_14procs = &rgb_pdf14_procs;
7660
0
            new_depth = 24 << deep;
7661
0
        }
7662
0
        break;
7663
0
    case DEVICE_CMYK:
7664
0
        if (pdev->color_info.num_components != 4) {
7665
0
            update_color_info = true;
7666
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7667
0
            new_num_comps = 4;
7668
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7669
0
            new_additive = false;
7670
            /* This is needed due to the mismatched compressed encode decode
7671
               between the device procs and the pdf14 procs */
7672
0
            if (dev->color_info.num_components > 4) {
7673
0
                new_14procs = &cmykspot_pdf14_procs;
7674
0
            }
7675
0
            else {
7676
0
                new_14procs = &cmyk_pdf14_procs;
7677
0
            }
7678
0
            new_depth = 32 << deep;
7679
0
        }
7680
0
        break;
7681
39.0k
    case ICC:
7682
        /* Check if the profile is different. */
7683
39.0k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7684
35.1k
            update_color_info = true;
7685
35.1k
            new_num_comps = new_profile->num_comps;
7686
35.1k
            new_depth = new_profile->num_comps * (8 << deep);
7687
35.1k
            switch (new_num_comps) {
7688
31.9k
            case 1:
7689
31.9k
                if (pdev->sep_device && !is_mask) {
7690
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7691
0
                    new_14procs = &grayspot_pdf14_procs;
7692
0
                }
7693
31.9k
                else {
7694
31.9k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7695
31.9k
                    new_14procs = &gray_pdf14_procs;
7696
31.9k
                }
7697
31.9k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7698
31.9k
                new_additive = true;
7699
31.9k
                break;
7700
2.28k
            case 3:
7701
2.28k
                if (pdev->sep_device) {
7702
738
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7703
738
                    new_14procs = &rgbspot_pdf14_procs;
7704
738
                }
7705
1.54k
                else {
7706
1.54k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7707
1.54k
                    new_14procs = &rgb_pdf14_procs;
7708
1.54k
                }
7709
2.28k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7710
2.28k
                new_additive = true;
7711
2.28k
                break;
7712
909
            case 4:
7713
909
                if (pdev->sep_device) {
7714
48
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7715
48
                    new_14procs = &cmykspot_pdf14_procs;
7716
48
                }
7717
861
                else {
7718
861
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7719
861
                    new_14procs = &cmyk_pdf14_procs;
7720
861
                }
7721
909
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7722
909
                new_additive = false;
7723
909
                break;
7724
0
            default:
7725
0
                return gs_throw(gs_error_undefinedresult,
7726
35.1k
                    "ICC Number of colorants illegal");
7727
35.1k
            }
7728
35.1k
        }
7729
39.0k
        break;
7730
62.2k
    case UNKNOWN:
7731
62.2k
        return 0;
7732
0
        break;
7733
0
    default:
7734
0
        return_error(gs_error_rangecheck);
7735
0
        break;
7736
101k
    }
7737
7738
39.0k
    if (!update_color_info) {
7739
        /* Profile not updated */
7740
3.82k
        new_group_color->icc_profile = NULL;
7741
3.82k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7742
3.82k
        return 0;
7743
3.82k
    }
7744
7745
35.1k
    if (has_tags) {
7746
0
        new_num_comps++;
7747
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7748
0
        if (pdev->num_planar_planes > 0)
7749
0
            new_depth += deep ? 16 : 8;
7750
0
        else
7751
0
            new_depth += 8;
7752
0
    }
7753
35.1k
    if (pdev->sep_device && !is_mask) {
7754
786
        int num_spots;
7755
7756
786
        if (old_profile == NULL)
7757
0
            return_error(gs_error_undefined);
7758
7759
786
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7760
7761
786
        if (num_spots > 0) {
7762
66
            new_num_comps += num_spots;
7763
66
            new_depth = (8 << deep) * new_num_comps;
7764
66
        }
7765
786
    }
7766
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7767
77.7k
    for (k = 0; k < new_num_comps; k++) {
7768
42.5k
        comp_bits[k] = 8 << deep;
7769
42.5k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7770
42.5k
    }
7771
35.1k
    if_debug2m('v', pdev->memory,
7772
35.1k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7773
35.1k
        pdev->color_info.num_components, new_num_comps);
7774
    /* Set new information in the device */
7775
35.1k
    {
7776
35.1k
        gx_device local_device;
7777
7778
35.1k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7779
35.1k
        local_device.initialize_device_procs((gx_device *)&local_device);
7780
35.1k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7781
35.1k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7782
35.1k
    }
7783
35.1k
    pdev->blend_procs = pdevproto->blend_procs;
7784
35.1k
    pdev->color_info.polarity = new_polarity;
7785
35.1k
    pdev->color_info.max_color = deep ? 65535 : 255;
7786
35.1k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7787
35.1k
    pdev->pdf14_procs = new_14procs;
7788
35.1k
    if (pdev->num_planar_planes > 0)
7789
5.31k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7790
35.1k
    pdev->color_info.num_components = new_num_comps;
7791
35.1k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7792
35.1k
    pdev->color_info.depth = new_depth;
7793
35.1k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7794
35.1k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7795
35.1k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7796
35.1k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7797
35.1k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7798
7799
    /* If we have a compressed color codec, and we are doing a soft mask
7800
       push operation then go ahead and update the color encode and
7801
       decode for the pdf14 device to not used compressed color
7802
       encoding while in the soft mask.  We will just check for gray
7803
       and compressed.  Note that we probably don't have_tags if we
7804
       are dealing with compressed color.  But is is possible so
7805
       we add it in to catch for future use. */
7806
35.1k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7807
35.1k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7808
35.1k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7809
35.1k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7810
35.1k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7811
35.1k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7812
    /* For the ICC profiles, we want to update the ICC profile for the
7813
       device.  We store the original in group_color.
7814
       That will be stored in the clist and restored during the reading phase. */
7815
35.1k
    if (group_color_type == ICC) {
7816
35.1k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7817
35.1k
        new_group_color->icc_profile =
7818
35.1k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7819
35.1k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7820
35.1k
    }
7821
35.1k
    if (pdev->ctx) {
7822
0
        pdev->ctx->additive = new_additive;
7823
0
    }
7824
35.1k
    return 1;  /* Lets us detect that we did do an update */
7825
35.1k
}
7826
7827
static int
7828
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7829
101k
{
7830
7831
101k
    pdf14_device *pdev = (pdf14_device *)dev;
7832
101k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7833
101k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7834
7835
101k
    if (group_color == NULL)
7836
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7837
7838
101k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7839
    /* The color procs are always pushed.  Simply restore them. */
7840
101k
    if (group_color->group_color_mapping_procs == NULL &&
7841
101k
        group_color->group_color_comp_index == NULL) {
7842
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7843
101k
    } else {
7844
101k
        bool has_tags = device_encodes_tags(dev);
7845
101k
        if_debug2m('v', pdev->memory,
7846
101k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7847
101k
                   pdev->color_info.num_components,group_color->num_components);
7848
101k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7849
101k
        gx_set_cmap_procs(pgs, dev);
7850
101k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7851
101k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7852
101k
        pdev->color_info.polarity = group_color->polarity;
7853
101k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7854
101k
        pdev->color_info.depth = group_color->depth;
7855
101k
        if (pdev->num_planar_planes > 0)
7856
13.4k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7857
101k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7858
101k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7859
101k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7860
101k
        pdev->blend_procs = group_color->blend_procs;
7861
101k
        pdev->pdf14_procs = group_color->unpack_procs;
7862
101k
        pdev->color_info.max_color = group_color->max_color;
7863
101k
        pdev->color_info.max_gray = group_color->max_gray;
7864
101k
        set_dev_proc(pdev, encode_color, group_color->encode);
7865
101k
        set_dev_proc(pdev, decode_color, group_color->decode);
7866
101k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7867
101k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7868
101k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7869
101k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7870
7871
        /* clist writer fill rect has no access to gs_gstate */
7872
        /* and it forwards the target device.  this information */
7873
        /* is passed along to use in this case */
7874
101k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7875
101k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7876
101k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7877
101k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7878
101k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7879
101k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7880
101k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7881
101k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7882
101k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7883
101k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7884
101k
        if (pdev->ctx){
7885
0
            pdev->ctx->additive = group_color->isadditive;
7886
0
        }
7887
       /* The device profile must be restored. */
7888
101k
        if (group_color->icc_profile != NULL) {
7889
35.1k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7890
35.1k
                                    -1, "pdf14_clist_pop_color_model");
7891
35.1k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7892
35.1k
        }
7893
101k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7894
101k
    }
7895
101k
   pdf14_pop_group_color(dev, pgs);
7896
101k
    return 0;
7897
101k
}
7898
7899
/* When a transparency group is popped, the parent colorprocs must be restored.
7900
   Since the color mapping procs are all based upon the device, we must have a
7901
   nested list based upon the transparency group color space.  This nesting
7902
   must be outside the nested ctx structures to allow the nesting for the
7903
   clist writer */
7904
static void
7905
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7906
101k
{
7907
101k
    pdf14_device *pdev = (pdf14_device *)dev;
7908
101k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7909
7910
101k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7911
7912
    /* Update the link */
7913
101k
    pdev->color_model_stack = group_color->previous;
7914
7915
    /* Free the old one */
7916
101k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7917
101k
}
7918
7919
static  int
7920
pdf14_begin_transparency_mask(gx_device *dev,
7921
                              const gx_transparency_mask_params_t *ptmp,
7922
                              const gs_rect *pbbox,
7923
                              gs_gstate *pgs, gs_memory_t *mem)
7924
7.17M
{
7925
7.17M
    pdf14_device *pdev = (pdf14_device *)dev;
7926
7.17M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7927
7.17M
    byte *transfer_fn;
7928
7.17M
    gs_int_rect rect;
7929
7.17M
    int code;
7930
7.17M
    int group_color_numcomps;
7931
7.17M
    gs_transparency_color_t group_color_type;
7932
7.17M
    bool deep = device_is_deep(dev);
7933
7.17M
    pdf14_group_color_t* group_color_info;
7934
7935
7.17M
    code = pdf14_initialize_ctx(dev, pgs);
7936
7.17M
    if (code < 0)
7937
0
        return code;
7938
7939
7.17M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7940
6.37M
        pdf14_ctx *ctx = pdev->ctx;
7941
7942
        /* free up any maskbuf on the current tos */
7943
6.37M
        if (ctx->mask_stack) {
7944
1.02M
            if (ctx->mask_stack->rc_mask->mask_buf != NULL ) {
7945
530k
                pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf);
7946
530k
                ctx->mask_stack->rc_mask->mask_buf = NULL;
7947
530k
            }
7948
1.02M
        }
7949
6.37M
        return 0;
7950
6.37M
    }
7951
800k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7952
800k
                                         "pdf14_begin_transparency_mask");
7953
800k
    if (transfer_fn == NULL)
7954
0
        return_error(gs_error_VMerror);
7955
800k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7956
800k
    if (code < 0)
7957
0
        return code;
7958
    /* If we have background components the background alpha may be nonzero */
7959
800k
    if (ptmp->Background_components)
7960
241k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7961
800k
    if_debug1m('v', dev->memory,
7962
800k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7963
800k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7964
   /* If the group color is unknown, then we must use the previous group color
7965
       space or the device process color space */
7966
800k
    if (ptmp->group_color_type == UNKNOWN){
7967
0
        if (pdev->ctx->stack){
7968
            /* Use previous group color space */
7969
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7970
0
        } else {
7971
            /* Use process color space */
7972
0
            group_color_numcomps = pdev->color_info.num_components;
7973
0
        }
7974
0
        switch (group_color_numcomps) {
7975
0
            case 1:
7976
0
                group_color_type = GRAY_SCALE;
7977
0
                break;
7978
0
            case 3:
7979
0
                group_color_type = DEVICE_RGB;
7980
0
                break;
7981
0
            case 4:
7982
0
                group_color_type = DEVICE_CMYK;
7983
0
            break;
7984
0
            default:
7985
                /* We can end up here if we are in a deviceN color space and
7986
                   we have a sep output device */
7987
0
                group_color_type = DEVICEN;
7988
0
            break;
7989
0
         }
7990
800k
    } else {
7991
800k
        group_color_type = ptmp->group_color_type;
7992
800k
        group_color_numcomps = ptmp->group_color_numcomps;
7993
800k
    }
7994
7995
800k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7996
800k
                                               ptmp->iccprofile, true);
7997
800k
    if (group_color_info == NULL)
7998
0
        return gs_error_VMerror;
7999
8000
    /* Note that the soft mask always follows the group color requirements even
8001
       when we have a separable device */
8002
800k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
8003
800k
                                        transfer_fn, ptmp->function_is_identity,
8004
800k
                                        ptmp->idle, ptmp->replacing,
8005
800k
                                        ptmp->mask_id, ptmp->subtype,
8006
800k
                                        group_color_numcomps,
8007
800k
                                        ptmp->Background_components,
8008
800k
                                        ptmp->Background,
8009
800k
                                        ptmp->Matte_components,
8010
800k
                                        ptmp->Matte,
8011
800k
                                        ptmp->GrayBackground,
8012
800k
                                        group_color_info);
8013
800k
    if (code < 0)
8014
0
        return code;
8015
8016
800k
    return 0;
8017
800k
}
8018
8019
static  int
8020
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8021
800k
{
8022
800k
    pdf14_device *pdev = (pdf14_device *)dev;
8023
800k
    pdf14_group_color_t *group_color;
8024
800k
    int ok;
8025
800k
    bool has_tags = device_encodes_tags(dev);
8026
8027
800k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8028
800k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8029
#ifdef DEBUG
8030
    pdf14_debug_mask_stack_state(pdev->ctx);
8031
#endif
8032
8033
    /* May need to reset some color stuff related
8034
     * to a mismatch between the Smask color space
8035
     * and the Smask blending space */
8036
800k
    if (pdev->ctx->stack != NULL ) {
8037
800k
        group_color = pdev->ctx->stack->group_color_info;
8038
800k
        if (!(group_color->group_color_mapping_procs == NULL &&
8039
800k
            group_color->group_color_comp_index == NULL)) {
8040
800k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8041
800k
            gx_set_cmap_procs(pgs, dev);
8042
800k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8043
800k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8044
800k
            pdev->color_info.polarity = group_color->polarity;
8045
800k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8046
800k
            if (pdev->num_planar_planes > 0)
8047
67.2k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8048
800k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8049
800k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8050
800k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8051
800k
            pdev->num_std_colorants = group_color->num_std_colorants;
8052
800k
            pdev->color_info.depth = group_color->depth;
8053
800k
            pdev->blend_procs = group_color->blend_procs;
8054
800k
            pdev->ctx->additive = group_color->isadditive;
8055
800k
            pdev->pdf14_procs = group_color->unpack_procs;
8056
800k
            pdev->color_info.max_color = group_color->max_color;
8057
800k
            pdev->color_info.max_gray = group_color->max_gray;
8058
800k
            set_dev_proc(pdev, encode_color, group_color->encode);
8059
800k
            set_dev_proc(pdev, decode_color, group_color->decode);
8060
800k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8061
800k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8062
800k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8063
800k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8064
            /* Take care of the ICC profile */
8065
800k
            if (group_color->icc_profile != NULL) {
8066
800k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8067
800k
                                        -1, "pdf14_end_transparency_mask");
8068
800k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8069
800k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8070
800k
                                         1, "pdf14_end_transparency_mask");
8071
800k
            }
8072
800k
        }
8073
800k
    }
8074
800k
    return ok;
8075
800k
}
8076
8077
static  int
8078
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8079
                                 gx_color_index color,
8080
                                 const gx_device_color *pdc, bool devn)
8081
5.24M
{
8082
5.24M
    pdf14_device *pdev = (pdf14_device *)dev;
8083
5.24M
    pdf14_buf *buf = pdev->ctx->stack;
8084
5.24M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8085
5.24M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8086
5.24M
        blend_mode == BLEND_MODE_Compatible ||
8087
5.24M
        blend_mode == BLEND_MODE_CompatibleOverprint;
8088
5.24M
    int i, j, k;
8089
5.24M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8090
5.24M
    byte src[PDF14_MAX_PLANES];
8091
5.24M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8092
5.24M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8093
5.24M
    intptr_t rowstride = buf->rowstride;
8094
5.24M
    intptr_t planestride = buf->planestride;
8095
5.24M
    int num_chan = buf->n_chan;
8096
5.24M
    int num_comp = num_chan - 1;
8097
5.24M
    intptr_t shape_off = num_chan * planestride;
8098
5.24M
    bool has_shape = buf->has_shape;
8099
5.24M
    bool has_alpha_g = buf->has_alpha_g;
8100
5.24M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8101
5.24M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8102
5.24M
                                   (has_shape ? planestride : 0);
8103
5.24M
    bool has_tags = buf->has_tags;
8104
5.24M
    bool additive = pdev->ctx->additive;
8105
5.24M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8106
5.24M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8107
5.24M
    int shift = 8;
8108
5.24M
    byte shape = 0; /* Quiet compiler. */
8109
5.24M
    byte src_alpha;
8110
5.24M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8111
5.24M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8112
4.78M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8113
5.24M
    gx_color_index comps;
8114
5.24M
    bool has_backdrop = buf->backdrop != NULL;
8115
8116
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8117
       subtractive) and we are doing overprint with drawn_comps == 0
8118
       then this is a no-operation */
8119
5.24M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8120
0
        return 0;
8121
8122
5.24M
    if (buf->data == NULL)
8123
0
        return 0;
8124
#if 0
8125
    if (sizeof(color) <= sizeof(ulong))
8126
        if_debug6m('v', dev->memory,
8127
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8128
                   x, y, w, h, (ulong)color, num_chan);
8129
    else
8130
        if_debug7m('v', dev->memory,
8131
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8132
                   x, y, w, h,
8133
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8134
                   num_chan);
8135
#endif
8136
    /*
8137
     * Unpack the gx_color_index values.  Complement the components for subtractive
8138
     * color spaces.
8139
     */
8140
5.24M
    if (devn) {
8141
708k
        if (has_tags) {
8142
0
            curr_tag = pdc->tag;
8143
0
        }
8144
708k
        if (additive) {
8145
1.85M
            for (j = 0; j < num_comp; j++) {
8146
1.38M
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8147
1.38M
            }
8148
463k
        } else {
8149
1.22M
            for (j = 0; j < num_comp; j++) {
8150
982k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8151
982k
            }
8152
245k
        }
8153
4.54M
    } else {
8154
4.54M
        if (has_tags) {
8155
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8156
0
        }
8157
4.54M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8158
4.54M
    }
8159
8160
5.24M
    if (!has_tags)
8161
5.24M
        tag_off = 0;
8162
8163
5.24M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8164
5.24M
    if (has_shape) {
8165
6.61k
        shape = (byte)floor (255 * pdev->shape + 0.5);
8166
5.24M
    } else {
8167
5.24M
        shape_off = 0;
8168
5.24M
    }
8169
8170
5.24M
    if (!has_alpha_g)
8171
0
        alpha_g_off = 0;
8172
5.24M
    src_alpha = 255 - src_alpha;
8173
5.24M
    shape = 255 - shape;
8174
8175
    /* Fit the mark into the bounds of the buffer */
8176
5.24M
    if (x < buf->rect.p.x) {
8177
0
        w += x - buf->rect.p.x;
8178
0
        x = buf->rect.p.x;
8179
0
    }
8180
5.24M
    if (y < buf->rect.p.y) {
8181
9
      h += y - buf->rect.p.y;
8182
9
      y = buf->rect.p.y;
8183
9
    }
8184
5.24M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8185
5.24M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8186
    /* Update the dirty rectangle with the mark. */
8187
5.24M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8188
5.24M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8189
5.24M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8190
5.24M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8191
8192
    /* composite with backdrop only. */
8193
5.24M
    if (has_backdrop)
8194
5.24M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8195
0
    else
8196
0
        bline = NULL;
8197
8198
5.24M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8199
8200
10.9M
    for (j = 0; j < h; ++j) {
8201
5.74M
        bg_ptr = bline;
8202
5.74M
        dst_ptr = line;
8203
229M
        for (i = 0; i < w; ++i) {
8204
            /* Complement the components for subtractive color spaces */
8205
224M
            if (has_backdrop) {
8206
224M
                if (additive) {
8207
832M
                    for (k = 0; k < num_comp; ++k)
8208
616M
                        dst[k] = bg_ptr[k * planestride];
8209
216M
                } else {
8210
39.6M
                    for (k = 0; k < num_comp; ++k)
8211
31.7M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8212
7.93M
                }
8213
224M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8214
224M
            }
8215
224M
            if (buf->isolated || !has_backdrop) {
8216
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8217
224M
            } else {
8218
224M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8219
224M
                                            blend_mode, pdev->blend_procs, pdev);
8220
224M
            }
8221
            /* Complement the results for subtractive color spaces */
8222
224M
            if (additive) {
8223
216M
                if (!overprint) {
8224
1.04G
                    for (k = 0; k < num_chan; ++k)
8225
832M
                        dst_ptr[k * planestride] = dst[k];
8226
216M
                } else {
8227
                    /* Hybrid additive with subtractive spots */
8228
                    /* We may have to do the compatible overprint blending */
8229
61.1k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8230
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8231
0
                            blend_mode, pdev->blend_procs, pdev);
8232
0
                    }
8233
244k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8234
183k
                        if ((comps & 0x1) != 0) {
8235
183k
                            dst_ptr[k * planestride] = dst[k];
8236
183k
                        } else {
8237
                            /* Compatible overprint blend result. */
8238
0
                            dst_ptr[k * planestride] = dst2[k];
8239
0
                        }
8240
183k
                    }
8241
61.1k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8242
61.1k
                }
8243
216M
            } else {
8244
7.93M
                if (overprint) {
8245
                    /* We may have to do the compatible overprint blending */
8246
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8247
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8248
0
                            blend_mode, pdev->blend_procs, pdev);
8249
0
                    }
8250
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8251
0
                        if ((comps & 0x1) != 0) {
8252
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8253
0
                        } else {
8254
                            /* Compatible overprint blend result. */
8255
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8256
0
                        }
8257
0
                    }
8258
7.93M
                } else {
8259
39.6M
                    for (k = 0; k < num_comp; ++k)
8260
31.7M
                        dst_ptr[k * planestride] = 255 - dst[k];
8261
7.93M
                }
8262
7.93M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8263
7.93M
            }
8264
224M
            if (tag_off) {
8265
                /* If src alpha is 100% then set to curr_tag, else or */
8266
                /* other than Normal BM, we always OR */
8267
0
                if (src[num_comp] == 255 && tag_blend) {
8268
0
                    dst_ptr[tag_off] = curr_tag;
8269
0
                } else {
8270
0
                    dst_ptr[tag_off] |= curr_tag;
8271
0
                }
8272
0
            }
8273
            /* Knockout group alpha and shape too */
8274
224M
            if (alpha_g_off)
8275
224M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8276
224M
            if (shape_off)
8277
6.93k
                dst_ptr[shape_off] = 255 - shape;
8278
224M
            ++dst_ptr;
8279
224M
            if (has_backdrop)
8280
224M
                ++bg_ptr;
8281
224M
        }
8282
5.74M
        bline += rowstride;
8283
5.74M
        line += rowstride;
8284
5.74M
    }
8285
#if 0
8286
/* #if RAW_DUMP */
8287
    /* Dump the current buffer to see what we have. */
8288
    dump_raw_buffer(pdev->ctx->memory,
8289
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8290
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8291
                    pdev->ctx->stack->n_planes,
8292
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8293
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8294
                    pdev->ctx->stack->deep);
8295
    global_index++;
8296
#endif
8297
5.24M
    return 0;
8298
5.24M
}
8299
8300
static  int
8301
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8302
                                   gx_color_index color,
8303
                                   const gx_device_color *pdc, bool devn)
8304
0
{
8305
0
    pdf14_device *pdev = (pdf14_device *)dev;
8306
0
    pdf14_buf *buf = pdev->ctx->stack;
8307
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8308
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8309
0
        blend_mode == BLEND_MODE_Compatible ||
8310
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8311
0
    int i, j, k;
8312
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8313
0
    uint16_t src[PDF14_MAX_PLANES];
8314
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8315
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8316
0
    intptr_t rowstride = buf->rowstride;
8317
0
    intptr_t planestride = buf->planestride;
8318
0
    int num_chan = buf->n_chan;
8319
0
    int num_comp = num_chan - 1;
8320
0
    intptr_t shape_off = num_chan * planestride;
8321
0
    bool has_shape = buf->has_shape;
8322
0
    bool has_alpha_g = buf->has_alpha_g;
8323
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8324
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8325
0
                                   (has_shape ? planestride : 0);
8326
0
    bool has_tags = buf->has_tags;
8327
0
    bool additive = pdev->ctx->additive;
8328
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8329
0
    uint16_t shape = 0; /* Quiet compiler. */
8330
0
    uint16_t src_alpha;
8331
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8332
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8333
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8334
0
    gx_color_index comps;
8335
0
    bool has_backdrop = buf->backdrop != NULL;
8336
8337
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8338
       subtractive) and we are doing overprint with drawn_comps == 0
8339
       then this is a no-operation */
8340
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8341
0
        return 0;
8342
8343
0
    if (buf->data == NULL)
8344
0
        return 0;
8345
#if 0
8346
    if (sizeof(color) <= sizeof(ulong))
8347
        if_debug6m('v', dev->memory,
8348
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8349
                   x, y, w, h, (ulong)color, num_chan);
8350
    else
8351
        if_debug7m('v', dev->memory,
8352
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8353
                   x, y, w, h,
8354
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8355
                   num_chan);
8356
#endif
8357
    /*
8358
     * Unpack the gx_color_index values.  Complement the components for subtractive
8359
     * color spaces.
8360
     */
8361
0
    if (devn) {
8362
0
        if (has_tags) {
8363
0
            curr_tag = pdc->tag;
8364
0
        }
8365
0
        if (additive) {
8366
0
            for (j = 0; j < num_comp; j++) {
8367
0
                src[j] = pdc->colors.devn.values[j];
8368
0
            }
8369
0
        } else {
8370
0
            for (j = 0; j < num_comp; j++) {
8371
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8372
0
            }
8373
0
        }
8374
0
    } else {
8375
0
        if (has_tags) {
8376
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8377
0
        }
8378
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8379
0
    }
8380
8381
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8382
0
    if (has_shape) {
8383
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8384
0
    } else {
8385
0
        shape_off = 0;
8386
0
    }
8387
8388
0
    if (!has_tags) {
8389
0
        tag_off = 0;
8390
0
    }
8391
8392
0
    if (!has_alpha_g)
8393
0
        alpha_g_off = 0;
8394
0
    src_alpha = 65535 - src_alpha;
8395
0
    shape = 65535 - shape;
8396
8397
    /* Fit the mark into the bounds of the buffer */
8398
0
    if (x < buf->rect.p.x) {
8399
0
        w += x - buf->rect.p.x;
8400
0
        x = buf->rect.p.x;
8401
0
    }
8402
0
    if (y < buf->rect.p.y) {
8403
0
      h += y - buf->rect.p.y;
8404
0
      y = buf->rect.p.y;
8405
0
    }
8406
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8407
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8408
    /* Update the dirty rectangle with the mark. */
8409
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8410
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8411
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8412
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8413
8414
8415
    /* composite with backdrop only. */
8416
0
    if (has_backdrop)
8417
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8418
0
    else
8419
0
        bline = NULL;
8420
8421
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8422
0
    planestride >>= 1;
8423
0
    rowstride >>= 1;
8424
0
    alpha_g_off >>= 1;
8425
0
    shape_off >>= 1;
8426
0
    tag_off >>= 1;
8427
8428
0
    for (j = 0; j < h; ++j) {
8429
0
        bg_ptr = bline;
8430
0
        dst_ptr = line;
8431
0
        for (i = 0; i < w; ++i) {
8432
            /* Complement the components for subtractive color spaces */
8433
0
            if (has_backdrop) {
8434
0
                if (additive) {
8435
0
                    for (k = 0; k < num_comp; ++k)
8436
0
                        dst[k] = bg_ptr[k * planestride];
8437
0
                } else {
8438
0
                    for (k = 0; k < num_comp; ++k)
8439
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8440
0
                }
8441
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8442
0
            }
8443
0
            if (buf->isolated || !has_backdrop) {
8444
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8445
0
            } else {
8446
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8447
0
                                              blend_mode, pdev->blend_procs, pdev);
8448
0
            }
8449
            /* Complement the results for subtractive color spaces */
8450
0
            if (additive) {
8451
0
                if (!overprint) {
8452
0
                    for (k = 0; k < num_chan; ++k)
8453
0
                        dst_ptr[k * planestride] = dst[k];
8454
0
                } else {
8455
                    /* Hybrid additive with subtractive spots */
8456
                    /* We may have to do the compatible overprint blending */
8457
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8458
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8459
0
                            blend_mode, pdev->blend_procs, pdev);
8460
0
                    }
8461
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8462
0
                        if ((comps & 0x1) != 0) {
8463
0
                            dst_ptr[k * planestride] = dst[k];
8464
0
                        } else {
8465
                            /* Compatible overprint blend result. */
8466
0
                            dst_ptr[k * planestride] = dst2[k];
8467
0
                        }
8468
0
                    }
8469
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8470
0
                }
8471
0
            } else {
8472
0
                if (overprint) {
8473
                    /* We may have to do the compatible overprint blending */
8474
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8475
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8476
0
                            blend_mode, pdev->blend_procs, pdev);
8477
0
                    }
8478
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8479
0
                        if ((comps & 0x1) != 0) {
8480
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8481
0
                        } else {
8482
                            /* Compatible overprint blend result. */
8483
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8484
0
                        }
8485
0
                    }
8486
0
                } else {
8487
0
                    for (k = 0; k < num_comp; ++k)
8488
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8489
0
                }
8490
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8491
0
            }
8492
0
            if (tag_off) {
8493
                /* FIXME: As we are knocking out, possibly, we should be
8494
                 * always overwriting tag values here? */
8495
                /* If src alpha is 100% then set to curr_tag, else or */
8496
                /* other than Normal BM, we always OR */
8497
0
                if (src[num_comp] == 65535 && tag_blend) {
8498
0
                    dst_ptr[tag_off] = curr_tag;
8499
0
                } else {
8500
0
                    dst_ptr[tag_off] |= curr_tag;
8501
0
                }
8502
0
            }
8503
            /* Knockout group alpha and shape too */
8504
0
            if (alpha_g_off)
8505
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8506
0
            if (shape_off)
8507
0
                dst_ptr[shape_off] = 65535 - shape;
8508
0
            ++dst_ptr;
8509
0
            if (has_backdrop)
8510
0
                ++bg_ptr;
8511
0
        }
8512
0
        bline += rowstride;
8513
0
        line += rowstride;
8514
0
    }
8515
#if 0
8516
/* #if RAW_DUMP */
8517
    /* Dump the current buffer to see what we have. */
8518
    dump_raw_buffer(pdev->ctx->memory,
8519
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8520
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8521
                    pdev->ctx->stack->n_planes,
8522
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8523
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8524
                    pdev->ctx->stack->deep);
8525
    global_index++;
8526
#endif
8527
0
    return 0;
8528
0
}
8529
8530
static  int
8531
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8532
                                    gx_color_index color,
8533
                                    const gx_device_color *pdc, bool devn)
8534
5.24M
{
8535
5.24M
    pdf14_device *pdev = (pdf14_device *)dev;
8536
5.24M
    pdf14_buf *buf = pdev->ctx->stack;
8537
8538
5.24M
    if (buf->deep)
8539
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8540
5.24M
    else
8541
5.24M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8542
5.24M
}
8543
8544
/**
8545
 * Here we have logic to override the cmap_procs with versions that
8546
 * do not apply the transfer function. These copies should track the
8547
 * versions in gxcmap.c.
8548
 **/
8549
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8550
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8551
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8552
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8553
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8554
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8555
8556
static  const gx_color_map_procs pdf14_cmap_many = {
8557
     pdf14_cmap_gray_direct,
8558
     pdf14_cmap_rgb_direct,
8559
     pdf14_cmap_cmyk_direct,
8560
     pdf14_cmap_separation_direct,
8561
     pdf14_cmap_devicen_direct,
8562
     pdf14_cmap_is_halftoned
8563
    };
8564
8565
/**
8566
 * Note: copied from gxcmap.c because it's inlined.
8567
 **/
8568
static  inline void
8569
map_components_to_colorants(const frac * pcc,
8570
                            const gs_devicen_color_map * pcolor_component_map,
8571
                            frac * plist)
8572
4.14M
{
8573
4.14M
    int i = pcolor_component_map->num_colorants - 1;
8574
4.14M
    int pos;
8575
8576
    /* Clear all output colorants first */
8577
20.7M
    for (; i >= 0; i--) {
8578
16.5M
        plist[i] = frac_0;
8579
16.5M
    }
8580
    /* Map color components into output list */
8581
8.79M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8582
4.64M
        pos = pcolor_component_map->color_map[i];
8583
4.64M
        if (pos >= 0)
8584
4.64M
            plist[pos] = pcc[i];
8585
4.64M
    }
8586
4.14M
}
8587
8588
/* See Section 7.6.4 of PDF 1.7 spec */
8589
static inline bool
8590
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8591
411M
{
8592
411M
    if (pgs->fillconstantalpha != 1.0 ||
8593
411M
        pgs->strokeconstantalpha != 1.0 ||
8594
411M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8595
410M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8596
16.8M
        return 0;
8597
8598
    /* We can only be opaque if we're not in an SMask. */
8599
394M
    return dev_proc(pdev, dev_spec_op)(pdev,
8600
394M
                                       gxdso_in_smask,
8601
394M
                                       NULL, 0) != 1;
8602
411M
}
8603
8604
static  void
8605
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8606
                       gx_device * dev, gs_color_select_t select)
8607
15.8M
{
8608
15.8M
    int i, nc, ncomps;
8609
15.8M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8610
15.8M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8611
15.8M
    gx_color_index color;
8612
15.8M
    gx_device *trans_device;
8613
15.8M
    const gx_device *map_dev;
8614
15.8M
    const gx_cm_color_map_procs *procs;
8615
8616
    /* If trans device is set, we need to use its procs. */
8617
15.8M
    if (pgs->trans_device != NULL) {
8618
4.22M
        trans_device = pgs->trans_device;
8619
11.6M
    } else {
8620
11.6M
        trans_device = dev;
8621
11.6M
    }
8622
15.8M
    ncomps = trans_device->color_info.num_components;
8623
8624
    /* map to the color model */
8625
15.8M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8626
15.8M
    procs->map_gray(map_dev, gray, cm_comps);
8627
8628
15.8M
    nc = ncomps;
8629
15.8M
    if (device_encodes_tags(trans_device))
8630
0
        nc--;
8631
15.8M
    if (pdf14_state_opaque(trans_device, pgs)) {
8632
9.20M
        for (i = 0; i < nc; i++)
8633
4.60M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8634
11.2M
    } else {
8635
22.5M
        for (i = 0; i < nc; i++)
8636
11.2M
            cv[i] = frac2cv(cm_comps[i]);
8637
11.2M
    }
8638
    /* Copy tags untransformed. */
8639
15.8M
    if (nc < ncomps)
8640
0
        cv[nc] = cm_comps[nc];
8641
8642
    /* If output device supports devn, we need to make sure we send it the
8643
       proper color type.  We now support Gray + spots as devn colors */
8644
15.8M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8645
1.88M
        for (i = 0; i < ncomps; i++)
8646
943k
            pdc->colors.devn.values[i] = cv[i];
8647
943k
        pdc->type = gx_dc_type_devn;
8648
14.9M
    } else {
8649
        /* encode as a color index */
8650
14.9M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8651
        /* check if the encoding was successful; we presume failure is rare */
8652
14.9M
        if (color != gx_no_color_index)
8653
14.9M
            color_set_pure(pdc, color);
8654
14.9M
    }
8655
15.8M
}
8656
8657
static  void
8658
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8659
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8660
370M
{
8661
370M
    int i, nc, ncomps;
8662
370M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8663
370M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8664
370M
    gx_color_index color;
8665
370M
    gx_device *trans_device;
8666
370M
    const gx_device *map_dev;
8667
370M
    const gx_cm_color_map_procs *procs;
8668
8669
    /* If trans device is set, we need to use its procs. */
8670
370M
    if (pgs->trans_device != NULL){
8671
1.59M
        trans_device = pgs->trans_device;
8672
369M
    } else {
8673
369M
        trans_device = dev;
8674
369M
    }
8675
370M
    ncomps = trans_device->color_info.num_components;
8676
    /* map to the color model */
8677
370M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8678
370M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8679
8680
370M
    nc = ncomps;
8681
370M
    if (device_encodes_tags(trans_device))
8682
0
        nc--;
8683
370M
    if (pdf14_state_opaque(trans_device, pgs)) {
8684
817M
        for (i = 0; i < nc; i++)
8685
612M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8686
204M
    } else {
8687
666M
        for (i = 0; i < nc; i++)
8688
499M
            cv[i] = frac2cv(cm_comps[i]);
8689
166M
    }
8690
    /* Copy tags untransformed. */
8691
370M
    if (nc < ncomps)
8692
0
        cv[nc] = cm_comps[nc];
8693
8694
    /* If output device supports devn, we need to make sure we send it the
8695
       proper color type.  We now support RGB + spots as devn colors */
8696
370M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8697
84.1M
        for (i = 0; i < ncomps; i++)
8698
63.1M
            pdc->colors.devn.values[i] = cv[i];
8699
21.0M
        pdc->type = gx_dc_type_devn;
8700
349M
    } else {
8701
        /* encode as a color index */
8702
349M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8703
        /* check if the encoding was successful; we presume failure is rare */
8704
349M
        if (color != gx_no_color_index)
8705
349M
            color_set_pure(pdc, color);
8706
349M
    }
8707
370M
}
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
24.4M
{
8714
24.4M
    int i, nc, ncomps;
8715
24.4M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8716
24.4M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8717
24.4M
    gx_color_index color;
8718
24.4M
    gx_device *trans_device;
8719
24.4M
    const gx_device *map_dev;
8720
24.4M
    const gx_cm_color_map_procs *procs;
8721
8722
8723
    /* If trans device is set, we need to use its procs. */
8724
24.4M
    if (pgs->trans_device != NULL){
8725
19.1M
        trans_device = pgs->trans_device;
8726
19.1M
    } else {
8727
5.29M
        trans_device = dev;
8728
5.29M
    }
8729
24.4M
    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
24.4M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8734
24.4M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8735
8736
24.4M
    nc = ncomps;
8737
24.4M
    if (device_encodes_tags(trans_device))
8738
0
        nc--;
8739
24.4M
    if (pdf14_state_opaque(trans_device, pgs)) {
8740
108M
        for (i = 0; i < nc; i++)
8741
86.8M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8742
21.7M
    } else {
8743
13.9M
        for (i = 0; i < nc; i++)
8744
11.1M
            cv[i] = frac2cv(cm_comps[i]);
8745
2.78M
    }
8746
    /* Copy tags untransformed. */
8747
24.4M
    if (nc < ncomps)
8748
0
        cv[nc] = cm_comps[nc];
8749
8750
    /* if output device supports devn, we need to make sure we send it the
8751
       proper color type */
8752
24.4M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8753
36.7M
        for (i = 0; i < ncomps; i++)
8754
29.3M
            pdc->colors.devn.values[i] = cv[i];
8755
7.34M
        pdc->type = gx_dc_type_devn;
8756
17.1M
    } else {
8757
        /* encode as a color index */
8758
17.1M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8759
        /* check if the encoding was successful; we presume failure is rare */
8760
17.1M
        if (color != gx_no_color_index)
8761
17.1M
            color_set_pure(pdc, color);
8762
17.1M
    }
8763
24.4M
}
8764
8765
static int
8766
pdf14_get_num_spots(gx_device * dev)
8767
4.14M
{
8768
4.14M
    cmm_dev_profile_t *dev_profile;
8769
4.14M
    cmm_profile_t *icc_profile;
8770
4.14M
    gsicc_rendering_param_t render_cond;
8771
8772
4.14M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8773
4.14M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8774
4.14M
        &render_cond);
8775
4.14M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8776
4.14M
}
8777
8778
static  void
8779
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8780
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8781
113k
{
8782
113k
    int i, nc, ncomps = dev->color_info.num_components;
8783
113k
    int num_spots = pdf14_get_num_spots(dev);
8784
113k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8785
113k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8786
113k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8787
113k
    gx_color_index color;
8788
8789
113k
    nc = ncomps;
8790
113k
    if (device_encodes_tags(dev))
8791
0
        nc--;
8792
8793
113k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8794
0
        frac comp_value = all;
8795
8796
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8797
0
            cm_comps[i] = comp_value;
8798
        /*
8799
         * Invert the photometric interpretation for additive
8800
         * color spaces because separations are always subtractive.
8801
         */
8802
0
        if (additive)
8803
0
            comp_value = frac_1 - comp_value;
8804
        /* Use the "all" value for all components */
8805
0
        for (; i >= 0; i--)
8806
0
            cm_comps[i] = comp_value;
8807
113k
    } else {
8808
113k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8809
8810
113k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8811
0
            color_set_null(pdc);
8812
0
            return;
8813
0
        }
8814
8815
        /* map to the color model */
8816
226k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8817
113k
            comp_value[i] = all;
8818
113k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps);
8819
113k
    }
8820
8821
    /* apply the transfer function(s); convert to color values */
8822
113k
    if (additive) {
8823
12.9k
        for (i = 0; i < nc; i++)
8824
10.3k
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8825
        /* We are in an additive mode (blend space) and drawing with a sep color
8826
        into a sep device.  Make sure we are drawing "white" with the process
8827
        colorants, but only if we are not in an ALL case */
8828
2.59k
        if (pgs->color_component_map.sep_type != SEP_ALL)
8829
10.3k
            for (i = 0; i < nc - num_spots; i++)
8830
7.78k
                cv[i] = gx_max_color_value;
8831
2.59k
    } else
8832
553k
        for (i = 0; i < nc; i++)
8833
442k
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8834
    /* Copy tags untransformed. */
8835
113k
    if (nc < ncomps)
8836
0
        cv[nc] = cm_comps[nc];
8837
8838
    /* if output device supports devn, we need to make sure we send it the
8839
       proper color type */
8840
113k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
8841
566k
        for (i = 0; i < ncomps; i++)
8842
453k
            pdc->colors.devn.values[i] = cv[i];
8843
113k
        pdc->type = gx_dc_type_devn;
8844
113k
    } else {
8845
        /* encode as a color index */
8846
0
        color = dev_proc(dev, encode_color)(dev, cv);
8847
        /* check if the encoding was successful; we presume failure is rare */
8848
0
        if (color != gx_no_color_index)
8849
0
            color_set_pure(pdc, color);
8850
0
    }
8851
113k
}
8852
8853
static  void
8854
pdf14_cmap_devicen_direct(const frac * pcc,
8855
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8856
    gs_color_select_t select, const gs_color_space *pcs)
8857
4.03M
{
8858
4.03M
    int i, nc, ncomps = dev->color_info.num_components;
8859
4.03M
    int num_spots = pdf14_get_num_spots(dev);
8860
4.03M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8861
4.03M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8862
4.03M
    gx_color_index color;
8863
4.03M
    gx_device *trans_device;
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
4.03M
    if (pgs->trans_device != NULL){
8871
4.03M
        trans_device = pgs->trans_device;
8872
4.03M
    } else {
8873
0
        trans_device = dev;
8874
0
    }
8875
4.03M
    ncomps = trans_device->color_info.num_components;
8876
    /* map to the color model */
8877
4.03M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);
8878
8879
4.03M
    nc = ncomps;
8880
4.03M
    if (device_encodes_tags(trans_device))
8881
0
        nc--;
8882
    /* apply the transfer function(s); convert to color values */
8883
4.03M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
8884
0
        for (i = 0; i < nc; i++)
8885
0
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8886
        /* We are in an additive mode (blend space) and drawing with a sep color
8887
        into a sep device.  Make sure we are drawing "white" with the process
8888
        colorants */
8889
0
        for (i = 0; i < nc - num_spots; i++)
8890
0
            cv[i] = gx_max_color_value;
8891
0
    } else
8892
20.1M
        for (i = 0; i < nc; i++)
8893
16.1M
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8894
    /* Copy tags untransformed. */
8895
4.03M
    if (nc < ncomps)
8896
0
        cv[nc] = cm_comps[nc];
8897
8898
    /* if output device supports devn, we need to make sure we send it the
8899
       proper color type */
8900
4.03M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8901
4.94M
        for (i = 0; i < ncomps; i++)
8902
3.95M
            pdc->colors.devn.values[i] = cv[i];
8903
988k
        pdc->type = gx_dc_type_devn;
8904
3.04M
    } else {
8905
    /* encode as a color index */
8906
3.04M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8907
        /* check if the encoding was successful; we presume failure is rare */
8908
3.04M
        if (color != gx_no_color_index)
8909
3.04M
            color_set_pure(pdc, color);
8910
3.04M
    }
8911
4.03M
}
8912
8913
static  bool
8914
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8915
370k
{
8916
370k
    return false;
8917
370k
}
8918
8919
static  const gx_color_map_procs *
8920
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8921
3.09M
{
8922
    /* The pdf14 marking device itself is always continuous tone. */
8923
3.09M
    return &pdf14_cmap_many;
8924
3.09M
}
8925
8926
static int
8927
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8928
                  void *data, int size)
8929
933M
{
8930
933M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8931
8932
933M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8933
1.96M
        return 1;
8934
931M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8935
60.0k
        return 1;
8936
930M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8937
1.13k
        if (data != NULL && size == sizeof(gx_device *))
8938
377
            *(gx_device **)data = pdev;
8939
1.13k
        return 1;
8940
1.13k
    }
8941
930M
    if (dev_spec_op == gxdso_device_child) {
8942
3.20k
        pdf14_device *dev = (pdf14_device *)pdev;
8943
3.20k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8944
3.20k
        if (d->target == pdev) {
8945
3.20k
            d->target = dev->target;
8946
3.20k
            return 1;
8947
3.20k
        }
8948
3.20k
    }
8949
930M
    if (dev_spec_op == gxdso_supports_devn
8950
930M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8951
491M
        cmm_dev_profile_t *dev_profile;
8952
491M
        int code;
8953
491M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8954
491M
        if (code == 0) {
8955
491M
            return dev_profile->supports_devn;
8956
491M
        } else {
8957
0
            return 0;
8958
0
        }
8959
491M
    }
8960
439M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8961
560k
        pdf14_device* dev = (pdf14_device*)pdev;
8962
8963
560k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8964
560k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8965
235k
            return 1;
8966
324k
        return 0;
8967
560k
    }
8968
438M
    if (dev_spec_op == gxdso_is_encoding_direct)
8969
609k
        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
438M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8977
687k
        return 0;
8978
437M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8979
301k
        return 0;
8980
437M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8981
59.6k
        return 0;
8982
437M
    if(dev_spec_op == gxdso_supports_hlcolor)
8983
1.65k
        return 0;
8984
437M
    if(dev_spec_op == gxdso_pattern_can_accum)
8985
165k
        return 0;
8986
437M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8987
2.61k
        return 0;
8988
437M
    if (dev_spec_op == gxdso_overprint_active) {
8989
7.35M
        if (p14dev->pclist_device != NULL) {
8990
7.32M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8991
7.32M
        } else {
8992
30.0k
            return p14dev->overprint || p14dev->stroke_overprint;
8993
30.0k
        }
8994
7.35M
    }
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
429M
    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
                }
9052
0
                code = gs_update_trans_marking_params(pgs);
9053
0
                break;
9054
9055
0
            case OP_FS_TRANS_PRESTROKE:
9056
0
                if (pdf14_abuf->group_needed) {
9057
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9058
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9059
0
                }
9060
0
                code = gs_update_trans_marking_params(pgs);
9061
0
                break;
9062
9063
0
            case OP_FS_TRANS_POSTSTROKE:
9064
0
                if (pdf14_abuf->group_needed) {
9065
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9066
0
                                                        pdf14_abuf->op_ca_eq_CA);
9067
0
                }
9068
0
                if (code >= 0)
9069
0
                    code = gs_update_trans_marking_params(pgs);
9070
9071
                /* fallthrough */
9072
9073
0
            case OP_FS_TRANS_CLEANUP:
9074
0
cleanup:
9075
0
                if (pdf14_abuf->group_needed) {
9076
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9077
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9078
0
                    if (code1 < 0)
9079
0
                        code = gs_note_error(gs_error_Fatal);
9080
0
                }
9081
0
                break;
9082
0
        }
9083
0
        pgs->device = curr_dev;
9084
9085
0
        return (code < 0) ? code : ret;
9086
0
    }
9087
9088
429M
    if (dev_spec_op == gxdso_in_smask_construction)
9089
7.55M
        return p14dev->in_smask_construction > 0;
9090
422M
    if (dev_spec_op == gxdso_in_smask)
9091
395M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9092
27.0M
    if (dev_spec_op == gxdso_replacecolor) {
9093
26.2M
        gx_device *tdev = p14dev->target;
9094
26.2M
        cmm_dev_profile_t *tdev_profile;
9095
26.2M
        int code;
9096
9097
         /* If in a softmask or softmask construction do not allow
9098
           replacement. */
9099
26.2M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9100
591k
            return 0;
9101
9102
        /* If the target CS is different than the pdf14 profile add this information
9103
           for the target device that will be handling the replacement. While not
9104
           perfect this at least lets you do the replacehment and have some information
9105
           about what the situation is. */
9106
25.6M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9107
25.6M
        if (code != 0)
9108
0
            return 0;
9109
9110
25.6M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9111
25.6M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9112
17.2M
            color_replace_t* replace_data = (color_replace_t*)data;
9113
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9114
               color remap operation. */
9115
17.2M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9116
17.2M
        }
9117
9118
        /* Pass on to target device */
9119
25.6M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9120
25.6M
    }
9121
769k
    if (dev_spec_op == gxdso_device_insert_child) {
9122
111
        gx_device *tdev = p14dev->target;
9123
111
        p14dev->target = (gx_device *)data;
9124
111
        rc_increment(p14dev->target);
9125
111
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9126
111
        return 0;
9127
111
    }
9128
769k
    if (dev_spec_op == gxdso_interpolate_threshold)
9129
16.1k
        return p14dev->interpolate_threshold;
9130
9131
753k
    if (dev_spec_op == gxdso_overprintsim_state) {
9132
16.1k
        unsigned char *data_uchar = (unsigned char *) data;
9133
16.1k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9134
16.1k
        if (p14dev->ctx != NULL)
9135
15
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9136
16.1k
        else
9137
16.1k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9138
16.1k
        return 1;
9139
16.1k
    }
9140
9141
737k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9142
753k
}
9143
9144
/* Needed to set color monitoring in the target device's profile */
9145
int
9146
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9147
0
{
9148
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9149
0
    gx_device *targ = p14dev->target;
9150
0
    cmm_dev_profile_t *dev_profile;
9151
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9152
9153
0
    if (code == 0)
9154
0
        dev_profile->pageneutralcolor = monitoring;
9155
0
    return code;
9156
0
}
9157
9158
static int
9159
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9160
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9161
1.71M
{
9162
1.71M
    pdf14_device dev_proto;
9163
1.71M
    pdf14_device * p14dev;
9164
1.71M
    int code;
9165
1.71M
    bool has_tags;
9166
1.71M
    cmm_profile_t *icc_profile;
9167
1.71M
    gsicc_rendering_param_t render_cond;
9168
1.71M
    cmm_dev_profile_t *dev_profile;
9169
1.71M
    uchar k;
9170
1.71M
    int max_bitmap;
9171
1.71M
    bool use_pdf14_accum = false;
9172
1.71M
    bool deep;
9173
9174
    /* Guard against later seg faults, this should not be possible */
9175
1.71M
    if (target == NULL)
9176
0
        return gs_throw_code(gs_error_Fatal);
9177
9178
1.71M
    has_tags = device_encodes_tags(target);
9179
1.71M
    deep = device_is_deep(target);
9180
1.71M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9181
1.71M
                                 target->space_params.MaxBitmap;
9182
    /* If the device is not a printer class device, it won't support saved-pages */
9183
    /* and so we may need to make a clist device in order to prevent very large  */
9184
    /* or high resolution pages from having allocation problems.                 */
9185
    /* We use MaxBitmap to decide when a clist is needed.*/
9186
1.71M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9187
1.71M
        gx_device_is_pattern_clist(target) == 0 &&
9188
1.71M
        gx_device_is_pattern_accum(target) == 0 &&
9189
1.71M
        gs_device_is_memory(target) == 0) {
9190
9191
6.25k
        uint32_t pdf14_trans_buffer_size =
9192
6.25k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9193
6.25k
                                         target->color_info.num_components,
9194
6.25k
                                         deep ? 16 : 8) >> 3);
9195
9196
6.25k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9197
6.25k
                pdf14_trans_buffer_size *= target->height;
9198
0
        else
9199
0
                max_bitmap = 0;     /* Force decision to clist */
9200
6.25k
        if (pdf14_trans_buffer_size > max_bitmap)
9201
6.02k
            use_pdf14_accum = true;
9202
6.25k
    }
9203
1.71M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9204
1.71M
    if (code < 0)
9205
0
        return code;
9206
1.71M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9207
1.71M
                          &render_cond);
9208
1.71M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9209
9210
    /* Get the proto from which to copy the device. This will always
9211
     * ignore tags! */
9212
1.71M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9213
1.71M
                                  pdf14pct, use_pdf14_accum);
9214
1.71M
    if (code < 0)
9215
0
        return code;
9216
1.71M
    code = gs_copydevice((gx_device **) &p14dev,
9217
1.71M
                         (const gx_device *) &dev_proto, mem);
9218
1.71M
    if (code < 0)
9219
0
        return code;
9220
9221
    /* Copying the params across will add tags to the colorinfo as required. */
9222
1.71M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9223
1.71M
    if (code < 0)
9224
0
        return code;
9225
9226
1.71M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9227
1.71M
    p14dev->pad = target->pad;
9228
1.71M
    p14dev->log2_align_mod = target->log2_align_mod;
9229
1.71M
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
9230
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9231
1.71M
    else if (pdf14pct->params.overprint_sim_push && target->num_planar_planes != 0)
9232
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9233
1.71M
    else
9234
1.71M
        p14dev->num_planar_planes = target->num_planar_planes;
9235
1.71M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9236
9237
1.71M
    p14dev->alpha = 1.0;
9238
1.71M
    p14dev->shape = 1.0;
9239
1.71M
    p14dev->opacity = 1.0;
9240
1.71M
    p14dev->fillconstantalpha = 1.0;
9241
1.71M
    p14dev->strokeconstantalpha = 1.0;
9242
9243
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9244
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9245
       do the mapping to the NCLR profile when the put_image occurs */
9246
1.71M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9247
1.71M
        icc_profile->data_cs == gsNCHANNEL) {
9248
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9249
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9250
0
            -1, "gs_pdf14_device_push");
9251
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9252
1.71M
    } else {
9253
        /* If the target profile was CIELAB (and we are not using a blend CS),
9254
           then overide with default RGB for proper blending.  During put_image
9255
           we will convert from RGB to CIELAB.  Need to check that we have a
9256
           default profile, which will not be the case if we are coming from the clist reader */
9257
1.71M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9258
1.71M
            && pgs->icc_manager->default_rgb != NULL &&
9259
1.71M
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9260
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9261
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9262
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9263
0
                -1, "gs_pdf14_device_push");
9264
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9265
0
        }
9266
1.71M
    }
9267
9268
1.71M
    if (pdf14pct->params.overprint_sim_push &&
9269
1.71M
        pdf14pct->params.num_spot_colors_int > 0) {
9270
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9271
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9272
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9273
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9274
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9275
0
    }
9276
9277
    /* The number of color planes should not exceed that of the target.
9278
       Unless we are using a blend CS */
9279
1.71M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9280
1.71M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9281
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9282
1.71M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9283
159k
            p14dev->color_info.max_components = target->color_info.max_components;
9284
1.71M
    }
9285
1.71M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9286
    /* If we have a tag device then go ahead and do a special encoder
9287
       decoder for the pdf14 device to make sure we maintain this
9288
       information in the encoded color information.  We could use
9289
       the target device's methods but the PDF14 device has to maintain
9290
       8 bit color always and we could run into other issues if the number
9291
       of colorants became large.  If we need to do compressed color with
9292
       tags that will be a special project at that time */
9293
1.71M
    if (deep) {
9294
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9295
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9296
0
    }
9297
1.71M
    if (has_tags) {
9298
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9299
0
    }
9300
    /* if the device has separations already defined (by SeparationOrderNames) */
9301
    /* we need to copy them (allocating new names) so the colorants are in the */
9302
    /* same order as the target device.                                        */
9303
1.71M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9304
159k
        code = devn_copy_params(target, (gx_device *)p14dev);
9305
159k
        if (code < 0) {
9306
70
            *pdev = NULL;
9307
70
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9308
70
            rc_decrement(p14dev, "gs_pdf14_device_push");
9309
70
            return code;
9310
70
        }
9311
159k
    }
9312
    /* by definition pdf14_encode _is_ standard */
9313
1.71M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9314
1.71M
    gx_device_fill_in_procs((gx_device *)p14dev);
9315
1.71M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9316
1.71M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9317
1.71M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9318
9319
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9320
6.09M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9321
4.38M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9322
4.38M
        p14dev->color_info.comp_shift[k] =
9323
4.38M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9324
4.38M
    }
9325
1.71M
    if (use_pdf14_accum) {
9326
        /* we will disable this device later, but we don't want to allocate large buffers */
9327
6.02k
        p14dev->width = 1;
9328
6.02k
        p14dev->height = 1;
9329
6.02k
    }
9330
9331
1.71M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9332
1.71M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9333
1.71M
    *pdev = (gx_device *) p14dev;
9334
1.71M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9335
1.71M
    p14dev->color_model_stack = NULL;
9336
9337
    /* In case we have alphabits set */
9338
1.71M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9339
9340
1.71M
    if (pdf14pct->params.is_pattern) {
9341
18.2k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9342
18.2k
        if (code < 0) {
9343
0
            *pdev = NULL;
9344
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9345
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9346
0
            return code;
9347
0
        }
9348
18.2k
    }
9349
9350
    /* We should never go into this when using a blend color space */
9351
1.71M
    if (use_pdf14_accum) {
9352
6.02k
        const gx_device_pdf14_accum *accum_proto = NULL;
9353
6.02k
        gx_device *new_target = NULL;
9354
6.02k
        gx_device_color pdcolor;
9355
6.02k
        frac pconc_white = frac_1;
9356
6.02k
        bool UsePlanarBuffer = false;
9357
9358
6.02k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9359
9360
        /* get the prototype for the accumulator device based on colorspace */
9361
6.02k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9362
1.01k
            case 1:
9363
1.01k
                accum_proto = &pdf14_accum_Gray;
9364
1.01k
                break;
9365
5.01k
            case 3:
9366
5.01k
                accum_proto = &pdf14_accum_RGB;
9367
5.01k
                break;
9368
0
            case 4:
9369
0
                accum_proto = &pdf14_accum_CMYK;
9370
0
                break;
9371
0
            default:
9372
0
                accum_proto = &pdf14_accum_CMYKspot;
9373
0
                UsePlanarBuffer = true;
9374
6.02k
        }
9375
6.02k
        if (accum_proto == NULL ||
9376
6.02k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9377
0
            goto no_clist_accum;
9378
9379
6.02k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9380
        /* Fill in values from the target device before opening */
9381
6.02k
        new_target->color_info = p14dev->color_info;
9382
6.02k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9383
6.02k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9384
6.02k
        set_linear_color_bits_mask_shift(new_target);
9385
6.02k
        gs_pdf14_device_copy_params(new_target, target);
9386
6.02k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9387
6.02k
        gx_device_fill_in_procs(new_target);
9388
9389
6.02k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9390
6.02k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9391
6.02k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9392
9393
6.02k
        new_target->PageHandlerPushed = true;
9394
6.02k
        new_target->ObjectHandlerPushed = true;
9395
6.02k
        new_target->NupHandlerPushed = true;
9396
        /* if the device has separations already defined (by SeparationOrderNames) */
9397
        /* we need to copy them (allocating new names) so the colorants are in the */
9398
        /* same order as the target device.                                        */
9399
6.02k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9400
0
            code = devn_copy_params(target, (gx_device *)pdev);
9401
0
            if (code < 0)
9402
0
                return code;
9403
0
        }
9404
        /* UsePlanarBuffer is true in case this is CMYKspot */
9405
6.02k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9406
6.02k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9407
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9408
0
            goto no_clist_accum;
9409
0
        }
9410
        /* Do the initial fillpage into the pdf14-accum device we just created */
9411
6.02k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9412
6.02k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9413
6.02k
                                            &pconc_white,
9414
6.02k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9415
6.02k
                                            dev_profile)) < 0)
9416
0
            goto no_clist_accum;
9417
9418
6.02k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9419
6.02k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9420
6.02k
        if (code < 0)
9421
0
            goto no_clist_accum;
9422
9423
6.02k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9424
6.02k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9425
6.02k
    }
9426
1.71M
    return code;
9427
9428
0
no_clist_accum:
9429
        /* FIXME: We allocated a really small p14dev, but that won't work */
9430
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9431
1.71M
}
9432
9433
/*
9434
 * In a modest violation of good coding practice, the gs_composite_common
9435
 * fields are "known" to be simple (contain no pointers to garbage
9436
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9437
 * to be simple, so we just create a trivial structure descriptor for the
9438
 * entire gs_pdf14trans_s structure.
9439
 */
9440
#define private_st_gs_pdf14trans_t()\
9441
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9442
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9443
9444
/* GC descriptor for gs_pdf14trans_t */
9445
private_st_gs_pdf14trans_t();
9446
9447
/*
9448
 * Check for equality of two PDF 1.4 transparency compositor objects.
9449
 *
9450
 * We are currently always indicating that PDF 1.4 transparency compositors are
9451
 * equal.  Two transparency compositors may have teh same data but still
9452
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9453
 * operations in a row mean that we are creating a group inside of a group.
9454
 */
9455
static  bool
9456
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9457
0
{
9458
0
    return false;
9459
0
}
9460
9461
#ifdef DEBUG
9462
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9463
#endif
9464
9465
#define put_value(dp, value)\
9466
11.4M
    BEGIN\
9467
11.4M
        memcpy(dp, &value, sizeof(value));\
9468
11.4M
        dp += sizeof(value);\
9469
11.4M
    END
9470
9471
static inline int
9472
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9473
1.35M
{
9474
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9475
       because clist writer may skip this command for some bands.
9476
       For a better result we need individual CTM for each band.
9477
     */
9478
1.35M
    byte *pbuf = *ppbuf;
9479
1.35M
    int len, code;
9480
9481
1.35M
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9482
1.35M
    pbuf--; /* For cmd_write_ctm. */
9483
1.35M
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9484
1.35M
    if (code < 0)
9485
0
        return code;
9486
1.35M
    pbuf += len + 1;
9487
1.35M
    *ppbuf = pbuf;
9488
1.35M
    return 0;
9489
1.35M
}
9490
9491
/*
9492
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9493
 * list device. This is also where we update the pdf14_needed. When set the clist
9494
 * painting procs will update the trans_bbox state for bands that are affected.
9495
*/
9496
static  int
9497
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9498
                   gx_device_clist_writer *cdev)
9499
3.26M
{
9500
3.26M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9501
3.26M
    int need, avail = *psize;
9502
3.26M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9503
        to fit the data written below. We don't implement a dynamic check for
9504
        the buffer owerflow, assuming that the consistency is verified in the
9505
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9506
3.26M
    byte * pbuf = buf;
9507
3.26M
    int opcode = pparams->pdf14_op;
9508
3.26M
    int mask_size = 0;
9509
3.26M
    uint mask_id = 0;
9510
3.26M
    int code;
9511
3.26M
    bool found_icc;
9512
3.26M
    int64_t hashcode = 0;
9513
3.26M
    cmm_profile_t *icc_profile;
9514
3.26M
    gsicc_rendering_param_t render_cond;
9515
3.26M
    cmm_dev_profile_t *dev_profile;
9516
    /* We maintain and update working copies until we actually write the clist */
9517
3.26M
    int pdf14_needed = cdev->pdf14_needed;
9518
3.26M
    int trans_group_level = cdev->pdf14_trans_group_level;
9519
3.26M
    int smask_level = cdev->pdf14_smask_level;
9520
3.26M
    bool deep = device_is_deep((gx_device *)cdev);
9521
9522
3.26M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9523
3.26M
                                                     &dev_profile);
9524
3.26M
    if (code < 0)
9525
0
        return code;
9526
3.26M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9527
3.26M
                          &render_cond);
9528
3.26M
    *pbuf++ = opcode;     /* 1 byte */
9529
3.26M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9530
4
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9531
9532
3.26M
    switch (opcode) {
9533
0
        default:      /* Should not occur. */
9534
0
            break;
9535
29.1k
        case PDF14_PUSH_DEVICE:
9536
29.1k
            trans_group_level = 0;
9537
29.1k
            cdev->pdf14_smask_level = 0;
9538
29.1k
            cdev->page_pdf14_needed = false;
9539
29.1k
            put_value(pbuf, pparams->num_spot_colors);
9540
29.1k
            put_value(pbuf, pparams->num_spot_colors_int);
9541
29.1k
            put_value(pbuf, pparams->overprint_sim_push);
9542
29.1k
            put_value(pbuf, pparams->is_pattern);
9543
9544
            /* If we happen to be going to a color space like CIELAB then
9545
               we are going to do our blending in default RGB and convert
9546
               to CIELAB at the end.  To do this, we need to store the
9547
               default RGB profile in the clist so that we can grab it
9548
               later on during the clist read back and put image command */
9549
29.1k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9550
                /* Get the default RGB profile.  Set the device hash code
9551
                   so that we can extract it during the put_image operation. */
9552
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9553
0
                found_icc =
9554
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9555
0
                if (!found_icc) {
9556
                    /* Add it to the table */
9557
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9558
0
                                       pparams->iccprofile);
9559
0
                }
9560
0
            }
9561
29.1k
            break;
9562
28.3k
        case PDF14_POP_DEVICE:
9563
28.3k
            pdf14_needed = false;   /* reset pdf14_needed */
9564
28.3k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9565
28.3k
            smask_level = 0;
9566
28.3k
            put_value(pbuf, pparams->is_pattern);
9567
28.3k
            break;
9568
733k
        case PDF14_END_TRANS_GROUP:
9569
741k
        case PDF14_END_TRANS_TEXT_GROUP:
9570
741k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9571
741k
            if (smask_level == 0 && trans_group_level == 0)
9572
38.1k
                pdf14_needed = cdev->page_pdf14_needed;
9573
741k
            break;      /* No data */
9574
11.5k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9575
741k
        case PDF14_BEGIN_TRANS_GROUP:
9576
741k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9577
741k
            trans_group_level++;
9578
741k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9579
741k
            if (code < 0)
9580
0
                return code;
9581
741k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9582
741k
            *pbuf++ = pparams->blend_mode;
9583
741k
            *pbuf++ = pparams->group_color_type;
9584
741k
            *pbuf++ = pparams->page_group;
9585
741k
            put_value(pbuf, pparams->group_color_numcomps);
9586
741k
            put_value(pbuf, pparams->opacity);
9587
741k
            put_value(pbuf, pparams->shape);
9588
741k
            put_value(pbuf, pparams->bbox);
9589
741k
            put_value(pbuf, pparams->shade_group);
9590
741k
            put_value(pbuf, pparams->text_group);
9591
741k
            mask_id = pparams->mask_id;
9592
741k
            put_value(pbuf, mask_id);
9593
            /* Color space information maybe ICC based
9594
               in this case we need to store the ICC
9595
               profile or the ID if it is cached already */
9596
741k
            if (pparams->group_color_type == ICC) {
9597
                /* Check if it is already in the ICC clist table */
9598
21.2k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9599
21.2k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9600
21.2k
                if (!found_icc) {
9601
                    /* Add it to the table */
9602
6.17k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9603
6.17k
                    put_value(pbuf, hashcode);
9604
15.0k
                } else {
9605
                    /* It will be in the clist. Just write out the hashcode */
9606
15.0k
                    put_value(pbuf, hashcode);
9607
15.0k
                }
9608
720k
            } else {
9609
720k
                put_value(pbuf, hashcode);
9610
720k
            }
9611
741k
            break;
9612
613k
        case PDF14_BEGIN_TRANS_MASK:
9613
613k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9614
525k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9615
525k
                smask_level++;
9616
525k
            }
9617
613k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9618
613k
            if (code < 0)
9619
0
                return code;
9620
613k
            put_value(pbuf, pparams->subtype);
9621
613k
            *pbuf++ = pparams->group_color_type;
9622
613k
            put_value(pbuf, pparams->group_color_numcomps);
9623
613k
            *pbuf++ = pparams->replacing;
9624
613k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9625
613k
            *pbuf++ = pparams->Background_components;
9626
613k
            *pbuf++ = pparams->Matte_components;
9627
613k
            put_value(pbuf, pparams->bbox);
9628
613k
            mask_id = pparams->mask_id;
9629
613k
            put_value(pbuf, mask_id);
9630
613k
            if (pparams->Background_components) {
9631
4.32k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9632
9633
4.32k
                memcpy(pbuf, pparams->Background, l);
9634
4.32k
                pbuf += l;
9635
4.32k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9636
4.32k
                pbuf += sizeof(pparams->GrayBackground);
9637
4.32k
            }
9638
613k
            if (pparams->Matte_components) {
9639
240
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9640
9641
240
                memcpy(pbuf, pparams->Matte, m);
9642
240
                pbuf += m;
9643
240
            }
9644
613k
            if (!pparams->function_is_identity)
9645
1.37k
                mask_size = (256+deep)<<deep;
9646
            /* Color space information may be ICC based
9647
               in this case we need to store the ICC
9648
               profile or the ID if it is cached already */
9649
613k
            if (pparams->group_color_type == ICC) {
9650
                /* Check if it is already in the ICC clist table */
9651
525k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9652
525k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9653
525k
                if (!found_icc) {
9654
                    /* Add it to the table */
9655
4.19k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9656
4.19k
                    put_value(pbuf, hashcode);
9657
521k
                } else {
9658
                    /* It will be in the clist. Just write out the hashcode */
9659
521k
                    put_value(pbuf, hashcode);
9660
521k
                }
9661
525k
            } else {
9662
87.1k
                put_value(pbuf, hashcode);
9663
87.1k
            }
9664
613k
            break;
9665
525k
        case PDF14_END_TRANS_MASK:
9666
525k
            smask_level--;
9667
525k
            if (smask_level == 0 && trans_group_level == 0)
9668
14.3k
                pdf14_needed = cdev->page_pdf14_needed;
9669
525k
            break;
9670
514k
        case PDF14_SET_BLEND_PARAMS:
9671
514k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9672
514k
                pparams->shape != 1.0)
9673
514k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9674
0
            else if (smask_level == 0 && trans_group_level == 0)
9675
0
                pdf14_needed = false;   /* At page level, set back to false */
9676
514k
            if (smask_level == 0 && trans_group_level == 0)
9677
180k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9678
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9679
514k
            put_value(pbuf, pparams->changed);
9680
514k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9681
53.3k
                *pbuf++ = pparams->blend_mode;
9682
514k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9683
27.5k
                *pbuf++ = pparams->text_knockout;
9684
514k
            if (pparams->changed & PDF14_SET_AIS)
9685
514k
                put_value(pbuf, pparams->ais);
9686
514k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9687
514k
                put_value(pbuf, pparams->overprint);
9688
514k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9689
514k
                put_value(pbuf, pparams->stroke_overprint);
9690
514k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9691
514k
                put_value(pbuf, pparams->fillconstantalpha);
9692
514k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9693
514k
                put_value(pbuf, pparams->strokeconstantalpha);
9694
514k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9695
514k
                put_value(pbuf, pparams->op_fs_state);
9696
514k
            break;
9697
0
        case PDF14_PUSH_TRANS_STATE:
9698
0
            break;
9699
74.9k
        case PDF14_POP_TRANS_STATE:
9700
74.9k
            break;
9701
0
        case PDF14_PUSH_SMASK_COLOR:
9702
0
            return 0;   /* We really should never be here */
9703
0
            break;
9704
0
        case PDF14_POP_SMASK_COLOR:
9705
0
            return 0;   /* We really should never be here */
9706
0
            break;
9707
3.26M
    }
9708
9709
    /* check for fit */
9710
3.26M
    need = (pbuf - buf) + mask_size;
9711
3.26M
    *psize = need;
9712
3.26M
    if (need > avail) {
9713
558k
        if (avail)
9714
0
            return_error(gs_error_rangecheck);
9715
558k
        else
9716
558k
            return gs_error_rangecheck;
9717
558k
    }
9718
9719
    /* If we are writing more than the maximum ever expected,
9720
     * return a rangecheck error. Second check is for Coverity
9721
     */
9722
2.70M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9723
2.70M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9724
0
        return_error(gs_error_rangecheck);
9725
9726
    /* Copy our serialized data into the output buffer */
9727
2.70M
    memcpy(data, buf, need - mask_size);
9728
2.70M
    if (mask_size)  /* Include the transfer mask data if present */
9729
1.04k
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9730
2.70M
    if_debug3m('v', cdev->memory,
9731
2.70M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9732
2.70M
               pdf14_opcode_names[opcode], mask_id, need);
9733
2.70M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9734
2.70M
    cdev->pdf14_trans_group_level = trans_group_level;
9735
2.70M
    cdev->pdf14_smask_level = smask_level;
9736
2.70M
    return 0;
9737
2.70M
}
9738
9739
#undef put_value
9740
9741
/* Function prototypes */
9742
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9743
                const gs_pdf14trans_params_t * pparams,
9744
                gs_memory_t * mem );
9745
9746
#define read_value(dp, value)\
9747
262M
    BEGIN\
9748
262M
        memcpy(&value, dp, sizeof(value));\
9749
262M
        dp += sizeof(value);\
9750
262M
    END
9751
9752
/*
9753
 * Convert the string representation of the PDF 1.4 transparency parameter
9754
 * into the full compositor.
9755
 */
9756
static  int
9757
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9758
                                uint size, gs_memory_t * mem )
9759
78.1M
{
9760
78.1M
    gs_pdf14trans_params_t params = {0};
9761
78.1M
    const byte * start = data;
9762
78.1M
    int used, code = 0;
9763
78.1M
    bool deep;
9764
9765
78.1M
    if (size < 1)
9766
0
        return_error(gs_error_rangecheck);
9767
9768
    /* Read PDF 1.4 compositor data from the clist */
9769
78.1M
    params.pdf14_op = *data++;
9770
78.1M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9771
78.1M
               pdf14_opcode_names[params.pdf14_op], size);
9772
78.1M
    memset(&params.ctm, 0, sizeof(params.ctm));
9773
78.1M
    switch (params.pdf14_op) {
9774
0
        default:      /* Should not occur. */
9775
0
            break;
9776
2.47M
        case PDF14_PUSH_DEVICE:
9777
2.47M
            read_value(data, params.num_spot_colors);
9778
2.47M
            read_value(data, params.num_spot_colors_int);
9779
2.47M
            read_value(data, params.overprint_sim_push);
9780
2.47M
            read_value(data, params.is_pattern);
9781
2.47M
            break;
9782
0
        case PDF14_ABORT_DEVICE:
9783
0
            break;
9784
2.47M
        case PDF14_POP_DEVICE:
9785
2.47M
            read_value(data, params.is_pattern);
9786
2.47M
            break;
9787
3.96M
        case PDF14_END_TRANS_GROUP:
9788
4.63M
        case PDF14_END_TRANS_TEXT_GROUP:
9789
#ifdef DEBUG
9790
            code += 0; /* A good place for a breakpoint. */
9791
#endif
9792
4.63M
            break;      /* No data */
9793
0
        case PDF14_PUSH_TRANS_STATE:
9794
0
            break;
9795
5.75M
        case PDF14_POP_TRANS_STATE:
9796
5.75M
            break;
9797
1.07M
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9798
4.63M
        case PDF14_BEGIN_TRANS_GROUP:
9799
            /*
9800
             * We are currently not using the bbox or the colorspace so they were
9801
             * not placed in the clist
9802
             */
9803
4.63M
            data = cmd_read_matrix(&params.ctm, data);
9804
4.63M
            params.Isolated = (*data) & 1;
9805
4.63M
            params.Knockout = (*data++ >> 1) & 1;
9806
4.63M
            params.blend_mode = *data++;
9807
4.63M
            params.group_color_type = *data++;  /* Trans group color */
9808
4.63M
            params.page_group = *data++;
9809
4.63M
            read_value(data,params.group_color_numcomps);  /* color group size */
9810
4.63M
            read_value(data, params.opacity);
9811
4.63M
            read_value(data, params.shape);
9812
4.63M
            read_value(data, params.bbox);
9813
4.63M
            read_value(data, params.shade_group);
9814
4.63M
            read_value(data, params.text_group);
9815
4.63M
            read_value(data, params.mask_id);
9816
4.63M
            read_value(data, params.icc_hash);
9817
4.63M
            break;
9818
8.58M
        case PDF14_BEGIN_TRANS_MASK:
9819
                /* This is the largest transparency parameter at this time (potentially
9820
                 * 1531 bytes in size if Background_components =
9821
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9822
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9823
                 *
9824
                 * NOTE:
9825
                 * The clist reader must be able to handle this sized device.
9826
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9827
                 * may also need to be changed correspondingly (defined in gstparam.h)
9828
                 * Also... if another compositor param should exceed this size, this
9829
                 * same condition applies.
9830
                 */
9831
8.58M
            data = cmd_read_matrix(&params.ctm, data);
9832
8.58M
            read_value(data, params.subtype);
9833
8.58M
            params.group_color_type = *data++;
9834
8.58M
            read_value(data, params.group_color_numcomps);
9835
8.58M
            params.replacing = *data++;
9836
8.58M
            params.function_is_identity = *data & 1;
9837
8.58M
            deep = (*data++)>>1;
9838
8.58M
            params.Background_components = *data++;
9839
8.58M
            params.Matte_components = *data++;
9840
8.58M
            read_value(data, params.bbox);
9841
8.58M
            read_value(data, params.mask_id);
9842
8.58M
            if (params.Background_components) {
9843
291k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9844
9845
291k
                memcpy(params.Background, data, l);
9846
291k
                data += l;
9847
291k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9848
291k
                data += sizeof(params.GrayBackground);
9849
291k
            }
9850
8.58M
            if (params.Matte_components) {
9851
6.27k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9852
9853
6.27k
                memcpy(params.Matte, data, m);
9854
6.27k
                data += m;
9855
6.27k
            }
9856
8.58M
            read_value(data, params.icc_hash);
9857
8.58M
            if (params.function_is_identity) {
9858
8.55M
                int i;
9859
9860
8.55M
                if (deep) {
9861
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9862
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9863
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9864
8.55M
                } else {
9865
2.19G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9866
2.18G
                        params.transfer_fn[i] = (byte)floor(i *
9867
2.18G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9868
2.18G
                    }
9869
8.55M
                }
9870
8.55M
            } else {
9871
37.0k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9872
37.0k
                data += (256+deep)<<deep;
9873
37.0k
            }
9874
8.58M
            break;
9875
885k
        case PDF14_END_TRANS_MASK:
9876
885k
            break;
9877
0
        case PDF14_PUSH_SMASK_COLOR:
9878
0
            return 0;
9879
0
            break;
9880
0
        case PDF14_POP_SMASK_COLOR:
9881
0
            return 0;
9882
0
            break;
9883
48.7M
        case PDF14_SET_BLEND_PARAMS:
9884
48.7M
            read_value(data, params.changed);
9885
48.7M
            if (params.changed & PDF14_SET_BLEND_MODE)
9886
5.14M
                params.blend_mode = *data++;
9887
48.7M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9888
2.41M
                params.text_knockout = *data++;
9889
48.7M
            if (params.changed & PDF14_SET_AIS)
9890
48.7M
                read_value(data, params.ais);
9891
48.7M
            if (params.changed & PDF14_SET_OVERPRINT)
9892
48.7M
                read_value(data, params.overprint);
9893
48.7M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9894
48.7M
                read_value(data, params.stroke_overprint);
9895
48.7M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9896
48.7M
                read_value(data, params.fillconstantalpha);
9897
48.7M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9898
48.7M
                read_value(data, params.strokeconstantalpha);
9899
48.7M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9900
48.7M
                read_value(data, params.op_fs_state);
9901
48.7M
            break;
9902
78.1M
    }
9903
78.1M
    code = gs_create_pdf14trans(ppct, &params, mem);
9904
78.1M
    if (code < 0)
9905
0
        return code;
9906
78.1M
    used = data - start;
9907
78.1M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9908
9909
    /* If we read more than the maximum expected, return a rangecheck error */
9910
78.1M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9911
0
        return_error(gs_error_rangecheck);
9912
78.1M
    else
9913
78.1M
        return used;
9914
78.1M
}
9915
9916
/*
9917
 * Adjust the compositor's CTM.
9918
 */
9919
static int
9920
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9921
41.2M
{
9922
41.2M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9923
41.2M
    gs_matrix mat = pct->params.ctm;
9924
9925
41.2M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9926
41.2M
               mat.xx, mat.xy, mat.yx, mat.yy,
9927
41.2M
               mat.tx, mat.ty);
9928
41.2M
    mat.tx -= x0;
9929
41.2M
    mat.ty -= y0;
9930
41.2M
    gs_gstate_setmatrix(pgs, &mat);
9931
41.2M
    return 0;
9932
41.2M
}
9933
9934
/*
9935
 * Create a PDF 1.4 transparency compositor.
9936
 *
9937
 * Note that this routine will be called only if the device is not already
9938
 * a PDF 1.4 transparency compositor.
9939
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9940
 */
9941
static  int
9942
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9943
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9944
    gs_memory_t * mem)
9945
1.74M
{
9946
1.74M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9947
1.74M
    int code = 0;
9948
9949
    /*
9950
     * We only handle the push operation.  All other operations are ignored.
9951
     * The other operations will be handled by the composite routine
9952
     * for the PDF 1.4 compositing device.
9953
     */
9954
1.74M
    switch (pdf14pct->params.pdf14_op) {
9955
1.71M
        case PDF14_PUSH_DEVICE:
9956
1.71M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9957
            /* Change (non-error) code to 1 to indicate that we created
9958
             * a device. */
9959
1.71M
            if (code >= 0)
9960
1.71M
                code = 1;
9961
1.71M
            break;
9962
29.3k
        default:
9963
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9964
29.3k
            *pp14dev = NULL;
9965
29.3k
            return_error(gs_error_unregistered);
9966
1.74M
    }
9967
1.71M
    return code;
9968
1.74M
}
9969
9970
/*
9971
 * Find an opening compositor op.
9972
 */
9973
static gs_compositor_closing_state
9974
find_opening_op(int opening_op, gs_composite_t **ppcte,
9975
                gs_compositor_closing_state return_code)
9976
4.16M
{
9977
    /* Assuming a right *BEGIN* - *END* operation balance. */
9978
4.16M
    gs_composite_t *pcte = *ppcte;
9979
9980
10.0M
    for (;;) {
9981
10.0M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9982
9.47M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9983
9.47M
            int op = pct->params.pdf14_op;
9984
9985
9.47M
            *ppcte = pcte;
9986
9.47M
            if (op == opening_op)
9987
2.69M
                return return_code;
9988
6.77M
            if (op != PDF14_SET_BLEND_PARAMS) {
9989
4.09M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9990
781
                    return COMP_ENQUEUE;
9991
4.09M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
9992
428k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
9993
376k
                        return COMP_ENQUEUE;
9994
428k
                }
9995
3.71M
                if (opening_op == PDF14_PUSH_DEVICE) {
9996
3.66M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
9997
3.66M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
9998
3.66M
                        op != PDF14_END_TRANS_TEXT_GROUP)
9999
243k
                        return COMP_ENQUEUE;
10000
3.66M
                }
10001
3.71M
            }
10002
6.77M
        } else
10003
582k
            return COMP_ENQUEUE;
10004
6.15M
        pcte = pcte->prev;
10005
6.15M
        if (pcte == NULL)
10006
263k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10007
6.15M
    }
10008
4.16M
}
10009
10010
/*
10011
 * Find an opening compositor op.
10012
 */
10013
static gs_compositor_closing_state
10014
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10015
40.3M
{
10016
40.3M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10017
40.3M
    gs_composite_t *pct = *ppcte;
10018
10019
40.3M
    for (;;) {
10020
40.3M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10021
35.3M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10022
10023
35.3M
            *ppcte = pct;
10024
35.3M
            if (pct_pdf14->params.pdf14_op != my_op)
10025
6.97M
                return COMP_ENQUEUE;
10026
28.4M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10027
                /* If the new parameters completely replace the old ones
10028
                   then remove the old one from the queu */
10029
28.4M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10030
28.4M
                    pct_pdf14->params.changed) {
10031
26.4M
                    return COMP_REPLACE_CURR;
10032
26.4M
                } else {
10033
1.94M
                    return COMP_ENQUEUE;
10034
1.94M
                }
10035
28.4M
            }
10036
28.4M
        } else
10037
4.97M
            return COMP_ENQUEUE;
10038
0
        pct = pct->prev;
10039
0
        if (pct == NULL)
10040
0
            return COMP_ENQUEUE; /* Not in queue. */
10041
0
    }
10042
40.3M
}
10043
10044
/*
10045
 * Check for closing compositor.
10046
 */
10047
static gs_compositor_closing_state
10048
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10049
                        gx_device *dev)
10050
67.7M
{
10051
67.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10052
67.7M
    int op0 = pct0->params.pdf14_op;
10053
10054
67.7M
    switch (op0) {
10055
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10056
1.82M
        case PDF14_PUSH_DEVICE:
10057
1.82M
            return COMP_ENQUEUE;
10058
0
        case PDF14_ABORT_DEVICE:
10059
0
            return COMP_ENQUEUE;
10060
1.82M
        case PDF14_POP_DEVICE:
10061
1.82M
            if (*ppcte == NULL)
10062
1.22M
                return COMP_ENQUEUE;
10063
600k
            else {
10064
600k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10065
10066
600k
                if (state == COMP_EXEC_IDLE)
10067
117k
                    return COMP_DROP_QUEUE;
10068
483k
                return state;
10069
600k
            }
10070
823k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10071
3.97M
        case PDF14_BEGIN_TRANS_GROUP:
10072
3.97M
            return COMP_ENQUEUE;
10073
3.35M
        case PDF14_END_TRANS_GROUP:
10074
3.97M
        case PDF14_END_TRANS_TEXT_GROUP:
10075
3.97M
            if (*ppcte == NULL)
10076
728k
                return COMP_EXEC_QUEUE;
10077
3.24M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10078
7.15M
        case PDF14_BEGIN_TRANS_MASK:
10079
7.15M
            return COMP_ENQUEUE;
10080
0
        case PDF14_PUSH_TRANS_STATE:
10081
0
            return COMP_ENQUEUE;
10082
4.78M
        case PDF14_POP_TRANS_STATE:
10083
4.78M
            return COMP_ENQUEUE;
10084
0
        case PDF14_PUSH_SMASK_COLOR:
10085
0
            return COMP_ENQUEUE;
10086
0
            break;
10087
0
        case PDF14_POP_SMASK_COLOR:
10088
0
            return COMP_ENQUEUE;
10089
0
            break;
10090
786k
        case PDF14_END_TRANS_MASK:
10091
786k
            if (*ppcte == NULL)
10092
475k
                return COMP_EXEC_QUEUE;
10093
310k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10094
43.3M
        case PDF14_SET_BLEND_PARAMS:
10095
43.3M
            if (*ppcte == NULL)
10096
3.03M
                return COMP_ENQUEUE;
10097
            /* hack : ignore csel - here it is always zero : */
10098
40.3M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10099
67.7M
    }
10100
67.7M
}
10101
10102
/*
10103
 * Check whether a next operation is friendly to the compositor.
10104
 */
10105
static bool
10106
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10107
7.04M
{
10108
7.04M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10109
7.04M
    int op0 = pct0->params.pdf14_op;
10110
10111
7.04M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10112
7.04M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10113
        /* Halftone commands are always passed to the target printer device,
10114
           because transparency buffers are always contone.
10115
           So we're safe to execute them before queued transparency compositors. */
10116
1.79M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10117
764k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10118
764k
            return true;
10119
1.02M
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10120
999k
            return true;
10121
1.02M
    }
10122
5.28M
    return false;
10123
7.04M
}
10124
10125
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10126
static composite_equal_proc(c_pdf14trans_equal);
10127
static composite_write_proc(c_pdf14trans_write);
10128
static composite_read_proc(c_pdf14trans_read);
10129
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10130
static composite_is_closing_proc(c_pdf14trans_is_closing);
10131
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10132
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10133
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10134
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10135
10136
/*
10137
 * Methods for the PDF 1.4 transparency compositor
10138
 *
10139
 * Note:  We have two set of methods.  They are the same except for the
10140
 * composite_clist_write_update method.  Once the clist write device is created,
10141
 * we use the second set of procedures.  This prevents the creation of multiple
10142
 * PDF 1.4 clist write compositor devices being chained together.
10143
 */
10144
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10145
    GX_COMPOSITOR_PDF14_TRANS,
10146
    {
10147
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10148
        c_pdf14trans_equal,                      /* procs.equal */
10149
        c_pdf14trans_write,                      /* procs.write */
10150
        c_pdf14trans_read,                       /* procs.read */
10151
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10152
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10153
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10154
                /* Create a PDF 1.4 clist write device */
10155
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10156
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10157
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10158
    }                                            /* procs */
10159
};
10160
10161
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10162
    GX_COMPOSITOR_PDF14_TRANS,
10163
    {
10164
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10165
        c_pdf14trans_equal,                      /* procs.equal */
10166
        c_pdf14trans_write,                      /* procs.write */
10167
        c_pdf14trans_read,                       /* procs.read */
10168
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10169
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10170
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10171
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10172
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10173
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10174
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10175
    }                                            /* procs */
10176
};
10177
10178
/*
10179
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10180
 */
10181
int
10182
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10183
551M
{
10184
551M
    return (pct->type == &gs_composite_pdf14trans_type
10185
551M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10186
551M
}
10187
10188
/*
10189
 * Create a PDF 1.4 transparency compositor data structure.
10190
 */
10191
static int
10192
gs_create_pdf14trans(
10193
    gs_composite_t **               ppct,
10194
    const gs_pdf14trans_params_t *  pparams,
10195
    gs_memory_t *                   mem )
10196
80.9M
{
10197
80.9M
    gs_pdf14trans_t *                pct;
10198
10199
80.9M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10200
80.9M
                             "gs_create_pdf14trans");
10201
80.9M
    if (pct == NULL)
10202
0
        return_error(gs_error_VMerror);
10203
80.9M
    pct->type = &gs_composite_pdf14trans_type;
10204
80.9M
    pct->id = gs_next_ids(mem, 1);
10205
80.9M
    pct->params = *pparams;
10206
80.9M
    pct->idle = false;
10207
80.9M
    *ppct = (gs_composite_t *)pct;
10208
80.9M
    return 0;
10209
80.9M
}
10210
10211
/*
10212
 * Send a PDF 1.4 transparency compositor action to the specified device.
10213
 */
10214
int
10215
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10216
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10217
2.55M
{
10218
2.55M
    gs_composite_t * pct = NULL;
10219
2.55M
    int code;
10220
10221
2.55M
    pparams->ctm = ctm_only(pgs);
10222
2.55M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10223
2.55M
    if (code < 0)
10224
0
        return code;
10225
2.55M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10226
2.55M
    if (code == gs_error_handled)
10227
0
        code = 0;
10228
10229
2.55M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10230
10231
2.55M
    return code;
10232
2.55M
}
10233
10234
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10235
10236
/*
10237
 * The PDF 1.4 transparency compositor device may have a different process
10238
 * color model than the output device.  If we are banding then we need to
10239
 * create two compositor devices.  The output side (clist reader) needs a
10240
 * compositor to actually composite the output.  We also need a compositor
10241
 * device before the clist writer.  This is needed to provide a process color
10242
 * model which matches the PDF 1.4 blending space.
10243
 *
10244
 * This section provides support for this device.
10245
 */
10246
10247
/*
10248
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10249
 * We actually use the same structure for both the clist writer and reader
10250
 * devices.  However we use separate names to identify the routines for each
10251
 * device.
10252
 */
10253
10254
static  dev_proc_composite(pdf14_clist_composite);
10255
static  dev_proc_composite(pdf14_clist_forward_composite);
10256
static  dev_proc_fill_path(pdf14_clist_fill_path);
10257
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10258
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10259
static  dev_proc_text_begin(pdf14_clist_text_begin);
10260
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10261
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10262
10263
static void
10264
pdf14_clist_init_procs(gx_device *dev,
10265
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10266
                       dev_proc_get_color_comp_index(get_color_comp_index))
10267
14.5k
{
10268
14.5k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10269
14.5k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10270
14.5k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10271
14.5k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10272
14.5k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10273
14.5k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10274
14.5k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10275
14.5k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10276
14.5k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10277
14.5k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10278
14.5k
    set_dev_proc(dev, put_params, pdf14_put_params);
10279
14.5k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10280
14.5k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10281
14.5k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10282
14.5k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10283
14.5k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10284
14.5k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10285
14.5k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10286
14.5k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10287
14.5k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10288
14.5k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10289
14.5k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10290
14.5k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10291
14.5k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10292
14.5k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10293
14.5k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10294
14.5k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10295
14.5k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10296
14.5k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10297
14.5k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10298
14.5k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10299
14.5k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10300
14.5k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10301
14.5k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10302
14.5k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10303
14.5k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10304
14.5k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10305
14.5k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10306
14.5k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10307
14.5k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10308
14.5k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10309
14.5k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10310
14.5k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10311
14.5k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10312
14.5k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10313
14.5k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10314
14.5k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10315
14.5k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10316
14.5k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10317
14.5k
}
10318
10319
static void
10320
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10321
3.53k
{
10322
3.53k
    pdf14_clist_init_procs(dev,
10323
3.53k
                           gx_default_DevGray_get_color_mapping_procs,
10324
3.53k
                           gx_default_DevGray_get_color_comp_index);
10325
3.53k
}
10326
10327
static void
10328
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10329
9.08k
{
10330
9.08k
    pdf14_clist_init_procs(dev,
10331
9.08k
                           gx_default_DevRGB_get_color_mapping_procs,
10332
9.08k
                           gx_default_DevRGB_get_color_comp_index);
10333
9.08k
}
10334
10335
static void
10336
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10337
12
{
10338
12
    pdf14_clist_init_procs(dev,
10339
12
                           gx_default_DevCMYK_get_color_mapping_procs,
10340
12
                           gx_default_DevCMYK_get_color_comp_index);
10341
12
}
10342
10343
static void
10344
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10345
1.96k
{
10346
1.96k
    pdf14_clist_init_procs(dev,
10347
1.96k
                           pdf14_cmykspot_get_color_mapping_procs,
10348
1.96k
                           pdf14_cmykspot_get_color_comp_index);
10349
1.96k
}
10350
10351
static void
10352
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10353
0
{
10354
0
    pdf14_clist_init_procs(dev,
10355
0
                           pdf14_rgbspot_get_color_mapping_procs,
10356
0
                           pdf14_rgbspot_get_color_comp_index);
10357
0
}
10358
10359
#if 0 /* NOT USED */
10360
static int
10361
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10362
{
10363
    pdf14_clist_init_procs(dev,
10364
                           pdf14_grayspot_get_color_mapping_procs,
10365
                           pdf14_grayspot_get_color_comp_index);
10366
}
10367
#endif  /* NOT USED */
10368
10369
const pdf14_clist_device pdf14_clist_Gray_device = {
10370
    std_device_color_stype_body(pdf14_clist_device,
10371
                                pdf14_clist_Gray_initialize_device_procs,
10372
                                "pdf14clistgray",
10373
                                &st_pdf14_device,
10374
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10375
    { 0 },      /* Procs */
10376
    NULL,     /* target */
10377
    { 0 },      /* devn_params - not used */
10378
    &gray_pdf14_procs,
10379
    &gray_blending_procs
10380
};
10381
10382
const pdf14_clist_device pdf14_clist_RGB_device = {
10383
    std_device_color_stype_body(pdf14_clist_device,
10384
                                pdf14_clist_RGB_initialize_device_procs,
10385
                                "pdf14clistRGB",
10386
                                &st_pdf14_device,
10387
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10388
    { 0 },      /* Procs */
10389
    NULL,     /* target */
10390
    { 0 },      /* devn_params - not used */
10391
    &rgb_pdf14_procs,
10392
    &rgb_blending_procs
10393
};
10394
10395
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10396
    std_device_part1_(pdf14_device,
10397
                      pdf14_clist_RGBspot_initialize_device_procs,
10398
                      "pdf14clistrgbspot",
10399
                      &st_pdf14_device,
10400
                      open_init_closed),
10401
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10402
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10403
    offset_margin_values(0, 0, 0, 0, 0, 0),
10404
    std_device_part3_(),
10405
    { 0 },      /* Procs */
10406
    NULL,     /* target */
10407
    /* DeviceN parameters */
10408
    { 8,      /* Not used - Bits per color */
10409
      DeviceRGBComponents,  /* Names of color model colorants */
10410
      3,      /* Number colorants for CMYK */
10411
      0,      /* MaxSeparations has not been specified */
10412
      -1,     /* PageSpotColors has not been specified */
10413
      {0},      /* SeparationNames */
10414
      0,      /* SeparationOrder names */
10415
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10416
    },
10417
    &rgbspot_pdf14_procs,
10418
    &rgb_blending_procs
10419
};
10420
10421
const pdf14_clist_device pdf14_clist_CMYK_device = {
10422
    std_device_std_color_full_body_type(pdf14_clist_device,
10423
                                        pdf14_clist_CMYK_initialize_device_procs,
10424
                                        "pdf14clistcmyk",
10425
                                        &st_pdf14_device,
10426
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10427
                                        0, 0, 0, 0, 0, 0),
10428
    { 0 },      /* Procs */
10429
    NULL,     /* target */
10430
    { 0 },      /* devn_params - not used */
10431
    &cmyk_pdf14_procs,
10432
    &cmyk_blending_procs
10433
};
10434
10435
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10436
    std_device_part1_(pdf14_device,
10437
                      pdf14_clist_CMYKspot_initialize_device_procs,
10438
                      "pdf14clistcmykspot",
10439
                      &st_pdf14_device,
10440
                      open_init_closed),
10441
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10442
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10443
    offset_margin_values(0, 0, 0, 0, 0, 0),
10444
    std_device_part3_(),
10445
    { 0 },      /* Procs */
10446
    NULL,     /* target */
10447
    /* DeviceN parameters */
10448
    { 8,      /* Not used - Bits per color */
10449
      DeviceCMYKComponents, /* Names of color model colorants */
10450
      4,      /* Number colorants for CMYK */
10451
      0,      /* MaxSeparations has not been specified */
10452
      -1,     /* PageSpotColors has not been specified */
10453
      {0},      /* SeparationNames */
10454
      0,      /* SeparationOrder names */
10455
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10456
    },
10457
    &cmykspot_pdf14_procs,
10458
    &cmyk_blending_procs
10459
};
10460
10461
const pdf14_clist_device pdf14_clist_custom_device = {
10462
    std_device_part1_(pdf14_device,
10463
                      pdf14_clist_CMYKspot_initialize_device_procs,
10464
                      "pdf14clistcustom",
10465
                      &st_pdf14_device,
10466
                      open_init_closed),
10467
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10468
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10469
    offset_margin_values(0, 0, 0, 0, 0, 0),
10470
    std_device_part3_(),
10471
    { 0 },      /* Procs */
10472
    NULL,     /* target */
10473
    /* DeviceN parameters */
10474
    { 8,      /* Not used - Bits per color */
10475
      DeviceCMYKComponents, /* Names of color model colorants */
10476
      4,      /* Number colorants for CMYK */
10477
      0,      /* MaxSeparations has not been specified */
10478
      -1,     /* PageSpotColors has not been specified */
10479
      {0},      /* SeparationNames */
10480
      0,      /* SeparationOrder names */
10481
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10482
    },
10483
    &custom_pdf14_procs,
10484
    &custom_blending_procs
10485
};
10486
10487
/*
10488
 * the PDF 1.4 transparency spec says that color space for blending
10489
 * operations can be based upon either a color space specified in the
10490
 * group or a default value based upon the output device.  We are
10491
 * currently only using a color space based upon the device.
10492
 */
10493
static  int
10494
get_pdf14_clist_device_proto(gx_device          *dev,
10495
                             pdf14_clist_device *pdevproto,
10496
                             gs_gstate          *pgs,
10497
                       const gs_pdf14trans_t    *pdf14pct,
10498
                             bool                use_pdf14_accum)
10499
14.5k
{
10500
14.5k
    pdf14_blend_cs_t blend_cs_state;
10501
14.5k
    pdf14_default_colorspace_t dev_cs =
10502
14.5k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10503
14.5k
                                                 &blend_cs_state);
10504
14.5k
    bool deep = device_is_deep(dev);
10505
14.5k
    int num_spots = pdf14pct->params.num_spot_colors;
10506
10507
    /* overprint overide */
10508
14.5k
    if (pdf14pct->params.overprint_sim_push &&
10509
14.5k
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10510
0
        int has_tags = device_encodes_tags(dev);
10511
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10512
0
            dev_cs = PDF14_DeviceCMYKspot;
10513
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10514
0
        } else
10515
0
            dev_cs = PDF14_DeviceCMYK;
10516
0
    }
10517
10518
14.5k
    switch (dev_cs) {
10519
3.53k
        case PDF14_DeviceGray:
10520
           /* We want gray to be single channel.  Low level
10521
               initialization of gray device prototype is
10522
               peculiar in that in dci_std_color_num_components
10523
               the comment is
10524
              "A device is monochrome only if it is bi-level"
10525
              Here we want monochrome anytime we have a gray device.
10526
              To avoid breaking things elsewhere, we will overide
10527
              the prototype intialization here */
10528
3.53k
            *pdevproto = pdf14_clist_Gray_device;
10529
3.53k
            pdevproto->color_info.max_components = 1;
10530
3.53k
            pdevproto->color_info.num_components =
10531
3.53k
                                    pdevproto->color_info.max_components;
10532
3.53k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10533
3.53k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10534
3.53k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10535
3.53k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10536
3.53k
            pdevproto->color_info.depth = deep ? 16 : 8;
10537
3.53k
            pdevproto->sep_device = false;
10538
3.53k
            break;
10539
9.08k
        case PDF14_DeviceRGB:
10540
9.08k
            *pdevproto = pdf14_clist_RGB_device;
10541
9.08k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10542
9.08k
            pdevproto->sep_device = false;
10543
9.08k
            if (deep) {
10544
0
                pdevproto->color_info.depth = 3*16;
10545
0
                pdevproto->color_info.max_color = 65535;
10546
0
                pdevproto->color_info.max_gray = 65535;
10547
0
                pdevproto->color_info.dither_colors = 65536;
10548
0
                pdevproto->color_info.dither_grays = 65536;
10549
0
            }
10550
9.08k
            break;
10551
12
        case PDF14_DeviceCMYK:
10552
12
            *pdevproto = pdf14_clist_CMYK_device;
10553
12
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10554
12
            pdevproto->sep_device = false;
10555
12
            if (deep) {
10556
0
                pdevproto->color_info.depth = 4*16;
10557
0
                pdevproto->color_info.max_color = 65535;
10558
0
                pdevproto->color_info.max_gray = 65535;
10559
0
                pdevproto->color_info.dither_colors = 65536;
10560
0
                pdevproto->color_info.dither_grays = 65536;
10561
0
            }
10562
12
            break;
10563
1.96k
        case PDF14_DeviceCMYKspot:
10564
1.96k
            *pdevproto = pdf14_clist_CMYKspot_device;
10565
            /*
10566
             * The number of components for the PDF14 device is the sum
10567
             * of the process components and the number of spot colors
10568
             * for the page. If we are using an NCLR ICC profile at
10569
             * the output device, those spot colors are skipped. They
10570
             * do not appear in the transparency buffer, but appear
10571
             * during put image transform of the page group to the target
10572
             * color space.
10573
             */
10574
1.96k
            if (num_spots >= 0) {
10575
1.96k
                pdevproto->devn_params.page_spot_colors = num_spots;
10576
1.96k
                pdevproto->color_info.num_components =
10577
1.96k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10578
1.96k
                if (pdevproto->color_info.num_components >
10579
1.96k
                              pdevproto->color_info.max_components)
10580
0
                    pdevproto->color_info.num_components =
10581
0
                              pdevproto->color_info.max_components;
10582
1.96k
                pdevproto->color_info.depth =
10583
1.96k
                              pdevproto->color_info.num_components * (8<<deep);
10584
1.96k
            }
10585
1.96k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10586
1.96k
            pdevproto->sep_device = true;
10587
1.96k
            break;
10588
0
        case PDF14_DeviceRGBspot:
10589
0
            *pdevproto = pdf14_clist_RGBspot_device;
10590
            /*
10591
             * The number of components for the PDF14 device is the sum
10592
             * of the process components and the number of spot colors
10593
             * for the page. If we are using an NCLR ICC profile at
10594
             * the output device, those spot colors are skipped. They
10595
             * do not appear in the transparency buffer, but appear
10596
             * during put image transform of the page group to the target
10597
             * color space.
10598
             */
10599
0
            if (num_spots >= 0) {
10600
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10601
0
                pdevproto->color_info.num_components =
10602
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10603
0
                if (pdevproto->color_info.num_components >
10604
0
                    pdevproto->color_info.max_components)
10605
0
                    pdevproto->color_info.num_components =
10606
0
                        pdevproto->color_info.max_components;
10607
0
                pdevproto->color_info.depth =
10608
0
                    pdevproto->color_info.num_components * (8 << deep);
10609
0
            }
10610
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10611
0
            pdevproto->sep_device = true;
10612
0
            break;
10613
0
        case PDF14_DeviceCustom:
10614
            /*
10615
             * We are using the output device's process color model.  The
10616
             * color_info for the PDF 1.4 compositing device needs to match
10617
             * the output device.
10618
             */
10619
0
            *pdevproto = pdf14_clist_custom_device;
10620
0
            pdevproto->color_info = dev->color_info;
10621
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10622
0
            pdevproto->color_info.depth =
10623
0
                pdevproto->color_info.num_components * (8<<deep);
10624
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10625
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10626
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10627
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10628
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10629
0
            break;
10630
0
        default:      /* Should not occur */
10631
0
            return_error(gs_error_rangecheck);
10632
14.5k
    }
10633
14.5k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10634
14.5k
    pdevproto->blend_cs_state = blend_cs_state;
10635
14.5k
    return 0;
10636
14.5k
}
10637
10638
static  int
10639
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10640
                                gx_device ** ppdev, gx_device * target,
10641
                                const gs_pdf14trans_t * pdf14pct)
10642
14.5k
{
10643
14.5k
    pdf14_clist_device dev_proto;
10644
14.5k
    pdf14_clist_device * pdev;
10645
14.5k
    int code;
10646
14.5k
    bool has_tags = device_encodes_tags(target);
10647
14.5k
    cmm_profile_t *target_profile;
10648
14.5k
    gsicc_rendering_param_t render_cond;
10649
14.5k
    cmm_dev_profile_t *dev_profile;
10650
14.5k
    uchar k;
10651
14.5k
    bool deep = device_is_deep(target);
10652
14.5k
    cmm_profile_t *icc_profile;
10653
10654
10655
14.5k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10656
14.5k
    if (code < 0)
10657
0
        return code;
10658
14.5k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10659
14.5k
                          &render_cond);
10660
14.5k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10661
    /* Prototypes never include tags. We add those in later. */
10662
14.5k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10663
14.5k
                                        pgs, pdf14pct, false);
10664
14.5k
    if (code < 0)
10665
0
        return code;
10666
14.5k
    code = gs_copydevice((gx_device **) &pdev,
10667
14.5k
                         (const gx_device *) &dev_proto, mem);
10668
14.5k
    if (code < 0)
10669
0
        return code;
10670
10671
    /* If we are not using a blending color space, the number of color planes
10672
       should not exceed that of the target */
10673
14.5k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10674
14.5k
        if (pdev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10675
0
            pdev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10676
14.5k
        if (pdev->color_info.max_components > target->color_info.max_components)
10677
2.00k
            pdev->color_info.max_components = target->color_info.max_components;
10678
14.5k
    }
10679
14.5k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10680
14.5k
    pdev->pad = target->pad;
10681
14.5k
    pdev->log2_align_mod = target->log2_align_mod;
10682
10683
14.5k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10684
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10685
14.5k
    else
10686
14.5k
        pdev->num_planar_planes = target->num_planar_planes;
10687
14.5k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10688
10689
14.5k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10690
10691
14.5k
    if (deep) {
10692
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10693
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10694
0
    }
10695
    /* If we have a tag device then go ahead and do a special encoder decoder
10696
       for the pdf14 device to make sure we maintain this information in the
10697
       encoded color information.  We could use the target device's methods but
10698
       the PDF14 device has to maintain 8 bit color always and we could run
10699
       into other issues if the number of colorants became large.  If we need to
10700
       do compressed color with tags that will be a special project at that time */
10701
14.5k
    if (has_tags) {
10702
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10703
0
    }
10704
14.5k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10705
14.5k
    gx_device_fill_in_procs((gx_device *)pdev);
10706
    /* Copying the params adds the tags to the color_info if required. */
10707
14.5k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10708
14.5k
    gx_device_set_target((gx_device_forward *)pdev, target);
10709
10710
    /* Components shift, etc have to be based upon 8 bit */
10711
53.3k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10712
38.7k
        pdev->color_info.comp_bits[k] = 8<<deep;
10713
38.7k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10714
38.7k
    }
10715
14.5k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10716
14.5k
    if (code < 0)
10717
0
        return code;
10718
14.5k
    pdev->pclist_device = target;
10719
10720
14.5k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10721
14.5k
    if (code < 0)
10722
0
        return code;
10723
14.5k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10724
14.5k
        &render_cond);
10725
14.5k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10726
10727
    /* Simulated overprint case.  We have to use CMYK-based profile
10728
       Also if the target profile is NCLR, we are going to use a pdf14
10729
       device that is CMYK based and do the mapping to the NCLR profile
10730
       when the put_image occurs */
10731
14.5k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10732
14.5k
         icc_profile->data_cs == gsNCHANNEL) {
10733
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10734
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10735
0
            -1, "pdf14_create_clist_device");
10736
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10737
14.5k
    } else {
10738
        /* If the target profile was CIELAB, then overide with default RGB for
10739
           proper blending.  During put_image we will convert from RGB to
10740
           CIELAB */
10741
14.5k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10742
14.5k
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10743
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10744
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10745
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10746
0
        }
10747
14.5k
    }
10748
10749
14.5k
    if (pdf14pct->params.overprint_sim_push &&
10750
14.5k
        pdf14pct->params.num_spot_colors_int > 0) {
10751
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10752
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10753
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10754
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10755
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10756
0
    }
10757
    /* if the device has separations already defined (by SeparationOrderNames) */
10758
    /* we need to copy them (allocating new names) so the colorants are in the */
10759
    /* same order as the target device.                                        */
10760
14.5k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
10761
2.12k
        code = devn_copy_params(target, (gx_device *)pdev);
10762
2.12k
        if (code < 0)
10763
0
            return code;
10764
2.12k
    }
10765
14.5k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10766
14.5k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10767
14.5k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10768
14.5k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10769
14.5k
    pdev->color_info.separable_and_linear =
10770
14.5k
        target->color_info.separable_and_linear;
10771
14.5k
    *ppdev = (gx_device *) pdev;
10772
14.5k
    return code;
10773
14.5k
}
10774
10775
/*
10776
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10777
 * compositor device is never removed.  (We do not have a remove compositor
10778
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10779
 * routine implements that action.
10780
 */
10781
static  int
10782
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10783
                                gx_device * dev)
10784
14.1k
{
10785
14.1k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10786
14.1k
    gx_device * target = pdev->target;
10787
10788
14.1k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10789
10790
    /*
10791
     * To disable the action of this device, we forward all device
10792
     * procedures to the target except the composite and copy
10793
     * the target's color_info.
10794
     */
10795
14.1k
    dev->color_info = target->color_info;
10796
14.1k
    pdf14_forward_device_procs(dev);
10797
14.1k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10798
14.1k
    return 0;
10799
14.1k
}
10800
10801
/*
10802
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10803
 * compositor device is never removed.  (We do not have a remove compositor
10804
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10805
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10806
 * again.
10807
 */
10808
static  int
10809
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10810
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10811
0
{
10812
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10813
0
    gx_device * target = pdev->target;
10814
0
    pdf14_clist_device dev_proto;
10815
0
    int code;
10816
10817
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10818
    /*
10819
     * We will not use the entire prototype device but we will set the
10820
     * color related info to match the prototype.
10821
     */
10822
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10823
0
                                        pgs, pdf14pct, false);
10824
0
    if (code < 0)
10825
0
        return code;
10826
0
    pdev->color_info = dev_proto.color_info;
10827
0
    pdev->procs = dev_proto.procs;
10828
0
    pdev->pad = target->pad;
10829
0
    pdev->log2_align_mod = target->log2_align_mod;
10830
10831
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10832
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10833
0
    else
10834
0
        pdev->num_planar_planes = target->num_planar_planes;
10835
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10836
10837
0
    copy_tag_setup(dev, target);
10838
10839
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10840
0
    gx_device_fill_in_procs((gx_device *)pdev);
10841
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10842
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10843
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10844
0
    check_device_separable((gx_device *)pdev);
10845
0
    return code;
10846
0
}
10847
10848
/*
10849
 * devicen params
10850
 */
10851
gs_devn_params *
10852
pdf14_ret_devn_params(gx_device *pdev)
10853
3.57M
{
10854
3.57M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10855
10856
3.57M
    return &(p14dev->devn_params);
10857
3.57M
}
10858
10859
/*
10860
 * devicen params
10861
 */
10862
gs_devn_params *
10863
pdf14_accum_ret_devn_params(gx_device *pdev)
10864
0
{
10865
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10866
10867
0
    return &(p14dev->devn_params);
10868
0
}
10869
10870
static int
10871
pdf14_accum_get_color_comp_index(gx_device * dev,
10872
    const char * pname, int name_size, int component_type)
10873
0
{
10874
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10875
0
    gx_device *target = p14dev->target;
10876
0
    int colorant_number = devn_get_color_comp_index(dev,
10877
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10878
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10879
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10880
10881
0
    if (target != NULL)
10882
        /* colorant_number returned here _should_ be the same as from above */
10883
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10884
0
                              (target, (const char *)pname, name_size, component_type);
10885
0
    return colorant_number;
10886
0
}
10887
10888
/*
10889
 * The following procedures are used to map the standard color spaces into
10890
 * the separation color components for the pdf14_accum device.
10891
 */
10892
static void
10893
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10894
0
{
10895
0
    int * map =
10896
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10897
10898
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10899
0
}
10900
10901
static void
10902
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10903
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10904
0
{
10905
0
    int * map =
10906
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10907
10908
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10909
0
}
10910
10911
static void
10912
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10913
    frac c, frac m, frac y, frac k, frac out[])
10914
0
{
10915
0
    const int * map =
10916
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10917
10918
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10919
0
}
10920
10921
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10922
    pdf14_accum_gray_cs_to_cmyk_cm,
10923
    pdf14_accum_rgb_cs_to_cmyk_cm,
10924
    pdf14_accum_cmyk_cs_to_cmyk_cm
10925
};
10926
10927
static const gx_cm_color_map_procs *
10928
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10929
0
{
10930
0
    *map_dev = dev;
10931
0
    return &pdf14_accum_cm_procs;
10932
0
}
10933
10934
/*
10935
 *  Device proc for updating the equivalent CMYK color for spot colors.
10936
 */
10937
static int
10938
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10939
0
{
10940
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10941
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10942
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10943
0
                                              &pdev->equiv_cmyk_colors);
10944
10945
0
    if (code >= 0 && tdev != NULL)
10946
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10947
0
    return code;
10948
0
}
10949
10950
/* Used when doing overprint simulation and have spot colors */
10951
static int
10952
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10953
0
{
10954
0
    pdf14_device *pdev = (pdf14_device *)dev;
10955
0
    int code;
10956
10957
    /* Make sure we are not All or None */
10958
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10959
0
        pcs->params.separation.sep_type != SEP_OTHER)
10960
0
            return 0;
10961
10962
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10963
0
        &pdev->op_pequiv_cmyk_colors);
10964
0
    return code;
10965
0
}
10966
10967
/*
10968
 * Retrieve a list of spot color names for the PDF14 device.
10969
 */
10970
int
10971
put_param_pdf14_spot_names(gx_device * pdev,
10972
                gs_separations * pseparations, gs_param_list * plist)
10973
119k
{
10974
119k
    int code, num_spot_colors, i;
10975
119k
    gs_param_string str;
10976
10977
    /* Check if the given keyname is present. */
10978
119k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10979
119k
                                                &num_spot_colors);
10980
119k
    switch (code) {
10981
0
        default:
10982
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10983
0
            break;
10984
119k
        case 1:
10985
119k
            return 0;
10986
0
        case 0:
10987
0
            if (num_spot_colors < 1 ||
10988
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
10989
0
                return_error(gs_error_rangecheck);
10990
0
            for (i = 0; i < num_spot_colors; i++) {
10991
0
                char buff[20];
10992
0
                byte * sep_name;
10993
10994
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
10995
0
                code = param_read_string(plist, buff, &str);
10996
0
                switch (code) {
10997
0
                    default:
10998
0
                        param_signal_error(plist, buff, code);
10999
0
                        break;
11000
0
                    case 0:
11001
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11002
0
                                str.size, "put_param_pdf14_spot_names");
11003
0
                        if (sep_name == NULL)
11004
0
                            return_error(gs_error_VMerror);
11005
11006
0
                        memcpy(sep_name, str.data, str.size);
11007
0
                        pseparations->names[i].size = str.size;
11008
0
                        pseparations->names[i].data = sep_name;
11009
0
                }
11010
0
            }
11011
0
            pseparations->num_separations = num_spot_colors;
11012
0
            break;
11013
119k
    }
11014
0
    return 0;;
11015
0
}
11016
11017
/*
11018
 * This procedure will have information from the PDF 1.4 clist writing
11019
 * clist compositior device.  This is information output the compressed
11020
 * color list info which is needed for the support of spot colors in
11021
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11022
 * clist reading compositor.  However this device is not created until
11023
 * the clist is read.  To get this info to that device, we have to
11024
 * temporarily store that info in the output device.  This routine saves
11025
 * that info in the output device.
11026
 */
11027
int
11028
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11029
                                        gs_param_list * plist)
11030
119k
{
11031
119k
    int code;
11032
119k
    code = put_param_pdf14_spot_names(pdev,
11033
119k
                       &pdevn_params->pdf14_separations, plist);
11034
119k
    return code;
11035
119k
}
11036
11037
/*
11038
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11039
 * when we are creating the clist.  The second is for imaging the data from
11040
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11041
 * This routine is only called once the PDF 1.4 clist write compositor already
11042
 * exists.
11043
 */
11044
static  int
11045
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11046
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11047
    gx_device *cdev)
11048
3.26M
{
11049
3.26M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11050
3.26M
    int code, is_pdf14_compositor;
11051
3.26M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11052
3.26M
    bool deep = device_is_deep(dev);
11053
11054
    /* We only handle a few PDF 1.4 transparency operations */
11055
3.26M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11056
2.14M
        switch (pdf14pct->params.pdf14_op) {
11057
0
            case PDF14_PUSH_DEVICE:
11058
                /* Re-activate the PDF 1.4 compositor */
11059
0
                pdev->saved_target_color_info = pdev->target->color_info;
11060
0
                pdev->target->color_info = pdev->color_info;
11061
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11062
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11063
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11064
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11065
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11066
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11067
0
                pdev->saved_target_get_color_mapping_procs =
11068
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11069
0
                pdev->saved_target_get_color_comp_index =
11070
0
                                        dev_proc(pdev->target, get_color_comp_index);
11071
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11072
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11073
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11074
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11075
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11076
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11077
0
                gx_set_cmap_procs(pgs, dev);
11078
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11079
0
                pdev->blend_mode = pdev->text_knockout = 0;
11080
0
                pdev->opacity = pdev->shape = 0.0;
11081
0
                if (code < 0)
11082
0
                    return code;
11083
                /*
11084
                 * This routine is part of the PDF 1.4 clist write device.
11085
                 * Change the compositor procs to not create another since we
11086
                 * do not need to create a chain of identical devices.
11087
                 */
11088
0
                {
11089
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11090
11091
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11092
0
                    code = dev_proc(pdev->target, composite)
11093
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11094
                    /* We should never have created a new device here. */
11095
0
                    assert(code != 1);
11096
0
                    return code;
11097
0
                }
11098
14.1k
            case PDF14_POP_DEVICE:
11099
14.1k
            {
11100
14.1k
                gx_device *clistdev = pdev->target;
11101
11102
                /* Find the clist device */
11103
14.1k
                while (1) {
11104
14.1k
                    gxdso_device_child_request req;
11105
                    /* Ignore any errors here, that's expected as non-clist
11106
                     * devices don't implement it. */
11107
14.1k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11108
14.1k
                    if (code == 1)
11109
14.1k
                        break;
11110
0
                    req.n = 0;
11111
0
                    req.target = clistdev;
11112
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11113
0
                    if (code < 0)
11114
0
                        return code;
11115
0
                    clistdev = req.target;
11116
0
                }
11117
11118
                /* If we have overprint simulation spot color information, store
11119
                   it in a pseudo-band of the clist */
11120
14.1k
                if (pdev->overprint_sim &&
11121
14.1k
                    pdev->devn_params.page_spot_colors > 0) {
11122
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11123
0
                        &pdev->op_pequiv_cmyk_colors);
11124
0
                    if (code < 0)
11125
0
                        return code;
11126
0
                }
11127
11128
                /* If we hit an error during an SMask, we need to undo the color
11129
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11130
                 * for itself if it needs to take action.
11131
                 */
11132
14.1k
                pdf14_decrement_smask_color(pgs, dev);
11133
                /* Restore the color_info for the clist device */
11134
14.1k
                clistdev->color_info = pdev->saved_target_color_info;
11135
14.1k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11136
14.1k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11137
14.1k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11138
14.1k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11139
14.1k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11140
14.1k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11141
14.1k
                gx_set_cmap_procs(pgs, clistdev);
11142
14.1k
                gx_device_decache_colors(clistdev);
11143
                /* Disable the PDF 1.4 compositor */
11144
14.1k
                pdf14_disable_clist_device(mem, pgs, dev);
11145
                /*
11146
                 * Make sure that the transfer funtions, etc. are current.
11147
                 */
11148
14.1k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11149
14.1k
                if (code < 0)
11150
0
                    return code;
11151
14.1k
                break;
11152
14.1k
            }
11153
14.1k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11154
69.2k
            case PDF14_BEGIN_TRANS_GROUP:
11155
69.2k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11156
31.8k
                    pdev->depth_within_smask++;
11157
69.2k
                pdev->smask_constructed = 0;
11158
                /*
11159
                 * Keep track of any changes made in the blending parameters.
11160
                   These need to be written out in the same bands as the group
11161
                   information is written.  Hence the passing of the dimensions
11162
                   for the group. */
11163
69.2k
                code = pdf14_clist_update_params(pdev, pgs, true,
11164
69.2k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11165
69.2k
                if (code < 0)
11166
0
                    return code;
11167
69.2k
                if (pdf14pct->params.Background_components != 0 &&
11168
69.2k
                    pdf14pct->params.Background_components !=
11169
0
                    pdev->color_info.num_components)
11170
0
                    return_error(gs_error_rangecheck);
11171
11172
                /* We need to update the clist writer device procs based upon the
11173
                   the group color space. This ensures the proper color data is
11174
                   written out to the device. For simplicity, the list item is
11175
                   created even if the color space did not change */
11176
69.2k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11177
69.2k
                if (code < 0)
11178
0
                    return code;
11179
11180
69.2k
                break;
11181
70.7k
            case PDF14_BEGIN_TRANS_MASK:
11182
                /* We need to update the clist writer device procs based upon the
11183
                   the group color space.  For simplicity, the list item is created
11184
                   even if the color space did not change */
11185
                /* First store the current ones */
11186
70.7k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11187
38.6k
                    break;
11188
11189
                /* Update the color settings of the clist writer.  Store information in stack */
11190
32.0k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11191
32.0k
                if (code < 0)
11192
0
                    return code;
11193
11194
                /* Also, if the BC is a value that may end up as something other
11195
                  than transparent. We must use the parent colors bounding box in
11196
                  determining the range of bands in which this mask can affect.
11197
                  So, if needed change the masks bounding box at this time */
11198
32.0k
                pdev->in_smask_construction++;
11199
32.0k
                break;
11200
885k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11201
885k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11202
0
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11203
0
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11204
0
                } else
11205
885k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11206
885k
                *pcdev = dev;
11207
885k
                return 0; /* Never put into clist. Only used during writing */
11208
916k
            case PDF14_END_TRANS_TEXT_GROUP:
11209
916k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11210
913k
                    *pcdev = dev;
11211
913k
                    return 0; /* Avoids spurious ET calls in interpreter */
11212
913k
                }
11213
3.43k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11214
3.43k
                code = pdf14_clist_pop_color_model(dev, pgs);
11215
3.43k
                if (code < 0)
11216
0
                    return code;
11217
3.43k
                break;
11218
32.0k
            case PDF14_END_TRANS_MASK:
11219
32.0k
                pdev->in_smask_construction--;
11220
32.0k
                if (pdev->in_smask_construction < 0)
11221
0
                    pdev->in_smask_construction = 0;
11222
32.0k
                if (pdev->in_smask_construction == 0)
11223
31.9k
                    pdev->smask_constructed = 1;
11224
                /* fallthrough */
11225
97.8k
            case PDF14_END_TRANS_GROUP:
11226
                /* We need to update the clist writer device procs based upon the
11227
                   the group color space. */
11228
97.8k
                code = pdf14_clist_pop_color_model(dev, pgs);
11229
97.8k
                if (pdev->depth_within_smask)
11230
31.8k
                    pdev->depth_within_smask--;
11231
97.8k
                if (code < 0)
11232
0
                    return code;
11233
97.8k
                break;
11234
97.8k
            case PDF14_PUSH_TRANS_STATE:
11235
0
                break;
11236
31.2k
            case PDF14_POP_TRANS_STATE:
11237
31.2k
                break;
11238
32.0k
            case PDF14_PUSH_SMASK_COLOR:
11239
32.0k
                code = pdf14_increment_smask_color(pgs,dev);
11240
32.0k
                *pcdev = dev;
11241
32.0k
                return code;  /* Note, this are NOT put in the clist */
11242
0
                break;
11243
32.0k
            case PDF14_POP_SMASK_COLOR:
11244
32.0k
                code = pdf14_decrement_smask_color(pgs,dev);
11245
32.0k
                *pcdev = dev;
11246
32.0k
                return code;  /* Note, this are NOT put in the clist */
11247
0
                break;
11248
0
            case PDF14_SET_BLEND_PARAMS:
11249
                /* If there is a change we go ahead and apply it to the target */
11250
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11251
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11252
0
                *pcdev = dev;
11253
0
                return code;
11254
0
                break;
11255
0
            case PDF14_ABORT_DEVICE:
11256
0
                code = gx_abort_trans_device(pgs, dev);
11257
0
                if (pdev->free_devicen) {
11258
0
                    devn_free_params(dev);
11259
0
                }
11260
0
                pdf14_disable_device(dev);
11261
0
                pdf14_close(dev);
11262
0
                *pcdev = dev;
11263
0
                return code;
11264
0
                break;
11265
0
            default:
11266
0
                break;   /* Pass remaining ops to target */
11267
2.14M
        }
11268
2.14M
    }
11269
1.40M
    code = dev_proc(pdev->target, composite)
11270
1.40M
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11271
    /* If we were accumulating into a pdf14-clist-accum device, */
11272
    /* we now have to render the page into it's target device */
11273
1.40M
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11274
1.40M
        pdev->target->stype == &st_gx_devn_accum_device) {
11275
11276
6.02k
        int i, y, rows_used;
11277
6.02k
        byte *linebuf;
11278
6.02k
        byte *actual_data;
11279
6.02k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11280
        /* get the target device we want to send the image to */
11281
6.02k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11282
6.02k
        gs_image1_t image;
11283
6.02k
        gs_color_space *pcs;
11284
6.02k
        gx_image_enum_common_t *info = NULL;
11285
6.02k
        gx_image_plane_t planes;
11286
6.02k
        gsicc_rendering_param_t render_cond;
11287
6.02k
        cmm_dev_profile_t *dev_profile;
11288
6.02k
        bool save_planar = pdev->num_planar_planes;
11289
6.02k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11290
6.02k
        int save_num_separations;
11291
6.02k
        gs_int_rect rect;
11292
11293
6.02k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11294
6.02k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11295
6.02k
        pdev->num_planar_planes = save_planar;
11296
11297
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11298
         * colors do require devn support
11299
         */
11300
6.02k
        if (tdev->color_info.num_components <= 4 ||
11301
6.02k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11302
            /*
11303
             * Set color space in preparation for sending an image.
11304
             */
11305
6.02k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11306
6.02k
            if (code < 0)
11307
0
                goto put_accum_error;
11308
11309
            /* Need to set this to avoid color management during the
11310
               image color render operation.  Exception is for the special case
11311
               when the destination was CIELAB.  Then we need to convert from
11312
               default RGB to CIELAB in the put image operation.  That will happen
11313
               here as we should have set the profile for the pdf14 device to RGB
11314
               and the target will be CIELAB */
11315
6.02k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11316
6.02k
            if (code < 0)
11317
0
                goto put_accum_error;
11318
6.02k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11319
6.02k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11320
            /* pcs takes a reference to the profile data it just retrieved. */
11321
6.02k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11322
6.02k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11323
6.02k
        } else {
11324
             /* DeviceN case -- need to handle spot colors */
11325
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11326
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11327
0
            if (code < 0)
11328
0
                goto put_accum_error;
11329
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11330
0
            pcs->params.device_n.use_alt_cspace = false;
11331
11332
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11333
0
                goto put_accum_error;
11334
0
            }
11335
            /* One last thing -- we need to fudge the pgs->color_component_map */
11336
0
            for (i=0; i < tdev->color_info.num_components; i++)
11337
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11338
            /* copy devn_params that were accumulated into the target device's devn_params */
11339
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11340
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11341
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11342
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11343
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11344
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11345
0
            target_devn_params->separations = tdev->devn_params.separations;
11346
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11347
0
                   sizeof(gs_separation_map));
11348
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11349
0
        }
11350
6.02k
        if (linebuf == NULL) {
11351
0
            code = gs_error_VMerror;
11352
0
            goto put_accum_error;
11353
0
        }
11354
6.02k
        gs_image_t_init_adjust(&image, pcs, false);
11355
6.02k
        image.ImageMatrix.xx = (float)pdev->width;
11356
6.02k
        image.ImageMatrix.yy = (float)pdev->height;
11357
6.02k
        image.Width = pdev->width;
11358
6.02k
        image.Height = pdev->height;
11359
6.02k
        image.BitsPerComponent = 8<<deep;
11360
6.02k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11361
6.02k
        ctm_only_writable(pgs).xy = 0;
11362
6.02k
        ctm_only_writable(pgs).yx = 0;
11363
6.02k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11364
6.02k
        ctm_only_writable(pgs).tx = 0.0;
11365
6.02k
        ctm_only_writable(pgs).ty = 0.0;
11366
6.02k
        code = dev_proc(target, begin_typed_image) (target,
11367
6.02k
                                                    pgs, NULL,
11368
6.02k
                                                    (gs_image_common_t *)&image,
11369
6.02k
                                                    NULL, NULL, NULL,
11370
6.02k
                                                    pgs->memory, &info);
11371
6.02k
        if (code < 0)
11372
0
            goto put_accum_error;
11373
6.02k
        rect.p.x = 0;
11374
6.02k
        rect.q.x = tdev->width;
11375
13.1M
        for (y=0; y < tdev->height; y++) {
11376
13.1M
            gs_get_bits_params_t params;
11377
11378
13.1M
            params.options = (GB_ALIGN_ANY |
11379
13.1M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11380
13.1M
                              GB_OFFSET_0 |
11381
13.1M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11382
13.1M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11383
13.1M
            params.x_offset = 0;
11384
13.1M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11385
13.1M
            params.data[0] = linebuf;
11386
13.1M
            rect.p.y = y;
11387
13.1M
            rect.q.y = y+1;
11388
13.1M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11389
13.1M
                                                      &rect, &params);
11390
13.1M
            if (code < 0)
11391
5
                goto put_accum_error;
11392
13.1M
            actual_data = params.data[0];
11393
13.1M
            planes.data = actual_data;
11394
13.1M
            planes.data_x = 0;
11395
13.1M
            planes.raster = tdev->width * tdev->color_info.num_components;
11396
13.1M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11397
0
                goto put_accum_error;
11398
13.1M
        }
11399
11400
6.02k
put_accum_error:
11401
6.02k
        if (info != NULL) {
11402
6.02k
            if (code < 0)
11403
5
                (void)info->procs->end_image(info, true);
11404
6.02k
            else
11405
6.02k
                code = info->procs->end_image(info, true);
11406
6.02k
        }
11407
11408
6.02k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11409
        /* This will also decrement the device profile */
11410
6.02k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11411
6.02k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11412
        /* Now unhook the clist device and hook to the original so we can clean up */
11413
6.02k
        gx_device_set_target((gx_device_forward *)pdev,
11414
6.02k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11415
6.02k
        pdev->pclist_device = pdev->target;
11416
6.02k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11417
6.02k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11418
6.02k
        if (target_devn_params != NULL) {
11419
            /* prevent devn_free_params from freeing names still in use by target device */
11420
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11421
0
            tdev->devn_params.separations.num_separations = 0;
11422
0
        }
11423
6.02k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11424
6.02k
        if (target_devn_params != NULL) {
11425
0
            target_devn_params->separations.num_separations = save_num_separations;
11426
0
        }
11427
6.02k
        return code;    /* DON'T perform set_target */
11428
6.02k
    }
11429
1.40M
    if (code == 1) {
11430
        /* We just wrapped pdev->target, so we need to update that.*/
11431
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11432
0
        code = 0; /* We did not wrap dev. */
11433
0
    }
11434
1.40M
    *pcdev = dev;
11435
1.40M
    return code;
11436
1.40M
}
11437
11438
/*
11439
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11440
 * compositor' method.  However the compositor is disabled when we are not
11441
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11442
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11443
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11444
 * to the targer.
11445
 */
11446
static  int
11447
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11448
        const gs_composite_t * pct, gs_gstate * pgs,
11449
        gs_memory_t * mem, gx_device *cdev)
11450
0
{
11451
0
    pdf14_device *pdev = (pdf14_device *)dev;
11452
0
    gx_device * tdev = pdev->target;
11453
0
    gx_device * ndev;
11454
0
    int code;
11455
11456
0
    *pcdev = dev;
11457
0
    if (gs_is_pdf14trans_compositor(pct)) {
11458
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11459
11460
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11461
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11462
0
        return 0;
11463
0
    }
11464
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11465
0
    if (code == 1) {
11466
        /* We just wrapped tdev, so update our target. */
11467
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11468
0
        code = 0; /* We did not wrap dev. */
11469
0
    }
11470
0
    return code;
11471
0
}
11472
11473
/*
11474
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11475
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11476
 */
11477
static  int
11478
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11479
                          bool crop_blend_params,
11480
                          gs_pdf14trans_params_t *group_params)
11481
7.75M
{
11482
7.75M
    gs_pdf14trans_params_t params = { 0 };
11483
7.75M
    gx_device * pcdev;
11484
7.75M
    int changed = 0;
11485
7.75M
    int code = 0;
11486
7.75M
    gs_composite_t *pct_new = NULL;
11487
11488
7.75M
    params.crop_blend_params = crop_blend_params;
11489
11490
7.75M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11491
7.75M
    if (pgs->blend_mode != pdev->blend_mode) {
11492
26.6k
        changed |= PDF14_SET_BLEND_MODE;
11493
26.6k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11494
26.6k
    }
11495
7.75M
    if (pgs->text_knockout != pdev->text_knockout) {
11496
13.7k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11497
13.7k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11498
13.7k
    }
11499
7.75M
    if (pgs->alphaisshape != pdev->ais) {
11500
4.37k
        changed |= PDF14_SET_AIS;
11501
4.37k
        params.ais = pdev->ais = pgs->alphaisshape;
11502
4.37k
    }
11503
7.75M
    if (pgs->overprint != pdev->overprint) {
11504
25.6k
        changed |= PDF14_SET_OVERPRINT;
11505
25.6k
        params.overprint = pdev->overprint = pgs->overprint;
11506
25.6k
    }
11507
7.75M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11508
25.5k
        changed |= PDF14_SET_STROKEOVERPRINT;
11509
25.5k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11510
25.5k
    }
11511
7.75M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11512
49.3k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11513
49.3k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11514
49.3k
    }
11515
7.75M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11516
39.9k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11517
39.9k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11518
39.9k
    }
11519
7.75M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11520
80.0k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11521
80.0k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11522
80.0k
        if_debug0m('v', pgs->memory,
11523
80.0k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11524
80.0k
    }
11525
7.75M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11526
81.4k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11527
81.4k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11528
81.4k
        if_debug0m('v', pgs->memory,
11529
81.4k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11530
81.4k
    }
11531
7.75M
    if (crop_blend_params) {
11532
69.2k
        params.ctm = group_params->ctm;
11533
69.2k
        params.bbox = group_params->bbox;
11534
69.2k
    }
11535
7.75M
    params.changed = changed;
11536
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11537
       now to the target.  Otherwise we send the compositor action
11538
       to the pdf14 device at this time.  This is due to the fact that we
11539
       need to often perform this operation when we are already starting to
11540
       do a compositor action */
11541
7.75M
    if (changed != 0) {
11542
257k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11543
257k
        if (code < 0)
11544
0
            return code;
11545
257k
        code = dev_proc(pdev->target, composite)
11546
257k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11547
257k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11548
257k
    }
11549
7.75M
    return code;
11550
7.75M
}
11551
11552
/*
11553
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11554
 * writing the clist.
11555
 */
11556
static  int
11557
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11558
                           gx_path *ppath, const gx_fill_params *params,
11559
                           const gx_drawing_color *pdcolor,
11560
                           const gx_clip_path *pcpath)
11561
2.54M
{
11562
2.54M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11563
2.54M
    gs_gstate new_pgs = *pgs;
11564
2.54M
    int code;
11565
2.54M
    gs_pattern2_instance_t *pinst = NULL;
11566
2.54M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11567
2.54M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11568
2.54M
    gsicc_rendering_param_t render_cond;
11569
2.54M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11570
2.54M
    int push_group = 0;
11571
11572
2.54M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11573
2.54M
    if (code < 0)
11574
0
        return code;
11575
2.54M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11576
2.54M
    if (code < 0)
11577
0
        return code;
11578
11579
2.54M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11580
1.08k
        check_device_separable(dev);
11581
11582
2.54M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11583
2.54M
                          &render_cond);
11584
2.54M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11585
2.54M
                          &render_cond);
11586
11587
    /*
11588
     * Ensure that that the PDF 1.4 reading compositor will have the current
11589
     * blending parameters.  This is needed since the fill_rectangle routines
11590
     * do not have access to the gs_gstate.  Thus we have to pass any
11591
     * changes explictly.
11592
     */
11593
2.54M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11594
2.54M
    if (code < 0)
11595
0
        return code;
11596
    /* If we are doing a shading fill and we are in a transparency group of a
11597
       different color space, then we do not want to do the shading in the
11598
       device color space. It must occur in the source space.  To handle it in
11599
       the device space would require knowing all the nested transparency group
11600
       color space as well as the transparency.  Some of the shading code ignores
11601
       this, so we have to pass on the clist_writer device to enable proper
11602
       mapping to the transparency group color space. */
11603
11604
2.54M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11605
        /* Non-idempotent blends require a transparency
11606
         * group to be pushed because shadings might
11607
         * paint several pixels twice. */
11608
60.0k
        push_group = pgs->fillconstantalpha != 1.0 ||
11609
60.0k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11610
60.0k
        pinst =
11611
60.0k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11612
60.0k
           pinst->saved->has_transparency = true;
11613
           /* The transparency color space operations are driven by the pdf14
11614
              clist writer device.  */
11615
60.0k
           pinst->saved->trans_device = dev;
11616
60.0k
    }
11617
2.54M
    if (push_group) {
11618
2.72k
        gs_fixed_rect box;
11619
2.72k
        gs_fixed_rect dev_bbox;
11620
11621
2.72k
        if (pcpath) {
11622
2.72k
            gx_cpath_outer_box(pcpath, &box);
11623
2.72k
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11624
2.72k
            rect_intersect(box, dev_bbox);
11625
2.72k
        } else
11626
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11627
11628
2.72k
        if (ppath) {
11629
16
            gs_fixed_rect path_box;
11630
11631
16
            gx_path_bbox(ppath, &path_box);
11632
16
            if (box.p.x < path_box.p.x)
11633
16
                box.p.x = path_box.p.x;
11634
16
            if (box.p.y < path_box.p.y)
11635
16
                box.p.y = path_box.p.y;
11636
16
            if (box.q.x > path_box.q.x)
11637
16
                box.q.x = path_box.q.x;
11638
16
            if (box.q.y > path_box.q.y)
11639
16
                box.q.y = path_box.q.y;
11640
16
        }
11641
11642
2.72k
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11643
            /* No need to do anything */
11644
424
            if (pinst != NULL) {
11645
424
                pinst->saved->trans_device = NULL;
11646
424
            }
11647
424
            return 0;
11648
424
        }
11649
11650
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11651
2.30k
        code = push_shfill_group(pdev, &new_pgs, &box);
11652
2.30k
    } else
11653
2.54M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11654
2.54M
    if (code >= 0) {
11655
2.54M
        new_pgs.trans_device = dev;
11656
2.54M
        new_pgs.has_transparency = true;
11657
2.54M
        if (gx_dc_is_pattern2_color(pdcolor))
11658
59.6k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11659
2.48M
        else
11660
2.48M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11661
2.54M
        new_pgs.trans_device = NULL;
11662
2.54M
        new_pgs.has_transparency = false;
11663
2.54M
    }
11664
2.54M
    if (code >= 0 && push_group) {
11665
2.29k
        code = pop_shfill_group(&new_pgs);
11666
2.29k
        if (code >= 0)
11667
2.29k
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11668
2.29k
    }
11669
2.54M
    if (pinst != NULL){
11670
59.6k
        pinst->saved->trans_device = NULL;
11671
59.6k
    }
11672
2.54M
    return code;
11673
2.54M
}
11674
11675
/*
11676
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11677
 * writing the clist.
11678
 */
11679
static  int
11680
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11681
                             gx_path *ppath, const gx_stroke_params *params,
11682
                             const gx_drawing_color *pdcolor,
11683
                             const gx_clip_path *pcpath)
11684
630k
{
11685
630k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11686
630k
    gs_gstate new_pgs = *pgs;
11687
630k
    int code = 0;
11688
630k
    gs_pattern2_instance_t *pinst = NULL;
11689
630k
    int push_group = 0;
11690
11691
    /*
11692
     * Ensure that that the PDF 1.4 reading compositor will have the current
11693
     * blending parameters.  This is needed since the fill_rectangle routines
11694
     * do not have access to the gs_gstate.  Thus we have to pass any
11695
     * changes explictly.
11696
     */
11697
630k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11698
630k
    if (code < 0)
11699
0
        return code;
11700
    /* If we are doing a shading stroke and we are in a transparency group of a
11701
       different color space, then we need to get the proper device information
11702
       passed along so that we use the correct color procs and colorinfo about
11703
       the transparency device and not the final target device */
11704
630k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11705
        /* Non-idempotent blends require a transparency
11706
         * group to be pushed because shadings might
11707
         * paint several pixels twice. */
11708
180
        push_group = pgs->strokeconstantalpha != 1.0 ||
11709
180
               !blend_is_idempotent(gs_currentblendmode(pgs));
11710
180
        if (pdev->color_model_stack != NULL) {
11711
180
            pinst =
11712
180
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11713
180
            pinst->saved->has_transparency = true;
11714
            /* The transparency color space operations are driven
11715
              by the pdf14 clist writer device.  */
11716
180
            pinst->saved->trans_device = dev;
11717
180
        }
11718
180
    }
11719
630k
    if (push_group) {
11720
0
        gs_fixed_rect box;
11721
0
        if (pcpath)
11722
0
            gx_cpath_outer_box(pcpath, &box);
11723
0
        else
11724
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11725
0
        if (ppath) {
11726
0
            gs_fixed_rect path_box;
11727
0
            gs_fixed_point expansion;
11728
11729
0
            gx_path_bbox(ppath, &path_box);
11730
            /* Expand the path bounding box by the scaled line width. */
11731
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11732
                /* The expansion is so large it caused a limitcheck. */
11733
0
                path_box.p.x = path_box.p.y = min_fixed;
11734
0
                path_box.q.x = path_box.q.y = max_fixed;
11735
0
            } else {
11736
0
                expansion.x += pgs->fill_adjust.x;
11737
0
                expansion.y += pgs->fill_adjust.y;
11738
                /*
11739
                 * It's theoretically possible for the following computations to
11740
                 * overflow, so we need to check for this.
11741
                 */
11742
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11743
0
                                path_box.p.x - expansion.x);
11744
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11745
0
                                path_box.p.y - expansion.y);
11746
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11747
0
                                path_box.q.x + expansion.x);
11748
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11749
0
                                path_box.q.y + expansion.y);
11750
0
            }
11751
0
            if (box.p.x < path_box.p.x)
11752
0
                box.p.x = path_box.p.x;
11753
0
            if (box.p.y < path_box.p.y)
11754
0
                box.p.y = path_box.p.y;
11755
0
            if (box.q.x > path_box.q.x)
11756
0
                box.q.x = path_box.q.x;
11757
0
            if (box.q.y > path_box.q.y)
11758
0
                box.q.y = path_box.q.y;
11759
0
        }
11760
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11761
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11762
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11763
0
    } else
11764
630k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11765
11766
630k
    if (code >= 0) {
11767
630k
        new_pgs.trans_device = dev;
11768
630k
        new_pgs.has_transparency = true;
11769
630k
        if (gx_dc_is_pattern2_color(pdcolor))
11770
180
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11771
630k
        else
11772
630k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11773
630k
        new_pgs.trans_device = NULL;
11774
630k
        new_pgs.has_transparency = false;
11775
630k
    }
11776
630k
    if (code >= 0 && push_group) {
11777
0
        code = pop_shfill_group(&new_pgs);
11778
0
        if (code >= 0)
11779
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11780
0
    }
11781
630k
    if (pinst != NULL)
11782
180
        pinst->saved->trans_device = NULL;
11783
630k
    return code;
11784
630k
}
11785
11786
/* Set up work for doing shading patterns in fill stroke through
11787
   the clist.  We have to do all the dirty work now since we are
11788
   going through the default fill and stroke operations individually */
11789
static int
11790
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11791
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11792
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11793
    const gx_clip_path* pcpath)
11794
0
{
11795
0
    union {
11796
0
        const gs_gstate *cpgs;
11797
0
        gs_gstate *pgs;
11798
0
    } const_breaker;
11799
0
    gs_gstate *pgs;
11800
0
    int code, code2;
11801
0
    gs_transparency_group_params_t params = { 0 };
11802
0
    gs_fixed_rect clip_bbox;
11803
0
    gs_rect bbox, group_stroke_box;
11804
0
    float fill_alpha;
11805
0
    float stroke_alpha;
11806
0
    gs_blend_mode_t blend_mode;
11807
0
    gs_fixed_rect path_bbox;
11808
0
    int expansion_code;
11809
0
    gs_fixed_point expansion;
11810
11811
    /* Break const just once, neatly */
11812
0
    const_breaker.cpgs = cpgs;
11813
0
    pgs = const_breaker.pgs;
11814
11815
0
    fill_alpha = pgs->fillconstantalpha;
11816
0
    stroke_alpha = pgs->strokeconstantalpha;
11817
0
    blend_mode = pgs->blend_mode;
11818
11819
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11820
0
    if (code < 0 && code != gs_error_unknownerror)
11821
0
        return code;
11822
0
    if (code == gs_error_unknownerror) {
11823
        /* didn't get clip box from gx_curr_fixed_bbox */
11824
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11825
0
        clip_bbox.q.x = int2fixed(dev->width);
11826
0
        clip_bbox.q.y = int2fixed(dev->height);
11827
0
    }
11828
0
    if (pcpath)
11829
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11830
11831
    /* expand the ppath using stroke expansion rule, then intersect it */
11832
0
    code = gx_path_bbox(ppath, &path_bbox);
11833
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11834
0
        return 0;   /* ignore empty path */
11835
0
    if (code < 0)
11836
0
        return code;
11837
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11838
0
    if (expansion_code >= 0) {
11839
0
        path_bbox.p.x -= expansion.x;
11840
0
        path_bbox.p.y -= expansion.y;
11841
0
        path_bbox.q.x += expansion.x;
11842
0
        path_bbox.q.y += expansion.y;
11843
0
    }
11844
0
    rect_intersect(path_bbox, clip_bbox);
11845
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11846
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11847
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11848
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11849
11850
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11851
0
    if (code < 0)
11852
0
        return code;
11853
11854
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11855
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11856
0
        pgs->overprint && pgs->stroke_overprint &&
11857
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11858
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11859
11860
0
        params.Isolated = false;
11861
0
        params.group_color_type = UNKNOWN;
11862
0
        params.Knockout = false;
11863
0
        params.page_group = false;
11864
0
        params.group_opacity = fill_alpha;
11865
0
        params.group_shape = 1.0;
11866
11867
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11868
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11869
0
        if (code < 0)
11870
0
            return code;
11871
11872
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11873
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11874
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11875
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11876
11877
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11878
0
        if (code < 0)
11879
0
            goto cleanup;
11880
11881
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11882
0
        if (code < 0)
11883
0
            goto cleanup;
11884
11885
0
    } else {
11886
        /* Push a non-isolated knockout group. Do not change the alpha or
11887
           blend modes */
11888
0
        params.Isolated = false;
11889
0
        params.group_color_type = UNKNOWN;
11890
0
        params.Knockout = true;
11891
0
        params.page_group = false;
11892
0
        params.group_opacity = 1.0;
11893
0
        params.group_shape = 1.0;
11894
11895
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11896
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11897
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11898
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11899
11900
        /* restore blend mode for actual drawing in the group */
11901
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11902
11903
0
        if (fill_alpha > 0.0) {
11904
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11905
11906
            /* If we are in an overprint situation, set the blend mode to compatible
11907
               overprint */
11908
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11909
0
                pgs->overprint &&
11910
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11911
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11912
11913
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11914
0
            if (code < 0)
11915
0
                goto cleanup;
11916
11917
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11918
0
                pgs->overprint &&
11919
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11920
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11921
0
        }
11922
11923
0
        if (stroke_alpha > 0.0) {
11924
            /* Note that the stroke can end up looking like a fill here */
11925
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11926
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11927
11928
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11929
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11930
11931
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11932
0
            if (code < 0)
11933
0
                goto cleanup;
11934
11935
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11936
0
                pgs->overprint &&
11937
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11938
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11939
0
        }
11940
0
    }
11941
11942
0
cleanup:
11943
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11944
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11945
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11946
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11947
11948
    /* Restore where we were. If an error occured while in the group push
11949
       return that error code but try to do the cleanup */
11950
0
    code2 = gs_end_transparency_group(pgs);
11951
0
    if (code2 < 0) {
11952
        /* At this point things have gone very wrong. We should just shut down */
11953
0
        code = gs_abort_pdf14trans_device(pgs);
11954
0
        return code2;
11955
0
    }
11956
11957
    /* Restore if there were any changes */
11958
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11959
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11960
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11961
11962
0
    return code;
11963
0
}
11964
11965
/*
11966
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11967
 * writing the clist.
11968
 */
11969
static  int
11970
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11971
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11972
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11973
                             const gx_clip_path *pcpath)
11974
15.1k
{
11975
15.1k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11976
15.1k
    gs_gstate new_pgs = *pgs;
11977
15.1k
    int code;
11978
11979
15.1k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
11980
15.1k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
11981
108
        return 0;
11982
11983
    /*
11984
     * Ensure that that the PDF 1.4 reading compositor will have the current
11985
     * blending parameters.  This is needed since the fill_rectangle routines
11986
     * do not have access to the gs_gstate.  Thus we have to pass any
11987
     * changes explictly.
11988
     */
11989
15.0k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11990
15.0k
    if (code < 0)
11991
0
        return code;
11992
    /* If we are doing a shading fill or stroke, the clist can't
11993
       deal with this and end up in the pdf_fill_stroke operation.
11994
       We will need to break up the fill stroke now and do
11995
       the appropriate group pushes and set up. */
11996
11997
15.0k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
11998
15.0k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
11999
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12000
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12001
0
    }
12002
15.0k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12003
15.0k
    new_pgs.trans_device = dev;
12004
15.0k
    new_pgs.has_transparency = true;
12005
15.0k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12006
15.0k
                                       params_stroke, pdevc_stroke, pcpath);
12007
15.0k
    new_pgs.trans_device = NULL;
12008
15.0k
    new_pgs.has_transparency = false;
12009
15.0k
    return code;
12010
15.0k
}
12011
12012
/*
12013
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12014
 * writing the clist.
12015
 */
12016
static  int
12017
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12018
                 const gs_text_params_t * text, gs_font * font,
12019
                 const gx_clip_path * pcpath,
12020
                 gs_text_enum_t ** ppenum)
12021
4.40M
{
12022
4.40M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12023
4.40M
    gs_text_enum_t *penum;
12024
4.40M
    int code;
12025
4.40M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12026
4.40M
    float opacity = pgs->fillconstantalpha;
12027
4.40M
    float shape = 1.0;
12028
4.40M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12029
4.40M
    bool draw = !(text->operation & TEXT_DO_NONE);
12030
4.40M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12031
4.40M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12032
4.40M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12033
12034
4.40M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12035
    /*
12036
     * Ensure that that the PDF 1.4 reading compositor will have the current
12037
     * blending parameters.  This is needed since the fill_rectangle routines
12038
     * do not have access to the gs_gstate.  Thus we have to pass any
12039
     * changes explictly.
12040
     */
12041
4.40M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12042
4.40M
    if (code < 0)
12043
0
        return code;
12044
    /* Pass text_begin to the target */
12045
4.40M
    code = gx_forward_text_begin(dev, pgs, text, font,
12046
4.40M
                                 pcpath, &penum);
12047
4.40M
    if (code < 0)
12048
1.24k
        return code;
12049
12050
   /* Catch case where we already pushed a group and are trying to push another one.
12051
   In that case, we will pop the current one first, as we don't want to be left
12052
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12053
   will not be caught until we do the put_image and notice that the stack is not
12054
   empty. */
12055
4.40M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12056
0
        code = gs_end_transparency_group(pgs);
12057
0
        if (code < 0)
12058
0
            return code;
12059
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12060
0
    }
12061
12062
    /* We may need to push a non-isolated transparency group if the following
12063
    is true.
12064
    1) We are not currently in one that we pushed for text.  This is
12065
    is determined by looking at the pdf14 device.
12066
    2) The blend mode is not Normal or the opacity is not 1.0
12067
    3) Text knockout is set to true
12068
    4) And we are actually drawing text
12069
    */
12070
12071
4.40M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12072
4.40M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12073
4.40M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12074
4.40M
        text_mode != 3 && /* don't bother with invisible text */
12075
4.40M
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12076
3.45k
        if (draw) {
12077
3.45k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12078
3.45k
            if (code == 0)
12079
3.45k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12080
3.45k
        }
12081
3.45k
    }
12082
4.40M
    *ppenum = (gs_text_enum_t *)penum;
12083
4.40M
    return code;
12084
4.40M
}
12085
12086
static  int
12087
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12088
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12089
                           const gs_int_rect * prect,
12090
                           const gx_drawing_color * pdcolor,
12091
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12092
                           gx_image_enum_common_t ** pinfo)
12093
68.9k
{
12094
68.9k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12095
68.9k
    int code;
12096
68.9k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12097
68.9k
    const gs_image_t *pim = (const gs_image_t *)pic;
12098
68.9k
    gx_image_enum *penum;
12099
68.9k
    gx_color_tile *ptile;
12100
68.9k
    gs_rect bbox_in, bbox_out;
12101
68.9k
    gs_transparency_group_params_t tgp;
12102
    /*
12103
     * Ensure that that the PDF 1.4 reading compositor will have the current
12104
     * blending parameters.  This is needed since the fill_rectangle routines
12105
     * do not have access to the gs_gstate.  Thus we have to pass any
12106
     * changes explictly.
12107
     */
12108
68.9k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12109
68.9k
    if (code < 0)
12110
0
        return code;
12111
    /* Pass image to the target */
12112
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12113
       case the clist writer cannot handle this image itself.  In such a case,
12114
       we want to make sure we dont use the target device.  I don't necc. like
12115
       doing it this way.  Probably need to go back and do something a bit
12116
       more elegant. */
12117
68.9k
    pgs_noconst->has_transparency = true;
12118
68.9k
    pgs_noconst->trans_device = dev;
12119
12120
    /* If we are filling an image mask with a pattern that has a transparency
12121
       then we need to do some special handling */
12122
68.9k
    if (pim->ImageMask) {
12123
73
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12124
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12125
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12126
0
                    ptile = pdcolor->colors.pattern.p_tile;
12127
                    /* Set up things in the ptile so that we get the proper
12128
                       blending etc */
12129
                    /* Set the blending procs and the is_additive setting based
12130
                       upon the number of channels */
12131
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12132
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12133
0
                        ptile->ttrans->is_additive = true;
12134
0
                    } else {
12135
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12136
0
                        ptile->ttrans->is_additive = false;
12137
0
                    }
12138
                    /* Set the blending mode in the ptile based upon the current
12139
                       setting in the gs_gstate */
12140
0
                    ptile->blending_mode = pgs->blend_mode;
12141
                    /* Set the procs so that we use the proper filling method. */
12142
                    /* Let the imaging stuff get set up */
12143
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12144
0
                                                        prect, pdcolor,
12145
0
                                                        pcpath, mem, pinfo);
12146
0
                    if (code < 0)
12147
0
                        return code;
12148
12149
0
                    penum = (gx_image_enum *) *pinfo;
12150
                    /* Apply inverse of the image matrix to our
12151
                       image size to get our bounding box. */
12152
0
                    bbox_in.p.x = 0;
12153
0
                    bbox_in.p.y = 0;
12154
0
                    bbox_in.q.x = pim->Width;
12155
0
                    bbox_in.q.y = pim->Height;
12156
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12157
0
                                                     &bbox_out);
12158
0
                    if (code < 0)
12159
0
                        return code;
12160
                    /* Set up a compositor action for pushing the group */
12161
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12162
0
                    tgp.Isolated = true;
12163
0
                    tgp.Knockout = false;
12164
0
                    tgp.page_group = false;
12165
0
                    tgp.mask_id = 0;
12166
0
                    tgp.image_with_SMask = false;
12167
0
                    tgp.idle = false;
12168
0
                    tgp.iccprofile = NULL;
12169
0
                    tgp.icc_hashcode = 0;
12170
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12171
0
                    tgp.ColorSpace = NULL;
12172
0
                    tgp.text_group = 0;
12173
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12174
0
                    tgp.group_shape = 1.0;
12175
                    /* This will handle the compositor command */
12176
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12177
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12178
0
                    ptile->ttrans->image_render = penum->render;
12179
0
                    penum->render = &pdf14_pattern_trans_render;
12180
0
                    ptile->trans_group_popped = false;
12181
0
                    pgs_noconst->has_transparency = false;
12182
0
                    pgs_noconst->trans_device = NULL;
12183
0
                    return code;
12184
0
                }
12185
0
            }
12186
21
        }
12187
73
    }
12188
    /* This basically tries high level images for clist. If that fails
12189
       then we do the default */
12190
68.9k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12191
68.9k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12192
68.9k
    if (code < 0){
12193
18.7k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12194
18.7k
                                        pdcolor, pcpath, mem, pinfo);
12195
18.7k
        pgs_noconst->has_transparency = false;
12196
18.7k
        pgs_noconst->trans_device = NULL;
12197
18.7k
        return code;
12198
50.1k
    } else {
12199
50.1k
        pgs_noconst->has_transparency = false;
12200
50.1k
        pgs_noconst->trans_device = NULL;
12201
50.1k
        return code;
12202
50.1k
    }
12203
68.9k
}
12204
12205
static int
12206
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12207
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12208
2.45k
{
12209
2.45k
    int code;
12210
12211
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12212
2.45k
                                  x, y, w, h, plane_height);
12213
2.45k
    return code;
12214
2.45k
}
12215
12216
static int
12217
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12218
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12219
14.5k
{
12220
14.5k
    int code;
12221
14.5k
    pdf14_clist_device *p14dev;
12222
14.5k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12223
12224
14.5k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12225
14.5k
    if (code < 0)
12226
0
        return code;
12227
    /*
12228
     * Set the color_info of the clist device to match the compositing
12229
     * device.  We will restore it when the compositor is popped.
12230
     * See pdf14_clist_composite for the restore.  Do the
12231
     * same with the gs_gstate's get_cmap_procs.  We do not want
12232
     * the gs_gstate to use transfer functions on our color values.
12233
     * The transfer functions will be applied at the end after we
12234
     * have done our PDF 1.4 blend operations.
12235
     */
12236
14.5k
    p14dev = (pdf14_clist_device *)(*pcdev);
12237
14.5k
    p14dev->saved_target_color_info = dev->color_info;
12238
14.5k
    dev->color_info = (*pcdev)->color_info;
12239
    /* Make sure that we keep the anti-alias information though */
12240
14.5k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12241
14.5k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12242
12243
    /* adjust the clist_color_info now */
12244
14.5k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12245
14.5k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12246
14.5k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12247
14.5k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12248
14.5k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12249
12250
14.5k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12251
14.5k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12252
14.5k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12253
14.5k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12254
14.5k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12255
14.5k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12256
14.5k
    p14dev->saved_target_get_color_mapping_procs =
12257
14.5k
                              dev_proc(dev, get_color_mapping_procs);
12258
14.5k
    p14dev->saved_target_get_color_comp_index =
12259
14.5k
                              dev_proc(dev, get_color_comp_index);
12260
14.5k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12261
14.5k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12262
14.5k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12263
14.5k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12264
14.5k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12265
14.5k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12266
14.5k
    gx_set_cmap_procs(pgs, dev);
12267
14.5k
    return code;
12268
14.5k
}
12269
/*
12270
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12271
 * to create a compositing device for clist writing.  The primary purpose of
12272
 * this device is to provide support for the process color model in which
12273
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12274
 * model of the output device.)  The actual work of compositing the image is
12275
 * done on the output (reader) side of the clist.
12276
 */
12277
static  int
12278
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12279
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12280
558k
{
12281
558k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12282
558k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12283
558k
    int code = 0;
12284
12285
    /* We only handle the push/pop operations */
12286
558k
    switch (pdf14pct->params.pdf14_op) {
12287
14.5k
        case PDF14_PUSH_DEVICE:
12288
14.5k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12289
            /* Change (non-error) code to 1 to indicate that we created
12290
             * a device. */
12291
14.5k
            if (code >= 0)
12292
14.5k
                code = 1;
12293
14.5k
            return code;
12294
12295
14.1k
        case PDF14_POP_DEVICE:
12296
14.1k
            code = clist_writer_check_empty_cropping_stack(cdev);
12297
14.1k
            break;
12298
12299
5.76k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12300
69.2k
        case PDF14_BEGIN_TRANS_GROUP:
12301
69.2k
            { /* HACK: store mask_id into our params for subsequent
12302
                   calls of c_pdf14trans_write. To do this we must
12303
                   break const. */
12304
69.2k
                gs_pdf14trans_t * pdf14pct_noconst;
12305
12306
69.2k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12307
                /* What ever the current mask ID is, that is the
12308
                   softmask group through which this transparency
12309
                   group must be rendered. Store it now. */
12310
69.2k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12311
69.2k
                if_debug1m('v', pgs->memory,
12312
69.2k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12313
69.2k
                           cdev->mask_id);
12314
69.2k
            }
12315
69.2k
            break;
12316
65.7k
        case PDF14_END_TRANS_GROUP:
12317
69.1k
        case PDF14_END_TRANS_TEXT_GROUP:
12318
69.1k
            code = 0; /* A place for breakpoint. */
12319
69.1k
            break;
12320
70.7k
        case PDF14_BEGIN_TRANS_MASK:
12321
            /* A new mask has been started */
12322
70.7k
            cdev->mask_id = ++cdev->mask_id_count;
12323
            /* replacing is set everytime that we
12324
               have a zpushtransparencymaskgroup */
12325
70.7k
            { /* HACK: store mask_id into our params for subsequent
12326
                   calls of c_pdf14trans_write. To do this we must
12327
                   break const. */
12328
70.7k
                gs_pdf14trans_t * pdf14pct_noconst;
12329
12330
70.7k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12331
70.7k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12332
70.7k
                if_debug1m('v', pgs->memory,
12333
70.7k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12334
70.7k
                           cdev->mask_id);
12335
70.7k
            }
12336
70.7k
            break;
12337
32.0k
        case PDF14_END_TRANS_MASK:
12338
32.0k
            code = 0; /* A place for breakpoint. */
12339
32.0k
            break;
12340
0
        case PDF14_PUSH_TRANS_STATE:
12341
0
            code = 0; /* A place for breakpoint. */
12342
0
            break;
12343
31.2k
        case PDF14_POP_TRANS_STATE:
12344
31.2k
            code = 0; /* A place for breakpoint. */
12345
31.2k
            break;
12346
0
        case PDF14_ABORT_DEVICE:
12347
0
            code = 0;
12348
0
            break;
12349
0
        case PDF14_PUSH_SMASK_COLOR:
12350
0
            *pcdev = dev;
12351
0
            return 0;
12352
0
            break;
12353
0
        case PDF14_POP_SMASK_COLOR:
12354
0
            *pcdev = dev;
12355
0
            return 0;
12356
0
            break;
12357
257k
        default:
12358
257k
            break;   /* do nothing for remaining ops */
12359
558k
    }
12360
543k
    *pcdev = dev;
12361
543k
    if (code < 0)
12362
0
        return code;
12363
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12364
       apply_composite. */
12365
543k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12366
    /* Wrote an extra ctm. */
12367
543k
    cmd_clear_known(cdev, ctm_known);
12368
12369
543k
    return code;
12370
543k
}
12371
12372
/*
12373
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12374
 * device color_info data match the compositing device.  We need to do this
12375
 * since the PDF 1.4 transparency compositing device may use a different
12376
 * process color model than the output device.  We do not need to modify the
12377
 * color related device procs since the compositing device has its own.  We
12378
 * restore the color_info data when the transparency device is popped.
12379
 */
12380
static  int
12381
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12382
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12383
40.5M
{
12384
40.5M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12385
40.5M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12386
40.5M
    gs_devn_params * pclist_devn_params;
12387
40.5M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12388
40.5M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12389
40.5M
    gsicc_rendering_param_t render_cond;
12390
40.5M
    cmm_dev_profile_t *dev_profile;
12391
12392
40.5M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12393
40.5M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12394
40.5M
                          &render_cond);
12395
12396
    /* If we are using the blending color space, then be sure to use that. */
12397
40.5M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12398
40.5M
        dev_profile->blend_profile != NULL)
12399
0
        cl_icc_profile = dev_profile->blend_profile;
12400
40.5M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12401
40.5M
        dev_profile->oi_profile != NULL)
12402
0
        cl_icc_profile = dev_profile->oi_profile;
12403
12404
40.5M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12405
40.5M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12406
40.5M
                          &render_cond);
12407
    /*
12408
     * We only handle the push/pop operations. Save and restore the color_info
12409
     * field for the clist device.  This is needed since the process color
12410
     * model of the clist device needs to match the PDF 1.4 compositing
12411
     * device.
12412
     */
12413
40.5M
    switch (pdf14pct->params.pdf14_op) {
12414
1.70M
    case PDF14_PUSH_DEVICE:
12415
        /* Overprint simulation sets the profile at prototype creation, as does
12416
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12417
1.70M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12418
1.70M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12419
1.70M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12420
1.70M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12421
1.70M
                -1, "c_pdf14trans_clist_read_update");
12422
1.70M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12423
1.70M
        }
12424
            /*
12425
             * If we are blending using spot colors (i.e. the output device
12426
             * supports spot colors) then we need to transfer
12427
             * color info from the clist PDF 1.4 compositing reader device
12428
             * to the clist writer PDF 1.4 compositing device.
12429
             * This info was transfered from that device to the output
12430
             * device as a set of device parameters.  However the clist
12431
             * reader PDF 1.4 compositing device did not exist when the
12432
             * device parameters were read from the clist.  So that info
12433
             * was buffered into the output device.
12434
             */
12435
1.70M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12436
1.70M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12437
6.99k
                int num_comp = p14dev->color_info.num_components;
12438
6.99k
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12439
                /*
12440
                 * The number of components for the PDF14 device is the sum
12441
                 * of the process components and the number of spot colors
12442
                 * for the page.  If the color capabilities of the parent
12443
                 * device (which coming into this are the same as the p14dev)
12444
                 * are smaller than the number of page spot colors then
12445
                 * use that for the number of components. Otherwise use
12446
                 * the page_spot_colors.  The exception is, if we had used
12447
                 * the sICCOutputColors setting, then just use that, which
12448
                 * should be already baked into num_comp. With clist patterns,
12449
                 * cdev->icc_struct may be null.
12450
                 */
12451
12452
6.99k
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12453
6.99k
                    p14dev->devn_params.page_spot_colors =
12454
6.99k
                        pclist_devn_params->page_spot_colors;
12455
6.99k
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12456
0
                        if (p14dev->num_planar_planes > 0)
12457
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12458
0
                        p14dev->color_info.num_components = num_comp;
12459
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12460
6.99k
                    } else {
12461
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12462
6.99k
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12463
6.99k
                            int n = p14dev->num_std_colorants +
12464
6.99k
                                    p14dev->devn_params.page_spot_colors + has_tags;
12465
6.99k
                            if (p14dev->num_planar_planes > 0)
12466
6.99k
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12467
6.99k
                            p14dev->color_info.num_components = n;
12468
6.99k
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12469
6.99k
                        }
12470
6.99k
                    }
12471
6.99k
                }
12472
                /* limit the num_components to the max. */
12473
6.99k
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12474
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12475
                /* Transfer the data for the spot color names
12476
                   But we have to free what may be there before we do this */
12477
6.99k
                devn_free_params((gx_device*) p14dev);
12478
6.99k
                p14dev->devn_params.separations =
12479
6.99k
                    pclist_devn_params->pdf14_separations;
12480
6.99k
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12481
6.99k
                if (num_comp != p14dev->color_info.num_components) {
12482
                    /* Historically, there has been a comment here:
12483
                       "When the pdf14 device is opened it creates a context and some
12484
                       soft mask related objects.  The push device compositor action
12485
                       will have already created these but they are the wrong size.
12486
                       We must destroy them though before reopening the device."
12487
                       I can't see why this is the case, and testing in the cluster
12488
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12489
                       shows that this freeing/NULLing the ctx here causes problems
12490
                       when the freed ctx is reinserted at the end of clist pattern
12491
                       files. Accordingly, I'm removing the freeing/NULLing for now
12492
                       at least. */
12493
0
                    int code = dev_proc(tdev, open_device) (tdev);
12494
0
                    if (code < 0)
12495
0
                        return code;
12496
0
                }
12497
6.99k
            }
12498
            /* Check if we need to swap out the ICC profile for the pdf14
12499
               device.  This will occur if our source profile for our device
12500
               happens to be something like CIELAB.  Then we will blend in
12501
               RGB (unless a trans group is specified) */
12502
1.70M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12503
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12504
0
                                        -1, "c_pdf14trans_clist_read_update");
12505
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12506
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12507
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12508
                /* Keep a pointer to the clist device */
12509
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12510
0
            }
12511
1.70M
            break;
12512
12513
1.70M
        case PDF14_POP_DEVICE:
12514
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12515
                    the clist playback. This code is not executed while clist
12516
                    writing. */
12517
            cdev->color_info = p14dev->saved_target_color_info;
12518
#     endif
12519
1.70M
           break;
12520
12521
37.1M
        default:
12522
37.1M
            break;   /* do nothing for remaining ops */
12523
40.5M
    }
12524
12525
40.5M
    return 0;
12526
40.5M
}
12527
12528
/*
12529
 * Get cropping for the compositor command.
12530
 */
12531
static  int
12532
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12533
                          int cropping_min, int cropping_max)
12534
558k
{
12535
558k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12536
558k
    switch (pdf14pct->params.pdf14_op) {
12537
14.5k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12538
14.1k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12539
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12540
5.76k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12541
69.2k
        case PDF14_BEGIN_TRANS_GROUP:
12542
69.2k
            { gs_int_rect rect;
12543
12544
                /* Text group always uses parents size*/
12545
69.2k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12546
3.45k
                    *ry = cropping_min;
12547
3.45k
                    *rheight = cropping_max - *ry;
12548
65.7k
                } else {
12549
65.7k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12550
65.7k
                        &pdf14pct->params.bbox, &rect);
12551
                    /* We have to crop this by the parent object.   */
12552
65.7k
                    *ry = max(rect.p.y, cropping_min);
12553
65.7k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12554
65.7k
                }
12555
69.2k
                return PUSHCROP; /* Push cropping. */
12556
5.76k
            }
12557
70.7k
        case PDF14_BEGIN_TRANS_MASK:
12558
70.7k
            { gs_int_rect rect;
12559
12560
70.7k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12561
70.7k
                                                    &pdf14pct->params.bbox, &rect);
12562
                /* We have to crop this by the parent object and worry about the BC outside
12563
                   the range, except for image SMask which don't affect areas outside the image.
12564
                   The presence of a transfer function opens the possibility of issues with this */
12565
70.7k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12566
41.1k
                      pdf14pct->params.function_is_identity)) {
12567
                    /* In this case there will not be a background effect to
12568
                       worry about.  The mask will not have any effect outside
12569
                       the bounding box.  This is NOT the default or common case. */
12570
29.5k
                    *ry = max(rect.p.y, cropping_min);
12571
29.5k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12572
29.5k
                    return PUSHCROP; /* Push cropping. */
12573
41.1k
                }  else {
12574
                    /* We need to make the soft mask range as large as the parent
12575
                       due to the fact that the background color can have an impact
12576
                       OUTSIDE the bounding box of the soft mask */
12577
41.1k
                    *ry = cropping_min;
12578
41.1k
                    *rheight = cropping_max - cropping_min;
12579
41.1k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12580
38.6k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12581
2.49k
                    else
12582
2.49k
                        return PUSHCROP; /* Push cropping. */
12583
41.1k
                }
12584
70.7k
            }
12585
65.7k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12586
3.43k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12587
32.0k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12588
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12589
31.2k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12590
257k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12591
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12592
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12593
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12594
558k
    }
12595
0
    return ALLBANDS;
12596
558k
}
12597
12598
/*
12599
 * This routine will check to see if the color component name matches those
12600
 * that are available amoung the current device's color components.  If the
12601
 * color name is known to the output device then we add it to the list of
12602
 * colorants for the PDF 1.4 transparency compositor.
12603
 *
12604
 * Notes:  There are currently three different versions of The PDF 1.4
12605
 * transparency compositor device.  The choice of which one is being used
12606
 * depends upon the process color model of the output device.  This procedure
12607
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12608
 * plus spot color process color model.
12609
 *
12610
 * Parameters:
12611
 *   dev - pointer to device data structure.
12612
 *   pname - pointer to name (zero termination not required)
12613
 *   nlength - length of the name
12614
 *   number of process colorants (either 1, 3, or 4)
12615
 *
12616
 * This routine returns a positive value (0 to n) which is the device colorant
12617
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12618
 * the colorant is not being used due to a SeparationOrder device parameter.
12619
 * It returns a negative value if not found.
12620
 */
12621
static int
12622
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12623
    int name_size, int component_type, int num_process_colors, int cmyk)
12624
23.8k
{
12625
23.8k
    pdf14_device *pdev = (pdf14_device *)dev;
12626
23.8k
    gx_device *tdev = pdev->target;
12627
23.8k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12628
23.8k
    gs_separations *pseparations;
12629
23.8k
    int comp_index;
12630
23.8k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12631
23.8k
    int offset;
12632
12633
23.8k
    while (tdev->child) {
12634
0
        tdev = tdev->child;
12635
0
    }
12636
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12637
    /* get the devn_params from the target to avoid accessing using the wrong  */
12638
    /* pointer. Bug 696372.                                                    */
12639
23.8k
    if (tdev == (gx_device *)pdev)
12640
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12641
23.8k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12642
23.8k
    pseparations = &pdevn_params->separations;
12643
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12644
     * where we are in a blend color space that is RGB or Gray based and we
12645
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12646
     * Yellow or Black, then we should use the alternate tint transform */
12647
23.8k
    if (num_process_colors < 4) {
12648
756
        int k;
12649
3.78k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12650
3.02k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12651
0
                return -1;
12652
3.02k
        }
12653
756
    }
12654
12655
23.8k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12656
12657
    /* The pdf14_clist_composite may have set the color procs.
12658
       We need the real target procs, but not if we are doing simulated
12659
       overprint */
12660
23.8k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12661
23.8k
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index) &&
12662
23.8k
        !pdev->overprint_sim)
12663
23.8k
        target_get_color_comp_index =
12664
23.8k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12665
    /*
12666
    * If this is not a separation name then simply forward it to the target
12667
    * device or return -1 if we are doing overprint simulation.
12668
    * The halftone setup expects this.
12669
    */
12670
23.8k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12671
23.8k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12672
17.5k
            if (target_get_color_comp_index != NULL)
12673
17.5k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12674
0
            else
12675
0
                return -1;
12676
17.5k
    }
12677
6.30k
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12678
0
        return -1;
12679
0
    }
12680
12681
    /*
12682
    * Check if the component is in either the process color model list
12683
    * or in the SeparationNames list.
12684
    */
12685
6.30k
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12686
6.30k
        name_size, component_type);
12687
12688
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12689
     * This is a decision we take here to avoid problems with PDFI not
12690
     * counting such colorants as spots. */
12691
6.30k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12692
52
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12693
0
            return -1;
12694
52
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12695
0
            return -1;
12696
52
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12697
0
            return -1;
12698
52
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12699
0
            return -1;
12700
52
    }
12701
    /* A psdrgb device, with simulate overprint will have become a cmyk
12702
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12703
     * either, but we need to return real numbers for them as the underlying
12704
     * routine won't know about these. */
12705
6.30k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12706
2
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12707
0
            return 3;
12708
2
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12709
0
            return 0;
12710
2
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12711
0
            return 1;
12712
2
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12713
0
            return 2;
12714
2
    }
12715
12716
    /*
12717
    * Return the colorant number if we know this name.  Note adjustment for
12718
    * compensating of blend color space.
12719
    */
12720
6.30k
    if (comp_index >= 0)
12721
6.24k
        return comp_index - offset;
12722
12723
    /* Only worry about the target if we are not doing an overprint simulation */
12724
54
    if (!pdev->overprint_sim) {
12725
        /*
12726
        * If we do not know this color, check if the output (target) device does.
12727
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12728
        * the colorant so we will only get < 0 returned when we hit the max. for
12729
        * the target device.
12730
        */
12731
54
        if (target_get_color_comp_index != NULL)
12732
54
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12733
0
        else
12734
0
            return -1;
12735
        /*
12736
        * Ignore color if unknown to the output device or if color is not being
12737
        * imaged due to the SeparationOrder device parameter.
12738
        */
12739
54
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12740
0
            return comp_index - offset;
12741
54
    }
12742
12743
    /*
12744
    * This is a new colorant.  Add it to our list of colorants.
12745
    * The limit accounts for the number of process colors (at least 4).
12746
    */
12747
54
    if ((pseparations->num_separations + 1) <
12748
54
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12749
54
        int sep_num = pseparations->num_separations++;
12750
54
        int color_component_number;
12751
54
        byte * sep_name;
12752
12753
54
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12754
54
            name_size, "pdf14_spot_get_color_comp_index");
12755
54
        if (sep_name == NULL) {
12756
0
            pseparations->num_separations--;  /* we didn't add it */
12757
0
            return -1;
12758
0
        }
12759
54
        memcpy(sep_name, pname, name_size);
12760
54
        pseparations->names[sep_num].size = name_size;
12761
54
        pseparations->names[sep_num].data = sep_name;
12762
54
        color_component_number = sep_num + num_process_colors;
12763
54
        if (color_component_number >= dev->color_info.max_components)
12764
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12765
54
        else
12766
54
            pdevn_params->separation_order_map[color_component_number] =
12767
54
            color_component_number;
12768
12769
        /* Indicate that we need to find equivalent CMYK color. */
12770
54
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12771
54
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12772
12773
54
        return color_component_number;
12774
54
    }
12775
12776
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12777
54
}
12778
12779
12780
/* CMYK process + spots */
12781
static int
12782
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12783
    int name_size, int component_type)
12784
23.0k
{
12785
23.0k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12786
23.0k
}
12787
12788
/* RGB process + spots */
12789
static int
12790
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12791
    int name_size, int component_type)
12792
756
{
12793
756
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12794
756
}
12795
12796
/* Gray process + spots */
12797
static int
12798
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12799
    int name_size, int component_type)
12800
0
{
12801
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12802
0
}
12803
12804
/* These functions keep track of when we are dealing with soft masks.
12805
   In such a case, we set the default color profiles to ones that ensure
12806
   proper soft mask rendering. */
12807
static int
12808
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12809
46.1k
{
12810
46.1k
    pdf14_device * pdev = (pdf14_device *) dev;
12811
46.1k
    pdf14_smaskcolor_t *result;
12812
46.1k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12813
46.1k
    int k;
12814
12815
    /* See if we have profiles already in place.   Note we also have to
12816
       worry about a corner case where this device does not have a
12817
       smaskcolor stucture to store the profiles AND the profiles were
12818
       already swapped out in the icc_manager.  This can occur when we
12819
       pushed a transparency mask and then inside the mask we have a pattern
12820
       which also has a transparency mask.   The state of the icc_manager
12821
       is that it already has done the swap and there is no need to fool
12822
       with any of this while dealing with the soft mask within the pattern */
12823
46.1k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12824
46.1k
        pgs->icc_manager->smask_profiles->swapped) {
12825
0
            return 0;
12826
0
    }
12827
46.1k
    if (pdev->smaskcolor != NULL) {
12828
118
        pdev->smaskcolor->ref_count++;
12829
118
        if_debug1m(gs_debug_flag_icc, dev->memory,
12830
118
                   "[icc] Increment smask color now %d\n",
12831
118
                   pdev->smaskcolor->ref_count);
12832
45.9k
    } else {
12833
        /* Allocate and swap out the current profiles.  The softmask
12834
           profiles should already be in place */
12835
45.9k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12836
45.9k
                                &st_pdf14_smaskcolor,
12837
45.9k
                                "pdf14_increment_smask_color");
12838
45.9k
        if (result == NULL)
12839
0
            return gs_error_VMerror;
12840
12841
45.9k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12842
45.9k
        if (result->profiles == NULL)
12843
0
            return gs_error_VMerror;
12844
12845
45.9k
        pdev->smaskcolor = result;
12846
12847
45.9k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12848
45.9k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12849
45.9k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12850
45.9k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12851
45.9k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12852
45.9k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12853
45.9k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12854
45.9k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12855
45.9k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12856
45.9k
        pgs->icc_manager->smask_profiles->swapped = true;
12857
45.9k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12858
45.9k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12859
45.9k
        pdev->smaskcolor->ref_count = 1;
12860
        /* We also need to update the profile that is currently in the
12861
           color spaces of the graphic state.  Otherwise this can be
12862
           referenced, which will result in a mismatch.  What we want to do
12863
           is see if it was the original default and only swap in that case. */
12864
137k
        for (k = 0; k < 2; k++) {
12865
91.9k
            gs_color_space *pcs     = pgs->color[k].color_space;
12866
91.9k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12867
91.9k
            if (profile != NULL) {
12868
89.2k
                switch(profile->data_cs) {
12869
49.1k
                    case gsGRAY:
12870
49.1k
                        if (profile->hashcode ==
12871
49.1k
                            result->profiles->smask_gray->hashcode) {
12872
45.9k
                                profile = pgs->icc_manager->default_gray;
12873
45.9k
                        }
12874
49.1k
                        break;
12875
39.3k
                    case gsRGB:
12876
39.3k
                        if (profile->hashcode ==
12877
39.3k
                            result->profiles->smask_rgb->hashcode) {
12878
17.6k
                                profile = pgs->icc_manager->default_rgb;
12879
17.6k
                        }
12880
39.3k
                        break;
12881
727
                    case gsCMYK:
12882
727
                        if (profile->hashcode ==
12883
727
                            result->profiles->smask_cmyk->hashcode) {
12884
727
                                profile = pgs->icc_manager->default_cmyk;
12885
727
                        }
12886
727
                        break;
12887
0
                    default:
12888
12889
0
                        break;
12890
89.2k
                }
12891
89.2k
                if (pcs->cmm_icc_profile_data != profile) {
12892
64.2k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12893
64.2k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12894
64.2k
                    pcs->cmm_icc_profile_data = profile;
12895
64.2k
                }
12896
89.2k
            }
12897
91.9k
        }
12898
45.9k
    }
12899
46.1k
    return 0;
12900
46.1k
}
12901
12902
static int
12903
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12904
60.2k
{
12905
60.2k
    pdf14_device * pdev = (pdf14_device *) dev;
12906
60.2k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12907
60.2k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12908
60.2k
    int k;
12909
12910
    /* See comment in pdf14_increment_smask_color to understand this one */
12911
60.2k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12912
60.2k
        pgs->icc_manager->smask_profiles->swapped) {
12913
0
            return 0;
12914
0
    }
12915
60.2k
    if (smaskcolor != NULL) {
12916
46.1k
        smaskcolor->ref_count--;
12917
46.1k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12918
46.1k
                   "[icc] Decrement smask color.  Now %d\n",
12919
46.1k
                   smaskcolor->ref_count);
12920
46.1k
        if (smaskcolor->ref_count == 0) {
12921
45.9k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12922
            /* Lets return the profiles and clean up */
12923
            /* First see if we need to "reset" the profiles that are in
12924
               the graphic state */
12925
45.9k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12926
137k
            for (k = 0; k < 2; k++) {
12927
91.9k
                gs_color_space *pcs = pgs->color[k].color_space;
12928
91.9k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12929
91.9k
                if (profile != NULL) {
12930
89.2k
                    switch(profile->data_cs) {
12931
49.1k
                        case gsGRAY:
12932
49.1k
                            if (profile->hashcode ==
12933
49.1k
                                pgs->icc_manager->default_gray->hashcode) {
12934
45.9k
                                    profile =
12935
45.9k
                                        smaskcolor->profiles->smask_gray;
12936
45.9k
                            }
12937
49.1k
                            break;
12938
39.3k
                        case gsRGB:
12939
39.3k
                            if (profile->hashcode ==
12940
39.3k
                                pgs->icc_manager->default_rgb->hashcode) {
12941
17.6k
                                    profile =
12942
17.6k
                                        smaskcolor->profiles->smask_rgb;
12943
17.6k
                            }
12944
39.3k
                            break;
12945
727
                        case gsCMYK:
12946
727
                            if (profile->hashcode ==
12947
727
                                pgs->icc_manager->default_cmyk->hashcode) {
12948
727
                                    profile =
12949
727
                                        smaskcolor->profiles->smask_cmyk;
12950
727
                            }
12951
727
                            break;
12952
0
                        default:
12953
12954
0
                            break;
12955
89.2k
                    }
12956
89.2k
                    if (pcs->cmm_icc_profile_data != profile) {
12957
64.2k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12958
64.2k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12959
64.2k
                        pcs->cmm_icc_profile_data = profile;
12960
64.2k
                    }
12961
89.2k
                }
12962
91.9k
            }
12963
12964
45.9k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12965
45.9k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12966
45.9k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12967
45.9k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12968
45.9k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
12969
45.9k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
12970
45.9k
            icc_manager->smask_profiles->swapped = false;
12971
            /* We didn't increment the reference count when we assigned these
12972
             * so NULL them to avoid decrementing when smaskcolor is freed
12973
             */
12974
45.9k
            smaskcolor->profiles->smask_gray =
12975
45.9k
              smaskcolor->profiles->smask_rgb =
12976
45.9k
              smaskcolor->profiles->smask_cmyk = NULL;
12977
12978
45.9k
            pdf14_free_smask_color(pdev);
12979
45.9k
        }
12980
46.1k
    }
12981
60.2k
    return 0;
12982
60.2k
}
12983
12984
static void
12985
pdf14_free_smask_color(pdf14_device * pdev)
12986
45.9k
{
12987
45.9k
    if (pdev->smaskcolor != NULL) {
12988
45.9k
        if ( pdev->smaskcolor->profiles != NULL) {
12989
            /* Do not decrement the profiles - the references were moved
12990
               here and moved back again, so the ref counts don't change
12991
             */
12992
45.9k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
12993
45.9k
                        "pdf14_free_smask_color");
12994
45.9k
        }
12995
45.9k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
12996
45.9k
        pdev->smaskcolor = NULL;
12997
45.9k
    }
12998
45.9k
}
12999
13000
static void
13001
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13002
1.72M
{
13003
1.72M
    gx_device * const dev = (gx_device *)vptr;
13004
1.72M
    pdf14_device * pdev = (pdf14_device *)dev;
13005
1.72M
    int k;
13006
13007
1.72M
    pdf14_cleanup_group_color_profiles (pdev);
13008
13009
1.72M
    if (pdev->ctx) {
13010
36
        pdf14_ctx_free(pdev->ctx);
13011
36
        pdev->ctx = NULL;
13012
36
    }
13013
13014
1.72M
    while (pdev->color_model_stack) {
13015
21
        pdf14_pop_group_color(dev, NULL);
13016
21
    }
13017
13018
1.72M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13019
54
        if (pdev->devn_params.separations.names[k].data) {
13020
54
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13021
54
            pdev->devn_params.separations.names[k].data = NULL;
13022
54
        }
13023
54
    }
13024
13025
1.72M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13026
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13027
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13028
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13029
0
        }
13030
0
    }
13031
13032
1.72M
    gx_device_finalize(cmem, vptr);
13033
1.72M
}
13034
13035
#if DUMP_MASK_STACK
13036
13037
static void
13038
dump_mask_stack(pdf14_mask_t *mask_stack)
13039
{
13040
    pdf14_mask_t *curr_mask = mask_stack;
13041
    int level = 0;
13042
13043
    while (curr_mask != NULL) {
13044
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13045
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13046
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13047
        level++;
13048
        curr_mask = curr_mask->previous;
13049
    }
13050
}
13051
13052
/* A function to display the current state of the mask stack */
13053
static void
13054
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13055
{
13056
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13057
    if (ctx->mask_stack != NULL) {
13058
        dump_mask_stack(ctx->mask_stack);
13059
    }
13060
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13061
    if (ctx->stack != NULL) {
13062
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13063
        if (ctx->stack->mask_stack != NULL) {
13064
            dump_mask_stack(ctx->stack->mask_stack);
13065
        }
13066
    }
13067
}
13068
13069
#else
13070
13071
#ifdef DEBUG
13072
static void
13073
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13074
{
13075
    return;
13076
}
13077
#endif
13078
13079
#endif /* DUMP_MASK_STACK */