Coverage Report

Created: 2026-08-08 08:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
#include "gdevkrnlsclass.h"
74
75
#if RAW_DUMP
76
unsigned int global_index = 0;
77
unsigned int clist_band_count = 0;
78
#endif
79
80
#define DUMP_MASK_STACK 0
81
82
/* Static prototypes */
83
/* Used for filling rects when we are doing a fill with a pattern that
84
   has transparency */
85
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
86
                                   gx_path * ppath, const gx_fill_params * params,
87
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
88
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
89
static void pdf14_free_smask_color(pdf14_device * pdev);
90
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
91
                                         const gs_rect *pbbox, gs_gstate *pgs);
92
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
93
                                     const gs_gstate * pgs,
94
                                     bool crop_blend_params,
95
                                     gs_pdf14trans_params_t *group_params);
96
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
97
                                               int w, int h, gx_color_index color,
98
                                               const gx_device_color *pdc,
99
                                               bool devn);
100
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
101
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
102
                                  gx_color_index color, const gx_device_color *pdc,
103
                                  int depth, bool devn);
104
105
/* Functions for dealing with soft mask color */
106
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
107
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
108
109
/*
110
 * We chose the blending color space based upon the process color model of the
111
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
112
 * usually simple.  For other devices or if the user is doing custom color
113
 * processing then the user may want to control this choice.
114
 */
115
#define AUTO_USE_CUSTOM_BLENDING 0
116
#define ALWAYS_USE_CUSTOM_BLENDING 1
117
#define DO_NOT_USE_CUSTOM_BLENDING 2
118
119
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
120
121
# define INCR(v) DO_NOTHING
122
123
/* Forward prototypes */
124
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
125
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
126
                                gx_device ** pdev, gx_device * target,
127
                                const gs_pdf14trans_t * pdf14pct);
128
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
129
                                      gx_device ** pdev, gx_device * target,
130
                                      const gs_pdf14trans_t * pdf14pct);
131
static int pdf14_tile_pattern_fill(gx_device * pdev,
132
                const gs_gstate * pgs, gx_path * ppath,
133
                const gx_fill_params * params,
134
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    GS_OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    mask_buf, previous);
169
170
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
171
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
172
                    profiles);
173
174
/* ------ The device descriptors ------ */
175
176
/*
177
 * Default X and Y resolution.
178
 */
179
#define X_DPI 72
180
#define Y_DPI 72
181
182
static int pdf14_initialize_device(gx_device *dev);
183
184
static  int pdf14_open(gx_device * pdev);
185
static  dev_proc_close_device(pdf14_close);
186
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
187
static  dev_proc_put_params(pdf14_put_params);
188
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
189
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
190
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
191
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
192
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
193
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
194
dev_proc_encode_color(pdf14_encode_color);
195
dev_proc_encode_color(pdf14_encode_color_tag);
196
dev_proc_decode_color(pdf14_decode_color);
197
dev_proc_encode_color(pdf14_encode_color16);
198
dev_proc_encode_color(pdf14_encode_color16_tag);
199
dev_proc_decode_color(pdf14_decode_color16);
200
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
201
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
202
static  dev_proc_fill_path(pdf14_fill_path);
203
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
204
static  dev_proc_copy_mono(pdf14_copy_mono);
205
static  dev_proc_fill_mask(pdf14_fill_mask);
206
static  dev_proc_stroke_path(pdf14_stroke_path);
207
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
208
static  dev_proc_text_begin(pdf14_text_begin);
209
static  dev_proc_composite(pdf14_composite);
210
static  dev_proc_composite(pdf14_forward_composite);
211
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
212
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
213
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
214
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
215
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
216
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
217
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
218
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
219
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
220
static  dev_proc_copy_alpha(pdf14_copy_alpha);
221
static  dev_proc_copy_planes(pdf14_copy_planes);
222
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
223
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
224
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
225
static  const gx_color_map_procs *
226
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
227
228
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
229
#define YSIZE (int)(11 * Y_DPI)
230
231
/* 24-bit color. */
232
233
static void
234
pdf14_procs_initialize(gx_device *dev,
235
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
236
                       dev_proc_get_color_comp_index(get_color_comp_index),
237
                       dev_proc_encode_color(encode_color),
238
                       dev_proc_decode_color(decode_color))
239
4.61M
{
240
4.61M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
4.61M
    set_dev_proc(dev, open_device, pdf14_open);
242
4.61M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
4.61M
    set_dev_proc(dev, close_device, pdf14_close);
244
4.61M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
4.61M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
4.61M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
4.61M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
4.61M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
4.61M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
4.61M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
4.61M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
4.61M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
4.61M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
4.61M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
4.61M
    set_dev_proc(dev, composite, pdf14_composite);
256
4.61M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
4.61M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
4.61M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
4.61M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
4.61M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
4.61M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
4.61M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
4.61M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
4.61M
    set_dev_proc(dev, encode_color, encode_color);
265
4.61M
    set_dev_proc(dev, decode_color, decode_color);
266
4.61M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
4.61M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
4.61M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
4.61M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
4.61M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
4.61M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
4.61M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
4.61M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
4.61M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
4.61M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
4.61M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
4.61M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.49M
{
282
1.49M
    pdf14_procs_initialize(dev,
283
1.49M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.49M
                           gx_default_DevGray_get_color_comp_index,
285
1.49M
                           pdf14_encode_color,
286
1.49M
                           pdf14_decode_color);
287
1.49M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
2.66M
{
292
2.66M
    pdf14_procs_initialize(dev,
293
2.66M
                           gx_default_DevRGB_get_color_mapping_procs,
294
2.66M
                           gx_default_DevRGB_get_color_comp_index,
295
2.66M
                           pdf14_encode_color,
296
2.66M
                           pdf14_decode_color);
297
2.66M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
229k
{
302
229k
    pdf14_procs_initialize(dev,
303
229k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
229k
                           gx_default_DevCMYK_get_color_comp_index,
305
229k
                           pdf14_encode_color,
306
229k
                           pdf14_decode_color);
307
229k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
157k
{
312
157k
    pdf14_procs_initialize(dev,
313
157k
                           pdf14_cmykspot_get_color_mapping_procs,
314
157k
                           pdf14_cmykspot_get_color_comp_index,
315
157k
                           pdf14_encode_color,
316
157k
                           pdf14_decode_color);
317
157k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
58.5k
{
322
58.5k
    pdf14_procs_initialize(dev,
323
58.5k
                           pdf14_rgbspot_get_color_mapping_procs,
324
58.5k
                           pdf14_rgbspot_get_color_comp_index,
325
58.5k
                           pdf14_encode_color,
326
58.5k
                           pdf14_decode_color);
327
58.5k
}
328
329
static void
330
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           pdf14_grayspot_get_color_mapping_procs,
334
0
                           pdf14_grayspot_get_color_comp_index,
335
0
                           pdf14_encode_color,
336
0
                           pdf14_decode_color);
337
0
}
338
339
static void
340
pdf14_custom_initialize_device_procs(gx_device *dev)
341
0
{
342
0
    pdf14_procs_initialize(dev,
343
0
                           gx_forward_get_color_mapping_procs,
344
0
                           gx_forward_get_color_comp_index,
345
0
                           gx_forward_encode_color,
346
0
                           gx_forward_decode_color);
347
0
}
348
349
static struct_proc_finalize(pdf14_device_finalize);
350
351
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
352
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
353
                          pdf14_device_finalize);
354
355
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
356
                                                        gx_device * target);
357
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
358
                                                        gx_device * target);
359
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
362
/* Alter pdf14 device color model based upon group or softmask. This occurs
363
   post clist or in immediate rendering case. Data stored with buffer */
364
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
365
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
366
                              cmm_profile_t *iccprofile, bool is_mask);
367
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
368
369
/* Alter clist writer device color model based upon group or softmask. Data
370
   stored in the device color model stack */
371
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
372
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
373
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
374
375
/* Used for cleaning up the stack if things go wrong */
376
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
377
378
static const pdf14_procs_t gray_pdf14_procs = {
379
    pdf14_unpack_additive,
380
    pdf14_put_image,
381
    pdf14_unpack16_additive
382
};
383
384
static const pdf14_procs_t rgb_pdf14_procs = {
385
    pdf14_unpack_additive,
386
    pdf14_put_image,
387
    pdf14_unpack16_additive
388
};
389
390
static const pdf14_procs_t cmyk_pdf14_procs = {
391
    pdf14_unpack_subtractive,
392
    pdf14_put_image,
393
    pdf14_unpack16_subtractive
394
};
395
396
static const pdf14_procs_t cmykspot_pdf14_procs = {
397
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
398
    pdf14_cmykspot_put_image,
399
    pdf14_unpack16_custom /* should never be used since we will use devn values */
400
};
401
402
static const pdf14_procs_t rgbspot_pdf14_procs = {
403
    pdf14_unpack_rgb_mix,
404
    pdf14_cmykspot_put_image,
405
    pdf14_unpack16_rgb_mix
406
};
407
408
static const pdf14_procs_t grayspot_pdf14_procs = {
409
    pdf14_unpack_gray_mix,
410
    pdf14_cmykspot_put_image,
411
    pdf14_unpack16_gray_mix
412
};
413
414
static const pdf14_procs_t custom_pdf14_procs = {
415
    pdf14_unpack_custom,
416
    pdf14_custom_put_image,
417
    pdf14_unpack16_custom
418
};
419
420
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
421
    art_blend_luminosity_custom_8,
422
    art_blend_saturation_custom_8,
423
    art_blend_luminosity_custom_16,
424
    art_blend_saturation_custom_16
425
};
426
427
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
428
    art_blend_luminosity_rgb_8,
429
    art_blend_saturation_rgb_8,
430
    art_blend_luminosity_rgb_16,
431
    art_blend_saturation_rgb_16
432
};
433
434
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
435
    art_blend_luminosity_cmyk_8,
436
    art_blend_saturation_cmyk_8,
437
    art_blend_luminosity_cmyk_16,
438
    art_blend_saturation_cmyk_16
439
};
440
441
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
442
    art_blend_luminosity_rgb_8,
443
    art_blend_saturation_rgb_8,
444
    art_blend_luminosity_rgb_16,
445
    art_blend_saturation_rgb_16
446
};
447
448
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
449
    art_blend_luminosity_custom_8,
450
    art_blend_saturation_custom_8,
451
    art_blend_luminosity_custom_16,
452
    art_blend_saturation_custom_16
453
};
454
455
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
456
    art_blend_luminosity_custom_8,
457
    art_blend_saturation_custom_8,
458
    art_blend_luminosity_custom_16,
459
    art_blend_saturation_custom_16
460
};
461
462
const pdf14_device gs_pdf14_Gray_device = {
463
    std_device_std_color_full_body_type(pdf14_device,
464
                                        pdf14_Gray_initialize_device_procs,
465
                                        "pdf14gray",
466
                                        &st_pdf14_device,
467
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
468
                                        0, 0, 0, 0, 0, 0),
469
    { 0 },      /* Procs */
470
    NULL,     /* target */
471
    { 0 },      /* devn_params - not used */
472
    &gray_pdf14_procs,
473
    &gray_blending_procs,
474
    1
475
};
476
477
const pdf14_device gs_pdf14_RGB_device = {
478
    std_device_color_stype_body(pdf14_device,
479
                                pdf14_RGB_initialize_device_procs,
480
                                "pdf14RGB",
481
                                &st_pdf14_device,
482
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
483
    { 0 },      /* Procs */
484
    NULL,     /* target */
485
    { 0 },      /* devn_params - not used */
486
    &rgb_pdf14_procs,
487
    &rgb_blending_procs,
488
    3
489
};
490
491
const pdf14_device gs_pdf14_CMYK_device = {
492
    std_device_std_color_full_body_type(pdf14_device,
493
                                        pdf14_CMYK_initialize_device_procs,
494
                                        "pdf14cmyk",
495
                                        &st_pdf14_device,
496
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
497
                                        0, 0, 0, 0, 0, 0),
498
    { 0 },      /* Procs */
499
    NULL,     /* target */
500
    { 0 },      /* devn_params - not used */
501
    &cmyk_pdf14_procs,
502
    &cmyk_blending_procs,
503
    4
504
};
505
506
const pdf14_device gs_pdf14_CMYKspot_device = {
507
    std_device_part1_(pdf14_device,
508
                      pdf14_CMYKspot_initialize_device_procs,
509
                      "pdf14cmykspot",
510
                      &st_pdf14_device,
511
                      open_init_closed),
512
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
513
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
514
    offset_margin_values(0, 0, 0, 0, 0, 0),
515
    std_device_part3_(),
516
    { 0 },      /* Procs */
517
    NULL,     /* target */
518
    /* DeviceN parameters */
519
    { 8,      /* Not used - Bits per color */
520
      DeviceCMYKComponents, /* Names of color model colorants */
521
      4,      /* Number colorants for CMYK */
522
      0,      /* MaxSeparations has not been specified */
523
      -1,     /* PageSpotColors has not been specified */
524
      {0},      /* SeparationNames */
525
      0,      /* SeparationOrder names */
526
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
527
    },
528
    &cmykspot_pdf14_procs,
529
    &cmyk_blending_procs,
530
    4
531
};
532
533
const pdf14_device gs_pdf14_RGBspot_device = {
534
    std_device_part1_(pdf14_device,
535
                      pdf14_RGBspot_initialize_device_procs,
536
                      "pdf14rgbspot",
537
                      &st_pdf14_device,
538
                      open_init_closed),
539
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
540
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
541
    offset_margin_values(0, 0, 0, 0, 0, 0),
542
    std_device_part3_(),
543
    { 0 },      /* Procs */
544
    NULL,     /* target */
545
                    /* DeviceN parameters */
546
    { 8,      /* Not used - Bits per color */
547
    0,              /* Names of color model colorants */
548
    3,          /* Number colorants for RGB */
549
    0,          /* MaxSeparations has not been specified */
550
    -1,         /* PageSpotColors has not been specified */
551
    { 0 },      /* SeparationNames */
552
    0,          /* SeparationOrder names */
553
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
554
    },
555
    &rgbspot_pdf14_procs,
556
    &rgbspot_blending_procs,
557
    3
558
};
559
560
const pdf14_device gs_pdf14_Grayspot_device = {
561
    std_device_part1_(pdf14_device,
562
                      pdf14_Grayspot_initialize_device_procs,
563
                      "pdf14grayspot",
564
                      &st_pdf14_device,
565
                      open_init_closed),
566
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
567
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
568
    offset_margin_values(0, 0, 0, 0, 0, 0),
569
    std_device_part3_(),
570
    { 0 },      /* Procs */
571
    NULL,     /* target */
572
                    /* DeviceN parameters */
573
    { 8,      /* Not used - Bits per color */
574
    0,              /* Names of color model colorants */
575
    3,          /* Number colorants for RGB */
576
    0,          /* MaxSeparations has not been specified */
577
    -1,         /* PageSpotColors has not been specified */
578
    { 0 },      /* SeparationNames */
579
    0,          /* SeparationOrder names */
580
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
581
    },
582
    &grayspot_pdf14_procs,
583
    &grayspot_blending_procs,
584
    1
585
};
586
587
/*
588
 * The 'custom' PDF 1.4 compositor device is for working with those devices
589
 * which support spot colors but do not have a CMYK process color model.
590
 *
591
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
592
 * blending modes.  These blending modes are 'non separable' and depend upon
593
 * knowing the details of the blending color space.  However we use the
594
 * process color model of the output device for our blending color space.
595
 * With an unknown process color model, we have to fall back to some 'guesses'
596
 * about how to treat these blending modes.
597
 */
598
const pdf14_device gs_pdf14_custom_device = {
599
    std_device_part1_(pdf14_device,
600
                      pdf14_custom_initialize_device_procs,
601
                      "pdf14custom",
602
                      &st_pdf14_device,
603
                      open_init_closed),
604
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
605
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
606
    offset_margin_values(0, 0, 0, 0, 0, 0),
607
    std_device_part3_(),
608
    { 0 },      /* Procs */
609
    NULL,     /* target */
610
    /* DeviceN parameters */
611
    { 8,      /* Not used - Bits per color */
612
      DeviceCMYKComponents, /* Names of color model colorants */
613
      4,      /* Number colorants for CMYK */
614
      0,      /* MaxSeparations has not been specified */
615
      -1,     /* PageSpotColors has not been specified */
616
      {0},      /* SeparationNames */
617
      0,      /* SeparationOrder names */
618
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
619
    },
620
    &custom_pdf14_procs,
621
    &custom_blending_procs,
622
    4
623
};
624
625
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
626
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
627
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
628
629
static dev_proc_print_page(no_print_page);
630
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
631
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
632
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
633
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
634
635
static int
636
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
637
0
{
638
0
    return_error(gs_error_unknownerror);
639
0
}
640
641
struct gx_device_pdf14_accum_s {
642
    gx_devn_prn_device_common;
643
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
644
};
645
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
646
647
int
648
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
649
5.56M
{
650
5.56M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
5.56M
    if (dev_spec_op == gxdso_device_child) {
653
1.92k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
1.92k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
1.92k
        req->target = adev->save_p14dev;
657
1.92k
        req->n = 0;
658
1.92k
        return 0;
659
1.92k
    }
660
661
5.56M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
5.56M
}
663
664
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
665
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
666
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
667
668
static void
669
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
670
671
{
671
671
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
671
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
671
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
671
}
676
677
const gx_device_pdf14_accum pdf14_accum_Gray = {
678
    prn_device_stype_body(gx_device_pdf14_accum,
679
                          pdf14_accum_Gray_initialize_device_procs,
680
                          "pdf14-accum-Gray",
681
                          &st_gx_devn_accum_device,
682
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
683
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
684
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
685
                          256/*dither_grays*/, 0/*dither_colors*/,
686
                          no_print_page),
687
    { 0 },      /* devn_params - not used */
688
    { 0 },      /* equivalent_cmyk_color_params - not used */
689
    0/*save_p14dev*/
690
};
691
692
static void
693
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
694
2.57k
{
695
2.57k
    gdev_prn_initialize_device_procs_rgb(dev);
696
2.57k
}
697
698
const gx_device_pdf14_accum pdf14_accum_RGB = {
699
    prn_device_stype_body(gx_device_pdf14_accum,
700
                          pdf14_accum_RGB_initialize_device_procs,
701
                          "pdf14-accum-RGB",
702
                          &st_gx_devn_accum_device,
703
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
704
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
705
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
706
                          1/*dither_grays*/, 256/*dither_colors*/,
707
                          no_print_page),
708
    { 0 },      /* devn_params - not used */
709
    { 0 },      /* equivalent_cmyk_color_params - not used */
710
    0/*save_p14dev*/
711
};
712
713
static void
714
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
715
0
{
716
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
717
718
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
719
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
720
0
}
721
722
const gx_device_pdf14_accum pdf14_accum_CMYK = {
723
    prn_device_stype_body(gx_device_pdf14_accum,
724
                          pdf14_accum_CMYK_initialize_device_procs,
725
                          "pdf14-accum-CMYK",
726
                          &st_gx_devn_accum_device,
727
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
728
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
729
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
730
                          256/*dither_grays*/, 256/*dither_colors*/,
731
                          no_print_page),
732
    { 0 },      /* devn_params - not used */
733
    { 0 },      /* equivalent_cmyk_color_params - not used */
734
    0/*save_p14dev*/
735
};
736
737
static void
738
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
739
0
{
740
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
741
742
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
743
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
744
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
745
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
746
0
}
747
748
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
749
    prn_device_stype_body(gx_device_pdf14_accum,
750
                          pdf14_accum_initialize_device_procs_cmykspot,
751
                          "pdf14-accum-CMYKspot",
752
                          &st_gx_devn_accum_device,
753
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
754
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
755
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
756
                          256/*dither_grays*/, 256/*dither_colors*/,
757
                          no_print_page),
758
    /* DeviceN parameters */
759
    { 8,      /* Not used - Bits per color */
760
      DeviceCMYKComponents, /* Names of color model colorants */
761
      4,      /* Number colorants for CMYK */
762
      0,      /* MaxSeparations has not been specified */
763
      -1,     /* PageSpotColors has not been specified */
764
      { 0 },      /* SeparationNames */
765
      0,      /* SeparationOrder names */
766
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
767
    },
768
    { true },     /* equivalent_cmyk_color_params */
769
    0/*save_p14dev*/
770
};
771
772
/* GC procedures */
773
static
774
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
775
0
{
776
0
    index -= 5;
777
0
    if (index < pdev->devn_params.separations.num_separations)
778
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
779
0
    index -= pdev->devn_params.separations.num_separations;
780
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
781
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
782
0
    return 0;
783
0
}
784
0
case 0: return ENUM_OBJ(pdev->ctx);
785
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
786
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
787
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
788
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
789
0
ENUM_PTRS_END
790
791
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
792
0
{
793
0
    {
794
0
        int i;
795
796
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
797
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
798
0
        }
799
0
    }
800
0
    RELOC_VAR(pdev->ctx);
801
0
    RELOC_VAR(pdev->smaskcolor);
802
0
    RELOC_VAR(pdev->color_model_stack);
803
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
804
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
805
0
}
806
0
RELOC_PTRS_END
807
808
/* ------ Private definitions ------ */
809
810
static void
811
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
812
              int width, int height, cmm_profile_t *src_profile, int deep)
813
1.44k
{
814
1.44k
    if (deep) {
815
0
        int x, y, i;
816
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
817
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
818
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
819
820
0
        src_planestride >>= 1;
821
0
        src_rowstride >>= 1;
822
823
0
        for (y = 0; y < height; y++) {
824
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
825
0
            uint16_t *src_curr_ptr = src_row_ptr;
826
0
            for (x = 0; x < width; x++) {
827
0
                uint16_t idx = *mask_curr_ptr;
828
0
                byte     top = idx>>8;
829
0
                uint16_t a   = mask_tr_fn[top];
830
0
                int      b   = mask_tr_fn[top+1]-a;
831
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
832
833
                /* matte's happen rarely enough that we allow ourselves to
834
                 * resort to 64bit here. */
835
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
836
0
                    for (i = 0; i < src_profile->num_comps; i++) {
837
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
838
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
839
840
                        /* clip */
841
0
                        if (temp > 0xffff)
842
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
843
0
                        else if (temp < 0)
844
0
                            src_curr_ptr[i * src_planestride] = 0;
845
0
                        else
846
0
                            src_curr_ptr[i * src_planestride] = temp;
847
0
                    }
848
0
                }
849
0
                mask_curr_ptr++;
850
0
                src_curr_ptr++;
851
0
            }
852
0
            src_row_ptr += src_rowstride;
853
0
            mask_row_ptr += (maskbuf->rowstride>>1);
854
0
        }
855
1.44k
    } else {
856
1.44k
        int x, y, i;
857
1.44k
        byte *mask_row_ptr  = maskbuf->data;
858
1.44k
        byte *src_row_ptr   = src_data;
859
1.44k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
860
861
18.5k
        for (y = 0; y < height; y++) {
862
17.1k
            byte *mask_curr_ptr = mask_row_ptr;
863
17.1k
            byte *src_curr_ptr = src_row_ptr;
864
21.6M
            for (x = 0; x < width; x++) {
865
21.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
866
21.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
867
12.2M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
9.20M
                        byte matte = maskbuf->matte[i]>>8;
869
9.20M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
9.20M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
9.20M
                        if (temp > 0xff)
874
4.59M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
4.60M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
4.60M
                        else
878
4.60M
                            src_curr_ptr[i * src_planestride] = temp;
879
9.20M
                    }
880
3.06M
                }
881
21.6M
                mask_curr_ptr++;
882
21.6M
                src_curr_ptr++;
883
21.6M
            }
884
17.1k
            src_row_ptr += src_rowstride;
885
17.1k
            mask_row_ptr += maskbuf->rowstride;
886
17.1k
        }
887
1.44k
    }
888
1.44k
}
889
890
/* Transform of color data and copy noncolor data.  Used in
891
   group pop and during the pdf14 put image calls when the blend color space
892
   is different than the target device color space.  The function will try do
893
   in-place conversion if possible.  If not, it will do an allocation.  The
894
   put_image call needs to know if an allocation was made so that it can adjust
895
   for the fact that we likely don't have a full page any longer and we don't
896
   need to do the offset to our data in the buffer. Bug 700686: If we are in
897
   a softmask that includes a matte entry, then we need to undo the matte
898
   entry here at this time in the image's native color space not the parent
899
   color space.   The endian_swap term here is only set to true if the data
900
   has been baked as BE during the put_image blending operation and we are
901
   on a LE machine.  */
902
static forceinline pdf14_buf*
903
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
904
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
905
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
906
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
907
11.9k
{
908
11.9k
    gsicc_rendering_param_t rendering_params;
909
11.9k
    gsicc_link_t *icc_link;
910
11.9k
    gsicc_bufferdesc_t src_buff_desc;
911
11.9k
    gsicc_bufferdesc_t des_buff_desc;
912
11.9k
    intptr_t src_planestride = src_buf->planestride;
913
11.9k
    intptr_t src_rowstride = src_buf->rowstride;
914
11.9k
    int src_n_planes = src_buf->n_planes;
915
11.9k
    int src_n_chan = src_buf->n_chan;
916
11.9k
    intptr_t des_planestride = src_planestride;
917
11.9k
    intptr_t des_rowstride = src_rowstride;
918
11.9k
    int des_n_planes = src_n_planes;
919
11.9k
    int des_n_chan = src_n_chan;
920
11.9k
    int diff;
921
11.9k
    int k, j;
922
11.9k
    byte *des_data = NULL;
923
11.9k
    pdf14_buf *output = src_buf;
924
11.9k
    pdf14_mask_t *mask_stack;
925
11.9k
    pdf14_buf *maskbuf;
926
11.9k
    int code;
927
928
11.9k
    *did_alloc = false;
929
930
    /* Same profile */
931
11.9k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
932
0
        return src_buf;
933
934
    /* Define the rendering intent get the link */
935
11.9k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
936
11.9k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
937
11.9k
    rendering_params.override_icc = false;
938
11.9k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
939
11.9k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
940
11.9k
    rendering_params.cmm = gsCMM_DEFAULT;
941
11.9k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
942
11.9k
        &rendering_params, pgs->memory, false);
943
11.9k
    if (icc_link == NULL)
944
0
        return NULL;
945
946
    /* If different data sizes, we have to do an allocation */
947
11.9k
    diff = des_profile->num_comps - src_profile->num_comps;
948
11.9k
    if (diff != 0) {
949
11.4k
        byte *src_ptr;
950
11.4k
        byte *des_ptr;
951
952
11.4k
        *did_alloc = true;
953
11.4k
        des_rowstride = ((width + 3) & -4)<<deep;
954
11.4k
        des_planestride = height * des_rowstride;
955
11.4k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
11.4k
        des_n_chan = src_n_chan + diff;
957
11.4k
        des_data = gs_alloc_bytes(ctx->memory,
958
11.4k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
11.4k
                                  "pdf14_transform_color_buffer");
960
11.4k
        if (des_data == NULL)
961
0
            return NULL;
962
963
        /* Copy over the noncolor planes. May only be a dirty part, so have
964
           to copy row by row */
965
11.4k
        src_ptr = src_data;
966
11.4k
        des_ptr = des_data;
967
127k
        for (j = 0; j < height; j++) {
968
231k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
115k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
115k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
115k
                       width<<deep);
972
115k
            }
973
115k
            src_ptr += src_rowstride;
974
115k
            des_ptr += des_rowstride;
975
115k
        }
976
11.4k
    } else
977
446
        des_data = src_data;
978
979
    /* Set up the buffer descriptors. */
980
11.9k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
981
11.9k
                      false, true, src_planestride, src_rowstride, height, width);
982
11.9k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
983
11.9k
                      false, true, des_planestride, des_rowstride, height, width);
984
985
11.9k
    src_buff_desc.endian_swap = endian_swap;
986
11.9k
    des_buff_desc.endian_swap = endian_swap;
987
988
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
989
       context to ensure that this is not done again during the group
990
       composition */
991
11.9k
    if (has_matte &&
992
        /* Should always happen, but check for safety */
993
1.96k
        ((mask_stack = ctx->mask_stack) != NULL) &&
994
1.96k
        ((maskbuf = mask_stack->mask_buf) != NULL) &&
995
1.96k
         (maskbuf->data != NULL))
996
1.44k
    {
997
1.44k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
998
1.44k
    }
999
1000
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1001
       Gray buffers, this transform does not need to worry about the cmap procs
1002
       of the target device. */
1003
11.9k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1004
11.9k
        src_data, des_data);
1005
11.9k
    gsicc_release_link(icc_link);
1006
11.9k
    if (code < 0)
1007
0
        return NULL;
1008
1009
11.9k
    output->planestride = des_planestride;
1010
11.9k
    output->rowstride = des_rowstride;
1011
11.9k
    output->n_planes = des_n_planes;
1012
11.9k
    output->n_chan = des_n_chan;
1013
    /* If not in-place conversion, then release. */
1014
11.9k
    if (des_data != src_data) {
1015
11.4k
        gs_free_object(ctx->memory, output->data,
1016
11.4k
            "pdf14_transform_color_buffer");
1017
11.4k
        output->data = des_data;
1018
        /* Note, this is needed for case where we did a put image, as the
1019
           resulting transformed buffer may not be a full page. */
1020
11.4k
        output->rect.p.x = x0;
1021
11.4k
        output->rect.p.y = y0;
1022
11.4k
        output->rect.q.x = x0 + width;
1023
11.4k
        output->rect.q.y = y0 + height;
1024
11.4k
    }
1025
11.9k
    return output;
1026
11.9k
}
1027
1028
/* This is a routine to do memset's but with 16 bit values.
1029
 * Note, that we still take bytes, NOT "num values to set".
1030
 * We assume dest is 16 bit aligned. We assume that bytes is
1031
 * a multiple of 2. */
1032
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1033
0
{
1034
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1035
0
    uint32_t v;
1036
0
    if (bytes < 0)
1037
0
        return;
1038
0
    if (((intptr_t)dest) & 2) {
1039
0
        *dest++ = value;
1040
0
        bytes--;
1041
0
        if (bytes == 0)
1042
0
            return;
1043
0
    }
1044
0
    v = value | (value<<16);
1045
0
    bytes -= 2;
1046
0
    while (bytes > 0) {
1047
0
        *(uint32_t *)dest = v;
1048
0
        dest += 2;
1049
0
        bytes -= 4;
1050
0
    }
1051
0
    bytes += 2;
1052
0
    if (bytes & 2) {
1053
0
        *dest = value;
1054
0
    }
1055
0
}
1056
1057
static pdf14_buf*
1058
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1059
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1060
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1061
    bool deep, bool endian_swap, int num_channels_to_lose)
1062
9.95k
{
1063
9.95k
    if (deep)
1064
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1065
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1066
9.95k
    else
1067
9.95k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
9.95k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
9.95k
}
1070
1071
static pdf14_buf*
1072
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1073
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1074
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1075
    bool deep, bool endian_swap)
1076
1.96k
{
1077
1.96k
    if (deep)
1078
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1079
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1080
1.96k
    else
1081
1.96k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1082
1.96k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1083
1.96k
}
1084
1085
/**
1086
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1087
 * @n_chan: Number of pixel channels including alpha, but not including
1088
 * shape, group alpha, or tags.
1089
 *
1090
 * Return value: Newly allocated buffer, or NULL on failure.
1091
 **/
1092
static  pdf14_buf *
1093
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1094
              bool has_shape, bool idle, int n_chan, int num_spots,
1095
              gs_memory_t *memory, bool deep)
1096
3.05M
{
1097
1098
    /* Note that alpha_g is the alpha for the GROUP */
1099
    /* This is distinct from the alpha that may also exist */
1100
    /* for the objects within the group.  Hence it can introduce */
1101
    /* yet another plane */
1102
1103
3.05M
    pdf14_buf *result;
1104
3.05M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
3.05M
    int64_t height = (rect->q.y - rect->p.y);
1106
3.05M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
3.05M
                   (has_tags ? 1 : 0);
1108
3.05M
    size_t planestride;
1109
#if ARCH_SIZEOF_SIZE_T <= 4
1110
    int64_t dsize = rowstride * height * n_planes;
1111
1112
    if (dsize > max_size_t)
1113
        return NULL;
1114
#endif
1115
1116
3.05M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
3.05M
                             "pdf14_buf_new");
1118
3.05M
    if (result == NULL)
1119
0
        return result;
1120
1121
3.05M
    result->memory = memory;
1122
3.05M
    result->backdrop = NULL;
1123
3.05M
    result->saved = NULL;
1124
3.05M
    result->isolated = false;
1125
3.05M
    result->knockout = false;
1126
3.05M
    result->has_alpha_g = has_alpha_g;
1127
3.05M
    result->has_shape = has_shape;
1128
3.05M
    result->has_tags = has_tags;
1129
3.05M
    result->rect = *rect;
1130
3.05M
    result->n_chan = n_chan;
1131
3.05M
    result->n_planes = n_planes;
1132
3.05M
    result->rowstride = rowstride;
1133
3.05M
    result->transfer_fn = NULL;
1134
3.05M
    result->is_ident = true;
1135
3.05M
    result->matte_num_comps = 0;
1136
3.05M
    result->matte = NULL;
1137
3.05M
    result->mask_stack = NULL;
1138
3.05M
    result->idle = idle;
1139
3.05M
    result->mask_id = 0;
1140
3.05M
    result->num_spots = num_spots;
1141
3.05M
    result->deep = deep;
1142
3.05M
    result->page_group = false;
1143
3.05M
    result->group_color_info = NULL;
1144
3.05M
    result->group_popped = false;
1145
1146
3.05M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.43M
        result->planestride = 0;
1149
1.43M
        result->data = 0;
1150
1.61M
    } else {
1151
1.61M
        planestride = rowstride * height;
1152
1.61M
        result->planestride = planestride;
1153
1.61M
        result->data = gs_alloc_bytes(memory,
1154
1.61M
                                      planestride * n_planes + CAL_SLOP,
1155
1.61M
                                      "pdf14_buf_new");
1156
1.61M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.61M
        if (has_alpha_g) {
1161
378k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
378k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
378k
        }
1165
1.61M
        if (has_tags) {
1166
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
0
            memset (result->data + tags_plane * planestride,
1169
0
                    GS_UNTOUCHED_TAG, planestride);
1170
0
        }
1171
1.61M
    }
1172
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1173
     * Any future drawing will make it valid again, so we won't blend back
1174
     * more than we need. */
1175
3.05M
    result->dirty.p.x = rect->q.x;
1176
3.05M
    result->dirty.p.y = rect->q.y;
1177
3.05M
    result->dirty.q.x = rect->p.x;
1178
3.05M
    result->dirty.q.y = rect->p.y;
1179
3.05M
    return result;
1180
3.05M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
3.05M
{
1185
3.05M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
3.05M
    gs_memory_t *memory = buf->memory;
1187
1188
3.05M
    if (buf->mask_stack)
1189
3.05M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
3.05M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
3.05M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
3.05M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
6.11M
    while (group_color_info) {
1196
3.05M
       if (group_color_info->icc_profile != NULL) {
1197
3.05M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
3.05M
       }
1199
3.05M
       buf->group_color_info = group_color_info->previous;
1200
3.05M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
3.05M
       group_color_info = buf->group_color_info;
1202
3.05M
    }
1203
1204
3.05M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
3.05M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
3.05M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
1.01M
{
1211
1.01M
    pdf14_ctx *result;
1212
1.01M
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
1.01M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
1.01M
    if (result == NULL)
1216
0
        return result;
1217
1.01M
    result->stack = NULL;
1218
1.01M
    result->mask_stack = pdf14_mask_element_new(memory);
1219
1.01M
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
1.01M
    result->memory = memory;
1224
1.01M
    result->smask_depth = 0;
1225
1.01M
    result->smask_blend = false;
1226
1.01M
    result->deep = deep;
1227
1.01M
    result->base_color = NULL;
1228
1.01M
    return result;
1229
1.01M
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
1.01M
{
1234
1.01M
    pdf14_buf *buf, *next;
1235
1236
1.01M
    if (ctx->base_color) {
1237
523k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
523k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
523k
    }
1240
1.01M
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
493k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
493k
    }
1244
1.86M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
856k
        next = buf->saved;
1246
856k
        pdf14_buf_free(buf);
1247
856k
    }
1248
1.01M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
1.01M
}
1250
1251
/**
1252
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1253
 *
1254
 * Return value: Backdrop buffer for current group operation, or NULL
1255
 * if backdrop is fully transparent.
1256
 **/
1257
static  pdf14_buf *
1258
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1259
910k
{
1260
    /* Our new buffer is buf */
1261
910k
    pdf14_buf *buf = ctx->stack;
1262
1263
910k
    *is_backdrop = false;
1264
1265
910k
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
910k
        if (buf->isolated) return NULL;
1268
1269
        /* If the previous buffer is a knockout group
1270
           then we need to use its backdrop as the backdrop. If
1271
           it was isolated then that back drop was NULL */
1272
378k
        if (buf->saved != NULL && buf->saved->knockout) {
1273
            /* Per the spec, if we have a non-isolated group
1274
               in a knockout group the non-isolated group
1275
               uses the backdrop of its parent group (the knockout group)
1276
               as its own backdrop.  The non-isolated group must
1277
               go through the standard re-composition operation
1278
               to avoid the double application of the backdrop */
1279
14
            *is_backdrop = true;
1280
14
            return buf->saved;
1281
14
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
378k
        if (buf->saved != NULL) {
1285
378k
            return buf->saved;
1286
378k
        }
1287
378k
    }
1288
0
    return NULL;
1289
910k
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
523k
{
1294
523k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
523k
    pdf14_group_color_t* group_color;
1296
523k
    bool deep = pdev->ctx->deep;
1297
523k
    bool has_tags = device_encodes_tags(dev);
1298
1299
523k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
523k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
523k
        pdf14_group_color_t, &st_pdf14_clr,
1303
523k
        "pdf14_make_base_group_color");
1304
1305
523k
    if (group_color == NULL)
1306
0
        return NULL;
1307
523k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
523k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
523k
    group_color->blend_procs = pdev->blend_procs;
1311
523k
    group_color->polarity = pdev->color_info.polarity;
1312
523k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
523k
    group_color->isadditive = pdev->ctx->additive;
1314
523k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
523k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
523k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
523k
    group_color->depth = pdev->color_info.depth;
1318
523k
    group_color->decode = dev_proc(pdev, decode_color);
1319
523k
    group_color->encode = dev_proc(pdev, encode_color);
1320
523k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
523k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
523k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
523k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
523k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
523k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
523k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
523k
    group_color->icc_profile =
1328
523k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
523k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
523k
    return group_color;
1332
523k
}
1333
1334
/* This wil create the first buffer when we have
1335
   either the first drawing operation or transparency
1336
   group push.  At that time, the color space in which
1337
   we are going to be doing the alpha blend will be known. */
1338
static int
1339
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1340
362M
{
1341
362M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
362M
    bool has_tags = device_encodes_tags(dev);
1343
362M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
362M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
362M
    int num_spots = pdev->ctx->num_spots;
1346
362M
    pdf14_buf* buf;
1347
362M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
362M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1351
0
        pdev->ctx->stack->idle) {
1352
0
        pdf14_buf_free(pdev->ctx->stack);
1353
0
        pdev->ctx->stack = NULL;
1354
0
    }
1355
1356
362M
    if (pdev->ctx->stack != NULL)
1357
362M
        return 0;
1358
1359
362M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
470k
        dev->width, dev->height);
1361
1362
470k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
470k
        num_spots, memory, pdev->ctx->deep);
1364
470k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
470k
    if_debug5m('v', memory,
1368
470k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
470k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
470k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
470k
    buf->saved = NULL;
1373
470k
    pdev->ctx->stack = buf;
1374
470k
    pdev->ctx->additive = additive;
1375
1376
    /* Every buffer needs group color information including the base
1377
       one that is created for when we have no group */
1378
470k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
470k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
470k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
470k
    if (pgs != NULL)
1384
244k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
225k
    else
1386
225k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
470k
    buf->group_color_info->group_color_mapping_procs =
1389
470k
        dev_proc(pdev, get_color_mapping_procs);
1390
470k
    buf->group_color_info->group_color_comp_index =
1391
470k
        dev_proc(pdev, get_color_comp_index);
1392
470k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
470k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
470k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
470k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
470k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
470k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
470k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
470k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
470k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
470k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
470k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
470k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
470k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
470k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
470k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
470k
    buf->group_color_info->icc_profile =
1408
470k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
470k
    if (buf->group_color_info->icc_profile != NULL)
1410
470k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
470k
    return 0;
1413
470k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
17.9k
{
1418
17.9k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
17.9k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
17.9k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
17.9k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
17.9k
    if (des->icc_profile != NULL)
1425
17.9k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
17.9k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
17.9k
    return des;
1429
17.9k
}
1430
1431
static  int
1432
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1433
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1434
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1435
                              int numcomps, bool cm_back_drop, bool shade_group,
1436
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1437
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1438
                              gx_device *dev)
1439
2.17M
{
1440
2.17M
    pdf14_buf *tos = ctx->stack;
1441
2.17M
    pdf14_buf *buf, * pdf14_backdrop;
1442
2.17M
    bool has_shape = false;
1443
2.17M
    bool is_backdrop;
1444
2.17M
    int num_spots;
1445
1446
2.17M
    if_debug1m('v', ctx->memory,
1447
2.17M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
2.17M
    if (tos != NULL)
1450
1.79M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
2.17M
    if (ctx->smask_depth > 0)
1453
1.38k
        num_spots = 0;
1454
2.17M
    else
1455
2.17M
        num_spots = ctx->num_spots;
1456
1457
1458
2.17M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
2.17M
                        num_spots, ctx->memory, ctx->deep);
1460
2.17M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
2.17M
    if_debug4m('v', ctx->memory,
1464
2.17M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
2.17M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
2.17M
    buf->isolated = isolated;
1467
2.17M
    buf->knockout = knockout;
1468
2.17M
    buf->alpha = alpha;
1469
2.17M
    buf->shape = shape;
1470
2.17M
    buf->opacity = opacity;
1471
2.17M
    buf->blend_mode = blend_mode;
1472
2.17M
    buf->mask_id = mask_id;
1473
2.17M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
2.17M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
2.17M
    buf->saved = tos;
1478
2.17M
    buf->group_color_info = group_color;
1479
1480
2.17M
    if (tos == NULL)
1481
386k
        buf->page_group = true;
1482
1483
2.17M
    ctx->stack = buf;
1484
2.17M
    if (buf->data == NULL)
1485
1.26M
        return 0;
1486
910k
    if (idle)
1487
0
        return 0;
1488
910k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
910k
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1492
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1493
        /* Memsetting by 0, so this copes with the deep case too */
1494
531k
        memset(buf->data, 0, buf->planestride *
1495
531k
                                          (buf->n_chan +
1496
531k
                                           (buf->has_shape ? 1 : 0) +
1497
531k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
531k
    } else {
1499
378k
        if (!cm_back_drop) {
1500
378k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
378k
                                    );
1505
378k
        } else {
1506
            /* We must have an non-isolated group with a mismatch in color spaces.
1507
                In this case, we can't just copy the buffer but must CM it */
1508
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1509
0
                                        ctx->memory, pgs, dev, is_backdrop);
1510
0
        }
1511
378k
    }
1512
1513
    /* If our new group is a non-isolated knockout group, we have to maintain
1514
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1515
       knockout group. They have to always blend with the groups backdrop
1516
       not what is currently drawn in the group. Selection of the backdrop
1517
       depends upon the properties of the parent group. For example, if
1518
       the parent itself is a knockout group we actually
1519
       need to blend with its backdrop. This could be NULL if the parent was
1520
       an isolated knockout group. */
1521
910k
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
34.4k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
34.4k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
34.4k
                                       "pdf14_push_transparency_group");
1525
34.4k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
34.4k
        memcpy(buf->backdrop, buf->data,
1530
34.4k
               buf->planestride * buf->n_planes);
1531
1532
#if RAW_DUMP
1533
        /* Dump the current buffer to see what we have. */
1534
        dump_raw_buffer(ctx->memory,
1535
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1536
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1537
            ctx->stack->planestride, ctx->stack->rowstride,
1538
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1539
        global_index++;
1540
#endif
1541
34.4k
    }
1542
#if RAW_DUMP
1543
    /* Dump the current buffer to see what we have. */
1544
    dump_raw_buffer(ctx->memory,
1545
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1546
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1547
                    ctx->stack->planestride, ctx->stack->rowstride,
1548
                    "TransGroupPush", ctx->stack->data, buf->deep);
1549
    global_index++;
1550
#endif
1551
910k
    return 0;
1552
910k
}
1553
1554
static  int
1555
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1556
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1557
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1558
2.17M
{
1559
2.17M
    pdf14_buf *tos = ctx->stack;
1560
2.17M
    pdf14_buf *nos = tos->saved;
1561
2.17M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
2.17M
    pdf14_buf *maskbuf;
1563
2.17M
    int x0, x1, y0, y1;
1564
2.17M
    int nos_num_color_comp;
1565
2.17M
    bool no_icc_match;
1566
2.17M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
2.17M
    bool overprint = pdev->overprint;
1568
2.17M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
2.17M
    bool has_matte = false;
1570
2.17M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
2.17M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
2.17M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
3.85k
        has_matte = true;
1578
1579
    /* Check if this is our last buffer, if yes, there is nothing to
1580
       compose to.  Keep this buffer until we have the put image.
1581
       If we have another group push, this group must be destroyed.
1582
       This only occurs sometimes when at clist creation time
1583
       push_shfill_group occured and nothing was drawn in this group.
1584
       There is also the complication if we have a softmask.  There
1585
       are two approaches to this problem.  Apply the softmask during
1586
       the put image or handle it now.  I choose the later as the
1587
       put_image code is already way to complicated. */
1588
2.17M
    if (nos == NULL && maskbuf == NULL) {
1589
385k
        tos->group_popped = true;
1590
385k
        return 0;
1591
385k
    }
1592
1593
    /* Here is the case with the soft mask.  Go ahead and create a new
1594
       target buffer (nos) with the same color information etc, but blank
1595
       and go ahead and do the blend with the softmask so that it gets applied. */
1596
1.79M
    if (nos == NULL && maskbuf != NULL) {
1597
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1598
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1599
0
        if (nos == NULL) {
1600
0
            code = gs_error_VMerror;
1601
0
            goto exit;
1602
0
        }
1603
1604
0
        if_debug4m('v', ctx->memory,
1605
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1606
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1607
1608
0
        nos->dirty = tos->dirty;
1609
0
        nos->isolated = tos->isolated;
1610
0
        nos->knockout = tos->knockout;
1611
0
        nos->alpha = 65535;
1612
0
        nos->shape = 65535;
1613
0
        nos->opacity = 65535;
1614
0
        nos->blend_mode = tos->blend_mode;
1615
0
        nos->mask_id = tos->mask_id;
1616
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1617
1618
0
        if (nos->data != NULL)
1619
0
            memset(nos->data, 0,
1620
0
                   nos->planestride * (nos->n_chan +
1621
0
                                       (nos->has_shape ? 1 : 0) +
1622
0
                                       (nos->has_alpha_g ? 1 : 0)));
1623
0
    }
1624
1625
    /* Before we get started, lets see if we have somehow gotten into
1626
       what should be an impossible situation where the group color
1627
       information does not match the buffer color information. This
1628
       can occur is there were memory issues that have perhaps blown
1629
       away information, or in the example of Bug 705197 the PDF interpreter
1630
       reuses a pattern during a circular reference causing an aliasing
1631
       of two nested patterns, one of which has a softmask. The change in
1632
       the buffer size of the inner one blows away the buffer of the
1633
       outer one leading to a mismatch of color spaces. Here
1634
       we can at least catch the case when the color space sizes have
1635
       changed and avoid buffer over-runs that would occur when we try
1636
       to do the group composition */
1637
1.79M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
1.79M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
1.79M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
1.79M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1643
1644
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1645
     * have made them overly large. */
1646
1.79M
    rect_intersect(tos->dirty, tos->rect);
1647
1.79M
    rect_intersect(nos->dirty, nos->rect);
1648
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1649
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1650
1.79M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
1.79M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
1.79M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
1.79M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
1.79M
    if (ctx->mask_stack) {
1655
        /* This can occur when we have a situation where we are ending out of
1656
           a group that has internal to it a soft mask and another group.
1657
           The soft mask left over from the previous trans group pop is put
1658
           into ctx->masbuf, since it is still active if another trans group
1659
           push occurs to use it.  If one does not occur, but instead we find
1660
           ourselves popping from a parent group, then this softmask is no
1661
           longer needed.  We will rc_decrement and set it to NULL. */
1662
66
        rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_group");
1663
66
        ctx->mask_stack = NULL;
1664
66
    }
1665
1.79M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
1.79M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
1.79M
    if (tos->idle)
1668
1.23M
        goto exit;
1669
553k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1670
0
        goto exit;
1671
1672
#if RAW_DUMP
1673
    /* Dump the current buffer to see what we have. */
1674
    dump_raw_buffer(ctx->memory,
1675
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1676
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1677
                    ctx->stack->planestride, ctx->stack->rowstride,
1678
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1679
    global_index++;
1680
#endif
1681
/* Note currently if a pattern space has transparency, the ICC profile is not used
1682
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1683
   This is partially due to the fact that pdf14_pop_transparency_group and
1684
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1685
   operations called in the tile transparency code.  Instead we may want to
1686
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1687
   is where all the ICC information is handled.  We will return to look at that later */
1688
553k
    if (nos->group_color_info->icc_profile != NULL) {
1689
553k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
553k
    } else {
1691
        /* Let the other tests make the decision if we need to transform */
1692
0
        no_icc_match = false;
1693
0
    }
1694
    /* If the color spaces are different and we actually did do a swap of
1695
       the procs for color */
1696
553k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
553k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
4.48k
        if (x0 < x1 && y0 < y1) {
1699
4.23k
            pdf14_buf *result;
1700
4.23k
            bool did_alloc; /* We don't care here */
1701
1702
4.23k
            if (has_matte) {
1703
1.96k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1704
1.96k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1705
1.96k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1706
1.96k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1707
1.96k
                has_matte = false;
1708
2.27k
            } else {
1709
2.27k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
2.27k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
2.27k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
2.27k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
2.27k
            }
1714
4.23k
            if (result == NULL) {
1715
                /* Clean up and return error code */
1716
0
                code = gs_error_unknownerror;
1717
0
                goto exit;
1718
0
            }
1719
1720
#if RAW_DUMP
1721
            /* Dump the current buffer to see what we have. */
1722
            dump_raw_buffer(ctx->memory,
1723
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1724
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1725
                            ctx->stack->planestride, ctx->stack->rowstride,
1726
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1727
                            ctx->stack->deep);
1728
#endif
1729
             /* compose. never do overprint in this case */
1730
4.23k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
4.23k
                 nos->group_color_info->isadditive,
1732
4.23k
                 nos->group_color_info->blend_procs,
1733
4.23k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
4.23k
        }
1735
548k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
548k
        if (x0 < x1 && y0 < y1)
1738
301k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
301k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
301k
                                drawn_comps, ctx->memory, dev);
1741
548k
    }
1742
1.79M
exit:
1743
1.79M
    ctx->stack = nos;
1744
    /* We want to detect the cases where we have luminosity soft masks embedded
1745
       within one another.  The "alpha" channel really needs to be merged into
1746
       the luminosity channel in this case.  This will occur during the mask pop */
1747
1.79M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1748
        /* Set the trigger so that we will blend if not alpha. Since
1749
           we have softmasks embedded in softmasks */
1750
522
        ctx->smask_blend = true;
1751
522
    }
1752
1.79M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
1.79M
    pdf14_buf_free(tos);
1754
1.79M
    if (code < 0)
1755
0
        return_error(code);
1756
1.79M
    return 0;
1757
1.79M
}
1758
1759
/*
1760
 * Create a transparency mask that will be used as the mask for
1761
 * the next transparency group that is created afterwards.
1762
 * The sequence of calls is:
1763
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1764
 */
1765
static  int
1766
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1767
                             byte *transfer_fn, bool is_ident, bool idle,
1768
                             bool replacing, uint mask_id,
1769
                             gs_transparency_mask_subtype_t subtype,
1770
                             int numcomps, int Background_components,
1771
                             const float Background[], int Matte_components,
1772
                             const float Matte[], const float GrayBackground,
1773
                             pdf14_group_color_t* group_color)
1774
407k
{
1775
407k
    pdf14_buf *buf;
1776
407k
    int i;
1777
1778
407k
    if_debug2m('v', ctx->memory,
1779
407k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
407k
               idle, replacing);
1781
407k
    ctx->smask_depth += 1;
1782
1783
407k
    if (ctx->stack == NULL) {
1784
0
        return_error(gs_error_VMerror);
1785
0
    }
1786
1787
    /* An optimization to consider is that if the SubType is Alpha
1788
       then we really should only be allocating the alpha band and
1789
       only draw with that channel.  Current architecture makes that
1790
       a bit tricky.  We need to create this based upon the size of
1791
       the color space + an alpha channel. NOT the device size
1792
       or the previous ctx size */
1793
    /* A mask doesn't worry about tags */
1794
407k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
407k
                        ctx->memory, ctx->deep);
1796
407k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
407k
    buf->alpha = bg_alpha;
1799
407k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
407k
    buf->isolated = true;
1802
407k
    buf->knockout = false;
1803
407k
    buf->shape = 0xffff;
1804
407k
    buf->blend_mode = BLEND_MODE_Normal;
1805
407k
    buf->transfer_fn = transfer_fn;
1806
407k
    buf->matte_num_comps = Matte_components;
1807
407k
    buf->group_color_info = group_color;
1808
1809
407k
    if (Matte_components) {
1810
3.85k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
3.85k
                                                "pdf14_push_transparency_mask");
1812
3.85k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
15.4k
        for (i = 0; i < Matte_components; i++) {
1815
11.5k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
11.5k
        }
1817
3.85k
    }
1818
407k
    buf->mask_id = mask_id;
1819
    /* If replacing=false, we start the mask for an image with SMask.
1820
       In this case the image's SMask temporary replaces the
1821
       mask of the containing group. Save the containing droup's mask
1822
       in buf->mask_stack */
1823
407k
    buf->mask_stack = ctx->mask_stack;
1824
407k
    if (buf->mask_stack)
1825
407k
        rc_increment(buf->mask_stack);
1826
#if RAW_DUMP
1827
    /* Dump the current buffer to see what we have. */
1828
    if (ctx->stack->planestride > 0 ){
1829
        dump_raw_buffer(ctx->memory,
1830
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1831
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1832
                        ctx->stack->planestride, ctx->stack->rowstride,
1833
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1834
        global_index++;
1835
    }
1836
#endif
1837
407k
    buf->saved = ctx->stack;
1838
407k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
407k
    buf->SMask_SubType = subtype;
1842
407k
    if (buf->data != NULL) {
1843
        /* We need to initialize it to the BC if it existed */
1844
        /* According to the spec, the CS has to be the same */
1845
        /* If the back ground component is black, then don't bother
1846
           with this.  Since we are forcing the rendering to gray
1847
           earlier now, go ahead and just use the GrayBackGround color
1848
           directly. */
1849
236k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
126
            if (buf->deep) {
1851
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1852
0
                gs_memset16(buf->data, gray, buf->planestride);
1853
                /* If we have a background component that was not black, then we
1854
                   need to set the alpha for this mask as if we had drawn in the
1855
                   entire soft mask buffer */
1856
0
                gs_memset16(buf->data + buf->planestride, 65535,
1857
0
                            buf->planestride *(buf->n_chan - 1));
1858
126
            } else {
1859
126
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
126
                memset(buf->data, gray, buf->planestride);
1861
                /* If we have a background component that was not black, then we
1862
                   need to set the alpha for this mask as if we had drawn in the
1863
                   entire soft mask buffer */
1864
126
                memset(buf->data + buf->planestride, 255,
1865
126
                       buf->planestride * (buf->n_chan - 1));
1866
126
            }
1867
236k
        } else {
1868
            /* Compose mask with opaque background */
1869
236k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
236k
        }
1871
236k
    }
1872
407k
    return 0;
1873
407k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
407k
{
1878
407k
    pdf14_buf* tos = ctx->stack;
1879
407k
    pdf14_buf* nos = tos->saved;
1880
407k
    byte *new_data_buf;
1881
407k
    int icc_match;
1882
407k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
407k
    cmm_profile_t *src_profile;
1884
407k
    gsicc_rendering_param_t rendering_params;
1885
407k
    gsicc_link_t *icc_link;
1886
407k
    gsicc_rendering_param_t render_cond;
1887
407k
    cmm_dev_profile_t *dev_profile;
1888
407k
    int code = 0;
1889
1890
407k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
407k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
407k
                          &render_cond);
1893
407k
    ctx->smask_depth -= 1;
1894
    /* icc_match == -1 means old non-icc code.
1895
       icc_match == 0 means use icc code
1896
       icc_match == 1 mean no conversion needed */
1897
407k
    if (des_profile != NULL && src_profile != NULL ) {
1898
407k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
407k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
407k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
407k
               tos->idle);
1904
407k
    ctx->stack = tos->saved;
1905
407k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
407k
    if (tos->mask_stack) {
1907
        /* During the soft mask push, the mask_stack was copied (not moved) from
1908
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1909
           just set to NULL.  However, before we do that we must perform
1910
           rc decrement to match the increment that occured was made.  Also,
1911
           if this is the last ref count of the rc_mask, we should free the
1912
           buffer now since no other groups need it. */
1913
115k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
115k
        tos->mask_stack = NULL;
1915
115k
    }
1916
1917
407k
    if (tos->data == NULL ) {
1918
        /* This can occur in clist rendering if the soft mask does
1919
           not intersect the current band.  It would be nice to
1920
           catch this earlier and just avoid creating the structure
1921
           to begin with.  For now we need to delete the structure
1922
           that was created.  Only delete if the alpha value is 65535 */
1923
170k
        if (ctx->mask_stack != NULL) {
1924
53.6k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
53.6k
            ctx->mask_stack = NULL;
1926
53.6k
        }
1927
170k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
170k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
5.03k
            pdf14_buf_free(tos);
1930
165k
        } else {
1931
            /* Assign as mask buffer */
1932
165k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
165k
            if (ctx->mask_stack == NULL) {
1934
0
                pdf14_buf_free(tos);
1935
0
                return gs_note_error(gs_error_VMerror);
1936
0
            }
1937
165k
            ctx->mask_stack->mask_buf = tos;
1938
165k
        }
1939
170k
        ctx->smask_blend = false;  /* just in case */
1940
236k
    } else {
1941
        /* If we are already in the source space then there is no reason
1942
           to do the transformation */
1943
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1944
        /* This will reduce our memory.  We won't reuse the existing one, due */
1945
        /* Due to the fact that on certain systems we may have issues recovering */
1946
        /* the data after a resize */
1947
236k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1948
236k
                                        "pdf14_pop_transparency_mask");
1949
236k
        if (new_data_buf == NULL) {
1950
0
            pdf14_buf_free(tos);
1951
0
            return_error(gs_error_VMerror);
1952
0
        }
1953
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
1954
           we won't be filling everything during the remap if it had not been
1955
           written into by the PDF14 fill rect */
1956
236k
        memset(new_data_buf, 0, tos->planestride);
1957
        /* If the subtype was alpha, then just grab the alpha channel now
1958
           and we are all done */
1959
236k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1960
39.1k
            ctx->smask_blend = false;  /* not used in this case */
1961
39.1k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1962
39.1k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1963
39.1k
                       tos->rowstride,
1964
39.1k
                       (tos->data)+tos->planestride, new_data_buf);
1965
#if RAW_DUMP
1966
            /* Dump the current buffer to see what we have. */
1967
            dump_raw_buffer(ctx->memory,
1968
                            tos->rect.q.y-tos->rect.p.y,
1969
                            tos->rowstride>>tos->deep, 1,
1970
                            tos->planestride, tos->rowstride,
1971
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
1972
                            tos->deep);
1973
            global_index++;
1974
#endif
1975
197k
        } else {
1976
197k
            if (icc_match == 1 || tos->n_chan == 2) {
1977
#if RAW_DUMP
1978
                /* Dump the current buffer to see what we have. */
1979
                dump_raw_buffer(ctx->memory,
1980
                                tos->rect.q.y-tos->rect.p.y,
1981
                                tos->rowstride>>tos->deep, tos->n_planes,
1982
                                tos->planestride, tos->rowstride,
1983
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
1984
                                tos->deep);
1985
                global_index++;
1986
#endif
1987
                /* There is no need to color convert.  Data is already gray scale.
1988
                   We just need to copy the gray plane.  However it is
1989
                   possible that the soft mask could have a soft mask which
1990
                   would end us up with some alpha blending information
1991
                   (Bug691803). In fact, according to the spec, the alpha
1992
                   blending has to occur.  See FTS test fts_26_2601.pdf
1993
                   for an example of this.  Softmask buffer is intialized
1994
                   with BG values.  It would be nice to keep track if buffer
1995
                   ever has a alpha value not 1 so that we could detect and
1996
                   avoid this blend if not needed. */
1997
197k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1998
197k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1999
197k
                            tos->planestride, tos->deep);
2000
#if RAW_DUMP
2001
                /* Dump the current buffer to see what we have. */
2002
                dump_raw_buffer(ctx->memory,
2003
                                tos->rect.q.y-tos->rect.p.y,
2004
                                tos->rowstride>>tos->deep, 1,
2005
                                tos->planestride, tos->rowstride,
2006
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2007
                                tos->deep);
2008
                global_index++;
2009
#endif
2010
197k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2011
197k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2012
197k
                           tos->rowstride, tos->data, new_data_buf);
2013
197k
            } else {
2014
0
                if ( icc_match == -1 ) {
2015
                    /* The slow old fashioned way */
2016
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2017
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2018
0
                        tos->rowstride, tos->planestride,
2019
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2020
0
                        tos->deep
2021
#if RAW_DUMP
2022
                        , ctx->memory
2023
#endif
2024
0
                        );
2025
0
                } else {
2026
                    /* ICC case where we use the CMM */
2027
                    /* Request the ICC link for the transform that we will need to use */
2028
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2029
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2030
0
                    rendering_params.override_icc = false;
2031
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2032
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2033
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2034
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2035
0
                        src_profile, &rendering_params, pgs->memory, false);
2036
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2037
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2038
0
                              tos->rowstride, tos->planestride,
2039
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2040
                    /* Release the link */
2041
0
                    gsicc_release_link(icc_link);
2042
0
                }
2043
0
            }
2044
197k
        }
2045
        /* Free the old object, NULL test was above */
2046
236k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2047
236k
        tos->data = new_data_buf;
2048
        /* Data is single channel now */
2049
236k
        tos->n_chan = 1;
2050
236k
        tos->n_planes = 1;
2051
        /* Assign as reference counted mask buffer */
2052
236k
        if (ctx->mask_stack != NULL) {
2053
            /* In this case, the source file is wacky as it already had a
2054
               softmask and now is getting a replacement. We need to clean
2055
               up the softmask stack before doing this free and creating
2056
               a new stack. Bug 693312 */
2057
62.0k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2058
62.0k
        }
2059
236k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2060
236k
        if (ctx->mask_stack == NULL) {
2061
0
            pdf14_buf_free(tos);
2062
0
            return gs_note_error(gs_error_VMerror);
2063
0
        }
2064
236k
        ctx->mask_stack->mask_buf = tos;
2065
236k
    }
2066
407k
    return code;
2067
407k
}
2068
2069
static void
2070
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2071
1.41M
{
2072
    /* Ending the mask buffer. */
2073
1.41M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2074
    /* free the pdf14 buffer. */
2075
1.41M
    if (mask->mask_buf != NULL) {
2076
108k
        pdf14_buf_free(mask->mask_buf);
2077
108k
    }
2078
1.41M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2079
1.41M
}
2080
2081
static pdf14_mask_t *
2082
pdf14_mask_element_new(gs_memory_t *memory)
2083
1.41M
{
2084
1.41M
    pdf14_mask_t *result;
2085
2086
1.41M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2087
1.41M
                             "pdf14_mask_element_new");
2088
1.41M
    if (result == NULL)
2089
0
        return NULL;
2090
2091
1.41M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2092
2093
1.41M
    result->mask_buf = NULL;
2094
1.41M
    result->memory = memory;
2095
1.41M
    result->previous = NULL;
2096
2097
1.41M
    return result;
2098
1.41M
}
2099
2100
static int
2101
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2102
0
{
2103
    /* We need to push the current soft mask.  We need to
2104
       be able to recover it if we draw a new one and
2105
       then obtain a Q operation ( a pop ) */
2106
2107
0
    pdf14_device *pdev = (pdf14_device *)dev;
2108
0
    pdf14_ctx *ctx = pdev->ctx;
2109
0
    pdf14_mask_t *new_mask;
2110
2111
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2112
    /* We need to push the current mask buffer   */
2113
    /* Allocate a new element for the stack.
2114
       Don't do anything if there is no mask present.*/
2115
0
    if (ctx->mask_stack != NULL) {
2116
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2117
0
        if (new_mask == NULL)
2118
0
            return gs_note_error(gs_error_VMerror);
2119
0
        new_mask->previous = ctx->mask_stack;
2120
0
        ctx->mask_stack = new_mask;
2121
0
    }
2122
#ifdef DEBUG
2123
    pdf14_debug_mask_stack_state(pdev->ctx);
2124
#endif
2125
0
    return 0;
2126
0
}
2127
2128
static int
2129
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2130
2.60M
{
2131
    /* Pop the soft mask.  It is no longer needed. Likely due to
2132
       a Q that has occurred. */
2133
2.60M
    pdf14_device *pdev = (pdf14_device *)dev;
2134
2.60M
    pdf14_ctx *ctx = pdev->ctx;
2135
2.60M
    pdf14_mask_t *old_mask;
2136
2137
2.60M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2138
    /* rc decrement the current link after we break it from
2139
       the list, then free the stack element.  Don't do
2140
       anything if there is no mask present. */
2141
2.60M
    if (ctx->mask_stack != NULL) {
2142
418k
        old_mask = ctx->mask_stack;
2143
418k
        ctx->mask_stack = ctx->mask_stack->previous;
2144
418k
        rc_decrement(old_mask, "pdf14_pop_transparency_state");
2145
        /* We need to have some special handling here for when we have nested
2146
           soft masks.  There may be a copy in the stack that we may need to
2147
           adjust. */
2148
418k
        if (ctx->smask_depth > 0) {
2149
422
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2150
411
                ctx->stack->mask_stack = ctx->mask_stack;
2151
411
            }
2152
422
        }
2153
418k
    }
2154
#ifdef DEBUG
2155
    pdf14_debug_mask_stack_state(pdev->ctx);
2156
#endif
2157
2.60M
    return 0;
2158
2.60M
}
2159
2160
static  int
2161
pdf14_open(gx_device *dev)
2162
1.01M
{
2163
1.01M
    pdf14_device *pdev = (pdf14_device *)dev;
2164
2165
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2166
1.01M
    if (pdev->ctx == NULL) {
2167
1.01M
        bool has_tags = device_encodes_tags(dev);
2168
1.01M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2169
1.01M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2170
1.01M
        if (pdev->ctx == NULL)
2171
0
            return_error(gs_error_VMerror);
2172
2173
1.01M
        pdev->ctx->rect.p.x = 0;
2174
1.01M
        pdev->ctx->rect.p.y = 0;
2175
1.01M
        pdev->ctx->rect.q.x = dev->width;
2176
1.01M
        pdev->ctx->rect.q.y = dev->height;
2177
1.01M
        pdev->ctx->has_tags = has_tags;
2178
1.01M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2179
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2180
         * is. I am not sure how to fix that. */
2181
1.01M
        if (pdev->ctx->num_spots < 0)
2182
0
            pdev->ctx->num_spots = 0;
2183
1.01M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2184
1.01M
    }
2185
1.01M
    pdev->free_devicen = true;
2186
1.01M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2187
1.01M
    return 0;
2188
1.01M
}
2189
2190
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2191
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2192
};
2193
2194
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2195
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2196
};
2197
2198
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2199
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2200
};
2201
2202
static const gx_cm_color_map_procs *
2203
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2204
8.34M
{
2205
8.34M
    *tdev = dev;
2206
8.34M
    return &pdf14_DeviceCMYKspot_procs;
2207
8.34M
}
2208
2209
static const gx_cm_color_map_procs *
2210
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2211
2.90M
{
2212
2.90M
    *tdev = dev;
2213
2.90M
    return &pdf14_DeviceRGBspot_procs;
2214
2.90M
}
2215
2216
static const gx_cm_color_map_procs *
2217
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2218
0
{
2219
0
    *tdev = dev;
2220
0
    return &pdf14_DeviceGrayspot_procs;
2221
0
}
2222
2223
static void
2224
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2225
0
{
2226
0
    for (; n != 0; n--) {
2227
0
        uint16_t in = *src++;
2228
0
        ((byte *)dst)[0] = in>>8;
2229
0
        ((byte *)dst)[1] = in;
2230
0
        dst++;
2231
0
    }
2232
0
}
2233
2234
/* Used to pass along information about the buffer created by the
2235
   pdf14 device.  This is used by the pattern accumulator when the
2236
   pattern contains transparency.  Note that if free_device is true then
2237
   we need to go ahead and get the buffer data copied and free up the
2238
   device.  This only occurs at the end of a pattern accumulation operation */
2239
int
2240
pdf14_get_buffer_information(const gx_device * dev,
2241
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2242
                             bool free_device)
2243
22.9k
{
2244
22.9k
    const pdf14_device * pdev = (pdf14_device *)dev;
2245
22.9k
    pdf14_buf *buf;
2246
22.9k
    gs_int_rect rect;
2247
22.9k
    int x1,y1,width,height;
2248
2249
22.9k
    if ( pdev->ctx == NULL){
2250
0
        return 0;  /* this can occur if the pattern is a clist */
2251
0
    }
2252
#ifdef DEBUG
2253
    pdf14_debug_mask_stack_state(pdev->ctx);
2254
#endif
2255
22.9k
    buf = pdev->ctx->stack;
2256
22.9k
    rect = buf->rect;
2257
22.9k
    transbuff->buf = (free_device ? NULL : buf);
2258
22.9k
    x1 = min(pdev->width, rect.q.x);
2259
22.9k
    y1 = min(pdev->height, rect.q.y);
2260
22.9k
    width = x1 - rect.p.x;
2261
22.9k
    height = y1 - rect.p.y;
2262
2263
22.9k
    transbuff->n_chan    = buf->n_chan;
2264
22.9k
    transbuff->has_tags  = buf->has_tags;
2265
22.9k
    transbuff->has_shape = buf->has_shape;
2266
22.9k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2267
22.9k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2268
22.9k
    transbuff->deep      = buf->deep;
2269
2270
22.9k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2271
7.35k
        transbuff->planestride = 0;
2272
7.35k
        transbuff->rowstride = 0;
2273
7.35k
        return 0;
2274
7.35k
    }
2275
2276
15.5k
    if (free_device) {
2277
4.96k
        transbuff->pdev14 = NULL;
2278
4.96k
        transbuff->rect = rect;
2279
4.96k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2280
            /* If the bbox is smaller than the whole buffer than go ahead and
2281
               create a new one to use.  This can occur if we drew in a smaller
2282
               area than was specified by the transparency group rect. */
2283
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2284
0
            intptr_t planestride = rowstride * height;
2285
0
            int k, j;
2286
0
            byte *buff_ptr_src, *buff_ptr_des;
2287
2288
0
            transbuff->planestride = planestride;
2289
0
            transbuff->rowstride = rowstride;
2290
0
            transbuff->transbytes =
2291
0
                         gs_alloc_bytes(mem,
2292
0
                                        planestride *
2293
0
                                                (buf->n_chan +
2294
0
                                                 (buf->has_tags ? 1 : 0)) + CAL_SLOP,
2295
0
                                        "pdf14_get_buffer_information");
2296
0
            if (transbuff->transbytes == NULL)
2297
0
                return gs_error_VMerror;
2298
2299
0
            transbuff->mem = mem;
2300
0
            if (transbuff->deep) {
2301
0
                for (j = 0; j < transbuff->n_chan; j++) {
2302
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2303
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2304
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2305
0
                    for (k = 0; k < height; k++) {
2306
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2307
0
                        buff_ptr_des += rowstride;
2308
0
                        buff_ptr_src += buf->rowstride;
2309
0
                    }
2310
0
                }
2311
0
            } else {
2312
0
                for (j = 0; j < transbuff->n_chan; j++) {
2313
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2314
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2315
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2316
0
                    for (k = 0; k < height; k++) {
2317
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2318
0
                        buff_ptr_des += rowstride;
2319
0
                        buff_ptr_src += buf->rowstride;
2320
0
                    }
2321
0
                }
2322
0
            }
2323
2324
4.96k
        } else {
2325
            /* The entire buffer is used.  Go ahead and grab the pointer and
2326
               clear the pointer in the pdf14 device data buffer so it is not
2327
               freed when we close the device */
2328
4.96k
            transbuff->planestride = buf->planestride;
2329
4.96k
            transbuff->rowstride = buf->rowstride;
2330
4.96k
            transbuff->transbytes = buf->data;
2331
4.96k
            transbuff->mem = buf->memory;
2332
4.96k
            buf->data = NULL;  /* So that the buffer is not freed */
2333
4.96k
            if (transbuff->deep) {
2334
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2335
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2336
0
                uint16_t *buff_ptr;
2337
0
                int j, k, z;
2338
0
                intptr_t rowstride = transbuff->rowstride>>1;
2339
0
                intptr_t planestride = transbuff->planestride;
2340
0
                for (j = 0; j < transbuff->n_chan; j++) {
2341
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2342
0
                    for (k = 0; k < height; k++) {
2343
0
                        for (z = 0; z < width; z++) {
2344
0
                            uint16_t in = buff_ptr[z];
2345
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2346
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2347
0
                        }
2348
0
                        buff_ptr += rowstride;
2349
0
                    }
2350
0
                }
2351
0
            }
2352
4.96k
        }
2353
#if RAW_DUMP
2354
        /* Dump the buffer that should be going into the pattern */;
2355
        dump_raw_buffer_be(buf->memory,
2356
                           height, width, transbuff->n_chan,
2357
                           transbuff->planestride, transbuff->rowstride,
2358
                           "pdf14_pattern_buff", transbuff->transbytes,
2359
                           transbuff->deep);
2360
        global_index++;
2361
#endif
2362
        /* Go ahead and free up the pdf14 device */
2363
4.96k
        dev_proc(dev, close_device)((gx_device *)dev);
2364
10.5k
    } else {
2365
        /* Here we are coming from one of the fill image / pattern / mask
2366
           operations */
2367
10.5k
        transbuff->pdev14 = dev;
2368
10.5k
        transbuff->planestride = buf->planestride;
2369
10.5k
        transbuff->rowstride = buf->rowstride;
2370
10.5k
        transbuff->transbytes = buf->data;
2371
10.5k
        transbuff->mem = buf->memory;
2372
10.5k
        transbuff->rect = rect;
2373
#if RAW_DUMP
2374
    /* Dump the buffer that should be going into the pattern */;
2375
        dump_raw_buffer(buf->memory,
2376
                        height, width, buf->n_chan,
2377
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2378
                        "pdf14_pattern_buff",
2379
                        buf->data,
2380
                        transbuff->deep);
2381
        global_index++;
2382
#endif
2383
10.5k
    }
2384
15.5k
    return 0;
2385
15.5k
}
2386
2387
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2388
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2389
2390
2391
static int
2392
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2393
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2394
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2395
7.67k
{
2396
7.67k
    pdf14_buf* cm_result = NULL;
2397
7.67k
    cmm_profile_t* des_profile;
2398
7.67k
    gsicc_rendering_param_t render_cond;
2399
7.67k
    bool did_alloc;
2400
7.67k
    bool endian_swap;
2401
2402
7.67k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2403
7.67k
        &render_cond);
2404
2405
#if RAW_DUMP
2406
#if !ARCH_IS_BIG_ENDIAN
2407
    if (was_blended && (*buf)->deep)
2408
      dump_raw_buffer_be(dev->ctx->memory,
2409
          height, width, (*buf)->n_planes, (*buf)->planestride,
2410
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2411
    else
2412
#endif
2413
      dump_raw_buffer(dev->ctx->memory,
2414
          height, width, (*buf)->n_planes, (*buf)->planestride,
2415
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2416
    global_index++;
2417
#endif
2418
2419
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2420
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2421
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2422
       will need to know if it is dealing with native or BE data. */
2423
7.67k
    if (was_blended && (*buf)->deep) {
2424
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2425
           color conversion */
2426
#if ARCH_IS_BIG_ENDIAN
2427
        endian_swap = false;
2428
#else
2429
0
        endian_swap = true;
2430
0
#endif
2431
7.67k
    } else {
2432
        /* Data is in native format. No swap needed for CMM */
2433
7.67k
        endian_swap = false;
2434
7.67k
    }
2435
2436
7.67k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2437
7.67k
        *buf_ptr, src_profile, des_profile, x, y, width,
2438
7.67k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2439
2440
7.67k
    if (cm_result == NULL)
2441
0
        return_error(gs_error_VMerror);
2442
2443
    /* Update */
2444
7.67k
    *buf = cm_result;
2445
2446
    /* Make sure our buf_ptr is pointing to the proper location */
2447
7.67k
    if (did_alloc)
2448
7.67k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2449
2450
#if RAW_DUMP
2451
    dump_raw_buffer(dev->ctx->memory,
2452
        height, width, (*buf)->n_planes, (*buf)->planestride,
2453
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2454
    global_index++;
2455
#endif
2456
7.67k
    return 0;
2457
7.67k
}
2458
2459
/**
2460
 * pdf14_put_image: Put rendered image to target device.
2461
 * @pdev: The PDF 1.4 rendering device.
2462
 * @pgs: State for image draw operation.
2463
 * @target: The target device.
2464
 *
2465
 * Puts the rendered image in @pdev's buffer to @target. This is called
2466
 * as part of the sequence of popping the PDF 1.4 device filter.
2467
 *
2468
 * Return code: negative on error.
2469
 **/
2470
static  int
2471
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2472
934k
{
2473
934k
    const pdf14_device * pdev = (pdf14_device *)dev;
2474
934k
    int code;
2475
934k
    gs_image1_t image;
2476
934k
    gx_image_enum_common_t *info;
2477
934k
    pdf14_buf *buf = pdev->ctx->stack;
2478
934k
    gs_int_rect rect;
2479
934k
    int y;
2480
934k
    int num_comp;
2481
934k
    byte *linebuf, *linebuf_unaligned;
2482
934k
    gs_color_space *pcs;
2483
934k
    int x1, y1, width, height;
2484
934k
    byte *buf_ptr;
2485
934k
    int num_rows_left;
2486
934k
    cmm_profile_t* src_profile = NULL;
2487
934k
    cmm_profile_t* des_profile = NULL;
2488
934k
    cmm_dev_profile_t *pdf14dev_profile;
2489
934k
    cmm_dev_profile_t *dev_target_profile;
2490
934k
    uint16_t bg;
2491
934k
    bool has_tags = device_encodes_tags(dev);
2492
934k
    bool deep = pdev->ctx->deep;
2493
934k
    intptr_t planestride;
2494
934k
    intptr_t rowstride;
2495
934k
    blend_image_row_proc_t *blend_row;
2496
934k
    bool color_mismatch = false;
2497
934k
    bool supports_alpha = false;
2498
934k
    int i;
2499
934k
    int alpha_offset, tag_offset;
2500
934k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2501
934k
    int rendering_intent_saved;
2502
934k
    int additive;
2503
2504
    /* Nothing was ever drawn. */
2505
934k
    if (buf == NULL)
2506
126k
        return 0;
2507
2508
808k
    additive = buf->group_color_info->isadditive;
2509
2510
808k
    src_profile = buf->group_color_info->icc_profile;
2511
2512
808k
    num_comp = buf->n_chan - 1;
2513
808k
    rect = buf->rect;
2514
808k
    planestride = buf->planestride;
2515
808k
    rowstride = buf->rowstride;
2516
2517
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2518
       potential problem. Bug 694190 */
2519
808k
    if (buf->saved != NULL) {
2520
14
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2521
14
    }
2522
808k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2523
808k
    rect_intersect(rect, buf->dirty);
2524
808k
    x1 = min(pdev->width, rect.q.x);
2525
808k
    y1 = min(pdev->height, rect.q.y);
2526
808k
    width = x1 - rect.p.x;
2527
808k
    height = y1 - rect.p.y;
2528
#ifdef DUMP_TO_PNG
2529
    dump_planar_rgba(pdev->memory, buf);
2530
#endif
2531
808k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2532
215k
        return 0;
2533
593k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2534
2535
    /* Check that target is OK.  From fuzzing results the target could have been
2536
       destroyed, for e.g if it were a pattern accumulator that was closed
2537
       prematurely (Bug 694154).  We should always be able to to get an ICC
2538
       profile from the target. */
2539
593k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2540
593k
    if (code < 0)
2541
0
        return code;
2542
593k
    if (dev_target_profile == NULL)
2543
0
        return gs_throw_code(gs_error_Fatal);
2544
2545
593k
    if (src_profile == NULL) {
2546
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2547
0
        if (code < 0) {
2548
0
            return code;
2549
0
        }
2550
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2551
0
    }
2552
2553
    /* Check if we have a color conversion issue */
2554
593k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2555
593k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2556
114k
        color_mismatch = true;
2557
2558
    /* Check if target supports alpha */
2559
593k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2560
593k
    code = 0;
2561
2562
#if RAW_DUMP
2563
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2564
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2565
        "pre_final_blend", buf_ptr, deep);
2566
#endif
2567
2568
    /* Note. The logic below will need a little rework if we ever
2569
       have a device that has tags and alpha support */
2570
593k
    if (supports_alpha) {
2571
0
        if (!color_mismatch) {
2572
0
            alpha_offset = num_comp;
2573
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2574
2575
0
            for (i = 0; i < buf->n_planes; i++)
2576
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2577
0
            for (; i < target->color_info.num_components; i++)
2578
0
                buf_ptrs[i] = 0;
2579
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2580
0
                rect.p.x, rect.p.y, width, height,
2581
0
                rowstride, alpha_offset,
2582
0
                tag_offset);
2583
            /* Right now code has number of rows written */
2584
0
        } else {
2585
            /* In this case, just color convert and maintain alpha.  This is a case
2586
               where we either either blend in the right color space and have no
2587
               alpha for the output device or hand back the wrong color space with
2588
               alpha data.  We choose the later. */
2589
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2590
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2591
0
                width, height, false);
2592
0
            if (code < 0)
2593
0
                return code;
2594
2595
            /* reset */
2596
0
            rowstride = buf->rowstride;
2597
0
            planestride = buf->planestride;
2598
0
            num_comp = buf->n_chan - 1;
2599
0
            alpha_offset = num_comp;
2600
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2601
2602
            /* And then out */
2603
0
            for (i = 0; i < buf->n_planes; i++)
2604
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2605
0
            for (; i < target->color_info.num_components; i++)
2606
0
                buf_ptrs[i] = 0;
2607
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2608
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2609
0
                tag_offset);
2610
            /* Right now code has number of rows written */
2611
0
        }
2612
593k
    } else if (has_tags) {
2613
        /* We are going out to a device that supports tags */
2614
0
        if (deep) {
2615
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2616
0
                buf->planestride, num_comp, additive, false);
2617
0
        } else {
2618
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2619
0
                buf->planestride, num_comp, additive);
2620
0
        }
2621
2622
#if RAW_DUMP
2623
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2624
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2625
            "post_final_blend", buf_ptr, deep);
2626
#endif
2627
2628
        /* Take care of color issues */
2629
0
        if (color_mismatch) {
2630
            /* In this case, just color convert and maintain alpha.  This is a case
2631
               where we either either blend in the right color space and have no
2632
               alpha for the output device or hand back the wrong color space with
2633
               alpha data.  We choose the later. */
2634
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2635
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2636
0
            if (code < 0)
2637
0
                return code;
2638
2639
#if RAW_DUMP
2640
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2641
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2642
                "final_color_manage", buf_ptr, deep);
2643
            global_index++;
2644
#endif
2645
0
        }
2646
2647
        /* reset */
2648
0
        rowstride = buf->rowstride;
2649
0
        planestride = buf->planestride;
2650
0
        num_comp = buf->n_chan - 1;
2651
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2652
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2653
2654
        /* And then out */
2655
0
        for (i = 0; i < buf->n_planes; i++)
2656
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2657
0
        for (; i < target->color_info.num_components; i++)
2658
0
            buf_ptrs[i] = 0;
2659
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2660
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2661
0
            tag_offset);
2662
        /* Right now code has number of rows written */
2663
2664
0
    }
2665
2666
    /* If code > 0 then put image worked.  Let it finish and then exit */
2667
593k
    if (code > 0) {
2668
        /* We processed some or all of the rows.  Continue until we are done */
2669
0
        num_rows_left = height - code;
2670
0
        while (num_rows_left > 0) {
2671
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2672
0
                                                rect.p.x, rect.p.y + code, width,
2673
0
                                                num_rows_left, rowstride,
2674
0
                                                alpha_offset, tag_offset);
2675
0
            num_rows_left = num_rows_left - code;
2676
0
        }
2677
0
        return 0;
2678
0
    }
2679
2680
    /* Target device did not support alpha or tags.
2681
     * Set color space in preparation for sending an image.
2682
     * color conversion will occur after blending with through
2683
     * the begin typed image work flow.
2684
     */
2685
2686
593k
    planestride = buf->planestride;
2687
593k
    rowstride = buf->rowstride;
2688
593k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2689
593k
    if (code < 0)
2690
0
        return code;
2691
    /* Need to set this to avoid color management during the image color render
2692
       operation.  Exception is for the special case when the destination was
2693
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2694
       image operation.  That will happen here as we should have set the profile
2695
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2696
       the case when we have a blend color space that is different than the
2697
       target device color space */
2698
593k
    pcs->cmm_icc_profile_data = src_profile;
2699
2700
    /* pcs takes a reference to the profile data it just retrieved. */
2701
593k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2702
593k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
2703
0
        return_error(gs_error_rangecheck);
2704
2705
593k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2706
593k
    gs_image_t_init_adjust(&image, pcs, false);
2707
593k
    image.ImageMatrix.xx = (float)width;
2708
593k
    image.ImageMatrix.yy = (float)height;
2709
593k
    image.Width = width;
2710
593k
    image.Height = height;
2711
593k
    image.BitsPerComponent = deep ? 16 : 8;
2712
593k
    image.ColorSpace = pcs;
2713
593k
    ctm_only_writable(pgs).xx = (float)width;
2714
593k
    ctm_only_writable(pgs).xy = 0;
2715
593k
    ctm_only_writable(pgs).yx = 0;
2716
593k
    ctm_only_writable(pgs).yy = (float)height;
2717
593k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2718
593k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2719
    /* Make sure that the relative colorimetric rendering intent is
2720
       used for this image. */
2721
593k
    rendering_intent_saved = pgs->renderingintent;
2722
593k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2723
593k
    code = dev_proc(target, begin_typed_image) (target,
2724
593k
                                                pgs, NULL,
2725
593k
                                                (gs_image_common_t *)&image,
2726
593k
                                                NULL, NULL, NULL,
2727
593k
                                                pgs->memory, &info);
2728
593k
    pgs->renderingintent = rendering_intent_saved;
2729
593k
    if (code < 0) {
2730
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2731
0
        return code;
2732
0
    }
2733
#if RAW_DUMP
2734
    /* Dump the current buffer to see what we have. */
2735
    dump_raw_buffer(pdev->ctx->memory,
2736
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2737
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2738
                    pdev->ctx->stack->n_planes,
2739
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2740
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2741
    dump_raw_buffer(pdev->ctx->memory,
2742
                    height, width, buf->n_planes,
2743
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2744
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2745
    global_index++;
2746
    clist_band_count++;
2747
#endif
2748
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2749
    /* 28 byte overflow for AVX CMYK case. */
2750
593k
#define SSE_ALIGN 32
2751
593k
#define SSE_OVERFLOW 28
2752
593k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2753
593k
    if (linebuf_unaligned == NULL)
2754
0
        return gs_error_VMerror;
2755
593k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2756
2757
593k
    blend_row = deep ? gx_build_blended_image_row16 :
2758
593k
                       gx_build_blended_image_row;
2759
#ifdef WITH_CAL
2760
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2761
                                  blend_row, num_comp, deep);
2762
#endif
2763
2764
593k
    bg = additive ? (deep ? 65535 : 255) : 0;
2765
6.58M
    for (y = 0; y < height; y++) {
2766
5.98M
        gx_image_plane_t planes;
2767
5.98M
        int rows_used;
2768
2769
5.98M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2770
5.98M
        planes.data = linebuf;
2771
5.98M
        planes.data_x = 0;
2772
5.98M
        planes.raster = width * num_comp;
2773
5.98M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2774
        /* todo: check return value */
2775
5.98M
        buf_ptr += buf->rowstride;
2776
5.98M
    }
2777
593k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2778
593k
    info->procs->end_image(info, true);
2779
    /* This will also decrement the device profile */
2780
593k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2781
593k
    return code;
2782
593k
}
2783
2784
/* Overprint simulation with spots.  Collapse to CMYK */
2785
static void
2786
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2787
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2788
    cmyk_composite_map *map, bool keep_alpha)
2789
0
{
2790
0
    int comp_num;
2791
0
    uint cyan, magenta, yellow, black;
2792
0
    cmyk_composite_map *cmyk_map_entry;
2793
0
    int x, y;
2794
0
    intptr_t position;
2795
0
    byte comp, a;
2796
2797
0
    for (y = 0; y < height; y++) {
2798
0
        position = y * rowstride;
2799
0
        for (x = 0; x < width; x++) {
2800
0
            a = buf_ptr[position + planestride * num_comp];
2801
0
            if (a != 0) {
2802
0
                cyan = buf_ptr[position] * frac_1;
2803
0
                magenta = buf_ptr[position + planestride] * frac_1;
2804
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2805
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2806
0
                cmyk_map_entry = &(map[4]);
2807
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2808
0
                    comp = buf_ptr[position + planestride * comp_num];
2809
0
                    cyan += cmyk_map_entry->c * comp;
2810
0
                    magenta += cmyk_map_entry->m * comp;
2811
0
                    yellow += cmyk_map_entry->y * comp;
2812
0
                    black += cmyk_map_entry->k * comp;
2813
0
                    cmyk_map_entry++;
2814
0
                }
2815
0
                cyan /= frac_1;
2816
0
                magenta /= frac_1;
2817
0
                yellow /= frac_1;
2818
0
                black /= frac_1;
2819
2820
0
                if (cyan > 255)
2821
0
                    cyan = 255;
2822
0
                if (magenta > 255)
2823
0
                    magenta = 255;
2824
0
                if (yellow > 255)
2825
0
                    yellow = 255;
2826
0
                if (black > 255)
2827
0
                    black = 255;
2828
2829
0
                buf_ptr[position] = cyan;
2830
0
                buf_ptr[position + planestride] = magenta;
2831
0
                buf_ptr[position + planestride * 2] = yellow;
2832
0
                buf_ptr[position + planestride * 3] = black;
2833
0
            }
2834
0
            if (keep_alpha) {
2835
                /* Move the alpha and tag data */
2836
0
                buf_ptr[position + planestride * 4] = a;
2837
0
                if (tag_offset > 0) {
2838
0
                    buf_ptr[position + planestride * 5] =
2839
0
                        buf_ptr[position + planestride * tag_offset];
2840
0
                }
2841
0
            } else {
2842
                /* Remove alpha but keep tags */
2843
0
                if (tag_offset > 0) {
2844
0
                    buf_ptr[position + planestride * 4] =
2845
0
                        buf_ptr[position + planestride * tag_offset];
2846
0
                }
2847
2848
0
            }
2849
0
            position += 1;
2850
0
        }
2851
0
    }
2852
0
}
2853
2854
static void
2855
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2856
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2857
    cmyk_composite_map *map, bool keep_alpha)
2858
0
{
2859
0
    int comp_num;
2860
0
    ulong cyan, magenta, yellow, black;
2861
0
    cmyk_composite_map *cmyk_map_entry;
2862
0
    int x, y;
2863
0
    intptr_t position;
2864
0
    ulong comp, a;
2865
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2866
2867
    /* planestride and rowstride are in bytes, and we want them in shorts */
2868
0
    planestride >>= 1;
2869
0
    rowstride >>= 1;
2870
2871
0
    for (y = 0; y < height; y++) {
2872
0
        position = y * rowstride;
2873
0
        for (x = 0; x < width; x++) {
2874
0
            a = buf_ptr[position + planestride * num_comp];
2875
0
            if (a != 0) {
2876
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2877
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2878
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2879
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2880
0
                cmyk_map_entry = &(map[4]);
2881
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2882
0
                    comp = buf_ptr[position + planestride * comp_num];
2883
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2884
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2885
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2886
0
                    black += (ulong)cmyk_map_entry->k * comp;
2887
0
                    cmyk_map_entry++;
2888
0
                }
2889
0
                cyan /= frac_1_long;
2890
0
                magenta /= frac_1_long;
2891
0
                yellow /= frac_1_long;
2892
0
                black /= frac_1_long;
2893
2894
0
                if (cyan > 65535)
2895
0
                    cyan = 65535;
2896
0
                if (magenta > 65535)
2897
0
                    magenta = 65535;
2898
0
                if (yellow > 65535)
2899
0
                    yellow = 65535;
2900
0
                if (black > 65535)
2901
0
                    black = 65535;
2902
2903
#if ARCH_IS_BIG_ENDIAN
2904
                buf_ptr[position] = cyan;
2905
                buf_ptr[position + planestride] = magenta;
2906
                buf_ptr[position + planestride * 2] = yellow;
2907
                buf_ptr[position + planestride * 3] = black;
2908
#else
2909
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2910
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2911
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2912
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2913
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2914
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2915
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2916
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2917
0
#endif
2918
0
            }
2919
            /* Move the alpha and tag data */
2920
#if ARCH_IS_BIG_ENDIAN
2921
            if (keep_alpha) {
2922
                buf_ptr[position + planestride * 4] = a;
2923
                if (tag_offset > 0) {
2924
                    buf_ptr[position + planestride * 5] =
2925
                        buf_ptr[position + planestride * tag_offset];
2926
                }
2927
            } else {
2928
                if (tag_offset > 0) {
2929
                    buf_ptr[position + planestride * 4] =
2930
                        buf_ptr[position + planestride * tag_offset];
2931
                }
2932
            }
2933
#else
2934
0
            if (keep_alpha) {
2935
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2936
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2937
0
                if (tag_offset > 0) {
2938
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2939
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2940
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2941
0
                        buf_ptr[position + planestride * tag_offset];
2942
0
                }
2943
0
            } else {
2944
0
                if (tag_offset > 0) {
2945
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2946
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2947
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2948
0
                        buf_ptr[position + planestride * tag_offset];
2949
0
                }
2950
0
            }
2951
0
#endif
2952
0
            position += 1;
2953
0
        }
2954
0
    }
2955
0
}
2956
2957
static void
2958
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2959
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2960
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2961
0
{
2962
0
    if (deep) {
2963
0
        if (keep_alpha) {
2964
0
            if (tag_offset > 0) {
2965
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2966
0
                    planestride, num_comp, spot_start, tag_offset,
2967
0
                    map, true);
2968
0
            } else {
2969
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2970
0
                    planestride, num_comp, spot_start, 0,
2971
0
                    map, true);
2972
0
            }
2973
0
        } else {
2974
0
            if (tag_offset > 0) {
2975
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2976
0
                    planestride, num_comp, spot_start, tag_offset,
2977
0
                    map, false);
2978
0
            } else {
2979
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2980
0
                    planestride, num_comp, spot_start, 0,
2981
0
                    map, false);
2982
0
            }
2983
0
        }
2984
0
    } else {
2985
0
        if (keep_alpha) {
2986
0
            if (tag_offset > 0) {
2987
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2988
0
                    planestride, num_comp, spot_start, tag_offset,
2989
0
                    map, true);
2990
0
            } else {
2991
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2992
0
                    planestride, num_comp, spot_start, 0,
2993
0
                    map, true);
2994
0
            }
2995
0
        } else {
2996
0
            if (tag_offset > 0) {
2997
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2998
0
                    planestride, num_comp, spot_start, tag_offset,
2999
0
                    map, false);
3000
0
            } else {
3001
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3002
0
                    planestride, num_comp, spot_start, 0,
3003
0
                    map, false);
3004
0
            }
3005
0
        }
3006
0
    }
3007
0
}
3008
3009
/* This is for the case where we have mixture of spots and additive color.
3010
   For example, RGB + spots or Gray + spots */
3011
static void
3012
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3013
    intptr_t planestride, int num_comp, int spot_start)
3014
7.67k
{
3015
7.67k
    int x, y;
3016
7.67k
    intptr_t position;
3017
7.67k
    byte comp, a;
3018
7.67k
    int tmp, comp_num;
3019
3020
79.9k
    for (y = 0; y < height; y++) {
3021
72.2k
        position = y * rowstride;
3022
65.4M
        for (x = 0; x < width; x++) {
3023
65.3M
            a = buf_ptr[position + planestride * num_comp];
3024
65.3M
            if ((a + 1) & 0xfe) {
3025
736k
                a ^= 0xff;
3026
2.94M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3027
2.21M
                    comp = buf_ptr[position + planestride * comp_num];
3028
2.21M
                    tmp = ((0xff - comp) * a) + 0x80;
3029
2.21M
                    comp += (tmp + (tmp >> 8)) >> 8;
3030
2.21M
                    buf_ptr[position + planestride * comp_num] = comp;
3031
2.21M
                }
3032
736k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3033
0
                    comp = buf_ptr[position + planestride * comp_num];
3034
0
                    tmp = ((-comp) * a) + 0x80;
3035
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3036
0
                    buf_ptr[position + planestride * comp_num] = comp;
3037
0
                }
3038
64.6M
            } else if (a == 0) {
3039
57.1M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3040
42.8M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3041
42.8M
                }
3042
14.3M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3043
32.2k
                    buf_ptr[position + planestride * comp_num] = 0;
3044
32.2k
                }
3045
14.2M
            }
3046
65.3M
            position += 1;
3047
65.3M
        }
3048
72.2k
    }
3049
7.67k
}
3050
3051
static void
3052
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3053
    intptr_t planestride, int num_comp, int spot_start)
3054
0
{
3055
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3056
0
    int x, y;
3057
0
    intptr_t position;
3058
0
    int comp, a;
3059
0
    int tmp, comp_num;
3060
3061
    /* planestride and rowstride are in bytes, and we want them in shorts */
3062
0
    planestride >>= 1;
3063
0
    rowstride >>= 1;
3064
3065
    /* Note that the input here is native endian, and the output must be in big endian! */
3066
0
    for (y = 0; y < height; y++) {
3067
0
        position = y * rowstride;
3068
0
        for (x = 0; x < width; x++) {
3069
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3070
0
            a = buf_ptr[position + planestride * num_comp];
3071
0
            if (a == 0) {
3072
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3073
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3074
0
                }
3075
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3076
0
                    buf_ptr[position + planestride * comp_num] = 0;
3077
0
                }
3078
0
            } else if (a == 0xffff) {
3079
#if ARCH_IS_BIG_ENDIAN
3080
#else
3081
                /* Convert from native -> big endian */
3082
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3083
0
                    comp = buf_ptr[position + planestride * comp_num];
3084
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3085
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3086
0
                }
3087
0
#endif
3088
0
            } else {
3089
0
                a ^= 0xffff;
3090
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3091
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3092
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3093
0
                    comp = buf_ptr[position + planestride * comp_num];
3094
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3095
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3096
                    /* Store as big endian */
3097
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3098
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3099
0
                }
3100
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3101
0
                    comp = buf_ptr[position + planestride * comp_num];
3102
0
                    tmp = ((0 - comp) * a) + 0x4000;
3103
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3104
                    /* Store as big endian */
3105
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3106
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3107
0
                }
3108
0
            }
3109
0
            position += 1;
3110
0
        }
3111
0
    }
3112
0
}
3113
3114
static int
3115
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3116
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3117
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3118
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3119
    gs_separations* pseparations, bool deep)
3120
23.4k
{
3121
23.4k
    pdf14_device* pdev = (pdf14_device*)dev;
3122
23.4k
    int code = 0;
3123
23.4k
    int y;
3124
23.4k
    int num_rows_left;
3125
23.4k
    int i;
3126
23.4k
    gs_int_rect rect = rect_in;
3127
23.4k
    intptr_t planestride = planestride_in;
3128
23.4k
    intptr_t rowstride = rowstride_in;
3129
23.4k
    byte* buf_ptr = NULL;
3130
23.4k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3131
23.4k
    cmm_profile_t* des_profile = NULL;
3132
23.4k
    cmm_dev_profile_t* dev_target_profile;
3133
23.4k
    cmm_dev_profile_t* pdf14dev_profile;
3134
23.4k
    bool color_mismatch = false;
3135
23.4k
    bool supports_alpha = false;
3136
23.4k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3137
23.4k
    int alpha_offset = num_comp;
3138
23.4k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3139
23.4k
    gs_color_space *pcs;
3140
23.4k
    gs_image1_t image;
3141
23.4k
    gx_image_enum_common_t *info;
3142
23.4k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3143
23.4k
    pdf14_buf *cm_result = NULL;
3144
23.4k
    bool did_alloc;
3145
23.4k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3146
23.4k
    bool has_spots = pdev->ctx->num_spots > 0;
3147
23.4k
    bool blend_spots = !target_sep_device && has_spots;
3148
23.4k
    bool lose_channels = false;
3149
3150
    /* Check if group color space is CMYK based */
3151
23.4k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3152
23.4k
    if (code < 0)
3153
0
        return code;
3154
23.4k
    if (dev_target_profile == NULL)
3155
0
        return gs_throw_code(gs_error_Fatal);
3156
3157
23.4k
    if (src_profile == NULL) {
3158
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3159
0
        if (code < 0) {
3160
0
            return code;
3161
0
        }
3162
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3163
0
    }
3164
3165
    /* If the target device does not support spot colors and we have spot colors
3166
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3167
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3168
23.4k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3169
3170
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3171
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3172
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3173
0
        if (cm_result == NULL)
3174
0
            return_error(gs_error_VMerror);
3175
3176
        /* Update */
3177
0
        buf = cm_result;
3178
0
        src_profile = pgs->icc_manager->default_cmyk;
3179
0
        num_comp = buf->n_chan - 1;
3180
0
        additive = 0;
3181
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3182
0
        alpha_offset = num_comp;
3183
3184
#if RAW_DUMP
3185
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3186
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3187
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3188
        global_index++;
3189
#endif
3190
0
    }
3191
3192
    /* Fix order map if needed */
3193
109k
    for (i = 0; i < num_comp; i++) {
3194
86.1k
        pdev->devn_params.separation_order_map[i] = i;
3195
86.1k
    }
3196
3197
    /* Check if we have a color conversion issue */
3198
23.4k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3199
23.4k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3200
7.67k
        color_mismatch = true;
3201
23.4k
    if (des_profile->data_cs == gsNCHANNEL)
3202
0
        lose_channels = true;
3203
3204
    /* Check if target supports alpha */
3205
23.4k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3206
23.4k
    code = 0;
3207
3208
23.4k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3209
3210
    /* Note. The logic below will need a little rework if we ever
3211
       have a device that has tags and alpha support */
3212
23.4k
    if (supports_alpha) {
3213
3214
        /* If doing simulated overprint, Bring the spot color channels into
3215
           CMYK. Data is planar and 16 bit data in native format. */
3216
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3217
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3218
3219
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3220
0
            if (pdev->pclist_device != NULL) {
3221
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3222
3223
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3224
0
                if (code < 0)
3225
0
                    return code;
3226
0
            }
3227
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3228
3229
            /* Now we go to big endian */
3230
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3231
0
                planestride, num_comp, src_profile->num_comps,
3232
0
                tag_offset, cmyk_map, true, deep);
3233
3234
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3235
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3236
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3237
0
            buf->num_spots = 0;
3238
0
            num_comp = buf->n_chan - 1;
3239
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3240
0
        }
3241
3242
0
        if (!color_mismatch) {
3243
0
            for (i = 0; i < buf->n_planes; i++)
3244
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3245
0
            for (; i < target->color_info.num_components; i++)
3246
0
                buf_ptrs[i] = 0;
3247
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3248
0
                rect.p.x, rect.p.y, width, height,
3249
0
                rowstride, alpha_offset, tag_offset);
3250
            /* Right now code has number of rows written */
3251
0
        } else {
3252
            /* In this case, just color convert and maintain alpha.
3253
               This is a case where we either either blend in the
3254
               right color space and have no alpha for the output
3255
               device or hand back the wrong color space with
3256
               alpha data.  We choose the later. */
3257
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3258
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3259
0
                        rect.p.y, width, height, false);
3260
0
            if (code < 0)
3261
0
                return code;
3262
3263
            /* reset */
3264
0
            rowstride = buf->rowstride;
3265
0
            planestride = buf->planestride;
3266
0
            num_comp = buf->n_chan - 1;
3267
0
            alpha_offset = num_comp;
3268
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3269
3270
            /* And then out */
3271
0
            for (i = 0; i < buf->n_planes; i++)
3272
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3273
0
            for (; i < target->color_info.num_components; i++)
3274
0
                buf_ptrs[i] = 0;
3275
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3276
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3277
0
                tag_offset);
3278
            /* Right now code has number of rows written.  Writing continues below */
3279
0
        }
3280
23.4k
    } else {
3281
        /* Device could not handle the alpha data (we actually don't have
3282
           a device that does spot colorants and has an alpha channel so
3283
           the above code is untested.  Go ahead and preblend now and then
3284
           color convert if needed */
3285
#if RAW_DUMP
3286
           /* Dump before and after the blend to make sure we are doing that ok */
3287
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3288
            "pre_put_image_blend_image", buf_ptr, deep);
3289
        global_index++;
3290
#endif
3291
3292
23.4k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3293
7.67k
            if (deep) {
3294
            /* In this case, we are NOT going to bring the spots into the CMYK
3295
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3296
               16 bit data will be converted now from native endian to big endian during
3297
               the blending process */
3298
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3299
0
                    planestride, num_comp, src_profile->num_comps);
3300
7.67k
            } else {
3301
7.67k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3302
7.67k
                    planestride, num_comp, src_profile->num_comps);
3303
7.67k
            }
3304
15.7k
        } else {
3305
15.7k
            if (deep) {
3306
            /* In this case, if blend_spots == true, we will shortly be bringing
3307
               the spot colors to CMYK equivalent colors. It is at that time that
3308
               we will convert from native endian to big endian. In all other
3309
               cases this blending will due to conversion from native to BE */
3310
0
                bool keep_native = (blend_spots == true);
3311
3312
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3313
0
                    planestride, num_comp, additive, keep_native);
3314
15.7k
            } else {
3315
15.7k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3316
15.7k
                    planestride, num_comp, additive);
3317
15.7k
            }
3318
15.7k
        }
3319
3320
23.4k
        if (deep && has_tags)
3321
0
        {
3322
            /* We still need to convert the tags from Native to BE */
3323
#if ARCH_IS_BIG_ENDIAN
3324
#else
3325
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3326
0
            int i, j;
3327
0
            for (j = 0; j < height; j++)
3328
0
            {
3329
0
                for (i = 0; i < width; i++)
3330
0
                {
3331
0
                    uint16_t tag = *tags++;
3332
0
                    ((byte *)tags)[-2] = tag >> 8;
3333
0
                    ((byte *)tags)[-1] = tag;
3334
0
                }
3335
0
                tags += (buf->rowstride>>1) - width;
3336
0
            }
3337
0
#endif
3338
0
        }
3339
3340
#if RAW_DUMP
3341
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3342
            "post_put_image_blend_image", buf_ptr, deep);
3343
        global_index++;
3344
#endif
3345
3346
        /* If doing simulated overprint and we are not going to a sep device and
3347
           we have spot colors, then bring the spot color channels into CMYK
3348
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3349
           At this point, data is planar and 16 bit data is still in native format. It is
3350
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3351
           above during the alpha blend operation. */
3352
23.4k
        if (blend_spots) {
3353
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3354
3355
            /* In the clist case, we need to get equiv spots out of the
3356
               pseudo-band. */
3357
0
            if (pdev->pclist_device != NULL) {
3358
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3359
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3360
0
                if (code < 0)
3361
0
                    return code;
3362
0
            }
3363
3364
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3365
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3366
0
                planestride, num_comp, src_profile->num_comps,
3367
0
                tag_offset, cmyk_map, false, deep);
3368
3369
            /* Reset buffer information. We have CMYK and maybe tags */
3370
0
            num_comp = 4;
3371
0
            alpha_offset = 0;
3372
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3373
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3374
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3375
0
            buf->num_spots = 0;
3376
3377
#if RAW_DUMP
3378
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3379
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3380
            global_index++;
3381
#endif
3382
0
        }
3383
3384
        /* Map to the destination color space */
3385
23.4k
        if (color_mismatch) {
3386
            /* We started out with the original process colorants, and spots. If we have an
3387
             * nchannel output profile, this can mean that the first few spots might come from
3388
             * that and the rest from the document itself. e.g:
3389
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3390
             * Then we might have a blend space that changes the process colorants:
3391
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3392
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3393
             * If we're not careful, we'll end up with:
3394
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3395
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3396
             */
3397
7.67k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3398
7.67k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3399
7.67k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3400
7.67k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3401
7.67k
            if (code < 0)
3402
0
                return code;
3403
3404
            /* reset */
3405
7.67k
            rowstride = buf->rowstride;
3406
7.67k
            planestride = buf->planestride;
3407
7.67k
            num_comp = buf->n_chan;
3408
7.67k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3409
7.67k
        }
3410
3411
#if RAW_DUMP
3412
        /* Dump after the CS transform */
3413
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3414
            "post_put_image_color_convert", buf_ptr, deep);
3415
        global_index++;
3416
        /* clist_band_count++; */
3417
#endif
3418
3419
        /* Try put_image again. This can occur if the
3420
           target, like psdcmyk and tiffsep, support put_image */
3421
23.4k
        alpha_offset = 0;
3422
140k
        for (i = 0; i < buf->n_planes; i++)
3423
117k
            buf_ptrs[i] = buf_ptr + i * planestride;
3424
23.4k
        for (; i < target->color_info.num_components; i++)
3425
0
            buf_ptrs[i] = 0;
3426
23.4k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3427
23.4k
            rect.p.x, rect.p.y, width, height,
3428
23.4k
            rowstride, alpha_offset, tag_offset);
3429
23.4k
    }
3430
3431
    /* Put image was succesful.  We processed some or all of the rows.
3432
       Continue until we are done */
3433
23.4k
    if (code > 0) {
3434
55
        num_rows_left = height - code;
3435
55
        while (num_rows_left > 0) {
3436
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3437
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3438
0
                alpha_offset, tag_offset);
3439
0
            if (code < 0) {
3440
0
                return code;
3441
0
            }
3442
0
            num_rows_left = num_rows_left - code;
3443
0
        }
3444
55
        return 0;
3445
55
    }
3446
3447
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3448
       as well as those devices that support alpha (pngalpha,
3449
       png16malpha). If we are here, then we are doing an
3450
       overprint simulation on some other device. Image data
3451
       is aleady blended and in device color space. */
3452
23.4k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3453
23.4k
    if (code < 0)
3454
0
        return code;
3455
3456
    /* Already in destination CS */
3457
23.4k
    pcs->cmm_icc_profile_data = des_profile;
3458
3459
    /* pcs takes a reference to the profile data it just retrieved. */
3460
23.4k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3461
23.4k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
3462
0
        return_error(gs_error_rangecheck);
3463
23.4k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3464
3465
    /* If we have more components to write out than are in the des_profile,
3466
     * then just using a PCS based on des_profile, will result in us dropping
3467
     * the spot colors.
3468
     * So, if our target supports devn colors, we instead construct a
3469
     * DevN device space with colors names taken from the devn_params, and
3470
     * use that instead. */
3471
23.4k
    if (des_profile->num_comps != target->color_info.num_components &&
3472
24
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3473
24
    {
3474
24
        int num_std;
3475
24
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3476
24
        gs_color_space *pcs2 = pcs;
3477
24
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3478
24
                                     pcs2, pgs->memory->non_gc_memory);
3479
24
        if (code < 0)
3480
0
            return code;
3481
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3482
24
        pcs->params.device_n.use_alt_cspace = false;
3483
24
        num_std = devn_params->num_std_colorant_names;
3484
120
        for (i = 0; i < num_std; i++) {
3485
96
            const char *name = devn_params->std_colorant_names[i];
3486
96
            size_t len = strlen(name);
3487
96
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3488
96
            if (pcs->params.device_n.names[i] == NULL) {
3489
0
                int j = 0;
3490
0
                for (j = 0;j < i; j++) {
3491
0
                    if (pcs->params.device_n.names[j] != NULL)
3492
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3493
0
                    pcs->params.device_n.names[j] = NULL;
3494
0
                }
3495
0
                return_error(gs_error_VMerror);
3496
0
            }
3497
96
            strcpy(pcs->params.device_n.names[i], name);
3498
96
        }
3499
24
        for (; i < devn_params->separations.num_separations; i++) {
3500
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3501
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");
3502
0
            if (pcs->params.device_n.names[i] == NULL) {
3503
0
                int j = 0;
3504
0
                for (j = 0;j < i; j++) {
3505
0
                    if (pcs->params.device_n.names[j] != NULL)
3506
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3507
0
                    pcs->params.device_n.names[j] = NULL;
3508
0
                }
3509
0
                return_error(gs_error_VMerror);
3510
0
            }
3511
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3512
0
            pcs->params.device_n.names[i][name->size] = 0;
3513
0
        }
3514
24
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3515
0
            return code;
3516
0
        }
3517
        /* One last thing -- we need to fudge the pgs->color_component_map */
3518
144
        for (i=0; i < dev->color_info.num_components; i++)
3519
120
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3520
24
    }
3521
3522
23.4k
    gs_image_t_init_adjust(&image, pcs, false);
3523
23.4k
    image.ImageMatrix.xx = (float)width;
3524
23.4k
    image.ImageMatrix.yy = (float)height;
3525
23.4k
    image.Width = width;
3526
23.4k
    image.Height = height;
3527
23.4k
    image.BitsPerComponent = deep ? 16 : 8;
3528
23.4k
    image.ColorSpace = pcs;
3529
23.4k
    image.format = gs_image_format_component_planar;
3530
3531
23.4k
    ctm_only_writable(pgs).xx = (float)width;
3532
23.4k
    ctm_only_writable(pgs).xy = 0;
3533
23.4k
    ctm_only_writable(pgs).yx = 0;
3534
23.4k
    ctm_only_writable(pgs).yy = (float)height;
3535
23.4k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3536
23.4k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3537
23.4k
    code = dev_proc(target, begin_typed_image) (target,
3538
23.4k
        pgs, NULL, (gs_image_common_t *)&image,
3539
23.4k
        NULL, NULL, NULL, pgs->memory, &info);
3540
23.4k
    if (code < 0) {
3541
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3542
0
        return code;
3543
0
    }
3544
#if RAW_DUMP
3545
    /* Dump the current buffer to see what we have. */
3546
    dump_raw_buffer(pdev->ctx->memory,
3547
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3548
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3549
        pdev->ctx->stack->n_planes,
3550
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3551
        "put_image_final_big", pdev->ctx->stack->data, deep);
3552
    dump_raw_buffer(pdev->ctx->memory,
3553
        height, width, buf->n_planes,
3554
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3555
        "put_image_final_small", buf_ptr, deep);
3556
    global_index++;
3557
    clist_band_count++;
3558
#endif
3559
3560
124k
    for (i = 0; i < num_comp; i++) {
3561
101k
        planes[i].data = buf_ptr + i * planestride;
3562
101k
        planes[i].data_x = 0;
3563
101k
        planes[i].raster = buf->rowstride;
3564
101k
    }
3565
3566
255k
    for (y = 0; y < height; y++) {
3567
232k
        int rows_used;
3568
3569
232k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3570
3571
1.23M
        for (i = 0; i < num_comp; i++) {
3572
1.00M
            planes[i].data += buf->rowstride;
3573
1.00M
        }
3574
232k
    }
3575
23.4k
    info->procs->end_image(info, true);
3576
3577
    /* This will also decrement the profile */
3578
23.4k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3579
23.4k
    return code;
3580
23.4k
}
3581
3582
/**
3583
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3584
 * @pdev: The PDF 1.4 rendering device.
3585
 * @pgs: State for image draw operation.
3586
 * @target: The target device.
3587
 *
3588
 * Puts the rendered image in @pdev's buffer to @target. This is called
3589
 * as part of the sequence of popping the PDF 1.4 device filter.
3590
 *
3591
 * Return code: negative on error.
3592
 **/
3593
static  int
3594
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3595
66.4k
{
3596
66.4k
    pdf14_device *pdev = (pdf14_device *)dev;
3597
66.4k
    pdf14_buf *buf = pdev->ctx->stack;
3598
66.4k
    gs_int_rect rect;
3599
66.4k
    int x1, y1, width, height;
3600
66.4k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3601
66.4k
    gs_separations *pseparations = &pdevn_params->separations;
3602
66.4k
    intptr_t planestride;
3603
66.4k
    intptr_t rowstride;
3604
66.4k
    bool deep = pdev->ctx->deep;
3605
66.4k
    int num_comp;
3606
3607
    /* Nothing was ever drawn. */
3608
66.4k
    if (buf == NULL)
3609
25.5k
        return 0;
3610
3611
40.8k
    num_comp = buf->n_chan - 1;
3612
40.8k
    rect = buf->rect;
3613
40.8k
    planestride = buf->planestride;
3614
40.8k
    rowstride = buf->rowstride;
3615
3616
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3617
       potential problem. Bug 694190 */
3618
40.8k
    if (buf->saved != NULL) {
3619
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3620
0
    }
3621
40.8k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3622
40.8k
    rect_intersect(rect, buf->dirty);
3623
40.8k
    x1 = min(pdev->width, rect.q.x);
3624
40.8k
    y1 = min(pdev->height, rect.q.y);
3625
40.8k
    width = x1 - rect.p.x;
3626
40.8k
    height = y1 - rect.p.y;
3627
40.8k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3628
17.4k
        return 0;
3629
3630
#if RAW_DUMP
3631
    /* Dump the current buffer to see what we have. */
3632
    dump_raw_buffer(pdev->ctx->memory,
3633
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3634
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3635
                    pdev->ctx->stack->n_planes,
3636
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3637
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3638
                    pdev->ctx->stack->deep);
3639
3640
    global_index++;
3641
    clist_band_count++;
3642
#endif
3643
3644
23.4k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3645
23.4k
                      buf, planestride, rowstride,
3646
23.4k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3647
23.4k
                      buf->has_tags, rect, pseparations, deep);
3648
40.8k
}
3649
3650
/**
3651
 * pdf14_custom_put_image: Put rendered image to target device.
3652
 * @pdev: The PDF 1.4 rendering device.
3653
 * @pgs: State for image draw operation.
3654
 * @target: The target device.
3655
 *
3656
 * Puts the rendered image in @pdev's buffer to @target. This is called
3657
 * as part of the sequence of popping the PDF 1.4 device filter.
3658
 *
3659
 * Return code: negative on error.
3660
 **/
3661
static  int
3662
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3663
0
{
3664
0
    pdf14_device * pdev = (pdf14_device *)dev;
3665
0
    pdf14_buf *buf = pdev->ctx->stack;
3666
0
    bool deep = pdev->ctx->deep;
3667
0
    gs_int_rect rect;
3668
0
    int x0, y0;
3669
0
    intptr_t planestride;
3670
0
    intptr_t rowstride;
3671
0
    int num_comp;
3672
0
    uint16_t bg;
3673
0
    int x1, y1, width, height;
3674
0
    byte *buf_ptr;
3675
3676
    /* Nothing was ever drawn. */
3677
0
    if (buf == NULL)
3678
0
        return 0;
3679
3680
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3681
0
    num_comp = buf->n_chan - 1;
3682
0
    rect = buf->rect;
3683
0
    x0 = rect.p.x;
3684
0
    y0 = rect.p.y;
3685
0
    planestride = buf->planestride;
3686
0
    rowstride = buf->rowstride;
3687
3688
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3689
       potential problem. Bug 694190 */
3690
0
    if (buf->saved != NULL) {
3691
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3692
0
    }
3693
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3694
0
    rect_intersect(rect, buf->dirty);
3695
0
    x1 = min(pdev->width, rect.q.x);
3696
0
    y1 = min(pdev->height, rect.q.y);
3697
0
    width = x1 - rect.p.x;
3698
0
    height = y1 - rect.p.y;
3699
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3700
0
        return 0;
3701
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3702
3703
0
    return gx_put_blended_image_custom(target, buf_ptr,
3704
0
                      planestride, rowstride,
3705
0
                      x0, y0, width, height, num_comp, bg, deep);
3706
0
}
3707
3708
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3709
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3710
 * putting everything back how it was, and cleaning up the reference counts.
3711
 */
3712
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3713
2.04M
{
3714
2.04M
    if (pdev->ctx && pdev->ctx->stack) {
3715
856k
        pdf14_buf *buf, *next;
3716
3717
856k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3718
16
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3719
16
            next = buf->saved;
3720
32
            while (group_color_info) {
3721
16
               if (group_color_info->icc_profile != NULL) {
3722
16
                   cmm_profile_t *group_profile;
3723
16
                   gsicc_rendering_param_t render_cond;
3724
16
                   cmm_dev_profile_t *dev_profile;
3725
16
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3726
3727
16
                   if (code >= 0) {
3728
16
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3729
16
                                             &render_cond);
3730
3731
16
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3732
16
                                               -1, "pdf14_end_transparency_group");
3733
16
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3734
16
                           group_color_info->icc_profile;
3735
16
                       group_color_info->icc_profile = NULL;
3736
16
                   }
3737
16
               }
3738
3739
16
               group_color_info = group_color_info->previous;
3740
16
            }
3741
16
        }
3742
856k
    }
3743
2.04M
}
3744
3745
static  int
3746
pdf14_close(gx_device *dev)
3747
1.01M
{
3748
1.01M
    pdf14_device *pdev = (pdf14_device *)dev;
3749
3750
1.01M
    pdf14_cleanup_group_color_profiles(pdev);
3751
3752
1.01M
    if (pdev->ctx) {
3753
1.01M
        pdf14_ctx_free(pdev->ctx);
3754
1.01M
        pdev->ctx = NULL;
3755
1.01M
    }
3756
1.01M
    return 0;
3757
1.01M
}
3758
3759
/* This is called when something has gone wrong and the interpreter received a
3760
   stop while in the middle of doing something with the PDF14 device.  We need
3761
   to clean up and end this in a graceful manner */
3762
static int
3763
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3764
0
{
3765
0
    pdf14_device *pdev = (pdf14_device *)dev;
3766
    /* The things that need to be cleaned up */
3767
0
    pdf14_ctx *ctx = pdev->ctx;
3768
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3769
3770
    /* Free up the smask color */
3771
0
    if (smaskcolor != NULL) {
3772
0
        smaskcolor->ref_count = 1;
3773
0
        pdf14_decrement_smask_color(pgs, dev);
3774
0
        pdev->smaskcolor = NULL;
3775
0
    }
3776
3777
    /* Free up the nested color procs and decrement the profiles */
3778
0
    while (pdev->color_model_stack)
3779
0
        pdf14_pop_group_color(dev, NULL);
3780
3781
    /* Start the context clean up */
3782
0
    if (ctx != NULL) {
3783
0
        pdf14_buf *buf, *next;
3784
0
        pdf14_group_color_t *procs, *prev_procs;
3785
3786
0
        if (ctx->mask_stack != NULL) {
3787
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3788
0
        }
3789
3790
        /* Now the stack of buffers */
3791
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3792
0
            next = buf->saved;
3793
3794
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3795
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3796
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3797
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3798
            /* During the soft mask push, the mask_stack was copied (not moved) from
3799
               the ctx to the tos mask_stack. We are done with this now so it is safe
3800
               to free this one object */
3801
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3802
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3803
0
                prev_procs = procs->previous;
3804
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3805
0
            }
3806
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3807
0
        }
3808
        /* Finally the context itself */
3809
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3810
0
        pdev->ctx = NULL;
3811
0
    }
3812
0
    return 0;
3813
0
}
3814
3815
static  int
3816
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3817
0
{
3818
0
    pdf14_device * pdev = (pdf14_device *)dev;
3819
3820
0
    if (pdev->target != NULL)
3821
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3822
0
    return 0;
3823
0
}
3824
3825
8.19M
#define COPY_PARAM(p) dev->p = target->p
3826
5.12M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3827
3828
static void
3829
copy_tag_setup(gx_device *dev, const gx_device *target)
3830
1.02M
{
3831
1.02M
    bool deep = device_is_deep(target);
3832
1.02M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3833
1.02M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3834
1.02M
    COPY_PARAM(graphics_type_tag);
3835
1.02M
    if (had_tags && !has_tags)
3836
0
    {
3837
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3838
0
        dev->color_info.num_components--;
3839
0
        dev->color_info.depth -= deep ? 16 : 8;
3840
0
    }
3841
1.02M
    else if (!had_tags && has_tags)
3842
0
    {
3843
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3844
0
        dev->color_info.num_components++;
3845
0
        dev->color_info.depth += deep ? 16 : 8;
3846
0
    }
3847
1.02M
}
3848
3849
/*
3850
 * Copy device parameters back from a target.  This copies all standard
3851
 * parameters related to page size and resolution, but not any of the
3852
 * color-related parameters, as the pdf14 device retains its own color
3853
 * handling. This routine is parallel to gx_device_copy_params().
3854
 * Note that it DOES copy the devn_params since these are required to
3855
 * keep agreement with colorant name->number mapping, and don't change
3856
 * with the pdf14 color handling.
3857
 */
3858
static  int
3859
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3860
1.02M
{
3861
1.02M
    cmm_dev_profile_t *profile_targ;
3862
1.02M
    cmm_dev_profile_t *profile_dev14;
3863
1.02M
    pdf14_device *pdev = (pdf14_device*) dev;
3864
1.02M
    cmm_profile_t *blend_profile = NULL;
3865
1.02M
    int k;
3866
3867
1.02M
    COPY_PARAM(width);
3868
1.02M
    COPY_PARAM(height);
3869
1.02M
    COPY_ARRAY_PARAM(MediaSize);
3870
1.02M
    COPY_ARRAY_PARAM(ImagingBBox);
3871
1.02M
    COPY_PARAM(ImagingBBox_set);
3872
1.02M
    COPY_ARRAY_PARAM(HWResolution);
3873
1.02M
    COPY_ARRAY_PARAM(Margins);
3874
1.02M
    COPY_ARRAY_PARAM(HWMargins);
3875
1.02M
    COPY_PARAM(PageCount);
3876
1.02M
    COPY_PARAM(MaxPatternBitmap);
3877
3878
3879
    /* Supposedly this function isn't supposed to change the color setup of dev.
3880
     * BUT... if we change the tags value, we have to change the color setup to
3881
     * keep it valid. This is because num_components and depth include tags. */
3882
1.02M
    copy_tag_setup(dev, target);
3883
1.02M
    COPY_PARAM(interpolate_control);
3884
1.02M
    COPY_PARAM(non_strict_bounds);
3885
1.02M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3886
3887
1.02M
    if (dev->icc_struct == NULL) {
3888
1.02M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3889
1.02M
        if (dev->icc_struct == NULL)
3890
0
            return_error(gs_error_VMerror);
3891
1.02M
        profile_dev14 = dev->icc_struct;
3892
1.02M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3893
1.02M
                                          &(profile_targ));
3894
3895
5.12M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3896
4.09M
            if (profile_targ->device_profile[k] != NULL) {
3897
1.02M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3898
1.02M
            }
3899
4.09M
            if (profile_dev14->device_profile[k] != NULL) {
3900
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3901
0
            }
3902
4.09M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3903
4.09M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3904
4.09M
        }
3905
3906
1.02M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3907
1.02M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3908
1.02M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3909
1.02M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3910
1.02M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3911
1.02M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3912
1.02M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3913
1.02M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3914
1.02M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3915
3916
1.02M
        switch (pdev->blend_cs_state) {
3917
1.02M
            case PDF14_BLEND_CS_UNSPECIFIED:
3918
1.02M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3919
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3920
                   during the device push, when we have
3921
                   access to the pgs */
3922
1.02M
                break;
3923
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3924
0
                blend_profile = profile_targ->oi_profile;
3925
0
                break;
3926
0
            case PDF14_BLEND_CS_SPECIFIED:
3927
0
                blend_profile = profile_targ->blend_profile;
3928
0
                break;
3929
0
            default:
3930
0
                break;
3931
1.02M
        }
3932
3933
1.02M
        if (blend_profile != NULL) {
3934
            /* Set the device profile to the blend profile. Note only default profile is set */
3935
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3936
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3937
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3938
0
        }
3939
3940
1.02M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3941
1.02M
    }
3942
1.02M
#undef COPY_ARRAY_PARAM
3943
1.02M
#undef COPY_PARAM
3944
1.02M
    return 0;
3945
1.02M
}
3946
3947
/*
3948
 * This is a forwarding version of the put_params device proc.  It is only
3949
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3950
 * check if the target device has closed and, if so, close itself.  The routine
3951
 * also sync the device parameters.
3952
 */
3953
static  int
3954
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3955
0
{
3956
0
    pdf14_device * pdev = (pdf14_device *)dev;
3957
0
    gx_device * tdev = pdev->target;
3958
0
    bool was_open = tdev->is_open;
3959
0
    int code = 0;
3960
3961
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3962
0
        gx_device_decache_colors(dev);
3963
0
        if (!tdev->is_open) {
3964
0
            code = gs_closedevice(dev);
3965
0
            if (code == 0)
3966
0
                code = was_open ? 1 : 0;   /* target device closed */
3967
0
        }
3968
0
        gx_device_copy_params(dev, tdev);
3969
0
    }
3970
0
    return code;
3971
0
}
3972
3973
/* Function prototypes */
3974
int put_param_pdf14_spot_names(gx_device * pdev,
3975
                gs_separations * pseparations, gs_param_list * plist);
3976
59.7k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3977
3978
/*
3979
 * The put_params method for the PDF 1.4 device will check if the
3980
 * target device has closed and, if so, close itself.  Note:  This routine is
3981
 * currently being used by both the pdf14_clist_device and the pdf_device.
3982
 * Please make sure that any changes are either applicable to both devices
3983
 * or clone the routine for each device.
3984
 */
3985
static  int
3986
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3987
0
{
3988
0
    pdf14_device * pdev = (pdf14_device *)dev;
3989
0
    gx_device * tdev = pdev->target;
3990
0
    bool was_open = tdev->is_open;
3991
0
    int code = 0, code2 = 0;
3992
3993
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3994
0
        gx_device_decache_colors(dev);
3995
0
        if (!tdev->is_open) {
3996
0
            code = gs_closedevice(dev);
3997
0
            if (code == 0)
3998
0
                code = was_open ? 1 : 0;   /* target device closed */
3999
0
        }
4000
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4001
0
        if (code2 < 0)
4002
0
            code = code2;
4003
0
    }
4004
0
    return code;
4005
0
}
4006
4007
/*
4008
 * Copy marking related parameters into the PDF 1.4 device structure for use
4009
 * by pdf14_fill_rectangle.
4010
 */
4011
static  void
4012
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4013
30.5M
{
4014
30.5M
    pdf14_device * pdev = (pdf14_device *)dev;
4015
4016
30.5M
    if (pgs->alphaisshape) {
4017
501k
        pdev->opacity = 1.0;
4018
501k
        if (pgs->is_fill_color) {
4019
490k
            pdev->shape = pgs->fillconstantalpha;
4020
490k
        } else {
4021
10.7k
            pdev->shape = pgs->strokeconstantalpha;
4022
10.7k
        }
4023
30.0M
    } else {
4024
30.0M
        pdev->shape = 1.0;
4025
30.0M
        if (pgs->is_fill_color) {
4026
10.9M
            pdev->opacity = pgs->fillconstantalpha;
4027
19.0M
        } else {
4028
19.0M
            pdev->opacity = pgs->strokeconstantalpha;
4029
19.0M
        }
4030
30.0M
    }
4031
30.5M
    pdev->alpha = pdev->opacity * pdev->shape;
4032
30.5M
    pdev->blend_mode = pgs->blend_mode;
4033
30.5M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4034
30.5M
        pdev->overprint = pgs->overprint;
4035
30.5M
        pdev->stroke_overprint = pgs->stroke_overprint;
4036
30.5M
    } else {
4037
0
        pdev->overprint = false;
4038
0
        pdev->stroke_overprint = false;
4039
0
    }
4040
4041
30.5M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4042
30.5M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4043
4044
30.5M
    if (pgs->is_fill_color)
4045
11.4M
        pdev->op_state = GS_OP_STATE_FILL;
4046
19.0M
    else
4047
19.0M
        pdev->op_state = GS_OP_STATE_STROKE;
4048
4049
30.5M
    if_debug6m('v', dev->memory,
4050
30.5M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4051
30.5M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4052
30.5M
               pdev->stroke_effective_op_mode);
4053
30.5M
}
4054
4055
static  void
4056
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4057
22.0M
{
4058
22.0M
    bool hastrans = false;
4059
4060
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4061
     * makes other operations much slower. We have no option however, if the
4062
     * current colour involves transparency, or if it's anything other than
4063
     * a completely solid (or transparent) operation in the normal blend mode.
4064
     */
4065
22.0M
    if (pdcolor != NULL)
4066
22.0M
    {
4067
22.0M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4068
444k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4069
4.98k
            hastrans = true;
4070
22.0M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4071
            /* FIXME: Here we assume that ALL type 2 patterns are
4072
             * transparent - this test could be better. */
4073
10.7k
            hastrans = true;
4074
10.7k
        }
4075
22.0M
    }
4076
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4077
       This appears to be the only place where this test is done so
4078
       not adding a is_idempotent method */
4079
22.0M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4080
118k
        pgs->blend_mode != BLEND_MODE_Darken &&
4081
113k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4082
21.9M
        (pgs->fillconstantalpha != 1.0) ||
4083
21.7M
        (pgs->strokeconstantalpha != 1.0) ||
4084
21.6M
        (hastrans))
4085
374k
    {
4086
        /*
4087
         * The blend operations are not idempotent.  Force non-idempotent
4088
         * filling and stroking operations.
4089
         */
4090
374k
        pgs->log_op |= lop_pdf14;
4091
374k
    }
4092
22.0M
}
4093
4094
static int
4095
push_shfill_group(pdf14_clist_device *pdev,
4096
                  gs_gstate *pgs,
4097
                  gs_fixed_rect *box)
4098
334
{
4099
334
    gs_transparency_group_params_t params = { 0 };
4100
334
    int code;
4101
334
    gs_rect cb;
4102
334
    gs_gstate fudged_pgs = *pgs;
4103
4104
334
    params.shade_group = true;
4105
4106
    /* gs_begin_transparency_group takes a bbox that it then
4107
     * transforms by ctm. Our bbox has already been transformed,
4108
     * so clear out the ctm. */
4109
334
    fudged_pgs.ctm.xx = 1.0;
4110
334
    fudged_pgs.ctm.xy = 0;
4111
334
    fudged_pgs.ctm.yx = 0;
4112
334
    fudged_pgs.ctm.yy = 1.0;
4113
334
    fudged_pgs.ctm.tx = 0;
4114
334
    fudged_pgs.ctm.ty = 0;
4115
334
    cb.p.x = fixed2int_pixround(box->p.x);
4116
334
    cb.p.y = fixed2int_pixround(box->p.y);
4117
334
    cb.q.x = fixed2int_pixround(box->q.x);
4118
334
    cb.q.y = fixed2int_pixround(box->q.y);
4119
4120
334
    params.Isolated = false;
4121
334
    params.Knockout = true;
4122
334
    params.page_group = false;
4123
334
    params.group_opacity = fudged_pgs.fillconstantalpha;
4124
334
    params.group_shape = 1.0;
4125
334
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4126
4127
    /* We have the group handle the blendmode and the opacity,
4128
     * and continue with the existing graphics state reset
4129
     * to normal, opaque operation. We could do it the other
4130
     * way around, but this way means that if we push a knockout
4131
     * group for a stroke, and then the code calls back into
4132
     * the fill operation as part of doing the stroking, we don't
4133
     * push another one. */
4134
334
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4135
334
    gs_setfillconstantalpha(pgs, 1.0);
4136
334
    gs_setstrokeconstantalpha(pgs, 1.0);
4137
334
    if (pdev) {
4138
334
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4139
334
        if (code < 0)
4140
0
            return code;
4141
334
    }
4142
4143
334
    return code;
4144
334
}
4145
4146
static int
4147
pop_shfill_group(gs_gstate *pgs)
4148
332
{
4149
332
     return gs_end_transparency_group(pgs);
4150
332
}
4151
4152
static int
4153
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4154
                           gx_path *ppath, const gx_fill_params *params,
4155
                           const gx_drawing_color *pdcolor,
4156
                           const gx_clip_path *pcpath)
4157
16.7M
{
4158
16.7M
    gs_gstate new_pgs = *pgs;
4159
16.7M
    int code = 0;
4160
16.7M
    gs_pattern2_instance_t *pinst = NULL;
4161
16.7M
    int push_group = 0;
4162
4163
16.7M
    code = pdf14_initialize_ctx(dev, pgs);
4164
16.7M
    if (code < 0)
4165
0
        return code;
4166
4167
16.7M
    if (pdcolor == NULL)
4168
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4169
16.7M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_STROKE;
4170
16.7M
    if (gx_dc_is_pattern1_color(pdcolor)){
4171
495k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4172
477k
            gx_pattern1_clist_has_trans(pdcolor) ){
4173
            /* In this case, we need to push a transparency group
4174
               and tile the pattern color, which is stored in
4175
               a pdf14 device buffer in the ctile object memember
4176
               variable ttrans */
4177
#if RAW_DUMP
4178
            /* Since we do not get a put_image to view what
4179
               we have do it now */
4180
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4181
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4182
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4183
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4184
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4185
                        ppatdev14->ctx->stack->rect.p.y *
4186
                        ppatdev14->ctx->stack->rowstride +
4187
                        ppatdev14->ctx->stack->rect.p.x;
4188
                    dump_raw_buffer(ppatdev14->ctx->memory,
4189
                                    (ppatdev14->ctx->stack->rect.q.y -
4190
                                     ppatdev14->ctx->stack->rect.p.y),
4191
                                    (ppatdev14->ctx->stack->rect.q.x -
4192
                                     ppatdev14->ctx->stack->rect.p.x),
4193
                                    ppatdev14->ctx->stack->n_planes,
4194
                                    ppatdev14->ctx->stack->planestride,
4195
                                    ppatdev14->ctx->stack->rowstride,
4196
                                    "Pattern_Fill", buf_ptr,
4197
                                    ppatdev14->ctx->stack->deep);
4198
                    global_index++;
4199
                } else {
4200
                     gx_pattern_trans_t *patt_trans =
4201
                                        pdcolor->colors.pattern.p_tile->ttrans;
4202
                     dump_raw_buffer(patt_trans->mem,
4203
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4204
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4205
                                     patt_trans->n_chan,
4206
                                     patt_trans->planestride, patt_trans->rowstride,
4207
                                     "Pattern_Fill_clist",
4208
                                     patt_trans->transbytes +
4209
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4210
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4211
                                     patt_trans->deep);
4212
                    global_index++;
4213
                }
4214
            }
4215
#endif
4216
59.3k
            pdf14_set_marking_params(dev, &new_pgs);
4217
59.3k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4218
59.3k
                params, pdcolor, pcpath);
4219
59.3k
            new_pgs.trans_device = NULL;
4220
59.3k
            new_pgs.has_transparency = false;
4221
59.3k
            return code;
4222
59.3k
        }
4223
495k
    }
4224
16.6M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4225
16.6M
        pdcolor->type == &gx_dc_devn_masked) {
4226
        /* Non-idempotent blends require a transparency
4227
         * group to be pushed because shadings might
4228
         * paint several pixels twice. */
4229
20
        push_group = pgs->fillconstantalpha != 1.0 ||
4230
20
               !blend_is_idempotent(gs_currentblendmode(pgs));
4231
20
        pinst =
4232
20
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4233
20
        pinst->saved->has_transparency = true;
4234
        /* The transparency color space operations are driven
4235
           by the pdf14 clist writer device.  */
4236
20
        pinst->saved->trans_device = dev;
4237
20
    }
4238
16.6M
    if (push_group) {
4239
0
        gs_fixed_rect box;
4240
0
        if (pcpath)
4241
0
            gx_cpath_outer_box(pcpath, &box);
4242
0
        else
4243
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4244
0
        if (ppath) {
4245
0
            gs_fixed_rect path_box;
4246
4247
0
            gx_path_bbox(ppath, &path_box);
4248
0
            if (box.p.x < path_box.p.x)
4249
0
                box.p.x = path_box.p.x;
4250
0
            if (box.p.y < path_box.p.y)
4251
0
                box.p.y = path_box.p.y;
4252
0
            if (box.q.x > path_box.q.x)
4253
0
                box.q.x = path_box.q.x;
4254
0
            if (box.q.y > path_box.q.y)
4255
0
                box.q.y = path_box.q.y;
4256
0
        }
4257
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4258
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4259
0
    } else
4260
16.6M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4261
16.6M
    pdf14_set_marking_params(dev, &new_pgs);
4262
16.6M
    if (code >= 0) {
4263
16.6M
        new_pgs.trans_device = dev;
4264
16.6M
        new_pgs.has_transparency = true;
4265
        /* ppath can permissibly be NULL here, if we want to have a
4266
         * shading or a pattern fill the clipping path. This upsets
4267
         * coverity, which is not smart enough to realise that the
4268
         * validity of a NULL ppath depends on the type of pdcolor.
4269
         * We'll mark it as a false positive. */
4270
16.6M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4271
16.6M
        new_pgs.trans_device = NULL;
4272
16.6M
        new_pgs.has_transparency = false;
4273
16.6M
    }
4274
16.6M
    if (code >= 0 && push_group) {
4275
0
        code = pop_shfill_group(&new_pgs);
4276
0
        pdf14_set_marking_params(dev, pgs);
4277
0
    }
4278
16.6M
    if (pinst != NULL){
4279
20
        pinst->saved->trans_device = NULL;
4280
20
    }
4281
16.6M
    return code;
4282
16.7M
}
4283
4284
static  int
4285
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4286
                             gx_path *ppath, const gx_stroke_params *params,
4287
                             const gx_drawing_color *pdcolor,
4288
                             const gx_clip_path *pcpath)
4289
4.16M
{
4290
4.16M
    gs_gstate new_pgs = *pgs;
4291
4.16M
    int push_group = 0;
4292
4.16M
    int code = 0;
4293
4294
4.16M
    if (pdcolor == NULL)
4295
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4296
4297
4.16M
    code = pdf14_initialize_ctx(dev, pgs);
4298
4.16M
    if (code < 0)
4299
0
        return code;
4300
4301
4.16M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4302
        /* Non-idempotent blends require a transparency
4303
         * group to be pushed because shadings might
4304
         * paint several pixels twice. */
4305
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4306
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4307
0
    }
4308
4.16M
    if (push_group) {
4309
0
        gs_fixed_rect box;
4310
0
        if (pcpath)
4311
0
            gx_cpath_outer_box(pcpath, &box);
4312
0
        else
4313
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4314
4315
        /* For fill_path, we accept ppath == NULL to mean
4316
         * fill the entire clipping region. That makes no
4317
         * sense for stroke_path, hence ppath is always non
4318
         * NULL here. */
4319
0
        {
4320
0
            gs_fixed_rect path_box;
4321
0
            gs_fixed_point expansion;
4322
4323
0
            gx_path_bbox(ppath, &path_box);
4324
            /* Expand the path bounding box by the scaled line width. */
4325
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4326
                /* The expansion is so large it caused a limitcheck. */
4327
0
                path_box.p.x = path_box.p.y = min_fixed;
4328
0
                path_box.q.x = path_box.q.y = max_fixed;
4329
0
            } else {
4330
0
                expansion.x += pgs->fill_adjust.x;
4331
0
                expansion.y += pgs->fill_adjust.y;
4332
                /*
4333
                 * It's theoretically possible for the following computations to
4334
                 * overflow, so we need to check for this.
4335
                 */
4336
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4337
0
                                path_box.p.x - expansion.x);
4338
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4339
0
                                path_box.p.y - expansion.y);
4340
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4341
0
                                path_box.q.x + expansion.x);
4342
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4343
0
                                path_box.q.y + expansion.y);
4344
0
            }
4345
0
            if (box.p.x < path_box.p.x)
4346
0
                box.p.x = path_box.p.x;
4347
0
            if (box.p.y < path_box.p.y)
4348
0
                box.p.y = path_box.p.y;
4349
0
            if (box.q.x > path_box.q.x)
4350
0
                box.q.x = path_box.q.x;
4351
0
            if (box.q.y > path_box.q.y)
4352
0
                box.q.y = path_box.q.y;
4353
0
        }
4354
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4355
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4356
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4357
0
    } else
4358
4.16M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4359
4.16M
    pdf14_set_marking_params(dev, &new_pgs);
4360
4.16M
    if (code >= 0) {
4361
4.16M
        GS_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4362
4363
4.16M
        ((pdf14_device*)dev)->op_state = GS_OP_STATE_STROKE;
4364
4.16M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4365
4.16M
        ((pdf14_device*)dev)->op_state = save_op_state;
4366
4.16M
    }
4367
4.16M
    if (code >= 0 && push_group) {
4368
0
        code = pop_shfill_group(&new_pgs);
4369
0
        pdf14_set_marking_params(dev, pgs);
4370
0
    }
4371
4372
4.16M
    return code;
4373
4.16M
}
4374
4375
/* Pull out steps of transparency updates for fill/stroke
4376
   so that they can be invoked elsewhere (e.g.
4377
   when the abuf device is handling the stroke/fill */
4378
4379
/* Set-up prior to fill operation in fill-stroke */
4380
static int
4381
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4382
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4383
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4384
21.5k
{
4385
21.5k
    int code = 0;
4386
21.5k
    gs_transparency_group_params_t params = { 0 };
4387
21.5k
    gs_fixed_rect clip_bbox;
4388
21.5k
    gs_rect bbox, group_stroke_box;
4389
21.5k
    gs_fixed_rect path_bbox;
4390
21.5k
    int expansion_code;
4391
21.5k
    gs_fixed_point expansion;
4392
21.5k
    pdf14_device* p14dev = (pdf14_device*)dev;
4393
4394
21.5k
    *path_empty = false;
4395
4396
21.5k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4397
21.4k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4398
54
    {
4399
54
        *op_ca_eq_CA = true;
4400
54
        *path_empty = true;
4401
54
        return 0;
4402
54
    }
4403
4404
    /* The clip box returned here is scaled up by path_log2scale, so we need
4405
     * to scale down by this later. */
4406
21.4k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4407
21.4k
    if (code < 0 && code != gs_error_unknownerror)
4408
0
        return code;
4409
4410
21.4k
    if (code == gs_error_unknownerror) {
4411
        /* didn't get clip box from gx_curr_fixed_bbox */
4412
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4413
         * scaling down by this in a moment. */
4414
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4415
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4416
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4417
0
    }
4418
    /* pcpath->outer_box is scaled by path_log2scale too. */
4419
21.4k
    if (pcpath)
4420
21.4k
        rect_intersect(clip_bbox, pcpath->outer_box);
4421
4422
    /* expand the ppath using stroke expansion rule, then intersect it */
4423
21.4k
    code = gx_path_bbox(ppath, &path_bbox);
4424
4425
    /* If we are coming from the abuf device, the path has been scaled
4426
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4427
       on the path_bbox so that we get the proper bounding box for our group. */
4428
21.4k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4429
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4430
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4431
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4432
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4433
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4434
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4435
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4436
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4437
0
    }
4438
4439
21.4k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4440
1.93k
        *path_empty = true;
4441
1.93k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4442
                     there are simply too many return cases that I can't account for. */
4443
1.93k
    }
4444
19.5k
    if (code < 0)
4445
0
        return code;
4446
4447
19.5k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4448
19.5k
    if (expansion_code >= 0) {
4449
19.4k
        path_bbox.p.x -= expansion.x;
4450
19.4k
        path_bbox.p.y -= expansion.y;
4451
19.4k
        path_bbox.q.x += expansion.x;
4452
19.4k
        path_bbox.q.y += expansion.y;
4453
19.4k
    }
4454
19.5k
    rect_intersect(path_bbox, clip_bbox);
4455
19.5k
    bbox.p.x = fixed2float(path_bbox.p.x);
4456
19.5k
    bbox.p.y = fixed2float(path_bbox.p.y);
4457
19.5k
    bbox.q.x = fixed2float(path_bbox.q.x);
4458
19.5k
    bbox.q.y = fixed2float(path_bbox.q.y);
4459
4460
19.5k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4461
19.5k
    if (code < 0)
4462
2
        return code;
4463
4464
19.5k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4465
0
        p14dev->overprint = pgs->overprint;
4466
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4467
0
    }
4468
4469
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4470
19.5k
    if (fill_alpha == stroke_alpha &&
4471
4.70k
        p14dev->overprint && p14dev->stroke_overprint &&
4472
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4473
4474
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4475
           compatible overprint mode.  Group will be composited with
4476
           original alpha and blend mode */
4477
0
        *op_ca_eq_CA = true;
4478
0
        params.Isolated = false;
4479
0
        params.group_color_type = UNKNOWN;
4480
0
        params.Knockout = false;
4481
0
        params.page_group = false;
4482
0
        params.group_opacity = 1.0;
4483
0
        params.group_shape = fill_alpha;
4484
4485
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4486
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4487
0
        if (code < 0)
4488
0
            return code;
4489
4490
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4491
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4492
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4493
4494
19.5k
    } else {
4495
        /* Push a non-isolated knockout group. Do not change the alpha or
4496
            blend modes. Note: we need to draw those that have alpha = 0 */
4497
19.5k
        *op_ca_eq_CA = false;
4498
19.5k
        params.Isolated = false;
4499
19.5k
        params.group_color_type = UNKNOWN;
4500
19.5k
        params.Knockout = true;
4501
19.5k
        params.page_group = false;
4502
19.5k
        params.group_shape = 1.0;
4503
19.5k
        params.group_opacity = 1.0;
4504
4505
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4506
19.5k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4507
19.5k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4508
19.5k
        if (code < 0)
4509
0
            return code;
4510
4511
        /* restore blend mode for actual drawing in the group */
4512
19.5k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4513
4514
        /* If we are in an overprint situation, set the blend mode to compatible
4515
            overprint */
4516
19.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4517
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4518
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4519
19.5k
    }
4520
19.5k
    p14dev->op_state = GS_OP_STATE_FILL;
4521
19.5k
    return code;
4522
19.5k
}
4523
4524
/* Set-up prior to stroke operation in fill-stroke */
4525
static void
4526
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4527
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4528
19.5k
{
4529
19.5k
    pdf14_device* p14dev = (pdf14_device*)dev;
4530
4531
19.5k
    if (op_ca_eq_CA) {
4532
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4533
19.5k
    } else {
4534
19.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4535
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4536
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4537
4538
        /* Note that the stroke can end up doing fill methods */
4539
19.5k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4540
4541
19.5k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4542
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4543
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4544
19.5k
    }
4545
19.5k
    p14dev->op_state = GS_OP_STATE_STROKE;
4546
19.5k
}
4547
4548
/* Cleanup after the stroke in fill-stroke  */
4549
static int
4550
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4551
19.5k
{
4552
19.5k
    int code;
4553
4554
19.5k
    if (!op_ca_eq_CA) {
4555
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4556
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4557
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4558
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4559
          * We therefore need to make sure it is set according to the current fill state.
4560
          */
4561
19.5k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4562
19.5k
        code = gs_update_trans_marking_params(pgs);
4563
19.5k
        if (code < 0)
4564
0
            return code;
4565
19.5k
        pdf14_set_marking_params(dev, pgs);
4566
19.5k
    }
4567
4568
19.5k
    return 0;
4569
19.5k
}
4570
4571
/* cleanup in fill-stroke  */
4572
static int
4573
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4574
    gs_blend_mode_t blend_mode, GS_OP_FS_STATE save_op_state)
4575
19.5k
{
4576
19.5k
    pdf14_device* p14dev = (pdf14_device*)dev;
4577
19.5k
    int code2;
4578
19.5k
    int code = 0;
4579
4580
    /* Restore the state */
4581
19.5k
    p14dev->op_state = save_op_state;
4582
19.5k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4583
19.5k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4584
19.5k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4585
4586
19.5k
    code2 = gs_end_transparency_group(pgs);
4587
19.5k
    if (code2 < 0) {
4588
        /* At this point things have gone very wrong. We should just shut down */
4589
0
        code = gs_abort_pdf14trans_device(pgs);
4590
0
        return code2;
4591
0
    }
4592
19.5k
    return code;
4593
19.5k
}
4594
4595
static int
4596
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4597
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4598
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4599
    const gx_clip_path *pcpath)
4600
85.6k
{
4601
85.6k
    bool op_ca_eq_CA;
4602
85.6k
    bool path_empty;
4603
85.6k
    int code;
4604
85.6k
    float stroke_alpha = cpgs->strokeconstantalpha;
4605
85.6k
    float fill_alpha = cpgs->fillconstantalpha;
4606
85.6k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4607
85.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4608
85.6k
    GS_OP_FS_STATE save_op_state = p14dev->op_state;
4609
85.6k
    gs_log2_scale_point path_log2scale;
4610
85.6k
    bool group_needed = true;
4611
85.6k
    gx_device* curr_pgs_dev = cpgs->device;
4612
4613
85.6k
    union {
4614
85.6k
        const gs_gstate* cpgs;
4615
85.6k
        gs_gstate* pgs;
4616
85.6k
    } const_breaker;
4617
85.6k
    gs_gstate* pgs;
4618
4619
    /* Break const just once, neatly */
4620
85.6k
    const_breaker.cpgs = cpgs;
4621
85.6k
    pgs = const_breaker.pgs;
4622
85.6k
    path_log2scale.x = 0;
4623
85.6k
    path_log2scale.y = 0;
4624
4625
85.6k
    code = pdf14_initialize_ctx(dev, pgs);
4626
85.6k
    if (code < 0)
4627
0
        return code;
4628
4629
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4630
     * blend is normal we don't do a group push. Just do the stroke
4631
     * and the fill, even with overprint */
4632
85.6k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4633
64.0k
        group_needed = false;
4634
4635
85.6k
    if (group_needed) {
4636
21.5k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4637
                              can be called on the clist writer side when dealing
4638
                              with the abuf/pdf14 interaction. Those calls have to
4639
                              go through the gs_trans API not the gx_trans or pdf14
4640
                              methods.  Perhaps these methods should have a different
4641
                              suffix, but they are static methods here in the pdf14
4642
                              file. */
4643
21.5k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4644
21.5k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4645
21.5k
        pgs->device = curr_pgs_dev;
4646
21.5k
        if (code < 0)
4647
2
            goto cleanup;
4648
21.5k
        if (path_empty)
4649
1.99k
            return 0;
4650
21.5k
    }
4651
4652
83.6k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4653
83.6k
    if (code < 0)
4654
0
        goto cleanup;
4655
4656
83.6k
    if (group_needed)
4657
19.5k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4658
83.6k
    gs_swapcolors_quick(pgs);
4659
4660
4661
#if RAW_DUMP
4662
    /* Dump the current buffer to see what we have. */
4663
    dump_raw_buffer(p14dev->ctx->memory,
4664
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4665
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4666
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4667
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4668
    global_index++;
4669
#endif
4670
4671
83.6k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4672
83.6k
    gs_swapcolors_quick(pgs);
4673
83.6k
    if (code < 0) {
4674
0
        goto cleanup;
4675
0
    }
4676
4677
#if RAW_DUMP
4678
    /* Dump the current buffer to see what we have. */
4679
    dump_raw_buffer(p14dev->ctx->memory,
4680
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4681
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4682
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4683
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4684
    global_index++;
4685
#endif
4686
83.6k
    if (group_needed)
4687
19.5k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4688
4689
83.6k
cleanup:
4690
83.6k
    if (group_needed) {
4691
19.5k
        int code1;
4692
19.5k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4693
19.5k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4694
19.5k
            save_op_state);
4695
19.5k
        if (code1 < 0)
4696
0
            code = code1;
4697
19.5k
        pgs->device = curr_pgs_dev;
4698
19.5k
    }
4699
83.6k
    return code;
4700
83.6k
}
4701
4702
static int
4703
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4704
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4705
                      gx_color_index color, int depth)
4706
0
{
4707
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4708
0
                                  color, NULL, depth, false);
4709
0
}
4710
4711
static int
4712
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4713
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4714
                      const gx_drawing_color *pdcolor, int depth)
4715
0
{
4716
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4717
0
                                  0, pdcolor, depth, true);
4718
0
}
4719
4720
static int
4721
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4722
                          int aa_raster, gx_bitmap_id id, int x, int y,
4723
                          int w, int h, gx_color_index color,
4724
                          const gx_device_color *pdc, int depth, bool devn)
4725
0
{
4726
0
    const byte *aa_row;
4727
0
    pdf14_device *pdev = (pdf14_device *)dev;
4728
0
    pdf14_buf *buf = pdev->ctx->stack;
4729
0
    int i, j, k;
4730
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4731
0
    byte src[PDF14_MAX_PLANES];
4732
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4733
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4734
0
    bool additive = pdev->ctx->additive;
4735
0
    intptr_t rowstride = buf->rowstride;
4736
0
    intptr_t planestride = buf->planestride;
4737
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4738
0
    bool has_alpha_g = buf->has_alpha_g;
4739
0
    bool has_shape = buf->has_shape;
4740
0
    bool has_tags = buf->has_tags;
4741
0
    bool knockout = buf->knockout;
4742
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4743
0
        blend_mode == BLEND_MODE_Compatible ||
4744
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4745
0
    int num_chan = buf->n_chan;
4746
0
    int num_comp = num_chan - 1;
4747
0
    intptr_t shape_off = num_chan * planestride;
4748
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4749
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4750
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4751
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4752
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4753
0
    gx_color_index comps;
4754
0
    byte shape = 0; /* Quiet compiler. */
4755
0
    byte src_alpha;
4756
0
    int alpha2_aa, alpha_aa, sx;
4757
0
    int alpha_aa_act;
4758
0
    int xoff;
4759
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4760
0
    int shift = 8;
4761
0
    bool has_backdrop = buf->backdrop != NULL;
4762
4763
0
    if (buf->data == NULL)
4764
0
        return 0;
4765
0
    aa_row = data;
4766
0
    if (has_tags) {
4767
0
        if (devn)
4768
0
            curr_tag = pdc->tag;
4769
0
        else
4770
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4771
0
    }
4772
4773
0
    if (devn) {
4774
0
        if (additive) {
4775
0
            for (j = 0; j < num_comp; j++) {
4776
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4777
0
            }
4778
0
        } else {
4779
0
            for (j = 0; j < num_comp; j++) {
4780
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4781
0
            }
4782
0
        }
4783
0
    } else
4784
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4785
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4786
0
    if (has_shape)
4787
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4788
    /* Limit the area we write to the bounding rectangle for this buffer */
4789
0
    if (x < buf->rect.p.x) {
4790
0
        xoff = data_x + buf->rect.p.x - x;
4791
0
        w += x - buf->rect.p.x;
4792
0
        x = buf->rect.p.x;
4793
0
    } else {
4794
0
        xoff = data_x;
4795
0
    }
4796
0
    if (y < buf->rect.p.y) {
4797
0
      h += y - buf->rect.p.y;
4798
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4799
0
      y = buf->rect.p.y;
4800
0
    }
4801
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4802
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4803
    /* Update the dirty rectangle. */
4804
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4805
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4806
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4807
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4808
4809
    /* composite with backdrop only. */
4810
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4811
0
    if (knockout && has_backdrop)
4812
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4813
0
    else
4814
0
        bline = line;
4815
4816
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4817
0
        back_ptr = bline;
4818
0
        dst_ptr = line;
4819
0
        sx = xoff;
4820
0
        for (i = 0; i < w; ++i, ++sx) {
4821
            /* Complement the components for subtractive color spaces */
4822
0
            if (additive) {
4823
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4824
0
                    dst[k] = back_ptr[k * planestride];
4825
0
            } else { /* Complement the components for subtractive color spaces */
4826
0
                for (k = 0; k < num_comp; ++k)
4827
0
                    dst[k] = 255 - back_ptr[k * planestride];
4828
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4829
0
            }
4830
            /* Get the aa alpha from the buffer */
4831
0
            switch(depth)
4832
0
            {
4833
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4834
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4835
0
                break;
4836
0
            case 4:
4837
0
                alpha2_aa = aa_row[sx >> 1];
4838
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4839
0
                break;
4840
0
            case 8:
4841
0
                alpha_aa = aa_row[sx];
4842
0
                break;
4843
0
            default:
4844
0
                return_error(gs_error_rangecheck);
4845
0
            }
4846
0
            if (alpha_aa != 0) {  /* This does happen */
4847
0
                if (alpha_aa != 255) {
4848
                    /* We have an alpha value from aa */
4849
0
                    alpha_aa_act = alpha_aa;
4850
0
                    if (src_alpha != 255) {
4851
                        /* Need to combine it with the existing alpha */
4852
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4853
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4854
0
                    }
4855
                    /* Set our source alpha value appropriately */
4856
0
                    src[num_comp] = alpha_aa_act;
4857
0
                } else {
4858
                    /* We may have to reset this is it was changed as we
4859
                       moved across the row */
4860
0
                    src[num_comp] = src_alpha;
4861
0
                }
4862
0
                if (knockout) {
4863
0
                    if (buf->isolated) {
4864
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4865
0
                    } else {
4866
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4867
0
                            blend_mode, pdev->blend_procs, pdev);
4868
0
                    }
4869
0
                } else {
4870
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4871
0
                                                    pdev->blend_procs, pdev);
4872
0
                }
4873
                /* Complement the results for subtractive color spaces */
4874
0
                if (additive) {
4875
0
                    for (k = 0; k < num_chan; ++k)
4876
0
                        dst_ptr[k * planestride] = dst[k];
4877
0
                } else {
4878
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4879
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4880
0
                                ++k, comps >>= 1) {
4881
0
                            if ((comps & 0x1) != 0) {
4882
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4883
0
                            }
4884
0
                        }
4885
                        /* The alpha channel */
4886
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4887
0
                    } else {
4888
0
                        for (k = 0; k < num_comp; ++k)
4889
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4890
                        /* The alpha channel */
4891
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4892
0
                    }
4893
0
                }
4894
0
                if (has_alpha_g) {
4895
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4896
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4897
0
                }
4898
0
                if (has_shape) {
4899
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4900
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4901
0
                }
4902
0
                if (has_tags) {
4903
                    /* If alpha is 100% then set to curr_tag, else or */
4904
                    /* other than Normal BM, we always OR */
4905
0
                    if (src[num_comp] == 255 && tag_blend) {
4906
0
                        dst_ptr[tag_off] = curr_tag;
4907
0
                    } else {
4908
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4909
0
                    }
4910
0
                }
4911
0
            }
4912
0
            ++dst_ptr;
4913
0
            ++back_ptr;
4914
0
        }
4915
0
        line += rowstride;
4916
0
        bline += rowstride;
4917
0
    }
4918
0
    return 0;
4919
0
}
4920
4921
static int
4922
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4923
                             int aa_raster, gx_bitmap_id id, int x, int y,
4924
                             int w, int h, gx_color_index color,
4925
                             const gx_device_color *pdc, int depth, bool devn)
4926
0
{
4927
0
    const byte *aa_row;
4928
0
    pdf14_device *pdev = (pdf14_device *)dev;
4929
0
    pdf14_buf *buf = pdev->ctx->stack;
4930
0
    int i, j, k;
4931
0
    byte *bline, *line;
4932
0
    uint16_t *dst_ptr, *back_ptr;
4933
0
    uint16_t src[PDF14_MAX_PLANES];
4934
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4935
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4936
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4937
0
        blend_mode == BLEND_MODE_Compatible ||
4938
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4939
0
    bool additive = pdev->ctx->additive;
4940
0
    intptr_t rowstride = buf->rowstride;
4941
0
    int planestride = buf->planestride;
4942
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4943
0
    bool has_alpha_g = buf->has_alpha_g;
4944
0
    bool has_shape = buf->has_shape;
4945
0
    bool has_tags = buf->has_tags;
4946
0
    bool knockout = buf->knockout;
4947
0
    int num_chan = buf->n_chan;
4948
0
    int num_comp = num_chan - 1;
4949
0
    intptr_t shape_off = num_chan * planestride;
4950
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4951
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4952
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4953
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4954
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4955
0
    gx_color_index comps;
4956
0
    uint16_t shape = 0; /* Quiet compiler. */
4957
0
    uint16_t src_alpha;
4958
0
    int alpha2_aa, alpha_aa, sx;
4959
0
    int alpha_aa_act;
4960
0
    int xoff;
4961
0
    bool has_backdrop = buf->backdrop != NULL;
4962
4963
0
    if (buf->data == NULL)
4964
0
        return 0;
4965
0
    aa_row = data;
4966
0
    if (has_tags) {
4967
0
        if (devn)
4968
0
            curr_tag = pdc->tag;
4969
0
        else
4970
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4971
0
    }
4972
4973
0
    if (devn) {
4974
0
        if (additive) {
4975
0
            for (j = 0; j < num_comp; j++) {
4976
0
                src[j] = pdc->colors.devn.values[j];
4977
0
            }
4978
0
        } else {
4979
0
            for (j = 0; j < num_comp; j++) {
4980
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4981
0
            }
4982
0
        }
4983
0
    } else
4984
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4985
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4986
0
    if (has_shape)
4987
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4988
    /* Limit the area we write to the bounding rectangle for this buffer */
4989
0
    if (x < buf->rect.p.x) {
4990
0
        xoff = data_x + buf->rect.p.x - x;
4991
0
        w += x - buf->rect.p.x;
4992
0
        x = buf->rect.p.x;
4993
0
    } else {
4994
0
        xoff = data_x;
4995
0
    }
4996
0
    if (y < buf->rect.p.y) {
4997
0
      h += y - buf->rect.p.y;
4998
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4999
0
      y = buf->rect.p.y;
5000
0
    }
5001
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5002
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5003
    /* Update the dirty rectangle. */
5004
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5005
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5006
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5007
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5008
5009
    /* composite with backdrop only. */
5010
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5011
0
    if (knockout && has_backdrop)
5012
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5013
0
    else
5014
0
        bline = line;
5015
5016
0
    planestride >>= 1;
5017
0
    rowstride   >>= 1;
5018
0
    alpha_g_off >>= 1;
5019
0
    shape_off   >>= 1;
5020
0
    tag_off     >>= 1;
5021
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5022
0
        back_ptr = (uint16_t *)(void *)bline;
5023
0
        dst_ptr = (uint16_t *)(void *)line;
5024
0
        sx = xoff;
5025
0
        for (i = 0; i < w; ++i, ++sx) {
5026
            /* Complement the components for subtractive color spaces */
5027
0
            if (additive) {
5028
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5029
0
                    dst[k] = back_ptr[k * planestride];
5030
0
            } else { /* Complement the components for subtractive color spaces */
5031
0
                for (k = 0; k < num_comp; ++k)
5032
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5033
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5034
0
            }
5035
            /* Get the aa alpha from the buffer */
5036
0
            switch(depth)
5037
0
            {
5038
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5039
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5040
0
                break;
5041
0
            case 4:
5042
0
                alpha2_aa = aa_row[sx >> 1];
5043
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5044
0
                break;
5045
0
            case 8:
5046
0
                alpha_aa = aa_row[sx];
5047
0
                break;
5048
0
            default:
5049
0
                return_error(gs_error_rangecheck);
5050
0
            }
5051
0
            if (alpha_aa != 0) {  /* This does happen */
5052
0
                if (alpha_aa != 255) {
5053
                    /* We have an alpha value from aa */
5054
0
                    alpha_aa_act = alpha_aa * 0x101;
5055
0
                    if (src_alpha != 65535) {
5056
                        /* Need to combine it with the existing alpha */
5057
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5058
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5059
0
                    }
5060
                    /* Set our source alpha value appropriately */
5061
0
                    src[num_comp] = alpha_aa_act;
5062
0
                } else {
5063
                    /* We may have to reset this is it was changed as we
5064
                       moved across the row */
5065
0
                    src[num_comp] = src_alpha;
5066
0
                }
5067
0
                if (knockout) {
5068
0
                    if (buf->isolated) {
5069
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5070
0
                    } else {
5071
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5072
0
                            blend_mode, pdev->blend_procs, pdev);
5073
0
                    }
5074
0
                } else {
5075
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5076
0
                                                     pdev->blend_procs, pdev);
5077
0
                }
5078
                /* Complement the results for subtractive color spaces */
5079
0
                if (additive) {
5080
0
                    for (k = 0; k < num_chan; ++k)
5081
0
                        dst_ptr[k * planestride] = dst[k];
5082
0
                } else {
5083
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5084
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5085
0
                                ++k, comps >>= 1) {
5086
0
                            if ((comps & 0x1) != 0) {
5087
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5088
0
                            }
5089
0
                        }
5090
                        /* The alpha channel */
5091
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5092
0
                    } else {
5093
0
                        for (k = 0; k < num_comp; ++k)
5094
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5095
                        /* The alpha channel */
5096
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5097
0
                    }
5098
0
                }
5099
0
                if (has_alpha_g) {
5100
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5101
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5102
0
                }
5103
0
                if (has_shape) {
5104
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5105
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5106
0
                }
5107
0
                if (has_tags) {
5108
                    /* If alpha is 100% then set to curr_tag, else or */
5109
                    /* other than Normal BM, we always OR */
5110
0
                    if (src[num_comp] == 65535 && tag_blend) {
5111
0
                        dst_ptr[tag_off] = curr_tag;
5112
0
                    } else {
5113
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5114
0
                    }
5115
0
                }
5116
0
            }
5117
0
            ++dst_ptr;
5118
0
            ++back_ptr;
5119
0
        }
5120
0
        line += rowstride;
5121
0
        bline += rowstride;
5122
0
    }
5123
0
    return 0;
5124
0
}
5125
5126
static int
5127
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5128
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5129
                      gx_color_index color, const gx_device_color *pdc,
5130
                      int depth, bool devn)
5131
0
{
5132
0
    bool deep = device_is_deep(dev);
5133
0
    int code;
5134
5135
0
    code = pdf14_initialize_ctx(dev, NULL);
5136
0
    if (code < 0)
5137
0
        return code;
5138
5139
0
    if (deep)
5140
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5141
0
                                            id, x, y, w, h,
5142
0
                                            color, pdc, depth, devn);
5143
0
    else
5144
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5145
0
                                         id, x, y, w, h,
5146
0
                                         color, pdc, depth, devn);
5147
0
}
5148
5149
static  int
5150
pdf14_fill_mask(gx_device * orig_dev,
5151
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5152
                     int x, int y, int w, int h,
5153
                     const gx_drawing_color * pdcolor, int depth,
5154
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5155
12.1M
{
5156
12.1M
    gx_device *dev;
5157
12.1M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5158
12.1M
    gx_device_clip cdev;
5159
12.1M
    gx_color_tile *ptile = NULL;
5160
12.1M
    int code = 0;
5161
12.1M
    gs_int_rect group_rect;
5162
12.1M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5163
12.1M
    bool has_pattern_trans = false;
5164
12.1M
    cmm_dev_profile_t *dev_profile;
5165
5166
12.1M
    if (pdcolor == NULL)
5167
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5168
5169
12.1M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5170
12.1M
    if (code < 0)
5171
0
        return code;
5172
5173
    /* If we are doing a fill with a pattern that has a transparency then
5174
       go ahead and do a push and a pop of the transparency group */
5175
12.1M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5176
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5177
0
            ptile = pdcolor->colors.pattern.p_tile;
5178
            /* Set up things in the ptile so that we get the proper
5179
               blending etc */
5180
            /* Set the blending procs and the is_additive setting based
5181
               upon the number of channels */
5182
0
            if (ptile->ttrans->n_chan-1 < 4) {
5183
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5184
0
                ptile->ttrans->is_additive = true;
5185
0
            } else {
5186
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5187
0
                ptile->ttrans->is_additive = false;
5188
0
            }
5189
            /* Set the procs so that we use the proper filling method. */
5190
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5191
            /* Based upon if the tiles overlap pick the type of rect
5192
               fill that we will want to use */
5193
0
            if (ptile->has_overlap) {
5194
                /* This one does blending since there is tile overlap */
5195
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5196
0
            } else {
5197
                /* This one does no blending since there is no tile overlap */
5198
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5199
0
            }
5200
            /* Push the group */
5201
0
            group_rect.p.x = x;
5202
0
            group_rect.p.y = max(0,y);
5203
0
            group_rect.q.x = x + w;
5204
0
            group_rect.q.y = y + h;
5205
0
            if (!(w <= 0 || h <= 0)) {
5206
5207
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5208
0
                if (group_color_info == NULL)
5209
0
                    return_error(gs_error_VMerror);
5210
5211
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5212
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5213
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5214
0
                     group_color_info, NULL, NULL);
5215
0
                if (code < 0)
5216
0
                    return code;
5217
                /* Set up the output buffer information now that we have
5218
                   pushed the group */
5219
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5220
0
                if (fill_trans_buffer == NULL)
5221
0
                    return_error(gs_error_VMerror);
5222
5223
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5224
0
                                              fill_trans_buffer, NULL, false);
5225
                /* Store this in the appropriate place in pdcolor.  This
5226
                   is released later after the mask fill */
5227
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5228
0
                has_pattern_trans = true;
5229
0
            }
5230
0
        }
5231
0
    }
5232
12.1M
    if (pcpath != 0) {
5233
1.42M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5234
1.42M
        dev = (gx_device *) & cdev;
5235
1.42M
    } else
5236
10.6M
        dev = orig_dev;
5237
12.1M
    if (depth > 1) {
5238
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5239
0
        code = (*dev_proc(dev, copy_alpha))
5240
0
            (dev, data, dx, raster, id, x, y, w, h,
5241
0
             gx_dc_pure_color(pdcolor), depth);
5242
12.1M
    } else {
5243
12.1M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5244
12.1M
                                          x, y, w, h, dev, lop, false);
5245
12.1M
    }
5246
12.1M
    if (has_pattern_trans) {
5247
0
        bool has_tags = device_encodes_tags(dev);
5248
0
        if (code >= 0)
5249
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5250
0
        if (code >= 0)
5251
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5252
0
                                                p14dev->blend_procs,
5253
0
                                                p14dev->color_info.num_components - has_tags,
5254
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5255
0
                                                orig_dev);
5256
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5257
0
                       "pdf14_fill_mask");
5258
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5259
0
    }
5260
12.1M
    if (pcpath != 0)
5261
1.42M
        gx_destroy_clip_device_on_stack(&cdev);
5262
12.1M
    return code;
5263
12.1M
}
5264
5265
5266
5267
/* Used for filling rects when we are doing a fill with a pattern that
5268
   has transparency */
5269
static  int
5270
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5271
                        gx_path * ppath, const gx_fill_params * params,
5272
                        const gx_device_color * pdevc,
5273
                        const gx_clip_path * pcpath)
5274
59.3k
{
5275
59.3k
    int code;
5276
59.3k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5277
59.3k
    gs_fixed_rect clip_box;
5278
59.3k
    gs_fixed_rect outer_box;
5279
59.3k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5280
59.3k
    gs_int_rect rect;
5281
59.3k
    gx_clip_rect *curr_clip_rect;
5282
59.3k
    gx_color_tile *ptile = NULL;
5283
59.3k
    int k;
5284
59.3k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5285
59.3k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5286
59.3k
    int n_chan_tile;
5287
59.3k
    gx_clip_path cpath_intersection;
5288
59.3k
    gx_path path_ttrans;
5289
59.3k
    pdf14_group_color_t *group_color_info;
5290
59.3k
    bool has_tags = device_encodes_tags(pdev);
5291
5292
59.3k
    if (ppath == NULL)
5293
0
        return_error(gs_error_unknownerror);  /* should not happen */
5294
59.3k
    if (pcpath != NULL) {
5295
55.9k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5296
55.9k
    } else {
5297
3.44k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5298
3.44k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5299
3.44k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5300
3.44k
    }
5301
59.3k
    if (code < 0)
5302
0
        return code;
5303
59.3k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5304
59.3k
                                          params->rule, pgs_noconst, params);
5305
59.3k
    if (code < 0)
5306
0
        return code;
5307
    /* One (common) case worth optimising for is where we have a pattern that
5308
     * is positioned such that only one repeat of the tile is actually
5309
     * visible. In this case, we can restrict the size of the blending group
5310
     * we need to produce to be that of the actual area of the tile that is
5311
     * used. */
5312
59.3k
    ptile = pdevc->colors.pattern.p_tile;
5313
59.3k
    if (ptile->ttrans != NULL)
5314
17.9k
    {
5315
17.9k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5316
17.9k
            (cpath_intersection.outer_box.p.y < 0) ||
5317
17.9k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5318
10.4k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5319
7.92k
        {
5320
            /* More than one repeat of the tile would be visible, so we can't
5321
             * use the optimisation here. (Actually, this test isn't quite
5322
             * right - it actually tests whether more than the '0th' repeat
5323
             * of the tile is visible. A better test would test if just one
5324
             * repeat of the tile was visible, irrespective of which one.
5325
             * This is (hopefully) relatively rare, and would make the code
5326
             * below more complex too, so we're ignoring that for now. If it
5327
             * becomes evident that it's a case that matters we can revisit
5328
             * it.) */
5329
10.0k
        } else {
5330
            /* Only the 0th repeat is visible. Restrict the size further to
5331
             * just the used area of that patch. */
5332
10.0k
            gx_path_init_local(&path_ttrans, ppath->memory);
5333
10.0k
            code = gx_path_add_rectangle(&path_ttrans,
5334
10.0k
                                         int2fixed(ptile->ttrans->rect.p.x),
5335
10.0k
                                         int2fixed(ptile->ttrans->rect.p.y),
5336
10.0k
                                         int2fixed(ptile->ttrans->rect.q.x),
5337
10.0k
                                         int2fixed(ptile->ttrans->rect.q.y));
5338
10.0k
            if (code < 0)
5339
0
                return code;
5340
10.0k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5341
10.0k
                                      params->rule, pgs_noconst);
5342
10.0k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5343
10.0k
            if (code < 0)
5344
0
                return code;
5345
10.0k
        }
5346
17.9k
    }
5347
    /* Now let us push a transparency group into which we are
5348
     * going to tile the pattern.  */
5349
59.3k
    if (ppath != NULL) {
5350
59.3k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5351
5352
59.3k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5353
59.3k
        rect.p.x = fixed2int(outer_box.p.x);
5354
59.3k
        rect.p.y = fixed2int(outer_box.p.y);
5355
59.3k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5356
59.3k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5357
5358
        /* The color space of this group must be the same as that of the
5359
           tile.  Then when we pop the group, if there is a mismatch between
5360
           the tile color space and the current context we will do the proper
5361
           conversion.  In this way, we ensure that if the tile has any overlapping
5362
           occuring it will be blended in the proper manner i.e in the tile
5363
           underlying color space. */
5364
59.3k
        if (ptile->cdev == NULL) {
5365
17.9k
            if (ptile->ttrans == NULL)
5366
0
                return_error(gs_error_unknownerror);  /* should not happen */
5367
17.9k
            n_chan_tile = ptile->ttrans->n_chan;
5368
41.4k
        } else {
5369
41.4k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5370
41.4k
        }
5371
59.3k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5372
5373
        /* Transparency handling with patterns confuses me, so some notes...
5374
         *
5375
         * For simple, non-transparent patterns, like you'd get in PS, we've
5376
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5377
         * times. To cope with unmarked pixels, we have a "transparency" plane
5378
         * (simple on/off) that says whether a pixel is marked or not.
5379
         *
5380
         * For patterns with transparency (but not blending), we can create an
5381
         * isolated transparency group, tile all the bitmap tiles into that, and
5382
         * then blend that back with the required alpha at the end. This works
5383
         * because the alpha values of the individual objects within the tile are
5384
         * recorded in that group.
5385
         *
5386
         * We can't do that for groups that use blending though, as each object
5387
         * in the pattern might use a different blend, and we don't (can't) record
5388
         * the blending mode. An isolated group doesn't even allow us to actually
5389
         * do the blending at all. So, for such patterns (any patterns that sets (or
5390
         * just has a resource that mentions) a non-normal blend mode), we use
5391
         * a pattern clist.
5392
         */
5393
59.3k
        if (ptile->cdev == NULL) {
5394
17.9k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5395
17.9k
            if (group_color_info == NULL)
5396
0
                return gs_error_VMerror;
5397
5398
17.9k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5399
17.9k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5400
17.9k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5401
17.9k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5402
17.9k
            if (code < 0)
5403
0
                return code;
5404
17.9k
        }
5405
5406
        /* Set the blending procs and the is_additive setting based
5407
           upon the number of channels */
5408
59.3k
        if (ptile->cdev == NULL) {
5409
17.9k
            if (n_chan_tile-1 < 4) {
5410
17.2k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5411
17.2k
                ptile->ttrans->is_additive = true;
5412
17.2k
            } else {
5413
690
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5414
690
                ptile->ttrans->is_additive = false;
5415
690
            }
5416
17.9k
        }
5417
        /* Now lets go through the rect list and fill with the pattern */
5418
        /* First get the buffer that we will be filling */
5419
59.3k
        if (ptile->cdev == NULL) {
5420
17.9k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5421
17.9k
            if (fill_trans_buffer == NULL) {
5422
0
                p14dev->pclist_device = NULL;
5423
0
                return_error(gs_error_VMerror);
5424
0
            }
5425
17.9k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5426
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5427
               want to use */
5428
17.9k
            if (ptile->has_overlap) {
5429
                /* This one does blending since there is tile overlap */
5430
1.34k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5431
16.5k
            } else {
5432
                /* This one does no blending since there is no tile overlap */
5433
16.5k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5434
16.5k
            }
5435
            /* fill the rectangles */
5436
17.9k
            phase.x = pdevc->phase.x;
5437
17.9k
            phase.y = pdevc->phase.y;
5438
17.9k
            if (cpath_intersection.rect_list->list.head != NULL){
5439
642
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5440
10.6k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5441
9.98k
                    if_debug5m('v', pgs->memory,
5442
9.98k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5443
9.98k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5444
9.98k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5445
9.98k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5446
9.98k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5447
9.98k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5448
9.98k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5449
9.98k
                    curr_clip_rect = curr_clip_rect->next;
5450
9.98k
                }
5451
17.3k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5452
                /* The case when there is just a single rect */
5453
17.0k
                if_debug5m('v', pgs->memory,
5454
17.0k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5455
17.0k
                           cpath_intersection.rect_list->list.single.xmin,
5456
17.0k
                           cpath_intersection.rect_list->list.single.ymin,
5457
17.0k
                           cpath_intersection.rect_list->list.single.xmax-
5458
17.0k
                              cpath_intersection.rect_list->list.single.xmin,
5459
17.0k
                           cpath_intersection.rect_list->list.single.ymax-
5460
17.0k
                              cpath_intersection.rect_list->list.single.ymin,
5461
17.0k
                           (int)ptile->id);
5462
17.0k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5463
17.0k
                                                  cpath_intersection.rect_list->list.single.ymin,
5464
17.0k
                                                  cpath_intersection.rect_list->list.single.xmax,
5465
17.0k
                                                  cpath_intersection.rect_list->list.single.ymax,
5466
17.0k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5467
17.0k
            }
5468
41.4k
        } else {
5469
            /* Clist pattern with transparency.  Create a clip device from our
5470
               cpath_intersection.  The above non-clist case could probably be
5471
               done this way too, which will reduce the amount of code here.
5472
               That is for another day though due to time constraints*/
5473
41.4k
            gx_device *dev;
5474
41.4k
            gx_device_clip clipdev;
5475
5476
41.4k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5477
41.4k
            dev = (gx_device *)&clipdev;
5478
41.4k
            phase.x = pdevc->phase.x;
5479
41.4k
            phase.y = pdevc->phase.y;
5480
41.4k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5481
41.4k
                                              ptile, fill_trans_buffer, phase,
5482
41.4k
                                              dev, pdevc, 1);
5483
41.4k
            gx_destroy_clip_device_on_stack(&clipdev);
5484
41.4k
        }
5485
        /* We're done drawing with the pattern, remove the reference to the
5486
         * pattern device
5487
         */
5488
59.3k
        p14dev->pclist_device = NULL;
5489
59.3k
        if (code < 0)
5490
0
            return code;
5491
5492
        /* free our buffer object */
5493
59.3k
        if (fill_trans_buffer != NULL) {
5494
17.9k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5495
17.9k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5496
17.9k
        }
5497
59.3k
        if (ptile->cdev == NULL) {
5498
            /* pop our transparency group which will force the blending.
5499
               This was all needed for Bug 693498 */
5500
17.9k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5501
17.9k
                                                p14dev->blend_procs,
5502
17.9k
                                                p14dev->color_info.num_components - has_tags,
5503
17.9k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5504
17.9k
                                                pdev);
5505
17.9k
        }
5506
59.3k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5507
59.3k
        p14dev->pclist_device = NULL;
5508
59.3k
    }
5509
59.3k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5510
59.3k
    return code;
5511
59.3k
}
5512
5513
/* Useful function that should probably go elsewhere.
5514
 * Call this function to find the topmost pdf14 device in the device chain,
5515
 * or NULL if there is not one.
5516
 */
5517
static pdf14_device *find_pdf14_device(gx_device *dev)
5518
0
{
5519
0
    pdf14_device *pdev;
5520
5521
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5522
0
        return NULL;
5523
0
    return pdev;
5524
0
}
5525
5526
/* Imager render for pattern transparency filling.  This is just here to catch
5527
   the final flush, at which time we will pop the group and reset a few items */
5528
static  int
5529
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5530
                    uint w, int h, gx_device * dev)
5531
0
{
5532
0
    int code;
5533
0
    pdf14_device * p14dev;
5534
0
    const gs_gstate * pgs = penum->pgs;
5535
0
    gx_device_color * pdcolor = (penum->icolor1);
5536
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5537
0
    bool has_tags = device_encodes_tags(dev);
5538
5539
    /* Pass along to the original renderer */
5540
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5541
0
    if (code < 0)
5542
0
        return code;
5543
    /* On our final time through here, go ahead and pop the transparency
5544
       group and reset the procs in the device color. And free the fill
5545
       trans buffer object */
5546
0
    if (h == 0 && ptile->trans_group_popped == false) {
5547
0
        p14dev = find_pdf14_device(dev);
5548
5549
0
        if (p14dev->pclist_device == NULL) {
5550
            /* Used if we are on clist writing phase.  Would only
5551
               occur if we somehow failed in high level clist
5552
               image writing */
5553
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5554
0
        } else {
5555
            /* Used if we are on clist reading phase.  If we had high level
5556
               image in clist */
5557
0
            cmm_dev_profile_t *dev_profile;
5558
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5559
0
            if (code < 0)
5560
0
                return code;
5561
5562
0
            if_debug2m('v', p14dev->ctx->memory,
5563
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5564
0
                       ptile->uid.id, ptile->id);
5565
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5566
0
                    p14dev->color_info.num_components - has_tags,
5567
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5568
0
                    (gx_device *) p14dev);
5569
0
        }
5570
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5571
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5572
0
                       "pdf14_pattern_trans_render");
5573
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5574
0
    }
5575
0
    return code;
5576
0
}
5577
5578
/* This function is used to get things in place for filling a mask image
5579
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5580
   and pdf14_clist_begin_type_image */
5581
static int
5582
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5583
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5584
                           const gs_int_rect * prect,
5585
                           const gx_drawing_color * pdcolor,
5586
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5587
                           gx_image_enum_common_t ** pinfo)
5588
0
{
5589
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5590
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5591
0
    gx_color_tile *ptile;
5592
0
    int code;
5593
0
    gs_int_rect group_rect;
5594
0
    gx_image_enum *penum;
5595
0
    gs_rect bbox_in, bbox_out;
5596
0
    gx_pattern_trans_t *fill_trans_buffer;
5597
5598
0
    ptile = pdcolor->colors.pattern.p_tile;
5599
    /* Set up things in the ptile so that we get the proper
5600
       blending etc */
5601
    /* Set the blending procs and the is_additive setting based
5602
       upon the number of channels */
5603
0
    if (ptile->ttrans->n_chan-1 < 4) {
5604
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5605
0
        ptile->ttrans->is_additive = true;
5606
0
    } else {
5607
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5608
0
        ptile->ttrans->is_additive = false;
5609
0
    }
5610
    /* Set the blending mode in the ptile based upon the current
5611
       setting in the gs_gstate */
5612
0
    ptile->blending_mode = pgs->blend_mode;
5613
    /* Based upon if the tiles overlap pick the type of rect
5614
       fill that we will want to use */
5615
0
    if (ptile->has_overlap) {
5616
        /* This one does blending since there is tile overlap */
5617
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5618
0
    } else {
5619
        /* This one does no blending since there is no tile overlap */
5620
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5621
0
    }
5622
    /* Set the procs so that we use the proper filling method. */
5623
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5624
    /* Let the imaging stuff get set up */
5625
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5626
0
                            prect, pdcolor,pcpath, mem, pinfo);
5627
0
    if (code < 0)
5628
0
        return code;
5629
    /* Now Push the group */
5630
    /* First apply the inverse of the image matrix to our
5631
       image size to get our bounding box. */
5632
0
    bbox_in.p.x = 0;
5633
0
    bbox_in.p.y = 0;
5634
0
    bbox_in.q.x = pim->Width;
5635
0
    bbox_in.q.y = pim->Height;
5636
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5637
0
                                &bbox_out);
5638
0
    if (code < 0)
5639
0
        return code;
5640
    /* That in turn will get hit by the matrix in the gs_gstate */
5641
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5642
0
                                            &bbox_out, (gs_gstate *)pgs);
5643
0
    if (code < 0)
5644
0
        return code;
5645
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5646
0
        if_debug2m('v', p14dev->ctx->memory,
5647
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5648
0
                   ptile->uid.id, ptile->id);
5649
5650
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5651
0
                                             65535, pgs->blend_mode, 0, 0,
5652
0
                                             ptile->ttrans->n_chan-1, false, false,
5653
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5654
5655
        /* Set up the output buffer information now that we have
5656
           pushed the group */
5657
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5658
0
        if (fill_trans_buffer == NULL)
5659
0
            return_error(gs_error_VMerror);
5660
5661
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5662
5663
        /* Store this in the appropriate place in pdcolor.  This
5664
           is released later in pdf14_pattern_trans_render when
5665
           we are all done with the mask fill */
5666
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5667
5668
        /* Change the renderer to handle this case so we can catch the
5669
           end.  We will then pop the group and reset the pdcolor proc.
5670
           Keep the base renderer also. */
5671
0
        penum = (gx_image_enum *) *pinfo;
5672
0
        ptile->ttrans->image_render = penum->render;
5673
0
        penum->render = &pdf14_pattern_trans_render;
5674
0
        ptile->trans_group_popped = false;
5675
0
    }
5676
0
    return code;
5677
0
}
5678
5679
static  int
5680
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5681
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5682
                           const gs_int_rect * prect,
5683
                           const gx_drawing_color * pdcolor,
5684
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5685
                           gx_image_enum_common_t ** pinfo)
5686
310k
{
5687
310k
    const gs_image_t *pim = (const gs_image_t *)pic;
5688
310k
    int code;
5689
5690
310k
    code = pdf14_initialize_ctx(dev, pgs);
5691
310k
    if (code < 0)
5692
0
        return code;
5693
5694
    /* If we are filling an image mask with a pattern that has a transparency
5695
       then we need to do some special handling */
5696
310k
    if (pim->ImageMask) {
5697
93
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5698
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5699
                /* If we are in a final run through here for this case then
5700
                   go ahead and push the transparency group.   Also, update
5701
                   the proc for the pattern color so that we used the
5702
                   appropriate fill operation.  Note that the group
5703
                   is popped and the proc will be reset when we flush the
5704
                   image data.  This is handled in a special pdf14 image
5705
                   renderer which will end up installed for this case.
5706
                   Detect setting of begin_image to gx_no_begin_image.
5707
                   (final recursive call) */
5708
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5709
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5710
0
                                                prect, pdcolor, pcpath, mem,
5711
0
                                                pinfo);
5712
0
                    return code;
5713
0
                }
5714
0
            }
5715
0
        }
5716
93
    }
5717
310k
    pdf14_set_marking_params(dev, pgs);
5718
310k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5719
310k
                                        pcpath, mem, pinfo);
5720
310k
}
5721
5722
static  void
5723
pdf14_set_params(gs_gstate * pgs,
5724
                 gx_device * dev,
5725
                 const gs_pdf14trans_params_t * pparams)
5726
8.29M
{
5727
8.29M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5728
8.29M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5729
1.98M
        pgs->blend_mode = pparams->blend_mode;
5730
8.29M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5731
1.01M
        pgs->text_knockout = pparams->text_knockout;
5732
8.29M
    if (pparams->changed & PDF14_SET_AIS)
5733
306k
        pgs->alphaisshape = pparams->ais;
5734
8.29M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5735
2.51M
        pgs->overprint = pparams->overprint;
5736
8.29M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5737
2.50M
        pgs->stroke_overprint = pparams->stroke_overprint;
5738
8.29M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5739
2.67M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5740
8.29M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5741
1.95M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5742
8.29M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5743
1.86M
        gs_swapcolors_quick(pgs);
5744
1.86M
        if (pparams->op_fs_state == GS_OP_STATE_STROKE)
5745
656k
            pgs->is_fill_color = false;
5746
1.20M
        else
5747
1.20M
            pgs->is_fill_color = true;
5748
1.86M
    }
5749
8.29M
    pdf14_set_marking_params(dev, pgs);
5750
8.29M
}
5751
5752
/*
5753
 * This open_device method for the PDF 1.4 compositor devices is only used
5754
 * when these devices are disabled.  This routine is about as close to
5755
 * a pure "forwarding" open_device operation as is possible. Its only
5756
 * significant function is to ensure that the is_open field of the
5757
 * PDF 1.4 compositor devices matches that of the target device.
5758
 *
5759
 * We assume this procedure is called only if the device is not already
5760
 * open, and that gs_opendevice will take care of the is_open flag.
5761
 */
5762
static  int
5763
pdf14_forward_open_device(gx_device * dev)
5764
0
{
5765
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5766
0
    gx_device * tdev = pdev->target;
5767
0
    int code;
5768
5769
    /* The PDF 1.4 compositing devices must have a target */
5770
0
    if (tdev == 0)
5771
0
        return_error(gs_error_unknownerror);
5772
0
    if ((code = gs_opendevice(tdev)) >= 0)
5773
0
        gx_device_copy_params(dev, tdev);
5774
0
    return code;
5775
0
}
5776
5777
/*
5778
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5779
 * for setting any device procs that should not be forwarded.
5780
 */
5781
static  void
5782
pdf14_forward_device_procs(gx_device * dev)
5783
1.01M
{
5784
1.01M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5785
1.01M
    pdf14_device *p14dev = (pdf14_device*)dev;
5786
5787
    /* If doing simulated overprint with spot colors
5788
       then makes sure to reset devn setting */
5789
1.01M
    if (p14dev->overprint_sim &&
5790
0
        p14dev->color_info.num_components > 4)
5791
0
        p14dev->icc_struct->supports_devn =
5792
0
            p14dev->target_support_devn;
5793
5794
    /*
5795
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5796
     * This will ensure that any new device procs are also set.  However that
5797
     * routine only changes procs which are NULL.  Thus we start by setting all
5798
     * procs to NULL.
5799
     */
5800
1.01M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5801
1.01M
    gx_device_forward_fill_in_procs(pdev);
5802
    /*
5803
     * gx_device_forward_fill_in_procs does not forward all procs.
5804
     * Set the remainding procs to also forward.
5805
     */
5806
1.01M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5807
1.01M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5808
1.01M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5809
1.01M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5810
1.01M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5811
1.01M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5812
1.01M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5813
1.01M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5814
1.01M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5815
1.01M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5816
    /* These are forwarding devices with minor tweaks. */
5817
1.01M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5818
1.01M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5819
1.01M
}
5820
5821
/*
5822
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5823
 * compositor device is never removed.  (We do not have a remove compositor
5824
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5825
 * routine implements that action.
5826
 */
5827
int
5828
pdf14_disable_device(gx_device * dev)
5829
1.00M
{
5830
1.00M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5831
5832
1.00M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5833
1.00M
    dev->color_info = pdev->target->color_info;
5834
1.00M
    pdf14_forward_device_procs(dev);
5835
1.00M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5836
1.00M
    return 0;
5837
1.00M
}
5838
5839
/*
5840
 * The default color space for PDF 1.4 blend modes is based upon the process
5841
 * color model of the output device.
5842
 */
5843
static  pdf14_default_colorspace_t
5844
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5845
                                 pdf14_blend_cs_t *blend_cs_state)
5846
2.98M
{
5847
    /* If a blend color space was specified, then go ahead and use that to
5848
       define the default color space for the blend modes.  Only Gray, RGB
5849
       or CMYK blend color spaces are allowed.  Note we do not allow this
5850
       setting if we are dealing with a separation device. */
5851
2.98M
    cmm_dev_profile_t *dev_profile;
5852
2.98M
    cmm_profile_t *blend_profile = NULL;
5853
2.98M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5854
2.98M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5855
2.98M
    bool valid_blend_cs = false;
5856
2.98M
    int has_tags = device_encodes_tags(pdev);
5857
5858
2.98M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5859
5860
    /* Are we using a blend color space or the output intent color space? Also
5861
       is there a conflict in the settings. i.e. has someone set a blend color
5862
       space and tried to use the output intent with simulate overprint setting.
5863
    */
5864
2.98M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5865
0
        dev_profile->oi_profile != NULL &&
5866
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5867
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5868
           possible conflicting command line settings and we will err on using the blend profile
5869
           if one was specified. */
5870
0
        if (dev_profile->blend_profile != NULL &&
5871
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5872
0
            blend_profile = dev_profile->blend_profile;
5873
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5874
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5875
0
        } else {
5876
            /* All good, use the output intent profile as we have one
5877
               and are doing simulate overprint with a different device
5878
               profile set. */
5879
0
            blend_profile = dev_profile->oi_profile;
5880
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5881
0
        }
5882
2.98M
    } else if (dev_profile->blend_profile != NULL &&
5883
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5884
        /* Blend profile is different than device profile */
5885
0
        blend_profile = dev_profile->blend_profile;
5886
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5887
0
    }
5888
5889
    /* Make sure any blend color space is valid along with other cond */
5890
2.98M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5891
0
        if (!blend_profile->isdevlink &&
5892
0
            !blend_profile->islab &&
5893
0
            (blend_profile->data_cs == gsGRAY ||
5894
0
             blend_profile->data_cs == gsRGB ||
5895
0
             blend_profile->data_cs == gsCMYK)) {
5896
            /* Also, do not allow the use of the blend space when we are pushing
5897
               a pattern pdf14 device.  Those should inherit from the parent */
5898
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5899
0
                  gx_device_is_pattern_accum(pdev))) {
5900
0
                valid_blend_cs = true;
5901
0
            }
5902
0
        }
5903
0
    }
5904
5905
    /* If num components is one, just go ahead and use gray.  This avoids
5906
       issues with additive/subtractive mono color devices  */
5907
2.98M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5908
2.76M
        pdev->color_info.num_components == 1) {
5909
        /*
5910
        * Note:  We do not allow the SeparationOrder device parameter for
5911
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5912
        * and 3 colorants for DeviceRGB.
5913
        */
5914
2.76M
        if (valid_blend_cs) {
5915
0
            *blend_cs_state = temp_cs_state;
5916
0
            switch (blend_profile->num_comps) {
5917
0
            case 1:
5918
0
                return PDF14_DeviceGray;
5919
0
            case 3:
5920
0
                return PDF14_DeviceRGB;
5921
0
            case 4:
5922
0
                return PDF14_DeviceCMYK;
5923
0
            }
5924
0
        }
5925
2.76M
        if (pdev->color_info.num_components - has_tags == 1)
5926
1.05M
            return PDF14_DeviceGray;
5927
1.70M
        else if (pdev->color_info.num_components - has_tags == 3)
5928
1.70M
            return PDF14_DeviceRGB;
5929
0
        else
5930
0
            return PDF14_DeviceRGBspot;
5931
2.76M
    } else {
5932
        /*
5933
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5934
         * the CMYK plus spot colors will not support the blend color space
5935
         */
5936
218k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5937
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5938
        return PDF14_DeviceCustom;
5939
#endif
5940
        /*
5941
         * Count the number of CMYK process components supported by the output
5942
         * device.
5943
         */
5944
1.09M
        for (i = 0; i < 4; i++) {
5945
875k
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5946
5947
875k
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5948
875k
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5949
875k
            if (output_comp_num >= 0) {
5950
875k
                num_cmyk++;
5951
875k
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5952
875k
                    num_cmyk_used++;
5953
875k
            }
5954
875k
        }
5955
        /*
5956
         * Check if the device supports only CMYK.  Otherewise we assume that
5957
         * the output device supports spot colors.  Note:  This algorithm can
5958
         * be fooled if the SeparationOrder device parameter is being used by
5959
         * the output device device to only select CMYK.
5960
         */
5961
218k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5962
208k
            && pdev->color_info.max_components == 4) {
5963
40.6k
            if (valid_blend_cs) {
5964
0
                *blend_cs_state = temp_cs_state;
5965
0
                switch (blend_profile->num_comps) {
5966
0
                case 1:
5967
0
                    return PDF14_DeviceGray;
5968
0
                case 3:
5969
0
                    return PDF14_DeviceRGB;
5970
0
                case 4:
5971
0
                    return PDF14_DeviceCMYK;
5972
0
                }
5973
0
            }
5974
40.6k
            return PDF14_DeviceCMYK;
5975
40.6k
        }
5976
        /*
5977
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5978
         * This device is only needed for those devices which do not support
5979
         * a basic CMYK process color model.
5980
         */
5981
178k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5982
178k
        if (num_cmyk != 4)
5983
0
            return PDF14_DeviceCustom;
5984
178k
#endif
5985
        /*
5986
         * Otherewise we use a CMYK plus spot colors for blending.
5987
         */
5988
178k
        if (valid_blend_cs)
5989
0
            *blend_cs_state = temp_cs_state;
5990
178k
        return PDF14_DeviceCMYKspot;
5991
178k
    }
5992
2.98M
}
5993
5994
/*
5995
 * the PDF 1.4 transparency spec says that color space for blending
5996
 * operations can be based upon either a color space specified in the
5997
 * group or a default value based upon the output device.  We are
5998
 * currently only using a color space based upon the device.
5999
 */
6000
static  int
6001
get_pdf14_device_proto(gx_device       *dev,
6002
                       pdf14_device    *pdevproto,
6003
                       gs_gstate       *pgs,
6004
                 const gs_pdf14trans_t *pdf14pct,
6005
                       bool             use_pdf14_accum)
6006
1.01M
{
6007
1.01M
    pdf14_blend_cs_t blend_cs_state;
6008
1.01M
    pdf14_default_colorspace_t dev_cs =
6009
1.01M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6010
1.01M
                                                 &blend_cs_state);
6011
1.01M
    bool deep = device_is_deep(dev);
6012
1.01M
    int num_spots = pdf14pct->params.num_spot_colors;
6013
1.01M
    bool has_tags = device_encodes_tags(dev);
6014
6015
    /* overprint overide */
6016
1.01M
    if (pdf14pct->params.overprint_sim_push &&
6017
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6018
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6019
0
            dev_cs = PDF14_DeviceCMYKspot;
6020
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6021
0
        } else
6022
0
            dev_cs = PDF14_DeviceCMYK;
6023
0
    }
6024
6025
1.01M
    switch (dev_cs) {
6026
403k
        case PDF14_DeviceGray:
6027
403k
            *pdevproto = gs_pdf14_Gray_device;
6028
403k
            pdevproto->color_info.max_components = 1 + has_tags;
6029
403k
            pdevproto->color_info.num_components =
6030
403k
                                    pdevproto->color_info.max_components + has_tags;
6031
403k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6032
403k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6033
403k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6034
403k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6035
403k
            pdevproto->sep_device = false;
6036
403k
            break;
6037
537k
        case PDF14_DeviceRGB:
6038
537k
            *pdevproto = gs_pdf14_RGB_device;
6039
537k
            pdevproto->color_info.max_components += has_tags;
6040
537k
            pdevproto->color_info.num_components += has_tags;
6041
537k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6042
537k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6043
537k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6044
537k
            pdevproto->sep_device = false;
6045
537k
            break;
6046
2.59k
        case PDF14_DeviceCMYK:
6047
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6048
2.59k
            pdevproto->color_info.max_components += has_tags;
6049
2.59k
            pdevproto->color_info.num_components += has_tags;
6050
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6051
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6052
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6053
2.59k
            pdevproto->sep_device = false;
6054
2.59k
            break;
6055
67.8k
        case PDF14_DeviceCMYKspot:
6056
67.8k
            *pdevproto = gs_pdf14_CMYKspot_device;
6057
            /* Need to figure out how we want to handle the device profile
6058
               for this case */
6059
            /*
6060
             * The number of components for the PDF14 device is the sum
6061
             * of the process components and the number of spot colors
6062
             * for the page.
6063
             */
6064
67.8k
            if (num_spots >= 0) {
6065
67.8k
                pdevproto->color_info.num_components =
6066
67.8k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6067
67.8k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6068
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6069
67.8k
                pdevproto->color_info.depth =
6070
67.8k
                                    pdevproto->color_info.num_components * (8<<deep);
6071
67.8k
                pdevproto->sep_device = true;
6072
67.8k
            }
6073
0
            else
6074
0
            {
6075
0
                pdevproto->color_info.max_components += has_tags;
6076
0
                pdevproto->color_info.num_components += has_tags;
6077
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6078
0
            }
6079
67.8k
            break;
6080
0
        case PDF14_DeviceRGBspot:
6081
0
            *pdevproto = gs_pdf14_RGBspot_device;
6082
            /* Need to figure out how we want to handle the device profile
6083
               for this case */
6084
            /*
6085
             * The number of components for the PDF14 device is the sum
6086
             * of the process components and the number of spot colors
6087
             * for the page.
6088
             */
6089
0
            if (num_spots >= 0) {
6090
0
                pdevproto->color_info.num_components =
6091
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6092
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6093
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6094
0
                pdevproto->color_info.depth =
6095
0
                    pdevproto->color_info.num_components * (8 << deep);
6096
0
                pdevproto->sep_device = true;
6097
0
            }
6098
0
            else
6099
0
            {
6100
0
                pdevproto->color_info.max_components += has_tags;
6101
0
                pdevproto->color_info.num_components += has_tags;
6102
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6103
0
            }
6104
0
            break;
6105
0
        case PDF14_DeviceCustom:
6106
            /*
6107
             * We are using the output device's process color model.  The
6108
             * color_info for the PDF 1.4 compositing device needs to match
6109
             * the output device.
6110
             */
6111
0
            *pdevproto = gs_pdf14_custom_device;
6112
0
            pdevproto->color_info = dev->color_info;
6113
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6114
0
            pdevproto->color_info.depth =
6115
0
                       pdevproto->color_info.num_components * (8<<deep);
6116
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6117
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6118
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6119
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6120
0
            break;
6121
0
        default:      /* Should not occur */
6122
0
            return_error(gs_error_rangecheck);
6123
1.01M
    }
6124
1.01M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6125
1.01M
    pdevproto->blend_cs_state = blend_cs_state;
6126
1.01M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6127
1.01M
    return 0;
6128
1.01M
}
6129
6130
/* When playing back the clist, we need to know if the buffer device is compatible */
6131
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6132
/* depth are critical since these must match when reading back colors.             */
6133
bool
6134
pdf14_ok_to_optimize(gx_device *dev)
6135
1.95M
{
6136
1.95M
    pdf14_blend_cs_t blend_cs_state;
6137
1.95M
    pdf14_default_colorspace_t pdf14_cs =
6138
1.95M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6139
1.95M
    gsicc_colorbuffer_t dev_icc_cs;
6140
1.95M
    bool ok = false;
6141
1.95M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6142
1.95M
    cmm_dev_profile_t *dev_profile;
6143
1.95M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6144
1.95M
    bool deep = device_is_deep(dev);
6145
6146
1.95M
    if (code < 0)
6147
0
        return false;
6148
6149
1.95M
    check_device_compatible_encoding(dev);
6150
6151
1.95M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6152
905k
        return false;
6153
6154
1.05M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6155
    /* If the outputprofile is not "standard" then colors converted to device color */
6156
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6157
1.05M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6158
0
        return false;                           /* can't handle funky output profiles */
6159
6160
1.05M
    switch (pdf14_cs) {
6161
276k
        case PDF14_DeviceGray:
6162
276k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6163
276k
            break;
6164
668k
        case PDF14_DeviceRGB:
6165
668k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6166
668k
            break;
6167
0
        case PDF14_DeviceCMYK:
6168
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6169
0
            break;
6170
109k
        case PDF14_DeviceCMYKspot:
6171
109k
            ok = false;     /* punt for this case */
6172
109k
            break;
6173
0
        case PDF14_DeviceRGBspot:
6174
0
            ok = false;     /* punt for this case */
6175
0
            break;
6176
0
        case PDF14_DeviceCustom:
6177
            /*
6178
             * We are using the output device's process color model.  The
6179
             * color_info for the PDF 1.4 compositing device needs to match
6180
             * the output device, but it may not have been contone.
6181
             */
6182
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6183
0
            break;
6184
0
        default:      /* Should not occur */
6185
0
            ok = false;
6186
1.05M
    }
6187
1.05M
    return ok;
6188
1.05M
}
6189
6190
/*
6191
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6192
 * compositor device is never removed.  (We do not have a remove compositor
6193
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6194
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6195
 * again.
6196
 */
6197
static  int
6198
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6199
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6200
0
{
6201
0
    pdf14_device * pdev = (pdf14_device *)dev;
6202
0
    gx_device * target = pdev->target;
6203
0
    pdf14_device dev_proto;
6204
0
    bool has_tags = device_encodes_tags(dev);
6205
0
    int code;
6206
0
    bool deep = device_is_deep(dev);
6207
6208
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6209
6210
    /*
6211
     * We will not use the entire prototype device but we will set the
6212
     * color related info and the device procs to match the prototype.
6213
     */
6214
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6215
0
                                  pdf14pct, false);
6216
0
    if (code < 0)
6217
0
        return code;
6218
0
    pdev->color_info = dev_proto.color_info;
6219
0
    pdev->pad = target->pad;
6220
0
    pdev->log2_align_mod = target->log2_align_mod;
6221
6222
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6223
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6224
0
    else
6225
0
        pdev->num_planar_planes = target->num_planar_planes;
6226
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6227
6228
0
    if (dev_proto.initialize_device_procs != NULL)
6229
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6230
0
    pdev->procs = dev_proto.procs;
6231
0
    if (deep) {
6232
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6233
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6234
0
    }
6235
0
    if (has_tags) {
6236
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6237
0
    }
6238
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6239
0
    gx_device_fill_in_procs((gx_device *)pdev);
6240
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6241
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6242
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6243
0
    check_device_separable(dev);
6244
0
    return dev_proc(pdev, open_device)(dev);
6245
0
}
6246
6247
/*
6248
 * Implement the various operations that can be specified via the PDF 1.4
6249
 * create compositor request.
6250
 */
6251
static  int
6252
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6253
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6254
20.5M
{
6255
20.5M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6256
20.5M
    gs_pdf14trans_params_t params = pdf14pct->params;
6257
20.5M
    int code = 0;
6258
6259
20.5M
    params.idle = pdf14pct->idle;
6260
20.5M
    switch (params.pdf14_op) {
6261
0
        default:      /* Should not occur. */
6262
0
            break;
6263
10.5k
        case PDF14_PUSH_DEVICE:
6264
10.5k
            if (!(params.is_pattern)) {
6265
0
                p14dev->blend_mode = 0;
6266
0
                p14dev->opacity = p14dev->shape = 0.0;
6267
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6268
0
            }
6269
10.5k
            break;
6270
0
        case PDF14_ABORT_DEVICE:
6271
            /* Something has gone very wrong.  Let transparency device clean up
6272
               what ever it has allocated and then we are shutting it down */
6273
0
            code = gx_abort_trans_device(pgs, pdev);
6274
0
            if (p14dev->free_devicen) {
6275
0
                devn_free_params(pdev);
6276
0
            }
6277
0
            pdf14_disable_device(pdev);
6278
0
            pdf14_close(pdev);
6279
0
            break;
6280
1.01M
        case PDF14_POP_DEVICE:
6281
1.01M
            if (!(params.is_pattern)) {
6282
1.00M
                if_debug0m('v', pdev->memory,
6283
1.00M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6284
1.00M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6285
1.00M
                gx_set_cmap_procs(pgs, p14dev->target);
6286
                /* Send image out raster data to output device */
6287
1.00M
                {
6288
                    /* Make a copy so we can change the ROP */
6289
1.00M
                    gs_gstate new_pgs = *pgs;
6290
6291
                    /* We don't use the gs_gstate log_op since this is for the */
6292
                    /* clist playback. Putting the image (band in the case of the */
6293
                    /* clist) only needs to use the default ROP to copy the data  */
6294
1.00M
                    new_pgs.log_op = rop3_default;
6295
1.00M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6296
1.00M
                }
6297
                /* Before we disable the device release any deviceN structures.
6298
                    free_devicen is set if the pdf14 device had inherited its
6299
                    deviceN parameters from the target clist device.  In this
6300
                    case they should not be freed */
6301
1.00M
                if (p14dev->free_devicen) {
6302
1.00M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6303
1.00M
                    if (devn_params) {
6304
1.00M
                        gxdso_spot_info si;
6305
1.00M
                        si.params = devn_params;
6306
1.00M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6307
1.00M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6308
1.00M
                    }
6309
1.00M
                    devn_free_params(pdev);
6310
1.00M
                }
6311
1.00M
                pdf14_disable_device(pdev);
6312
1.00M
                pdf14_close(pdev);
6313
1.00M
            }
6314
1.01M
            break;
6315
386k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6316
2.16M
        case PDF14_BEGIN_TRANS_GROUP:
6317
2.16M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6318
338k
                p14dev->depth_within_smask++;
6319
2.16M
            p14dev->smask_constructed = 0;
6320
2.16M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6321
2.16M
            break;
6322
1.76M
        case PDF14_END_TRANS_GROUP:
6323
1.76M
            code = gx_end_transparency_group(pgs, pdev);
6324
1.76M
            if (p14dev->depth_within_smask)
6325
337k
                p14dev->depth_within_smask--;
6326
1.76M
            break;
6327
131
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6328
131
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6329
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6330
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6331
0
            } else
6332
131
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6333
131
            break;
6334
395k
        case PDF14_END_TRANS_TEXT_GROUP:
6335
395k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6336
395k
                code = gx_end_transparency_group(pgs, pdev);
6337
395k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6338
395k
            break;
6339
3.85M
        case PDF14_BEGIN_TRANS_MASK:
6340
3.85M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6341
3.85M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6342
407k
                p14dev->in_smask_construction++;
6343
3.85M
            break;
6344
407k
        case PDF14_END_TRANS_MASK:
6345
407k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6346
407k
            if (code >= 0) {
6347
407k
                p14dev->in_smask_construction--;
6348
407k
                if (p14dev->in_smask_construction < 0)
6349
0
                    p14dev->in_smask_construction = 0;
6350
407k
                if (p14dev->in_smask_construction == 0)
6351
406k
                    p14dev->smask_constructed = 1;
6352
407k
            }
6353
407k
            break;
6354
8.29M
        case PDF14_SET_BLEND_PARAMS:
6355
8.29M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6356
8.29M
            break;
6357
0
        case PDF14_PUSH_TRANS_STATE:
6358
0
            code = gx_push_transparency_state(pgs, pdev);
6359
0
            break;
6360
2.60M
        case PDF14_POP_TRANS_STATE:
6361
2.60M
            code = gx_pop_transparency_state(pgs, pdev);
6362
2.60M
            break;
6363
4.26k
        case PDF14_PUSH_SMASK_COLOR:
6364
4.26k
            code = pdf14_increment_smask_color(pgs, pdev);
6365
4.26k
            break;
6366
4.26k
        case PDF14_POP_SMASK_COLOR:
6367
4.26k
            code = pdf14_decrement_smask_color(pgs, pdev);
6368
4.26k
            break;
6369
20.5M
    }
6370
20.5M
    return code;
6371
20.5M
}
6372
6373
/*
6374
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6375
 * compositor' method.  However the compositor is disabled when we are not
6376
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6377
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6378
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6379
 * to the target.
6380
 */
6381
static  int
6382
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6383
        const gs_composite_t * pct, gs_gstate * pgs,
6384
        gs_memory_t * mem, gx_device *cdev)
6385
1.34k
{
6386
1.34k
    pdf14_device *pdev = (pdf14_device *)dev;
6387
1.34k
    gx_device * tdev = pdev->target;
6388
1.34k
    int code;
6389
6390
1.34k
    *pcdev = dev;
6391
1.34k
    if (gs_is_pdf14trans_compositor(pct)) {
6392
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6393
6394
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6395
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6396
0
        return 0;
6397
0
    }
6398
1.34k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6399
1.34k
    if (code == 1) {
6400
        /* We have created a new compositor that wrapped tdev. This means
6401
         * that our target should be updated to point to that. */
6402
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6403
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6404
0
    }
6405
1.34k
    return code;
6406
1.34k
}
6407
6408
/*
6409
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6410
 * and return. Since the gs_pdf14_device only supports the high-level routines
6411
 * of the interface, don't bother trying to handle any other compositor.
6412
 */
6413
static int
6414
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6415
        const gs_composite_t * pct, gs_gstate * pgs,
6416
        gs_memory_t * mem, gx_device *cdev)
6417
113M
{
6418
113M
    pdf14_device *p14dev = (pdf14_device *)dev;
6419
113M
    if (gs_is_pdf14trans_compositor(pct)) {
6420
20.5M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6421
20.5M
        *pcdev = dev;
6422
        /* cdev, may be the clist reader device which may contain information that
6423
           we will need related to the ICC color spaces that define transparency
6424
           groups.  We want this propogated through all the pdf14 functions.  Store
6425
           a pointer to it in the pdf14 device */
6426
20.5M
        p14dev->pclist_device = cdev;
6427
20.5M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6428
93.3M
    } else if (gs_is_overprint_compositor(pct)) {
6429
                /* If we had an overprint compositer action, then the
6430
                   color components that were drawn should be updated.
6431
                   The overprint compositor logic and its interactions
6432
                   with the clist is a little odd as it passes uninitialized
6433
                   values around a fair amount.  Hence the forced assignement here.
6434
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6435
93.3M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6436
93.3M
                gx_color_index drawn_comps;
6437
93.3M
                GS_OP_FS_STATE curr_state = p14dev->op_state;
6438
6439
93.3M
                p14dev->op_state = op_pct->params.op_state;
6440
93.3M
                if (p14dev->op_state == GS_OP_STATE_NONE) {
6441
46.7M
                    if (op_pct->params.retain_any_comps) {
6442
21.3k
                        drawn_comps = op_pct->params.drawn_comps;
6443
46.6M
                    } else {
6444
                        /* Draw everything. If this parameter was not set, clist does
6445
                           not fill it in.  */
6446
46.6M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6447
46.6M
                    }
6448
6449
46.7M
                    if (op_pct->params.is_fill_color) {
6450
25.5M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6451
25.5M
                        p14dev->drawn_comps_fill = drawn_comps;
6452
25.5M
                    } else {
6453
21.2M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6454
21.2M
                        p14dev->drawn_comps_stroke = drawn_comps;
6455
21.2M
                    }
6456
                    /* We restore the NONE states as that is used just to force
6457
                       overprint settings in the overprint compositor communication */
6458
46.7M
                    p14dev->op_state = curr_state;
6459
46.7M
                }
6460
93.3M
                *pcdev = dev;
6461
93.3M
                return 0;
6462
93.3M
    } else
6463
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6464
113M
}
6465
6466
static int
6467
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6468
                      gs_blend_mode_t blend_mode, float opacity,
6469
                      float shape, bool is_clist)
6470
2.20k
{
6471
2.20k
    int code;
6472
2.20k
    gs_transparency_group_params_t params = { 0 };
6473
2.20k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6474
2.20k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6475
2.20k
    float alpha = pgs->fillconstantalpha;
6476
6477
    /* Push a non-isolated knock-out group making sure the opacity and blend
6478
       mode are correct */
6479
2.20k
    params.Isolated = false;
6480
2.20k
    params.Knockout = true;
6481
2.20k
    params.page_group = false;
6482
2.20k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6483
2.20k
    params.group_opacity = 1.0;
6484
2.20k
    params.group_shape = 1.0;
6485
6486
2.20k
    gs_setfillconstantalpha(pgs, 1.0);
6487
2.20k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6488
6489
2.20k
    if (is_clist) {
6490
2.20k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6491
2.20k
        if (code < 0)
6492
0
            return code;
6493
2.20k
    }
6494
6495
2.20k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6496
2.20k
    gs_setfillconstantalpha(pgs, alpha);
6497
2.20k
    gs_setblendmode(pgs, blend_mode);
6498
2.20k
    if (code < 0)
6499
0
        return code;
6500
6501
2.20k
    if (is_clist) {
6502
2.20k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6503
2.20k
    }
6504
2.20k
    return code;
6505
2.20k
}
6506
6507
static  int
6508
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6509
                 const gs_text_params_t * text, gs_font * font,
6510
                 const gx_clip_path * pcpath,
6511
                 gs_text_enum_t ** ppenum)
6512
287
{
6513
287
    int code;
6514
287
    gs_text_enum_t *penum;
6515
287
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6516
287
    float opacity = pgs->fillconstantalpha;
6517
287
    float shape = 1.0;
6518
287
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6519
287
    pdf14_device *pdev = (pdf14_device*)dev;
6520
287
    bool draw = !(text->operation & TEXT_DO_NONE);
6521
287
    uint text_mode = gs_currenttextrenderingmode(pgs);
6522
287
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6523
287
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6524
6525
287
    code = pdf14_initialize_ctx(dev, pgs);
6526
287
    if (code < 0)
6527
0
        return code;
6528
6529
287
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6530
287
    pdf14_set_marking_params(dev, pgs);
6531
287
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6532
287
    if (code < 0)
6533
0
        return code;
6534
6535
    /* We may need to push a non-isolated transparency group if the following
6536
       is true.
6537
       1) We are not currently in one that we pushed for text and we are in
6538
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6539
       2) The blend mode is not Normal or the opacity is not 1.0
6540
       3) Text knockout is set to true
6541
       4) We are actually doing a text drawing
6542
6543
       Special note:  If text-knockout is set to false while we are within a
6544
       BT ET pair, we should pop the group.  I need to create a test file for
6545
       this case.  */
6546
6547
       /* Catch case where we already pushed a group and are trying to push another one.
6548
       In that case, we will pop the current one first, as we don't want to be left
6549
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6550
       will not be caught until we do the put_image and notice that the stack is not
6551
       empty. */
6552
287
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6553
0
        code = gs_end_transparency_group(pgs);
6554
0
        if (code < 0)
6555
0
            return code;
6556
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6557
0
    }
6558
6559
287
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6560
286
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6561
286
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6562
1
         text_mode != 3 && /* don't bother with invisible text */
6563
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6564
1
        if (draw) {
6565
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6566
1
                false);
6567
1
        }
6568
287
    *ppenum = (gs_text_enum_t *)penum;
6569
287
    return code;
6570
287
}
6571
6572
static  int
6573
pdf14_initialize_device(gx_device *new_dev)
6574
1.01M
{
6575
1.01M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6576
6577
1.01M
    pdev->ctx = NULL;
6578
1.01M
    pdev->color_model_stack = NULL;
6579
1.01M
    pdev->smaskcolor = NULL;
6580
6581
1.01M
    return 0;
6582
1.01M
}
6583
6584
/*
6585
 * Implement copy_mono by filling lots of small rectangles.
6586
 */
6587
static int
6588
pdf14_copy_mono(gx_device * dev,
6589
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6590
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6591
12.2M
{
6592
12.2M
    const byte *sptr;
6593
12.2M
    const byte *line;
6594
12.2M
    int sbit, first_bit;
6595
12.2M
    int code, sbyte, bit, count;
6596
12.2M
    int run_length, startx, current_bit, bit_value;
6597
12.2M
    gx_color_index current_color;
6598
6599
12.2M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6600
12.2M
    line = base + (sourcex >> 3);
6601
12.2M
    sbit = sourcex & 7;
6602
12.2M
    first_bit = 7 - sbit;
6603
6604
    /* Loop through the height of the specified area. */
6605
92.5M
    while (h-- > 0) {
6606
        /* Set up for the start of each line of the area. */
6607
80.2M
        sptr = line;
6608
80.2M
        sbyte = *sptr++;
6609
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6610
         * the loop below so adding 1 means that we don't fall into the bit == 0
6611
         * case and incorrectly read a new byte from the source. This weirdness is because
6612
         * the original code wouold read off the end of the buffer if the number of bits in
6613
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6614
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6615
         * of the loop to the beginning meant we would not read past the end of the buffer
6616
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6617
         * reading another byte.
6618
         */
6619
80.2M
        bit = first_bit + 1;
6620
80.2M
        count = w;
6621
80.2M
        run_length = 0;
6622
80.2M
        startx = x;
6623
80.2M
        current_bit = 0;
6624
80.2M
        current_color = zero;
6625
6626
        /* Loop across each pixel of a line. */
6627
1.14G
        do {
6628
            /* Move to the next input bit. */
6629
1.14G
            if (bit == 0) {
6630
98.6M
                bit = 7;
6631
98.6M
                sbyte = *sptr++;
6632
98.6M
            }
6633
1.04G
            else
6634
1.04G
                bit--;
6635
1.14G
            bit_value = (sbyte >> bit) & 1;
6636
1.14G
            if (bit_value == current_bit) {
6637
                /* The value did not change, simply increment our run length */
6638
941M
                run_length++;
6639
941M
            } else {
6640
                /* The value changed, fill the current rectangle. */
6641
200M
                if (run_length != 0) {
6642
191M
                    if (current_color != gx_no_color_index) {
6643
82.5M
                        code = (*dev_proc(dev, fill_rectangle))
6644
82.5M
                                (dev, startx, y, run_length, 1, current_color);
6645
82.5M
                        if (code < 0)
6646
0
                            return code;
6647
82.5M
                    }
6648
191M
                    startx += run_length;
6649
191M
                }
6650
200M
                run_length = 1;
6651
200M
                current_color = bit_value ? one : zero;
6652
200M
                current_bit = bit_value;
6653
200M
            }
6654
1.14G
        } while (--count > 0);
6655
        /* Fill the last rectangle in the line. */
6656
80.2M
        if (run_length != 0 && current_color != gx_no_color_index) {
6657
35.5M
            code = (*dev_proc(dev, fill_rectangle))
6658
35.5M
                        (dev, startx, y, run_length, 1, current_color);
6659
35.5M
            if (code < 0)
6660
0
                return code;
6661
35.5M
        }
6662
        /* Move to the next line */
6663
80.2M
        line += sraster;
6664
80.2M
        y++;
6665
80.2M
    }
6666
12.2M
    return 0;
6667
12.2M
}
6668
6669
/* Added to avoid having to go back and forth between fixed and int
6670
   in some of the internal methods used for dealing with tiling
6671
   and devn colors */
6672
static int
6673
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6674
    const gx_drawing_color *pdcolor)
6675
962
{
6676
962
    pdf14_device *pdev = (pdf14_device *)dev;
6677
962
    pdf14_buf *buf;
6678
962
    int code;
6679
6680
962
    fit_fill_xywh(dev, x, y, w, h);
6681
962
    if (w <= 0 || h <= 0)
6682
0
        return 0;
6683
6684
962
    code = pdf14_initialize_ctx(dev, NULL);
6685
962
    if (code < 0)
6686
0
        return code;
6687
962
    buf = pdev->ctx->stack;
6688
6689
962
    if (buf->knockout)
6690
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6691
0
            true);
6692
962
    else
6693
962
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6694
962
}
6695
6696
/* Step through and do rect fills with the devn colors as
6697
   we hit each transition in the bitmap. It is possible
6698
   that one of the colors is not devn, but is pure and
6699
   is set to gx_no_color_index. This type of mix happens
6700
   for example from tile_clip_fill_rectangle_hl_color */
6701
static int
6702
pdf14_copy_mono_devn(gx_device *dev,
6703
    const byte *base, int sourcex, int sraster,
6704
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6705
    const gx_drawing_color *pdcolor1)
6706
248
{
6707
248
    const byte *sptr;
6708
248
    const byte *line;
6709
248
    int sbit, first_bit;
6710
248
    int code, sbyte, bit, count;
6711
248
    int run_length, startx, current_bit, bit_value;
6712
248
    const gx_drawing_color *current_color;
6713
6714
248
    if ((x | y) < 0) {
6715
0
        if (x < 0) {
6716
0
            w += x;
6717
0
            sourcex -= x;
6718
0
            x = 0;
6719
0
        }
6720
0
        if (y < 0) {
6721
0
            h += y;
6722
0
            base -= (int)(y * sraster);
6723
0
            y = 0;
6724
0
        }
6725
0
    }
6726
248
    if (w > (dev)->width - x)
6727
0
        w = (dev)->width - x;
6728
248
    if (h > (dev)->height - y)
6729
0
        h = (dev)->height - y;
6730
248
    if (w <= 0 || h <= 0)
6731
0
        return 0;
6732
6733
248
    line = base + (sourcex >> 3);
6734
248
    sbit = sourcex & 7;
6735
248
    first_bit = 7 - sbit;
6736
6737
    /* Loop through the height of the specified area. */
6738
815
    while (h-- > 0) {
6739
        /* Set up for the start of each line of the area. */
6740
567
        sptr = line;
6741
567
        sbyte = *sptr++;
6742
567
        bit = first_bit;
6743
567
        count = w;
6744
567
        run_length = 0;
6745
567
        startx = x;
6746
567
        current_bit = 0;
6747
567
        current_color = pdcolor0;
6748
6749
        /* Loop across each pixel of a line. */
6750
6.15k
        do {
6751
6.15k
            bit_value = (sbyte >> bit) & 1;
6752
6.15k
            if (bit_value == current_bit) {
6753
                /* The value did not change, simply increment our run length */
6754
4.47k
                run_length++;
6755
4.47k
            } else {
6756
                /* The value changed, fill the current rectangle. */
6757
1.67k
                if (run_length != 0) {
6758
1.51k
                    if (current_color->type != gx_dc_type_pure &&
6759
717
                        current_color->colors.pure != gx_no_color_index) {
6760
717
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6761
717
                            run_length, 1, current_color);
6762
717
                        if (code < 0)
6763
0
                            return code;
6764
717
                    }
6765
1.51k
                    startx += run_length;
6766
1.51k
                }
6767
1.67k
                run_length = 1;
6768
1.67k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6769
1.67k
                current_bit = bit_value;
6770
1.67k
            }
6771
6772
            /* Move to the next input bit. */
6773
6.15k
            if (bit == 0) {
6774
553
                bit = 7;
6775
553
                sbyte = *sptr++;
6776
553
            } else
6777
5.60k
                bit--;
6778
6.15k
        } while (--count > 0);
6779
6780
        /* Fill the last rectangle in the line. */
6781
567
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6782
245
            current_color->colors.pure != gx_no_color_index) {
6783
245
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6784
245
                run_length, 1, current_color);
6785
245
            if (code < 0)
6786
0
                return code;
6787
245
        }
6788
        /* Move to the next line */
6789
567
        line += sraster;
6790
567
        y++;
6791
567
    }
6792
248
    return 0;
6793
248
}
6794
6795
/* Step through the tiles doing essentially copy_mono but with devn colors */
6796
static int
6797
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6798
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6799
    const gx_drawing_color *pdcolor1, int px, int py)
6800
248
{   /* Fill the rectangle in chunks. */
6801
248
    int width = tiles->size.x;
6802
248
    int height = tiles->size.y;
6803
248
    int raster = tiles->raster;
6804
248
    int rwidth = tiles->rep_width;
6805
248
    int rheight = tiles->rep_height;
6806
248
    int shift = tiles->shift;
6807
6808
248
    if (rwidth == 0 || rheight == 0)
6809
0
        return_error(gs_error_unregistered);
6810
248
    fit_fill_xy(dev, x, y, w, h);
6811
6812
248
     {
6813
248
        int xoff = (shift == 0 ? px :
6814
248
                px + (y + py) / rheight * tiles->rep_shift);
6815
248
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6816
0
            (x + xoff) & (rwidth - 1) :
6817
248
            (x + xoff) % rwidth);
6818
248
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6819
0
            (y + py) & (rheight - 1) :
6820
248
            (y + py) % rheight);
6821
248
        int icw = width - irx;
6822
248
        int ch = height - ry;
6823
248
        byte *row = tiles->data + ry * raster;
6824
248
        int code = 0;
6825
6826
248
        if (ch >= h) {      /* Shallow operation */
6827
248
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6828
248
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6829
248
                    w, h, pdcolor0, pdcolor1);
6830
248
                if (code < 0)
6831
0
                    return_error(code);
6832
248
            } else {
6833
0
                int ex = x + w;
6834
0
                int fex = ex - width;
6835
0
                int cx = x + icw;
6836
6837
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6838
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6839
0
                if (code < 0)
6840
0
                    return_error(code);
6841
6842
0
                while (cx <= fex) {
6843
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6844
0
                        width, h, pdcolor0, pdcolor1);
6845
0
                    if (code < 0)
6846
0
                        return_error(code);
6847
0
                    cx += width;
6848
0
                }
6849
0
                if (cx < ex) {
6850
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6851
0
                        ex - cx, h, pdcolor0, pdcolor1);
6852
0
                    if (code < 0)
6853
0
                        return_error(code);
6854
0
                }
6855
0
            }
6856
248
        } else if (icw >= w && shift == 0) {
6857
            /* Narrow operation, no shift */
6858
0
            int ey = y + h;
6859
0
            int fey = ey - height;
6860
0
            int cy = y + ch;
6861
6862
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6863
0
                x, y, w, ch, pdcolor0, pdcolor1);
6864
0
            if (code < 0)
6865
0
                return_error(code);
6866
0
            row = tiles->data;
6867
0
            do {
6868
0
                ch = (cy > fey ? ey - cy : height);
6869
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6870
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6871
0
                if (code < 0)
6872
0
                    return_error(code);
6873
0
            } while ((cy += ch) < ey);
6874
0
        } else {
6875
            /* Full operation.  If shift != 0, some scan lines */
6876
            /* may be narrow.  We could test shift == 0 in advance */
6877
            /* and use a slightly faster loop, but right now */
6878
            /* we don't bother. */
6879
0
            int ex = x + w, ey = y + h;
6880
0
            int fex = ex - width, fey = ey - height;
6881
0
            int cx, cy;
6882
6883
0
            for (cy = y;;) {
6884
0
                if (icw >= w) {
6885
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6886
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6887
0
                    if (code < 0)
6888
0
                        return_error(code);
6889
0
                } else {
6890
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6891
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6892
0
                    if (code < 0)
6893
0
                        return_error(code);
6894
0
                    cx = x + icw;
6895
0
                    while (cx <= fex) {
6896
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6897
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6898
0
                        if (code < 0)
6899
0
                            return_error(code);
6900
0
                        cx += width;
6901
0
                    }
6902
0
                    if (cx < ex) {
6903
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6904
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6905
0
                        if (code < 0)
6906
0
                            return_error(code);
6907
0
                    }
6908
0
                }
6909
0
                if ((cy += ch) >= ey)
6910
0
                    break;
6911
0
                ch = (cy > fey ? ey - cy : height);
6912
0
                if ((irx += shift) >= rwidth)
6913
0
                    irx -= rwidth;
6914
0
                icw = width - irx;
6915
0
                row = tiles->data;
6916
0
            }
6917
0
        }
6918
248
    }
6919
248
    return 0;
6920
248
}
6921
6922
/* pdf14 device supports devn */
6923
static int
6924
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6925
    int x, int y, int w, int h,
6926
    const gx_drawing_color *pdcolor0,
6927
    const gx_drawing_color *pdcolor1, int px, int py)
6928
248
{
6929
248
    pdf14_device *pdev = (pdf14_device *)dev;
6930
248
    pdf14_buf *buf;
6931
248
    int num_comp;
6932
248
    int k;
6933
248
    bool same = false;
6934
248
    int code;
6935
6936
248
    code = pdf14_initialize_ctx(dev, NULL);
6937
248
    if (code < 0)
6938
0
        return code;
6939
248
    buf = pdev->ctx->stack;
6940
248
    num_comp = buf->n_chan - 1;
6941
6942
    /* if color0 is identical to color1, do rect fill */
6943
248
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6944
0
        same = true;
6945
0
        for (k = 0; k < num_comp; k++) {
6946
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6947
0
                same = false;
6948
0
                break;
6949
0
            }
6950
0
        }
6951
0
    }
6952
6953
248
    if (same) {
6954
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6955
248
    } else {
6956
        /* Go through the tile stepping using code stolen from
6957
           gx_default_strip_tile_rectangle and call the rect fills
6958
           using code stolen from pdf14_copy_mono but using devn
6959
           colors */
6960
248
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6961
248
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6962
248
    }
6963
248
    return code;
6964
248
}
6965
6966
/* Used in a few odd cases where the target device is planar and we have
6967
   a planar tile (pattern) and we are copying it into place here */
6968
static int
6969
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6970
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6971
2.45k
{
6972
2.45k
    pdf14_device *pdev = (pdf14_device *)dev;
6973
2.45k
    pdf14_ctx *ctx;
6974
2.45k
    pdf14_buf *buf;
6975
2.45k
    int xo = x;
6976
2.45k
    int yo = y;
6977
2.45k
    pdf14_buf fake_tos;
6978
2.45k
    int deep;
6979
6980
2.45k
    int code = pdf14_initialize_ctx(dev, NULL);
6981
2.45k
    if (code < 0)
6982
0
        return code;
6983
6984
2.45k
    fit_fill_xywh(dev, x, y, w, h);
6985
2.45k
    if (w <= 0 || h <= 0)
6986
0
        return 0;
6987
6988
2.45k
    ctx = pdev->ctx;
6989
2.45k
    buf = ctx->stack;
6990
2.45k
    deep = ctx->deep;
6991
6992
2.45k
    fake_tos.deep = deep;
6993
2.45k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
6994
2.45k
    fake_tos.backdrop = NULL;
6995
2.45k
    fake_tos.blend_mode = pdev->blend_mode;
6996
2.45k
    fake_tos.color_space = buf->color_space;
6997
2.45k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
6998
2.45k
    fake_tos.dirty.p.x = x;
6999
2.45k
    fake_tos.dirty.p.y = y;
7000
2.45k
    fake_tos.dirty.q.x = x + w;
7001
2.45k
    fake_tos.dirty.q.y = y + h;
7002
2.45k
    fake_tos.has_alpha_g = 0;
7003
2.45k
    fake_tos.has_shape = 0;
7004
2.45k
    fake_tos.has_tags = device_encodes_tags(dev);
7005
2.45k
    fake_tos.idle = false;
7006
2.45k
    fake_tos.isolated = false;
7007
2.45k
    fake_tos.knockout = false;
7008
2.45k
    fake_tos.mask_id = 0;
7009
2.45k
    fake_tos.mask_stack = NULL;
7010
2.45k
    fake_tos.matte = NULL;
7011
2.45k
    fake_tos.matte_num_comps = 0;
7012
2.45k
    fake_tos.memory = dev->memory;
7013
2.45k
    fake_tos.n_chan = dev->color_info.num_components;
7014
2.45k
    fake_tos.n_planes = dev->color_info.num_components;
7015
2.45k
    fake_tos.num_spots = 0;
7016
2.45k
    fake_tos.group_color_info = NULL;
7017
2.45k
    fake_tos.planestride = raster * (size_t)plane_height;
7018
2.45k
    fake_tos.rect.p.x = x;
7019
2.45k
    fake_tos.rect.p.y = y;
7020
2.45k
    fake_tos.rect.q.x = x + w;
7021
2.45k
    fake_tos.rect.q.y = y + h;
7022
2.45k
    fake_tos.rowstride = raster;
7023
2.45k
    fake_tos.saved = NULL;
7024
2.45k
    fake_tos.shape = 0xffff;
7025
2.45k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7026
2.45k
    fake_tos.transfer_fn = NULL;
7027
2.45k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7028
2.45k
                                  pdev->ctx->memory, dev);
7029
2.45k
    return 0;
7030
2.45k
}
7031
7032
static int
7033
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7034
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7035
    const gx_clip_path *pcpath)
7036
16.2M
{
7037
16.2M
    pdf14_device *pdev = (pdf14_device *)dev;
7038
16.2M
    pdf14_buf* buf;
7039
16.2M
    int code;
7040
16.2M
    int x = fixed2int(rect->p.x);
7041
16.2M
    int y = fixed2int(rect->p.y);
7042
16.2M
    int w = fixed2int(rect->q.x) - x;
7043
16.2M
    int h = fixed2int(rect->q.y) - y;
7044
7045
16.2M
    fit_fill_xywh(dev, x, y, w, h);
7046
16.2M
    if (w <= 0 || h <= 0)
7047
207k
        return 0;
7048
7049
16.0M
    code = pdf14_initialize_ctx(dev, pgs);
7050
16.0M
    if (code < 0)
7051
0
        return code;
7052
16.0M
    buf = pdev->ctx->stack;
7053
7054
16.0M
    if (buf->knockout)
7055
141k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7056
141k
                                                   true);
7057
15.9M
    else
7058
15.9M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7059
16.0M
}
7060
7061
static  int
7062
pdf14_fill_rectangle(gx_device * dev,
7063
                    int x, int y, int w, int h, gx_color_index color)
7064
319M
{
7065
319M
    pdf14_device *pdev = (pdf14_device *)dev;
7066
319M
    pdf14_buf *buf;
7067
319M
    int code;
7068
7069
319M
    fit_fill_xywh(dev, x, y, w, h);
7070
319M
    if (w <= 0 || h <= 0)
7071
9.45M
        return 0;
7072
7073
309M
    code = pdf14_initialize_ctx(dev, NULL);
7074
309M
    if (code < 0)
7075
0
        return code;
7076
7077
309M
    buf = pdev->ctx->stack;
7078
7079
309M
    if (buf->knockout)
7080
1.93M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7081
1.93M
                                                   false);
7082
307M
    else
7083
307M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7084
309M
}
7085
7086
static int
7087
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7088
                                    const gs_rect *pbbox, gs_int_rect *rect)
7089
2.24M
{
7090
2.24M
    gs_rect dev_bbox;
7091
2.24M
    int code;
7092
7093
2.24M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7094
2.24M
    if (code < 0)
7095
0
        return code;
7096
2.24M
    rect->p.x = (int)floor(dev_bbox.p.x);
7097
2.24M
    rect->p.y = (int)floor(dev_bbox.p.y);
7098
2.24M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7099
2.24M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7100
    /* Sanity check rect for insane ctms */
7101
2.24M
    if (rect->p.x < 0)
7102
231k
        rect->p.x = 0;
7103
2.24M
    if (rect->q.x < rect->p.x)
7104
2.21k
        rect->q.x = rect->p.x;
7105
2.24M
    if (rect->p.y < 0)
7106
2.06M
        rect->p.y = 0;
7107
2.24M
    if (rect->q.y < rect->p.y)
7108
60.9k
        rect->q.y = rect->p.y;
7109
2.24M
    return 0;
7110
2.24M
}
7111
7112
static  int
7113
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7114
                              const gs_rect *pbbox, gs_gstate *pgs)
7115
2.17M
{
7116
2.17M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7117
7118
2.17M
    if (code < 0)
7119
0
        return code;
7120
2.17M
    rect_intersect(*rect, pdev->ctx->rect);
7121
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7122
2.17M
    if (rect->q.x < rect->p.x)
7123
10.5k
        rect->q.x = rect->p.x;
7124
2.17M
    if (rect->q.y < rect->p.y)
7125
38.8k
        rect->q.y = rect->p.y;
7126
2.17M
    return 0;
7127
2.17M
}
7128
7129
static  int
7130
pdf14_begin_transparency_group(gx_device* dev,
7131
    const gs_transparency_group_params_t* ptgp,
7132
    const gs_rect* pbbox,
7133
    gs_gstate* pgs, gs_memory_t* mem)
7134
2.16M
{
7135
2.16M
    pdf14_device* pdev = (pdf14_device*)dev;
7136
2.16M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7137
2.16M
    gs_int_rect rect;
7138
2.16M
    int code;
7139
2.16M
    bool isolated = ptgp->Isolated;
7140
2.16M
    gs_transparency_color_t group_color_type;
7141
2.16M
    cmm_profile_t* group_profile;
7142
2.16M
    cmm_profile_t* tos_profile;
7143
2.16M
    gsicc_rendering_param_t render_cond;
7144
2.16M
    cmm_dev_profile_t* dev_profile;
7145
2.16M
    bool cm_back_drop = false;
7146
2.16M
    bool new_icc = false;
7147
2.16M
    pdf14_group_color_t* group_color_info;
7148
2.16M
    bool has_tags = device_encodes_tags(dev);
7149
7150
2.16M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7151
2.16M
    if (code < 0)
7152
0
        return code;
7153
2.16M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7154
7155
2.16M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7156
396k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7157
396k
    }
7158
7159
2.16M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7160
396k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7161
1.76M
    else
7162
1.76M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7163
7164
2.16M
    if (code < 0)
7165
0
        return code;
7166
2.16M
    if_debug5m('v', pdev->memory,
7167
2.16M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7168
2.16M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7169
7170
    /* If the group color is unknown then use the current device profile. */
7171
2.16M
    if (ptgp->group_color_type == UNKNOWN) {
7172
1.76M
        group_color_type = ICC;
7173
1.76M
        group_profile = tos_profile;
7174
1.76M
    }
7175
393k
    else {
7176
393k
        group_color_type = ptgp->group_color_type;
7177
393k
        group_profile = ptgp->iccprofile;
7178
393k
    }
7179
7180
    /* We have to handle case where the profile is in the clist */
7181
2.16M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7182
        /* Get the serialized data from the clist. */
7183
393k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7184
393k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7185
393k
        if (group_profile == NULL)
7186
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7187
        /* Keep a pointer to the clist device */
7188
393k
        group_profile->dev = (gx_device*)pcrdev;
7189
393k
        new_icc = true;
7190
393k
    }
7191
2.16M
    if (group_profile != NULL) {
7192
        /* If we have a non-isolated group and the color space is different,
7193
            we will need to CM the backdrop. */
7194
2.16M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7195
191k
            cm_back_drop = true;
7196
191k
        }
7197
2.16M
    }
7198
7199
    /* Always create the base color group information as it is only through
7200
       groups that we can have a color space change.  This will survive
7201
       the life of the context. */
7202
2.16M
    if (pdev->ctx->base_color == NULL) {
7203
523k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7204
523k
    }
7205
7206
    /* If this is not the page group and we don't yet have a group, we need
7207
       to create a buffer for the whole page so that we can handle stuff drawn
7208
       outside this current group (e.g. two non inclusive groups drawn independently) */
7209
2.16M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7210
60.2k
        code = pdf14_initialize_ctx(dev, NULL);
7211
60.2k
        if (code < 0)
7212
0
            return code;
7213
60.2k
        pdev->ctx->stack->isolated = true;
7214
60.2k
    }
7215
7216
2.16M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7217
2.16M
        group_profile, false);
7218
2.16M
    if (group_color_info == NULL)
7219
0
        return gs_error_VMerror;
7220
2.16M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7221
7222
2.16M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7223
2.16M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7224
2.16M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7225
2.16M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7226
2.16M
                                        pgs->blend_mode, ptgp->idle,
7227
2.16M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7228
2.16M
                                         cm_back_drop, ptgp->shade_group,
7229
2.16M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7230
2.16M
    if (new_icc)
7231
393k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7232
2.16M
    return code;
7233
2.16M
}
7234
7235
static void
7236
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7237
2.15M
{
7238
2.15M
    pdf14_device* pdev = (pdf14_device*)dev;
7239
7240
2.15M
    if (group_color != NULL &&
7241
2.15M
        !(group_color->group_color_mapping_procs == NULL &&
7242
2.15M
            group_color->group_color_comp_index == NULL)) {
7243
2.15M
        bool has_tags = device_encodes_tags(dev);
7244
2.15M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7245
2.15M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7246
2.15M
        pdev->color_info.polarity = group_color->polarity;
7247
2.15M
        if (pdev->num_planar_planes > 0)
7248
80.0k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7249
2.15M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7250
2.15M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7251
2.15M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7252
2.15M
        pdev->blend_procs = group_color->blend_procs;
7253
2.15M
        pdev->ctx->additive = group_color->isadditive;
7254
2.15M
        pdev->pdf14_procs = group_color->unpack_procs;
7255
2.15M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7256
2.15M
        pdev->color_info.depth = group_color->depth;
7257
2.15M
        pdev->color_info.max_color = group_color->max_color;
7258
2.15M
        pdev->color_info.max_gray = group_color->max_gray;
7259
2.15M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7260
2.15M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7261
2.15M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7262
2.15M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7263
2.15M
        if (group_color->icc_profile != NULL) {
7264
            /* make sure to decrement the device profile.  If it was allocated
7265
               with the push then it will be freed. */
7266
2.15M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7267
2.15M
                                    -1, "pdf14_pop_color_model");
7268
2.15M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7269
2.15M
                                    group_color->icc_profile;
7270
7271
2.15M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7272
2.15M
                                    1, "pdf14_pop_color_model");
7273
2.15M
        }
7274
2.15M
        pdev->num_std_colorants = group_color->num_std_colorants;
7275
2.15M
    }
7276
2.15M
}
7277
7278
static  int
7279
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7280
2.15M
{
7281
2.15M
    pdf14_device* pdev = (pdf14_device*)dev;
7282
2.15M
    int code;
7283
2.15M
    cmm_profile_t* group_profile;
7284
2.15M
    gsicc_rendering_param_t render_cond;
7285
2.15M
    cmm_dev_profile_t* dev_profile;
7286
2.15M
    int has_tags = device_encodes_tags(dev);
7287
7288
2.15M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7289
2.15M
    if (code < 0)
7290
0
        return code;
7291
7292
2.15M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7293
2.15M
        &render_cond);
7294
2.15M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7295
7296
2.15M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7297
2.15M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7298
2.15M
    if (code < 0)
7299
0
        return code;
7300
#ifdef DEBUG
7301
    pdf14_debug_mask_stack_state(pdev->ctx);
7302
#endif
7303
    /* If this group is the base group, then restore the color model
7304
       of the device at this time.  Note that during the actual device pop
7305
       we will need to use the profile of the buffer not the pdf14 device
7306
       as the source color space */
7307
2.15M
    if (pdev->ctx->stack->group_popped) {
7308
385k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7309
1.77M
    } else {
7310
1.77M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7311
1.77M
    }
7312
7313
2.15M
    return code;
7314
2.15M
}
7315
7316
static pdf14_group_color_t*
7317
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7318
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7319
                        bool is_mask)
7320
2.56M
{
7321
2.56M
    pdf14_device *pdevproto = NULL;
7322
2.56M
    pdf14_device *pdev = (pdf14_device *)dev;
7323
2.56M
    const pdf14_procs_t *new_14procs = NULL;
7324
2.56M
    pdf14_group_color_t *group_color;
7325
2.56M
    gx_color_polarity_t new_polarity;
7326
2.56M
    uchar new_num_comps;
7327
2.56M
    bool new_additive;
7328
2.56M
    gx_device_clist_reader *pcrdev;
7329
2.56M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7330
2.56M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7331
2.56M
    int k;
7332
2.56M
    bool has_tags = device_encodes_tags(dev);
7333
2.56M
    bool deep = pdev->ctx->deep;
7334
7335
2.56M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7336
7337
2.56M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7338
7339
2.56M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7340
2.56M
                               pdf14_group_color_t, &st_pdf14_clr,
7341
2.56M
                               "pdf14_push_color_model");
7342
2.56M
    if (group_color == NULL)
7343
0
        return NULL;
7344
7345
2.56M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7346
7347
2.56M
    switch (group_color_type) {
7348
0
        case GRAY_SCALE:
7349
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7350
0
            new_num_comps = 1;
7351
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7352
0
            new_additive = true;
7353
0
            new_14procs = &gray_pdf14_procs;
7354
0
            break;
7355
0
        case DEVICE_RGB:
7356
0
        case CIE_XYZ:
7357
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7358
0
            new_num_comps = 3;
7359
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7360
0
            new_additive = true;
7361
0
            new_14procs = &rgb_pdf14_procs;
7362
0
            break;
7363
0
        case DEVICE_CMYK:
7364
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7365
0
            new_num_comps = 4;
7366
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7367
0
            new_additive = false;
7368
            /* This is needed due to the mismatched compressed encode decode
7369
                between the device procs and the pdf14 procs */
7370
0
            if (dev->color_info.num_components > 4){
7371
0
                new_14procs = &cmykspot_pdf14_procs;
7372
0
            } else {
7373
0
                new_14procs = &cmyk_pdf14_procs;
7374
0
            }
7375
0
            break;
7376
2.56M
        case ICC:
7377
            /* If we are coming from the clist reader, then we need to get
7378
                the ICC data now  */
7379
2.56M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7380
                /* Get the serialized data from the clist.  Not the whole
7381
                    profile. */
7382
402k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7383
402k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7384
402k
                                                    icc_hashcode);
7385
402k
                if (iccprofile == NULL)
7386
0
                    return NULL;
7387
                /* Keep a pointer to the clist device */
7388
402k
                iccprofile->dev = (gx_device *) pcrdev;
7389
2.16M
            } else {
7390
                /* Go ahead and rc increment right now.  This way when
7391
                    we pop, we will make sure to decrement and avoid a
7392
                    leak for the above profile that we just created.  This
7393
                    goes with the assignment to the device's profile.
7394
                    Note that we still do the increment for the group_color
7395
                    assignment below. */
7396
2.16M
                if (iccprofile == NULL)
7397
0
                    return NULL;
7398
2.16M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7399
2.16M
            }
7400
2.56M
            new_num_comps = iccprofile->num_comps;
7401
2.56M
            if (new_num_comps == 4) {
7402
245k
                new_additive = false;
7403
245k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7404
2.32M
            } else {
7405
2.32M
                new_additive = true;
7406
2.32M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7407
2.32M
            }
7408
2.56M
            switch (new_num_comps) {
7409
675k
                case 1:
7410
675k
                    if (pdev->sep_device && !is_mask) {
7411
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7412
0
                        new_14procs = &grayspot_pdf14_procs;
7413
675k
                    } else {
7414
675k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7415
675k
                        new_14procs = &gray_pdf14_procs;
7416
675k
                    }
7417
675k
                    break;
7418
1.64M
                case 3:
7419
1.64M
                    if (pdev->sep_device) {
7420
58.1k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7421
58.1k
                        new_14procs = &rgbspot_pdf14_procs;
7422
58.1k
                    }
7423
1.58M
                    else {
7424
1.58M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7425
1.58M
                        new_14procs = &rgb_pdf14_procs;
7426
1.58M
                    }
7427
1.64M
                    break;
7428
245k
                case 4:
7429
245k
                    if (pdev->sep_device) {
7430
21.9k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7431
21.9k
                        new_14procs = &cmykspot_pdf14_procs;
7432
223k
                    } else {
7433
223k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7434
223k
                        new_14procs = &cmyk_pdf14_procs;
7435
223k
                    }
7436
245k
                    break;
7437
0
                default:
7438
0
                    return NULL;
7439
0
                    break;
7440
2.56M
            }
7441
2.56M
            break;
7442
2.56M
        default:
7443
0
            return NULL;
7444
0
            break;
7445
2.56M
    }
7446
7447
    /* We might just have changed the colorspace of the device, which means
7448
     * the number of colorants have changed. */
7449
2.56M
    group_color->num_std_colorants = new_num_comps;
7450
2.56M
    pdev->num_std_colorants = new_num_comps;
7451
7452
2.56M
    if (has_tags)
7453
0
        new_num_comps++;
7454
7455
2.56M
    if (group_color_type == ICC && iccprofile != NULL) {
7456
2.56M
        group_color->icc_profile = iccprofile;
7457
2.56M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7458
2.56M
    }
7459
7460
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7461
       spot colorants and know how to index into them */
7462
2.56M
    if (pdev->sep_device && !is_mask) {
7463
80.0k
        int num_spots = dev->color_info.num_components - has_tags -
7464
80.0k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7465
7466
80.0k
        if (num_spots > 0)
7467
339
            new_num_comps += num_spots;
7468
80.0k
    }
7469
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7470
9.16M
    for (k = 0; k < new_num_comps; k++) {
7471
6.59M
        comp_bits[k] = 8<<deep;
7472
6.59M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7473
6.59M
    }
7474
7475
    /* Set device values now and store settings in group_color.  Then they
7476
       are available when we pop the previous group */
7477
2.56M
    if_debug2m('v', pdev->memory,
7478
2.56M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7479
2.56M
                pdev->color_info.num_components,new_num_comps);
7480
2.56M
    {
7481
2.56M
        gx_device local_device;
7482
7483
2.56M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7484
2.56M
        local_device.initialize_device_procs((gx_device *)&local_device);
7485
2.56M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7486
2.56M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7487
2.56M
    }
7488
2.56M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7489
2.56M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7490
2.56M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7491
2.56M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7492
2.56M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7493
2.56M
    if (pdev->num_planar_planes > 0)
7494
106k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7495
2.56M
    group_color->num_components = new_num_comps - has_tags;
7496
2.56M
    pdev->color_info.num_components = new_num_comps;
7497
2.56M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7498
2.56M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7499
2.56M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7500
2.56M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7501
2.56M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7502
2.56M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7503
2.56M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7504
2.56M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7505
2.56M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7506
2.56M
    group_color->depth = pdev->color_info.depth;
7507
2.56M
    group_color->decode = dev_proc(pdev, decode_color);
7508
2.56M
    group_color->encode = dev_proc(pdev, encode_color);
7509
2.56M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7510
2.56M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7511
2.56M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7512
2.56M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7513
2.56M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7514
2.56M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7515
2.56M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7516
7517
    /* If the CS was ICC based, we need to update the device ICC profile
7518
        in the ICC manager, since that is the profile that is used for the
7519
        PDF14 device */
7520
2.56M
    if (group_color_type == ICC && iccprofile != NULL) {
7521
        /* iccprofile was incremented above if we had not just created it.
7522
           When we do the pop we will decrement and if we just created it, it
7523
           will be destroyed */
7524
2.56M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7525
2.56M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7526
2.56M
    }
7527
2.56M
    return group_color;
7528
2.56M
}
7529
7530
static int
7531
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7532
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7533
                             bool is_mask)
7534
54.0k
{
7535
54.0k
    pdf14_device* pdev = (pdf14_device*)dev;
7536
54.0k
    pdf14_group_color_t* new_group_color;
7537
54.0k
    gsicc_rendering_param_t render_cond;
7538
54.0k
    cmm_dev_profile_t* dev_profile;
7539
54.0k
    pdf14_device* pdevproto;
7540
54.0k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7541
54.0k
    const pdf14_procs_t* new_14procs;
7542
54.0k
    bool update_color_info;
7543
54.0k
    gx_color_polarity_t new_polarity;
7544
54.0k
    int new_num_comps;
7545
54.0k
    bool new_additive = false;
7546
54.0k
    byte new_depth;
7547
54.0k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7548
54.0k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7549
54.0k
    int k;
7550
54.0k
    bool has_tags = device_encodes_tags(dev);
7551
54.0k
    bool deep = device_is_deep(dev);
7552
54.0k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7553
54.0k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7554
54.0k
    cmm_profile_t *old_profile = NULL;
7555
7556
54.0k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7557
7558
54.0k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7559
54.0k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7560
54.0k
        &render_cond);
7561
54.0k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7562
7563
    /* Allocate a new one */
7564
54.0k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7565
54.0k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7566
7567
54.0k
    if (new_group_color == NULL)
7568
0
        return_error(gs_error_VMerror);
7569
7570
    /* Link to old one */
7571
54.0k
    new_group_color->previous = pdev->color_model_stack;
7572
7573
    /* Reassign new one to dev */
7574
54.0k
    pdev->color_model_stack = new_group_color;
7575
7576
    /* Initialize with values */
7577
54.0k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7578
54.0k
    new_group_color->group_color_mapping_procs =
7579
54.0k
        dev_proc(pdev, get_color_mapping_procs);
7580
54.0k
    new_group_color->group_color_comp_index =
7581
54.0k
        dev_proc(pdev, get_color_comp_index);
7582
54.0k
    new_group_color->blend_procs = pdev->blend_procs;
7583
54.0k
    new_group_color->polarity = pdev->color_info.polarity;
7584
54.0k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7585
54.0k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7586
54.0k
    new_group_color->depth = pdev->color_info.depth;
7587
54.0k
    new_group_color->max_color = pdev->color_info.max_color;
7588
54.0k
    new_group_color->max_gray = pdev->color_info.max_gray;
7589
54.0k
    new_group_color->decode = dev_proc(pdev, decode_color);
7590
54.0k
    new_group_color->encode = dev_proc(pdev, encode_color);
7591
54.0k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7592
54.0k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7593
54.0k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7594
54.0k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7595
7596
54.0k
    if (new_profile == NULL)
7597
33.0k
        new_group_color->icc_profile = NULL;
7598
7599
    /* isadditive is only used in ctx */
7600
54.0k
    if (pdev->ctx) {
7601
0
        new_group_color->isadditive = pdev->ctx->additive;
7602
0
    }
7603
7604
54.0k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7605
54.0k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7606
7607
54.0k
    if (group_color_type == ICC && new_profile == NULL)
7608
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7609
54.0k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7610
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7611
       are based upon the color space of the device.  We want to remain in the
7612
       color space defined by the color space of the soft mask or transparency
7613
       group as opposed to the device color space. Later, when we pop the softmask
7614
       we will collapse it to a single band and then compose with it to the device
7615
       color space (or the parent layer space).  In the case where we pop an
7616
       isolated transparency group, we will do the blending in the proper color
7617
       space and then transform the data when we pop the group.  Remember that only
7618
       isolated groups can have color spaces that are different than their parent. */
7619
54.0k
    update_color_info = false;
7620
54.0k
    switch (group_color_type) {
7621
0
    case GRAY_SCALE:
7622
0
        if (pdev->color_info.num_components != 1) {
7623
0
            update_color_info = true;
7624
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7625
0
            new_num_comps = 1;
7626
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7627
0
            new_additive = true;
7628
0
            new_14procs = &gray_pdf14_procs;
7629
0
            new_depth = 8 << deep;
7630
0
        }
7631
0
        break;
7632
0
    case DEVICE_RGB:
7633
0
    case CIE_XYZ:
7634
0
        if (pdev->color_info.num_components != 3) {
7635
0
            update_color_info = true;
7636
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7637
0
            new_num_comps = 3;
7638
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7639
0
            new_additive = true;
7640
0
            new_14procs = &rgb_pdf14_procs;
7641
0
            new_depth = 24 << deep;
7642
0
        }
7643
0
        break;
7644
0
    case DEVICE_CMYK:
7645
0
        if (pdev->color_info.num_components != 4) {
7646
0
            update_color_info = true;
7647
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7648
0
            new_num_comps = 4;
7649
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7650
0
            new_additive = false;
7651
            /* This is needed due to the mismatched compressed encode decode
7652
               between the device procs and the pdf14 procs */
7653
0
            if (dev->color_info.num_components > 4) {
7654
0
                new_14procs = &cmykspot_pdf14_procs;
7655
0
            }
7656
0
            else {
7657
0
                new_14procs = &cmyk_pdf14_procs;
7658
0
            }
7659
0
            new_depth = 32 << deep;
7660
0
        }
7661
0
        break;
7662
21.0k
    case ICC:
7663
        /* Check if the profile is different. */
7664
21.0k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7665
19.2k
            update_color_info = true;
7666
19.2k
            new_num_comps = new_profile->num_comps;
7667
19.2k
            new_depth = new_profile->num_comps * (8 << deep);
7668
19.2k
            switch (new_num_comps) {
7669
17.1k
            case 1:
7670
17.1k
                if (pdev->sep_device && !is_mask) {
7671
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7672
0
                    new_14procs = &grayspot_pdf14_procs;
7673
0
                }
7674
17.1k
                else {
7675
17.1k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7676
17.1k
                    new_14procs = &gray_pdf14_procs;
7677
17.1k
                }
7678
17.1k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7679
17.1k
                new_additive = true;
7680
17.1k
                break;
7681
1.79k
            case 3:
7682
1.79k
                if (pdev->sep_device) {
7683
402
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7684
402
                    new_14procs = &rgbspot_pdf14_procs;
7685
402
                }
7686
1.39k
                else {
7687
1.39k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7688
1.39k
                    new_14procs = &rgb_pdf14_procs;
7689
1.39k
                }
7690
1.79k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7691
1.79k
                new_additive = true;
7692
1.79k
                break;
7693
255
            case 4:
7694
255
                if (pdev->sep_device) {
7695
7
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7696
7
                    new_14procs = &cmykspot_pdf14_procs;
7697
7
                }
7698
248
                else {
7699
248
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7700
248
                    new_14procs = &cmyk_pdf14_procs;
7701
248
                }
7702
255
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7703
255
                new_additive = false;
7704
255
                break;
7705
0
            default:
7706
0
                return gs_throw(gs_error_undefinedresult,
7707
19.2k
                    "ICC Number of colorants illegal");
7708
19.2k
            }
7709
19.2k
        }
7710
21.0k
        break;
7711
33.0k
    case UNKNOWN:
7712
33.0k
        return 0;
7713
0
        break;
7714
0
    default:
7715
0
        return_error(gs_error_rangecheck);
7716
0
        break;
7717
54.0k
    }
7718
7719
21.0k
    if (!update_color_info) {
7720
        /* Profile not updated */
7721
1.82k
        new_group_color->icc_profile = NULL;
7722
1.82k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7723
1.82k
        return 0;
7724
1.82k
    }
7725
7726
19.2k
    if (has_tags) {
7727
0
        new_num_comps++;
7728
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7729
0
        if (pdev->num_planar_planes > 0)
7730
0
            new_depth += deep ? 16 : 8;
7731
0
        else
7732
0
            new_depth += 8;
7733
0
    }
7734
19.2k
    if (pdev->sep_device && !is_mask) {
7735
409
        int num_spots;
7736
7737
409
        if (old_profile == NULL)
7738
0
            return_error(gs_error_undefined);
7739
7740
409
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7741
7742
409
        if (num_spots > 0) {
7743
33
            new_num_comps += num_spots;
7744
33
            new_depth = (8 << deep) * new_num_comps;
7745
33
        }
7746
409
    }
7747
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7748
42.8k
    for (k = 0; k < new_num_comps; k++) {
7749
23.5k
        comp_bits[k] = 8 << deep;
7750
23.5k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7751
23.5k
    }
7752
19.2k
    if_debug2m('v', pdev->memory,
7753
19.2k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7754
19.2k
        pdev->color_info.num_components, new_num_comps);
7755
    /* Set new information in the device */
7756
19.2k
    {
7757
19.2k
        gx_device local_device;
7758
7759
19.2k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7760
19.2k
        local_device.initialize_device_procs((gx_device *)&local_device);
7761
19.2k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7762
19.2k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7763
19.2k
    }
7764
19.2k
    pdev->blend_procs = pdevproto->blend_procs;
7765
19.2k
    pdev->color_info.polarity = new_polarity;
7766
19.2k
    pdev->color_info.max_color = deep ? 65535 : 255;
7767
19.2k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7768
19.2k
    pdev->pdf14_procs = new_14procs;
7769
19.2k
    if (pdev->num_planar_planes > 0)
7770
2.32k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7771
19.2k
    pdev->color_info.num_components = new_num_comps;
7772
19.2k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7773
19.2k
    pdev->color_info.depth = new_depth;
7774
19.2k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7775
19.2k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7776
19.2k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7777
19.2k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7778
19.2k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7779
7780
    /* If we have a compressed color codec, and we are doing a soft mask
7781
       push operation then go ahead and update the color encode and
7782
       decode for the pdf14 device to not used compressed color
7783
       encoding while in the soft mask.  We will just check for gray
7784
       and compressed.  Note that we probably don't have_tags if we
7785
       are dealing with compressed color.  But is is possible so
7786
       we add it in to catch for future use. */
7787
19.2k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7788
19.2k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7789
19.2k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7790
19.2k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7791
19.2k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7792
19.2k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7793
    /* For the ICC profiles, we want to update the ICC profile for the
7794
       device.  We store the original in group_color.
7795
       That will be stored in the clist and restored during the reading phase. */
7796
19.2k
    if (group_color_type == ICC) {
7797
19.2k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7798
19.2k
        new_group_color->icc_profile =
7799
19.2k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7800
19.2k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7801
19.2k
    }
7802
19.2k
    if (pdev->ctx) {
7803
0
        pdev->ctx->additive = new_additive;
7804
0
    }
7805
19.2k
    return 1;  /* Lets us detect that we did do an update */
7806
19.2k
}
7807
7808
static int
7809
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7810
54.0k
{
7811
7812
54.0k
    pdf14_device *pdev = (pdf14_device *)dev;
7813
54.0k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7814
54.0k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7815
7816
54.0k
    if (group_color == NULL)
7817
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7818
7819
54.0k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7820
    /* The color procs are always pushed.  Simply restore them. */
7821
54.0k
    if (group_color->group_color_mapping_procs == NULL &&
7822
0
        group_color->group_color_comp_index == NULL) {
7823
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7824
54.0k
    } else {
7825
54.0k
        bool has_tags = device_encodes_tags(dev);
7826
54.0k
        if_debug2m('v', pdev->memory,
7827
54.0k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7828
54.0k
                   pdev->color_info.num_components,group_color->num_components);
7829
54.0k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7830
54.0k
        gx_set_cmap_procs(pgs, dev);
7831
54.0k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7832
54.0k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7833
54.0k
        pdev->color_info.polarity = group_color->polarity;
7834
54.0k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7835
54.0k
        pdev->color_info.depth = group_color->depth;
7836
54.0k
        if (pdev->num_planar_planes > 0)
7837
5.27k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7838
54.0k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7839
54.0k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7840
54.0k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7841
54.0k
        pdev->blend_procs = group_color->blend_procs;
7842
54.0k
        pdev->pdf14_procs = group_color->unpack_procs;
7843
54.0k
        pdev->color_info.max_color = group_color->max_color;
7844
54.0k
        pdev->color_info.max_gray = group_color->max_gray;
7845
54.0k
        set_dev_proc(pdev, encode_color, group_color->encode);
7846
54.0k
        set_dev_proc(pdev, decode_color, group_color->decode);
7847
54.0k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7848
54.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7849
54.0k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7850
54.0k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7851
7852
        /* clist writer fill rect has no access to gs_gstate */
7853
        /* and it forwards the target device.  this information */
7854
        /* is passed along to use in this case */
7855
54.0k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7856
54.0k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7857
54.0k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7858
54.0k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7859
54.0k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7860
54.0k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7861
54.0k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7862
54.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7863
54.0k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7864
54.0k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7865
54.0k
        if (pdev->ctx){
7866
0
            pdev->ctx->additive = group_color->isadditive;
7867
0
        }
7868
       /* The device profile must be restored. */
7869
54.0k
        if (group_color->icc_profile != NULL) {
7870
19.1k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7871
19.1k
                                    -1, "pdf14_clist_pop_color_model");
7872
19.1k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7873
19.1k
        }
7874
54.0k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7875
54.0k
    }
7876
54.0k
   pdf14_pop_group_color(dev, pgs);
7877
54.0k
    return 0;
7878
54.0k
}
7879
7880
/* When a transparency group is popped, the parent colorprocs must be restored.
7881
   Since the color mapping procs are all based upon the device, we must have a
7882
   nested list based upon the transparency group color space.  This nesting
7883
   must be outside the nested ctx structures to allow the nesting for the
7884
   clist writer */
7885
static void
7886
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7887
54.0k
{
7888
54.0k
    pdf14_device *pdev = (pdf14_device *)dev;
7889
54.0k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7890
7891
54.0k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7892
7893
    /* Update the link */
7894
54.0k
    pdev->color_model_stack = group_color->previous;
7895
7896
    /* Free the old one */
7897
54.0k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7898
54.0k
}
7899
7900
static  int
7901
pdf14_begin_transparency_mask(gx_device *dev,
7902
                              const gx_transparency_mask_params_t *ptmp,
7903
                              const gs_rect *pbbox,
7904
                              gs_gstate *pgs, gs_memory_t *mem)
7905
3.85M
{
7906
3.85M
    pdf14_device *pdev = (pdf14_device *)dev;
7907
3.85M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7908
3.85M
    byte *transfer_fn;
7909
3.85M
    gs_int_rect rect;
7910
3.85M
    int code;
7911
3.85M
    int group_color_numcomps;
7912
3.85M
    gs_transparency_color_t group_color_type;
7913
3.85M
    bool deep = device_is_deep(dev);
7914
3.85M
    pdf14_group_color_t* group_color_info;
7915
7916
3.85M
    code = pdf14_initialize_ctx(dev, pgs);
7917
3.85M
    if (code < 0)
7918
0
        return code;
7919
7920
3.85M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7921
3.44M
        pdf14_ctx *ctx = pdev->ctx;
7922
7923
        /* free up any maskbuf on the current tos */
7924
3.44M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7925
293k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7926
293k
            ctx->mask_stack->mask_buf = NULL;
7927
293k
        }
7928
3.44M
        return 0;
7929
3.44M
    }
7930
407k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7931
407k
                                         "pdf14_begin_transparency_mask");
7932
407k
    if (transfer_fn == NULL)
7933
0
        return_error(gs_error_VMerror);
7934
407k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7935
407k
    if (code < 0)
7936
0
        return code;
7937
    /* If we have background components the background alpha may be nonzero */
7938
407k
    if (ptmp->Background_components)
7939
77.5k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7940
407k
    if_debug1m('v', dev->memory,
7941
407k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7942
407k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7943
   /* If the group color is unknown, then we must use the previous group color
7944
       space or the device process color space */
7945
407k
    if (ptmp->group_color_type == UNKNOWN){
7946
0
        if (pdev->ctx->stack){
7947
            /* Use previous group color space */
7948
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7949
0
        } else {
7950
            /* Use process color space */
7951
0
            group_color_numcomps = pdev->color_info.num_components;
7952
0
        }
7953
0
        switch (group_color_numcomps) {
7954
0
            case 1:
7955
0
                group_color_type = GRAY_SCALE;
7956
0
                break;
7957
0
            case 3:
7958
0
                group_color_type = DEVICE_RGB;
7959
0
                break;
7960
0
            case 4:
7961
0
                group_color_type = DEVICE_CMYK;
7962
0
            break;
7963
0
            default:
7964
                /* We can end up here if we are in a deviceN color space and
7965
                   we have a sep output device */
7966
0
                group_color_type = DEVICEN;
7967
0
            break;
7968
0
         }
7969
407k
    } else {
7970
407k
        group_color_type = ptmp->group_color_type;
7971
407k
        group_color_numcomps = ptmp->group_color_numcomps;
7972
407k
    }
7973
7974
407k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7975
407k
                                               ptmp->iccprofile, true);
7976
407k
    if (group_color_info == NULL)
7977
0
        return gs_error_VMerror;
7978
7979
    /* Note that the soft mask always follows the group color requirements even
7980
       when we have a separable device */
7981
407k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7982
407k
                                        transfer_fn, ptmp->function_is_identity,
7983
407k
                                        ptmp->idle, ptmp->replacing,
7984
407k
                                        ptmp->mask_id, ptmp->subtype,
7985
407k
                                        group_color_numcomps,
7986
407k
                                        ptmp->Background_components,
7987
407k
                                        ptmp->Background,
7988
407k
                                        ptmp->Matte_components,
7989
407k
                                        ptmp->Matte,
7990
407k
                                        ptmp->GrayBackground,
7991
407k
                                        group_color_info);
7992
407k
    if (code < 0)
7993
0
        return code;
7994
7995
407k
    return 0;
7996
407k
}
7997
7998
static  int
7999
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8000
407k
{
8001
407k
    pdf14_device *pdev = (pdf14_device *)dev;
8002
407k
    pdf14_group_color_t *group_color;
8003
407k
    int ok;
8004
407k
    bool has_tags = device_encodes_tags(dev);
8005
8006
407k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8007
407k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8008
#ifdef DEBUG
8009
    pdf14_debug_mask_stack_state(pdev->ctx);
8010
#endif
8011
8012
    /* May need to reset some color stuff related
8013
     * to a mismatch between the Smask color space
8014
     * and the Smask blending space */
8015
407k
    if (pdev->ctx->stack != NULL ) {
8016
407k
        group_color = pdev->ctx->stack->group_color_info;
8017
407k
        if (!(group_color->group_color_mapping_procs == NULL &&
8018
407k
            group_color->group_color_comp_index == NULL)) {
8019
407k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8020
407k
            gx_set_cmap_procs(pgs, dev);
8021
407k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8022
407k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8023
407k
            pdev->color_info.polarity = group_color->polarity;
8024
407k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8025
407k
            if (pdev->num_planar_planes > 0)
8026
26.9k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8027
407k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8028
407k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8029
407k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8030
407k
            pdev->num_std_colorants = group_color->num_std_colorants;
8031
407k
            pdev->color_info.depth = group_color->depth;
8032
407k
            pdev->blend_procs = group_color->blend_procs;
8033
407k
            pdev->ctx->additive = group_color->isadditive;
8034
407k
            pdev->pdf14_procs = group_color->unpack_procs;
8035
407k
            pdev->color_info.max_color = group_color->max_color;
8036
407k
            pdev->color_info.max_gray = group_color->max_gray;
8037
407k
            set_dev_proc(pdev, encode_color, group_color->encode);
8038
407k
            set_dev_proc(pdev, decode_color, group_color->decode);
8039
407k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8040
407k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8041
407k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8042
407k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8043
            /* Take care of the ICC profile */
8044
407k
            if (group_color->icc_profile != NULL) {
8045
407k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8046
407k
                                        -1, "pdf14_end_transparency_mask");
8047
407k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8048
407k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8049
407k
                                         1, "pdf14_end_transparency_mask");
8050
407k
            }
8051
407k
        }
8052
407k
    }
8053
407k
    return ok;
8054
407k
}
8055
8056
static  int
8057
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8058
                                 gx_color_index color,
8059
                                 const gx_device_color *pdc, bool devn)
8060
2.07M
{
8061
2.07M
    pdf14_device *pdev = (pdf14_device *)dev;
8062
2.07M
    pdf14_buf *buf = pdev->ctx->stack;
8063
2.07M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8064
2.07M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8065
162k
        blend_mode == BLEND_MODE_Compatible ||
8066
162k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8067
2.07M
    int i, j, k;
8068
2.07M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8069
2.07M
    byte src[PDF14_MAX_PLANES];
8070
2.07M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8071
2.07M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8072
2.07M
    intptr_t rowstride = buf->rowstride;
8073
2.07M
    intptr_t planestride = buf->planestride;
8074
2.07M
    int num_chan = buf->n_chan;
8075
2.07M
    int num_comp = num_chan - 1;
8076
2.07M
    intptr_t shape_off = num_chan * planestride;
8077
2.07M
    bool has_shape = buf->has_shape;
8078
2.07M
    bool has_alpha_g = buf->has_alpha_g;
8079
2.07M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8080
2.07M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8081
2.07M
                                   (has_shape ? planestride : 0);
8082
2.07M
    bool has_tags = buf->has_tags;
8083
2.07M
    bool additive = pdev->ctx->additive;
8084
2.07M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8085
2.07M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8086
2.07M
    int shift = 8;
8087
2.07M
    byte shape = 0; /* Quiet compiler. */
8088
2.07M
    byte src_alpha;
8089
2.07M
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8090
2.07M
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8091
1.74M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8092
2.07M
    gx_color_index comps;
8093
2.07M
    bool has_backdrop = buf->backdrop != NULL;
8094
8095
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8096
       subtractive) and we are doing overprint with drawn_comps == 0
8097
       then this is a no-operation */
8098
2.07M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8099
0
        return 0;
8100
8101
2.07M
    if (buf->data == NULL)
8102
2
        return 0;
8103
#if 0
8104
    if (sizeof(color) <= sizeof(ulong))
8105
        if_debug6m('v', dev->memory,
8106
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8107
                   x, y, w, h, (ulong)color, num_chan);
8108
    else
8109
        if_debug7m('v', dev->memory,
8110
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8111
                   x, y, w, h,
8112
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8113
                   num_chan);
8114
#endif
8115
    /*
8116
     * Unpack the gx_color_index values.  Complement the components for subtractive
8117
     * color spaces.
8118
     */
8119
2.07M
    if (devn) {
8120
141k
        if (has_tags) {
8121
0
            curr_tag = pdc->tag;
8122
0
        }
8123
141k
        if (additive) {
8124
70.5k
            for (j = 0; j < num_comp; j++) {
8125
52.8k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8126
52.8k
            }
8127
124k
        } else {
8128
620k
            for (j = 0; j < num_comp; j++) {
8129
496k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8130
496k
            }
8131
124k
        }
8132
1.93M
    } else {
8133
1.93M
        if (has_tags) {
8134
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8135
0
        }
8136
1.93M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8137
1.93M
    }
8138
8139
2.07M
    if (!has_tags)
8140
2.07M
        tag_off = 0;
8141
8142
2.07M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8143
2.07M
    if (has_shape) {
8144
147
        shape = (byte)floor (255 * pdev->shape + 0.5);
8145
2.07M
    } else {
8146
2.07M
        shape_off = 0;
8147
2.07M
    }
8148
8149
2.07M
    if (!has_alpha_g)
8150
0
        alpha_g_off = 0;
8151
2.07M
    src_alpha = 255 - src_alpha;
8152
2.07M
    shape = 255 - shape;
8153
8154
    /* Fit the mark into the bounds of the buffer */
8155
2.07M
    if (x < buf->rect.p.x) {
8156
90
        w += x - buf->rect.p.x;
8157
90
        x = buf->rect.p.x;
8158
90
    }
8159
2.07M
    if (y < buf->rect.p.y) {
8160
10
      h += y - buf->rect.p.y;
8161
10
      y = buf->rect.p.y;
8162
10
    }
8163
2.07M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8164
2.07M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8165
    /* Update the dirty rectangle with the mark. */
8166
2.07M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8167
2.07M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8168
2.07M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8169
2.07M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8170
8171
    /* composite with backdrop only. */
8172
2.07M
    if (has_backdrop)
8173
2.07M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8174
0
    else
8175
0
        bline = NULL;
8176
8177
2.07M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8178
8179
4.35M
    for (j = 0; j < h; ++j) {
8180
2.27M
        bg_ptr = bline;
8181
2.27M
        dst_ptr = line;
8182
102M
        for (i = 0; i < w; ++i) {
8183
            /* Complement the components for subtractive color spaces */
8184
99.7M
            if (has_backdrop) {
8185
99.7M
                if (additive) {
8186
361M
                    for (k = 0; k < num_comp; ++k)
8187
262M
                        dst[k] = bg_ptr[k * planestride];
8188
99.0M
                } else {
8189
3.69M
                    for (k = 0; k < num_comp; ++k)
8190
2.95M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8191
738k
                }
8192
99.7M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8193
99.7M
            }
8194
99.7M
            if (buf->isolated || !has_backdrop) {
8195
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8196
99.7M
            } else {
8197
99.7M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8198
99.7M
                                            blend_mode, pdev->blend_procs, pdev);
8199
99.7M
            }
8200
            /* Complement the results for subtractive color spaces */
8201
99.7M
            if (additive) {
8202
99.0M
                if (!overprint) {
8203
460M
                    for (k = 0; k < num_chan; ++k)
8204
361M
                        dst_ptr[k * planestride] = dst[k];
8205
98.9M
                } else {
8206
                    /* Hybrid additive with subtractive spots */
8207
                    /* We may have to do the compatible overprint blending */
8208
48.5k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8209
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8210
0
                            blend_mode, pdev->blend_procs, pdev);
8211
0
                    }
8212
194k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8213
145k
                        if ((comps & 0x1) != 0) {
8214
145k
                            dst_ptr[k * planestride] = dst[k];
8215
145k
                        } else {
8216
                            /* Compatible overprint blend result. */
8217
0
                            dst_ptr[k * planestride] = dst2[k];
8218
0
                        }
8219
145k
                    }
8220
48.5k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8221
48.5k
                }
8222
99.0M
            } else {
8223
738k
                if (overprint) {
8224
                    /* We may have to do the compatible overprint blending */
8225
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8226
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8227
0
                            blend_mode, pdev->blend_procs, pdev);
8228
0
                    }
8229
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8230
0
                        if ((comps & 0x1) != 0) {
8231
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8232
0
                        } else {
8233
                            /* Compatible overprint blend result. */
8234
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8235
0
                        }
8236
0
                    }
8237
738k
                } else {
8238
3.69M
                    for (k = 0; k < num_comp; ++k)
8239
2.95M
                        dst_ptr[k * planestride] = 255 - dst[k];
8240
738k
                }
8241
738k
                dst_ptr[num_comp * planestride] = dst[num_comp];
8242
738k
            }
8243
99.7M
            if (tag_off) {
8244
                /* If src alpha is 100% then set to curr_tag, else or */
8245
                /* other than Normal BM, we always OR */
8246
0
                if (src[num_comp] == 255 && tag_blend) {
8247
0
                    dst_ptr[tag_off] = curr_tag;
8248
0
                } else {
8249
0
                    dst_ptr[tag_off] |= curr_tag;
8250
0
                }
8251
0
            }
8252
            /* Knockout group alpha and shape too */
8253
99.7M
            if (alpha_g_off)
8254
99.7M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8255
99.7M
            if (shape_off)
8256
306
                dst_ptr[shape_off] = 255 - shape;
8257
99.7M
            ++dst_ptr;
8258
99.7M
            if (has_backdrop)
8259
99.7M
                ++bg_ptr;
8260
99.7M
        }
8261
2.27M
        bline += rowstride;
8262
2.27M
        line += rowstride;
8263
2.27M
    }
8264
#if 0
8265
/* #if RAW_DUMP */
8266
    /* Dump the current buffer to see what we have. */
8267
    dump_raw_buffer(pdev->ctx->memory,
8268
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8269
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8270
                    pdev->ctx->stack->n_planes,
8271
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8272
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8273
                    pdev->ctx->stack->deep);
8274
    global_index++;
8275
#endif
8276
2.07M
    return 0;
8277
2.07M
}
8278
8279
static  int
8280
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8281
                                   gx_color_index color,
8282
                                   const gx_device_color *pdc, bool devn)
8283
0
{
8284
0
    pdf14_device *pdev = (pdf14_device *)dev;
8285
0
    pdf14_buf *buf = pdev->ctx->stack;
8286
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8287
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8288
0
        blend_mode == BLEND_MODE_Compatible ||
8289
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8290
0
    int i, j, k;
8291
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8292
0
    uint16_t src[PDF14_MAX_PLANES];
8293
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8294
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8295
0
    intptr_t rowstride = buf->rowstride;
8296
0
    intptr_t planestride = buf->planestride;
8297
0
    int num_chan = buf->n_chan;
8298
0
    int num_comp = num_chan - 1;
8299
0
    intptr_t shape_off = num_chan * planestride;
8300
0
    bool has_shape = buf->has_shape;
8301
0
    bool has_alpha_g = buf->has_alpha_g;
8302
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8303
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8304
0
                                   (has_shape ? planestride : 0);
8305
0
    bool has_tags = buf->has_tags;
8306
0
    bool additive = pdev->ctx->additive;
8307
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8308
0
    uint16_t shape = 0; /* Quiet compiler. */
8309
0
    uint16_t src_alpha;
8310
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8311
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8312
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8313
0
    gx_color_index comps;
8314
0
    bool has_backdrop = buf->backdrop != NULL;
8315
8316
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8317
       subtractive) and we are doing overprint with drawn_comps == 0
8318
       then this is a no-operation */
8319
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8320
0
        return 0;
8321
8322
0
    if (buf->data == NULL)
8323
0
        return 0;
8324
#if 0
8325
    if (sizeof(color) <= sizeof(ulong))
8326
        if_debug6m('v', dev->memory,
8327
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8328
                   x, y, w, h, (ulong)color, num_chan);
8329
    else
8330
        if_debug7m('v', dev->memory,
8331
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8332
                   x, y, w, h,
8333
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8334
                   num_chan);
8335
#endif
8336
    /*
8337
     * Unpack the gx_color_index values.  Complement the components for subtractive
8338
     * color spaces.
8339
     */
8340
0
    if (devn) {
8341
0
        if (has_tags) {
8342
0
            curr_tag = pdc->tag;
8343
0
        }
8344
0
        if (additive) {
8345
0
            for (j = 0; j < num_comp; j++) {
8346
0
                src[j] = pdc->colors.devn.values[j];
8347
0
            }
8348
0
        } else {
8349
0
            for (j = 0; j < num_comp; j++) {
8350
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8351
0
            }
8352
0
        }
8353
0
    } else {
8354
0
        if (has_tags) {
8355
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8356
0
        }
8357
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8358
0
    }
8359
8360
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8361
0
    if (has_shape) {
8362
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8363
0
    } else {
8364
0
        shape_off = 0;
8365
0
    }
8366
8367
0
    if (!has_tags) {
8368
0
        tag_off = 0;
8369
0
    }
8370
8371
0
    if (!has_alpha_g)
8372
0
        alpha_g_off = 0;
8373
0
    src_alpha = 65535 - src_alpha;
8374
0
    shape = 65535 - shape;
8375
8376
    /* Fit the mark into the bounds of the buffer */
8377
0
    if (x < buf->rect.p.x) {
8378
0
        w += x - buf->rect.p.x;
8379
0
        x = buf->rect.p.x;
8380
0
    }
8381
0
    if (y < buf->rect.p.y) {
8382
0
      h += y - buf->rect.p.y;
8383
0
      y = buf->rect.p.y;
8384
0
    }
8385
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8386
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8387
    /* Update the dirty rectangle with the mark. */
8388
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8389
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8390
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8391
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8392
8393
8394
    /* composite with backdrop only. */
8395
0
    if (has_backdrop)
8396
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8397
0
    else
8398
0
        bline = NULL;
8399
8400
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8401
0
    planestride >>= 1;
8402
0
    rowstride >>= 1;
8403
0
    alpha_g_off >>= 1;
8404
0
    shape_off >>= 1;
8405
0
    tag_off >>= 1;
8406
8407
0
    for (j = 0; j < h; ++j) {
8408
0
        bg_ptr = bline;
8409
0
        dst_ptr = line;
8410
0
        for (i = 0; i < w; ++i) {
8411
            /* Complement the components for subtractive color spaces */
8412
0
            if (has_backdrop) {
8413
0
                if (additive) {
8414
0
                    for (k = 0; k < num_comp; ++k)
8415
0
                        dst[k] = bg_ptr[k * planestride];
8416
0
                } else {
8417
0
                    for (k = 0; k < num_comp; ++k)
8418
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8419
0
                }
8420
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8421
0
            }
8422
0
            if (buf->isolated || !has_backdrop) {
8423
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8424
0
            } else {
8425
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8426
0
                                              blend_mode, pdev->blend_procs, pdev);
8427
0
            }
8428
            /* Complement the results for subtractive color spaces */
8429
0
            if (additive) {
8430
0
                if (!overprint) {
8431
0
                    for (k = 0; k < num_chan; ++k)
8432
0
                        dst_ptr[k * planestride] = dst[k];
8433
0
                } else {
8434
                    /* Hybrid additive with subtractive spots */
8435
                    /* We may have to do the compatible overprint blending */
8436
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8437
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8438
0
                            blend_mode, pdev->blend_procs, pdev);
8439
0
                    }
8440
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8441
0
                        if ((comps & 0x1) != 0) {
8442
0
                            dst_ptr[k * planestride] = dst[k];
8443
0
                        } else {
8444
                            /* Compatible overprint blend result. */
8445
0
                            dst_ptr[k * planestride] = dst2[k];
8446
0
                        }
8447
0
                    }
8448
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8449
0
                }
8450
0
            } else {
8451
0
                if (overprint) {
8452
                    /* We may have to do the compatible overprint blending */
8453
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8454
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8455
0
                            blend_mode, pdev->blend_procs, pdev);
8456
0
                    }
8457
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8458
0
                        if ((comps & 0x1) != 0) {
8459
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8460
0
                        } else {
8461
                            /* Compatible overprint blend result. */
8462
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8463
0
                        }
8464
0
                    }
8465
0
                } else {
8466
0
                    for (k = 0; k < num_comp; ++k)
8467
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8468
0
                }
8469
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8470
0
            }
8471
0
            if (tag_off) {
8472
                /* FIXME: As we are knocking out, possibly, we should be
8473
                 * always overwriting tag values here? */
8474
                /* If src alpha is 100% then set to curr_tag, else or */
8475
                /* other than Normal BM, we always OR */
8476
0
                if (src[num_comp] == 65535 && tag_blend) {
8477
0
                    dst_ptr[tag_off] = curr_tag;
8478
0
                } else {
8479
0
                    dst_ptr[tag_off] |= curr_tag;
8480
0
                }
8481
0
            }
8482
            /* Knockout group alpha and shape too */
8483
0
            if (alpha_g_off)
8484
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8485
0
            if (shape_off)
8486
0
                dst_ptr[shape_off] = 65535 - shape;
8487
0
            ++dst_ptr;
8488
0
            if (has_backdrop)
8489
0
                ++bg_ptr;
8490
0
        }
8491
0
        bline += rowstride;
8492
0
        line += rowstride;
8493
0
    }
8494
#if 0
8495
/* #if RAW_DUMP */
8496
    /* Dump the current buffer to see what we have. */
8497
    dump_raw_buffer(pdev->ctx->memory,
8498
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8499
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8500
                    pdev->ctx->stack->n_planes,
8501
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8502
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8503
                    pdev->ctx->stack->deep);
8504
    global_index++;
8505
#endif
8506
0
    return 0;
8507
0
}
8508
8509
static  int
8510
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8511
                                    gx_color_index color,
8512
                                    const gx_device_color *pdc, bool devn)
8513
2.07M
{
8514
2.07M
    pdf14_device *pdev = (pdf14_device *)dev;
8515
2.07M
    pdf14_buf *buf = pdev->ctx->stack;
8516
8517
2.07M
    if (buf->deep)
8518
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8519
2.07M
    else
8520
2.07M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8521
2.07M
}
8522
8523
/**
8524
 * Here we have logic to override the cmap_procs with versions that
8525
 * do not apply the transfer function. These copies should track the
8526
 * versions in gxcmap.c.
8527
 **/
8528
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8529
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8530
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8531
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8532
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8533
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8534
8535
static  const gx_color_map_procs pdf14_cmap_many = {
8536
     pdf14_cmap_gray_direct,
8537
     pdf14_cmap_rgb_direct,
8538
     pdf14_cmap_cmyk_direct,
8539
     pdf14_cmap_separation_direct,
8540
     pdf14_cmap_devicen_direct,
8541
     pdf14_cmap_is_halftoned
8542
    };
8543
8544
/**
8545
 * Note: copied from gxcmap.c because it's inlined.
8546
 **/
8547
static  inline void
8548
map_components_to_colorants(const frac * pcc,
8549
                            const gs_devicen_color_map * pcolor_component_map,
8550
                            frac * plist,
8551
                            int num_additives)
8552
1.22M
{
8553
1.22M
    int i = pcolor_component_map->num_colorants - 1;
8554
1.22M
    int pos;
8555
8556
    /* Clear all output colorants first */
8557
6.13M
    for (; i >= num_additives; i--) {
8558
4.90M
        plist[i] = frac_0;
8559
4.90M
    }
8560
1.22M
    for (; i >= 0; i--) {
8561
2.52k
        plist[i] = frac_1;
8562
2.52k
    }
8563
    /* Map color components into output list */
8564
2.62M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8565
1.40M
        pos = pcolor_component_map->color_map[i];
8566
1.40M
        if (pos >= 0) {
8567
1.40M
            if (pos < num_additives)
8568
0
                plist[pos] = frac_1 - pcc[i];
8569
1.40M
            else
8570
1.40M
                plist[pos] = pcc[i];
8571
1.40M
        }
8572
1.40M
    }
8573
1.22M
}
8574
8575
/* See Section 7.6.4 of PDF 1.7 spec */
8576
static inline bool
8577
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8578
23.7M
{
8579
23.7M
    if (pgs->fillconstantalpha != 1.0 ||
8580
23.7M
        pgs->strokeconstantalpha != 1.0 ||
8581
23.7M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8582
156k
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8583
181k
        return 0;
8584
8585
    /* We can only be opaque if we're not in an SMask. */
8586
23.5M
    return dev_proc(pdev, dev_spec_op)(pdev,
8587
23.5M
                                       gxdso_in_smask,
8588
23.5M
                                       NULL, 0) != 1;
8589
23.7M
}
8590
8591
static  void
8592
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8593
                       gx_device * dev, gs_color_select_t select)
8594
8.51M
{
8595
8.51M
    int i, nc, ncomps;
8596
8.51M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8597
8.51M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8598
8.51M
    gx_color_index color;
8599
8.51M
    gx_device *trans_device;
8600
8.51M
    const gx_device *map_dev;
8601
8.51M
    const gx_cm_color_map_procs *procs;
8602
8603
    /* If trans device is set, we need to use its procs. */
8604
8.51M
    if (pgs->trans_device != NULL) {
8605
4.16M
        trans_device = pgs->trans_device;
8606
4.34M
    } else {
8607
4.34M
        trans_device = dev;
8608
4.34M
    }
8609
8.51M
    ncomps = trans_device->color_info.num_components;
8610
8611
    /* map to the color model */
8612
8.51M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8613
8.51M
    procs->map_gray(map_dev, gray, cm_comps);
8614
8615
8.51M
    nc = ncomps;
8616
8.51M
    if (device_encodes_tags(trans_device))
8617
0
        nc--;
8618
8.51M
    if (pdf14_state_opaque(trans_device, pgs)) {
8619
8.96M
        for (i = 0; i < nc; i++)
8620
4.48M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8621
4.47M
    } else {
8622
8.06M
        for (i = 0; i < nc; i++)
8623
4.03M
            cv[i] = frac2cv(cm_comps[i]);
8624
4.03M
    }
8625
    /* Copy tags untransformed. */
8626
8.51M
    if (nc < ncomps)
8627
0
        cv[nc] = dev->graphics_type_tag;
8628
8629
    /* If output device supports devn, we need to make sure we send it the
8630
       proper color type.  We now support Gray + spots as devn colors */
8631
8.51M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8632
370k
        for (i = 0; i < ncomps; i++)
8633
185k
            pdc->colors.devn.values[i] = cv[i];
8634
11.8M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8635
11.6M
            pdc->colors.devn.values[i] = 0;
8636
185k
        pdc->type = gx_dc_type_devn;
8637
8.32M
    } else {
8638
        /* encode as a color index */
8639
8.32M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8640
        /* check if the encoding was successful; we presume failure is rare */
8641
8.32M
        if (color != gx_no_color_index)
8642
8.32M
            color_set_pure(pdc, color);
8643
8.32M
    }
8644
8.51M
}
8645
8646
static  void
8647
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8648
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8649
3.93M
{
8650
3.93M
    int i, nc, ncomps;
8651
3.93M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8652
3.93M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8653
3.93M
    gx_color_index color;
8654
3.93M
    gx_device *trans_device;
8655
3.93M
    const gx_device *map_dev;
8656
3.93M
    const gx_cm_color_map_procs *procs;
8657
8658
    /* If trans device is set, we need to use its procs. */
8659
3.93M
    if (pgs->trans_device != NULL){
8660
621k
        trans_device = pgs->trans_device;
8661
3.31M
    } else {
8662
3.31M
        trans_device = dev;
8663
3.31M
    }
8664
3.93M
    ncomps = trans_device->color_info.num_components;
8665
    /* map to the color model */
8666
3.93M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8667
3.93M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8668
8669
3.93M
    nc = ncomps;
8670
3.93M
    if (device_encodes_tags(trans_device))
8671
0
        nc--;
8672
3.93M
    if (pdf14_state_opaque(trans_device, pgs)) {
8673
9.88M
        for (i = 0; i < nc; i++)
8674
7.41M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8675
2.47M
    } else {
8676
5.85M
        for (i = 0; i < nc; i++)
8677
4.39M
            cv[i] = frac2cv(cm_comps[i]);
8678
1.46M
    }
8679
    /* Copy tags untransformed. */
8680
3.93M
    if (nc < ncomps)
8681
0
        cv[nc] = dev->graphics_type_tag;
8682
8683
    /* If output device supports devn, we need to make sure we send it the
8684
       proper color type.  We now support RGB + spots as devn colors */
8685
3.93M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8686
11.6M
        for (i = 0; i < ncomps; i++)
8687
8.70M
            pdc->colors.devn.values[i] = cv[i];
8688
179M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8689
176M
            pdc->colors.devn.values[i] = 0;
8690
2.89M
        pdc->type = gx_dc_type_devn;
8691
2.89M
    } else {
8692
        /* encode as a color index */
8693
1.04M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8694
        /* check if the encoding was successful; we presume failure is rare */
8695
1.04M
        if (color != gx_no_color_index)
8696
1.04M
            color_set_pure(pdc, color);
8697
1.04M
    }
8698
3.93M
}
8699
8700
static  void
8701
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8702
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8703
     const gs_color_space *pcs)
8704
11.2M
{
8705
11.2M
    int i, nc, ncomps;
8706
11.2M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8707
11.2M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8708
11.2M
    gx_color_index color;
8709
11.2M
    gx_device *trans_device;
8710
11.2M
    const gx_device *map_dev;
8711
11.2M
    const gx_cm_color_map_procs *procs;
8712
8713
8714
    /* If trans device is set, we need to use its procs. */
8715
11.2M
    if (pgs->trans_device != NULL){
8716
8.87M
        trans_device = pgs->trans_device;
8717
8.87M
    } else {
8718
2.40M
        trans_device = dev;
8719
2.40M
    }
8720
11.2M
    ncomps = trans_device->color_info.num_components;
8721
8722
    /* Map to the color model. Transfer function is only used
8723
       if we are drawing with an opaque color. */
8724
11.2M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8725
11.2M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8726
8727
11.2M
    nc = ncomps;
8728
11.2M
    if (device_encodes_tags(trans_device))
8729
0
        nc--;
8730
11.2M
    if (pdf14_state_opaque(trans_device, pgs)) {
8731
50.2M
        for (i = 0; i < nc; i++)
8732
40.2M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8733
10.0M
    } else {
8734
6.12M
        for (i = 0; i < nc; i++)
8735
4.89M
            cv[i] = frac2cv(cm_comps[i]);
8736
1.22M
    }
8737
    /* Copy tags untransformed. */
8738
11.2M
    if (nc < ncomps)
8739
0
        cv[nc] = dev->graphics_type_tag;
8740
8741
    /* if output device supports devn, we need to make sure we send it the
8742
       proper color type */
8743
11.2M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8744
41.7M
        for (i = 0; i < ncomps; i++)
8745
33.3M
            pdc->colors.devn.values[i] = cv[i];
8746
508M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8747
500M
            pdc->colors.devn.values[i] = 0;
8748
8.34M
        pdc->type = gx_dc_type_devn;
8749
8.34M
    } else {
8750
        /* encode as a color index */
8751
2.93M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8752
        /* check if the encoding was successful; we presume failure is rare */
8753
2.93M
        if (color != gx_no_color_index)
8754
2.93M
            color_set_pure(pdc, color);
8755
2.93M
    }
8756
11.2M
}
8757
8758
static int
8759
pdf14_get_num_spots(gx_device * dev)
8760
1.22M
{
8761
1.22M
    cmm_dev_profile_t *dev_profile;
8762
1.22M
    cmm_profile_t *icc_profile;
8763
1.22M
    gsicc_rendering_param_t render_cond;
8764
8765
1.22M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8766
1.22M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8767
1.22M
        &render_cond);
8768
1.22M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8769
1.22M
}
8770
8771
static  void
8772
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8773
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8774
1.32k
{
8775
1.32k
    int i, nc, ncomps = dev->color_info.num_components;
8776
1.32k
    int num_spots = pdf14_get_num_spots(dev);
8777
1.32k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8778
1.32k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8779
1.32k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8780
1.32k
    gx_color_index color;
8781
1.32k
    int n = 0;
8782
8783
1.32k
    nc = ncomps;
8784
1.32k
    if (device_encodes_tags(dev))
8785
0
        nc--;
8786
8787
1.32k
    n = additive ? nc - num_spots : 0;
8788
1.32k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8789
0
        frac comp_value = all;
8790
8791
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8792
0
            cm_comps[i] = comp_value;
8793
        /*
8794
         * Invert the photometric interpretation for additive
8795
         * color spaces because separations are always subtractive.
8796
         */
8797
0
        if (additive)
8798
0
            comp_value = frac_1 - comp_value;
8799
        /* Use the "all" value for all components */
8800
0
        for (; i >= 0; i--)
8801
0
            cm_comps[i] = comp_value;
8802
1.32k
    } else {
8803
1.32k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8804
8805
1.32k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8806
0
            color_set_null(pdc);
8807
0
            return;
8808
0
        }
8809
8810
        /* map to the color model */
8811
2.65k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8812
1.32k
            comp_value[i] = all;
8813
1.32k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8814
1.32k
    }
8815
8816
    /* apply the transfer function(s); convert to color values */
8817
3.85k
    for (i = 0; i < n; i++)
8818
2.52k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8819
4.10k
    for (; i < nc; i++)
8820
2.77k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8821
8822
    /* Copy tags untransformed. */
8823
1.32k
    if (nc < ncomps)
8824
0
        cv[nc] = dev->graphics_type_tag;
8825
8826
    /* if output device supports devn, we need to make sure we send it the
8827
       proper color type */
8828
1.32k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8829
6.63k
        for (i = 0; i < ncomps; i++)
8830
5.30k
            pdc->colors.devn.values[i] = cv[i];
8831
80.8k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8832
79.5k
            pdc->colors.devn.values[i] = 0;
8833
1.32k
        pdc->type = gx_dc_type_devn;
8834
1.32k
    } else {
8835
        /* encode as a color index */
8836
0
        color = dev_proc(dev, encode_color)(dev, cv);
8837
        /* check if the encoding was successful; we presume failure is rare */
8838
0
        if (color != gx_no_color_index)
8839
0
            color_set_pure(pdc, color);
8840
0
    }
8841
1.32k
}
8842
8843
static  void
8844
pdf14_cmap_devicen_direct(const frac * pcc,
8845
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8846
    gs_color_select_t select, const gs_color_space *pcs)
8847
1.22M
{
8848
1.22M
    int i, nc, ncomps = dev->color_info.num_components;
8849
1.22M
    int num_spots = pdf14_get_num_spots(dev);
8850
1.22M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8851
1.22M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8852
1.22M
    gx_color_index color;
8853
1.22M
    gx_device *trans_device;
8854
1.22M
    int num_add_colorants = 0;
8855
8856
     /*  We may be coming from the clist writer which often forwards us the
8857
         target device. If this occurs we actually need to get to the color
8858
         space defined by the transparency group and we use the operators
8859
         defined by the transparency device to do the job.
8860
       */
8861
1.22M
    if (pgs->trans_device != NULL){
8862
1.22M
        trans_device = pgs->trans_device;
8863
1.22M
    } else {
8864
0
        trans_device = dev;
8865
0
    }
8866
1.22M
    ncomps = trans_device->color_info.num_components;
8867
1.22M
    nc = ncomps;
8868
1.22M
    if (device_encodes_tags(trans_device))
8869
0
        nc--;
8870
8871
1.22M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8872
0
        num_add_colorants = nc - num_spots;
8873
8874
    /* map to the color model */
8875
1.22M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8876
8877
    /* apply the transfer function(s); convert to color values */
8878
    /* The additive ones (if there are any) need to be inverted. */
8879
1.22M
    for (i = 0; i < num_add_colorants; i++)
8880
1.22M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8881
6.13M
    for (; i < nc; i++)
8882
4.90M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8883
    /* Copy tags untransformed. */
8884
1.22M
    if (nc < ncomps)
8885
0
        cv[nc] = dev->graphics_type_tag;
8886
8887
    /* if output device supports devn, we need to make sure we send it the
8888
       proper color type */
8889
1.22M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8890
237k
        for (i = 0; i < ncomps; i++)
8891
189k
            pdc->colors.devn.values[i] = cv[i];
8892
2.89M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8893
2.84M
            pdc->colors.devn.values[i] = 0;
8894
47.4k
        pdc->type = gx_dc_type_devn;
8895
1.17M
    } else {
8896
    /* encode as a color index */
8897
1.17M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8898
        /* check if the encoding was successful; we presume failure is rare */
8899
1.17M
        if (color != gx_no_color_index)
8900
1.17M
            color_set_pure(pdc, color);
8901
1.17M
    }
8902
1.22M
}
8903
8904
static  bool
8905
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8906
76.6k
{
8907
76.6k
    return false;
8908
76.6k
}
8909
8910
static  const gx_color_map_procs *
8911
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8912
1.61M
{
8913
    /* The pdf14 marking device itself is always continuous tone. */
8914
1.61M
    return &pdf14_cmap_many;
8915
1.61M
}
8916
8917
static int
8918
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8919
                  void *data, int size)
8920
100M
{
8921
100M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8922
8923
100M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8924
692k
        return 1;
8925
100M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8926
11.2k
        return 1;
8927
100M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8928
888
        if (data != NULL && size == sizeof(gx_device *))
8929
400
            *(gx_device **)data = pdev;
8930
888
        return 1;
8931
888
    }
8932
100M
    if (dev_spec_op == gxdso_device_child) {
8933
2.05k
        pdf14_device *dev = (pdf14_device *)pdev;
8934
2.05k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8935
2.05k
        if (d->target == pdev) {
8936
2.05k
            d->target = dev->target;
8937
2.05k
            return 1;
8938
2.05k
        }
8939
2.05k
    }
8940
100M
    if (dev_spec_op == gxdso_supports_devn
8941
51.1M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8942
51.1M
        cmm_dev_profile_t *dev_profile;
8943
51.1M
        int code;
8944
51.1M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8945
51.1M
        if (code == 0) {
8946
51.1M
            return dev_profile->supports_devn;
8947
51.1M
        } else {
8948
0
            return 0;
8949
0
        }
8950
51.1M
    }
8951
48.8M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8952
287k
        pdf14_device* dev = (pdf14_device*)pdev;
8953
8954
287k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8955
287k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8956
110k
            return 1;
8957
177k
        return 0;
8958
287k
    }
8959
48.5M
    if (dev_spec_op == gxdso_is_encoding_direct)
8960
1.35M
        return 1;
8961
8962
    /* We don't want to pass on these spec_ops either, because the child might respond
8963
     * with an inappropriate response when the PDF14 device is active. For example; the
8964
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8965
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8966
     */
8967
47.2M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8968
320k
        return 0;
8969
46.8M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8970
1.08M
        return 0;
8971
45.8M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8972
11.0k
        return 0;
8973
45.7M
    if(dev_spec_op == gxdso_supports_hlcolor)
8974
967
        return 0;
8975
45.7M
    if(dev_spec_op == gxdso_pattern_can_accum)
8976
83.5k
        return 0;
8977
45.7M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8978
1.51k
        return 0;
8979
45.7M
    if (dev_spec_op == gxdso_overprint_active) {
8980
3.21M
        if (p14dev->pclist_device != NULL) {
8981
3.20M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8982
3.20M
        } else {
8983
9.79k
            return p14dev->overprint || p14dev->stroke_overprint;
8984
9.79k
        }
8985
3.21M
    }
8986
8987
    /* These should be coming only from the abuf device
8988
       during fill-stroke operation. Any other use will
8989
       result in bad things. */
8990
42.5M
    if (dev_spec_op == gxdso_abuf_optrans)
8991
0
    {
8992
0
        int ret = p14dev->op_state;
8993
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
8994
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
8995
0
        const gs_gstate* cpgs = state_data->pgs;
8996
0
        union {
8997
0
            const gs_gstate* cpgs;
8998
0
            gs_gstate* pgs;
8999
0
        } const_breaker;
9000
0
        gs_gstate* pgs;
9001
0
        int code = 0;
9002
0
        int code1 = 0;
9003
9004
        /* A compile time assert to check our storage types are appropriately sized. */
9005
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9006
9007
        /* I don't really like this, but there is no easy way around it. The device
9008
           in the pgs needs to be the pdf14 device to ensure that the compositor
9009
           actions occur with the gs_transparency calls. We have to call at that
9010
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9011
           operations are invoked. We could change the gs_trans calls to take a
9012
           device to avoid this dance but that changes the device procs. */
9013
0
        gx_device *curr_dev;
9014
9015
0
        const_breaker.cpgs = cpgs;
9016
0
        pgs = const_breaker.pgs;
9017
0
        curr_dev = pgs->device;
9018
0
        pgs->device = pdev;
9019
9020
0
        switch (state_data->op_trans) {
9021
9022
0
            case OP_FS_TRANS_PREFILL:
9023
0
                pdf14_abuf->orig_state = p14dev->op_state;
9024
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9025
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9026
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9027
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9028
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9029
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9030
0
                    pdf14_abuf->group_needed = false;
9031
0
                else
9032
0
                    pdf14_abuf->group_needed = true;
9033
9034
0
                if (pdf14_abuf->group_needed) {
9035
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9036
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9037
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9038
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9039
0
                        state_data->alpha_buf_path_scale);
9040
0
                    if (code < 0)
9041
0
                        goto cleanup;
9042
0
                    if (pdf14_abuf->path_empty)
9043
0
                        pdf14_abuf->group_needed = 0;
9044
0
                }
9045
0
                code = gs_update_trans_marking_params(pgs);
9046
0
                break;
9047
9048
0
            case OP_FS_TRANS_PRESTROKE:
9049
0
                if (pdf14_abuf->group_needed) {
9050
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9051
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9052
0
                }
9053
0
                code = gs_update_trans_marking_params(pgs);
9054
0
                break;
9055
9056
0
            case OP_FS_TRANS_POSTSTROKE:
9057
0
                if (pdf14_abuf->group_needed) {
9058
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9059
0
                                                        pdf14_abuf->op_ca_eq_CA);
9060
0
                }
9061
0
                if (code >= 0)
9062
0
                    code = gs_update_trans_marking_params(pgs);
9063
9064
                /* fallthrough */
9065
9066
0
            case OP_FS_TRANS_CLEANUP:
9067
0
cleanup:
9068
0
                if (pdf14_abuf->group_needed) {
9069
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9070
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, pdf14_abuf->orig_state);
9071
0
                    if (code1 < 0)
9072
0
                        code = gs_note_error(gs_error_Fatal);
9073
0
                }
9074
0
                break;
9075
0
        }
9076
0
        pgs->device = curr_dev;
9077
9078
0
        return (code < 0) ? code : ret;
9079
0
    }
9080
9081
42.5M
    if (dev_spec_op == gxdso_in_smask_construction)
9082
3.33M
        return p14dev->in_smask_construction > 0;
9083
39.1M
    if (dev_spec_op == gxdso_in_smask)
9084
24.5M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9085
14.5M
    if (dev_spec_op == gxdso_replacecolor) {
9086
14.3M
        gx_device *tdev = p14dev->target;
9087
14.3M
        cmm_dev_profile_t *tdev_profile;
9088
14.3M
        int code;
9089
9090
         /* If in a softmask or softmask construction do not allow
9091
           replacement. */
9092
14.3M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9093
248k
            return 0;
9094
9095
        /* If the target CS is different than the pdf14 profile add this information
9096
           for the target device that will be handling the replacement. While not
9097
           perfect this at least lets you do the replacehment and have some information
9098
           about what the situation is. */
9099
14.1M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9100
14.1M
        if (code != 0)
9101
0
            return 0;
9102
9103
14.1M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9104
14.1M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9105
3.09M
            color_replace_t* replace_data = (color_replace_t*)data;
9106
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9107
               color remap operation. */
9108
3.09M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9109
3.09M
        }
9110
9111
        /* Pass on to target device */
9112
14.1M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9113
14.1M
    }
9114
213k
    if (dev_spec_op == gxdso_device_insert_child) {
9115
128
        gx_device *tdev = p14dev->target;
9116
128
        p14dev->target = (gx_device *)data;
9117
128
        rc_increment(p14dev->target);
9118
128
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9119
128
        return 0;
9120
128
    }
9121
213k
    if (dev_spec_op == gxdso_interpolate_threshold)
9122
5.30k
        return p14dev->interpolate_threshold;
9123
9124
208k
    if (dev_spec_op == gxdso_overprintsim_state) {
9125
5.28k
        unsigned char *data_uchar = (unsigned char *) data;
9126
5.28k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9127
5.28k
        if (p14dev->ctx != NULL)
9128
7
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9129
5.27k
        else
9130
5.27k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9131
5.28k
        return 1;
9132
5.28k
    }
9133
9134
203k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9135
208k
}
9136
9137
/* Needed to set color monitoring in the target device's profile */
9138
int
9139
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9140
0
{
9141
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9142
0
    gx_device *targ = p14dev->target;
9143
0
    cmm_dev_profile_t *dev_profile;
9144
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9145
9146
0
    if (code == 0)
9147
0
        dev_profile->pageneutralcolor = monitoring;
9148
0
    return code;
9149
0
}
9150
9151
static int
9152
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9153
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9154
1.01M
{
9155
1.01M
    pdf14_device dev_proto;
9156
1.01M
    pdf14_device * p14dev;
9157
1.01M
    int code;
9158
1.01M
    bool has_tags;
9159
1.01M
    cmm_profile_t *icc_profile;
9160
1.01M
    gsicc_rendering_param_t render_cond;
9161
1.01M
    cmm_dev_profile_t *dev_profile;
9162
1.01M
    uchar k;
9163
1.01M
    int max_bitmap;
9164
1.01M
    bool use_pdf14_accum = false;
9165
1.01M
    bool deep;
9166
9167
    /* Guard against later seg faults, this should not be possible */
9168
1.01M
    if (target == NULL)
9169
0
        return gs_throw_code(gs_error_Fatal);
9170
9171
1.01M
    has_tags = device_encodes_tags(target);
9172
1.01M
    deep = device_is_deep(target);
9173
1.01M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9174
1.01M
                                 target->space_params.MaxBitmap;
9175
    /* If the device is not a printer class device, it won't support saved-pages */
9176
    /* and so we may need to make a clist device in order to prevent very large  */
9177
    /* or high resolution pages from having allocation problems.                 */
9178
    /* We use MaxBitmap to decide when a clist is needed.*/
9179
1.01M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9180
5.90k
        gx_device_is_pattern_clist(target) == 0 &&
9181
5.90k
        gx_device_is_pattern_accum(target) == 0 &&
9182
3.46k
        gs_device_is_memory(target) == 0) {
9183
9184
3.46k
        uint32_t pdf14_trans_buffer_size =
9185
3.46k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9186
3.46k
                                         target->color_info.num_components,
9187
3.46k
                                         deep ? 16 : 8) >> 3);
9188
9189
3.46k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9190
3.46k
                pdf14_trans_buffer_size *= target->height;
9191
0
        else
9192
0
                max_bitmap = 0;     /* Force decision to clist */
9193
3.46k
        if (pdf14_trans_buffer_size > max_bitmap)
9194
3.24k
            use_pdf14_accum = true;
9195
3.46k
    }
9196
1.01M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9197
1.01M
    if (code < 0)
9198
0
        return code;
9199
1.01M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9200
1.01M
                          &render_cond);
9201
1.01M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9202
9203
    /* Get the proto from which to copy the device. This will always
9204
     * ignore tags! */
9205
1.01M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9206
1.01M
                                  pdf14pct, use_pdf14_accum);
9207
1.01M
    if (code < 0)
9208
0
        return code;
9209
1.01M
    code = gs_copydevice((gx_device **) &p14dev,
9210
1.01M
                         (const gx_device *) &dev_proto, mem);
9211
1.01M
    if (code < 0)
9212
0
        return code;
9213
9214
1.01M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9215
9216
    /* Copying the params across will add tags to the colorinfo as required. */
9217
1.01M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9218
1.01M
    if (code < 0)
9219
0
        return code;
9220
9221
1.01M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9222
1.01M
    p14dev->pad = target->pad;
9223
1.01M
    p14dev->log2_align_mod = target->log2_align_mod;
9224
1.01M
    if (target->num_planar_planes == 0)
9225
944k
        p14dev->num_planar_planes = 0;
9226
67.8k
    else
9227
67.8k
        p14dev->num_planar_planes = p14dev->color_info.num_components;
9228
1.01M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9229
9230
1.01M
    p14dev->alpha = 1.0;
9231
1.01M
    p14dev->shape = 1.0;
9232
1.01M
    p14dev->opacity = 1.0;
9233
1.01M
    p14dev->fillconstantalpha = 1.0;
9234
1.01M
    p14dev->strokeconstantalpha = 1.0;
9235
9236
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9237
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9238
       do the mapping to the NCLR profile when the put_image occurs */
9239
1.01M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9240
1.01M
        icc_profile->data_cs == gsNCHANNEL) {
9241
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9242
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9243
0
            -1, "gs_pdf14_device_push");
9244
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9245
1.01M
    } else {
9246
        /* If the target profile was CIELAB (and we are not using a blend CS),
9247
           then overide with default RGB for proper blending.  During put_image
9248
           we will convert from RGB to CIELAB.  Need to check that we have a
9249
           default profile, which will not be the case if we are coming from the clist reader */
9250
1.01M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9251
0
            && pgs->icc_manager->default_rgb != NULL &&
9252
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9253
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9254
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9255
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9256
0
                -1, "gs_pdf14_device_push");
9257
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9258
0
        }
9259
1.01M
    }
9260
9261
1.01M
    if (pdf14pct->params.overprint_sim_push &&
9262
0
        pdf14pct->params.num_spot_colors_int > 0) {
9263
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9264
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9265
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9266
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9267
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9268
0
    }
9269
9270
    /* The number of color planes should not exceed that of the target.
9271
       Unless we are using a blend CS */
9272
1.01M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9273
1.01M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev)) {
9274
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9275
0
            if (p14dev->num_planar_planes != 0)
9276
0
                p14dev->num_planar_planes = p14dev->color_info.num_components;
9277
0
        }
9278
1.01M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9279
67.8k
            p14dev->color_info.max_components = target->color_info.max_components;
9280
1.01M
    }
9281
1.01M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9282
    /* If we have a tag device then go ahead and do a special encoder
9283
       decoder for the pdf14 device to make sure we maintain this
9284
       information in the encoded color information.  We could use
9285
       the target device's methods but the PDF14 device has to maintain
9286
       8 bit color always and we could run into other issues if the number
9287
       of colorants became large.  If we need to do compressed color with
9288
       tags that will be a special project at that time */
9289
1.01M
    if (deep) {
9290
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9291
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9292
0
    }
9293
1.01M
    if (has_tags) {
9294
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9295
0
    }
9296
    /* if the device has separations already defined (by SeparationOrderNames) */
9297
    /* we need to copy them (allocating new names) so the colorants are in the */
9298
    /* same order as the target device.                                        */
9299
1.01M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9300
67.8k
        code = devn_copy_params(target, (gx_device *)p14dev);
9301
67.8k
        if (code < 0) {
9302
50
            *pdev = NULL;
9303
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9304
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9305
50
            return code;
9306
50
        }
9307
67.8k
    }
9308
    /* by definition pdf14_encode _is_ standard */
9309
1.01M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9310
1.01M
    gx_device_fill_in_procs((gx_device *)p14dev);
9311
1.01M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9312
1.01M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9313
1.01M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9314
9315
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9316
3.31M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9317
2.29M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9318
2.29M
        p14dev->color_info.comp_shift[k] =
9319
2.29M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9320
2.29M
    }
9321
1.01M
    if (use_pdf14_accum) {
9322
        /* we will disable this device later, but we don't want to allocate large buffers */
9323
3.24k
        p14dev->width = 1;
9324
3.24k
        p14dev->height = 1;
9325
3.24k
    }
9326
9327
1.01M
    p14dev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
9328
1.01M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9329
1.01M
    *pdev = (gx_device *) p14dev;
9330
1.01M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9331
1.01M
    p14dev->color_model_stack = NULL;
9332
9333
    /* In case we have alphabits set */
9334
1.01M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9335
9336
1.01M
    if (pdf14pct->params.is_pattern) {
9337
7.42k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9338
7.42k
        if (code < 0) {
9339
0
            *pdev = NULL;
9340
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9341
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9342
0
            return code;
9343
0
        }
9344
7.42k
    }
9345
9346
    /* We should never go into this when using a blend color space */
9347
1.01M
    if (use_pdf14_accum) {
9348
3.24k
        const gx_device_pdf14_accum *accum_proto = NULL;
9349
3.24k
        gx_device *new_target = NULL;
9350
3.24k
        gx_device_color pdcolor;
9351
3.24k
        frac pconc_white = frac_1;
9352
3.24k
        bool UsePlanarBuffer = false;
9353
9354
3.24k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9355
9356
        /* get the prototype for the accumulator device based on colorspace */
9357
3.24k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9358
671
            case 1:
9359
671
                accum_proto = &pdf14_accum_Gray;
9360
671
                break;
9361
2.57k
            case 3:
9362
2.57k
                accum_proto = &pdf14_accum_RGB;
9363
2.57k
                break;
9364
0
            case 4:
9365
0
                accum_proto = &pdf14_accum_CMYK;
9366
0
                break;
9367
0
            default:
9368
0
                accum_proto = &pdf14_accum_CMYKspot;
9369
0
                UsePlanarBuffer = true;
9370
3.24k
        }
9371
3.24k
        if (accum_proto == NULL ||
9372
3.24k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9373
0
            goto no_clist_accum;
9374
9375
3.24k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9376
        /* Fill in values from the target device before opening */
9377
3.24k
        new_target->color_info = p14dev->color_info;
9378
3.24k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9379
3.24k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9380
3.24k
        set_linear_color_bits_mask_shift(new_target);
9381
3.24k
        gs_pdf14_device_copy_params(new_target, target);
9382
3.24k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9383
3.24k
        gx_device_fill_in_procs(new_target);
9384
9385
3.24k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9386
3.24k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9387
3.24k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9388
9389
        /* This is used to mark the various internal subclass devices as having already
9390
         * been pushed, so that opening the device won't result in us trying to push
9391
         * them again, which leads to trouble.
9392
         */
9393
3.24k
        code = mark_internal_subclass_devices(new_target);
9394
3.24k
        if (code < 0)
9395
0
            return code;
9396
9397
        /* if the device has separations already defined (by SeparationOrderNames) */
9398
        /* we need to copy them (allocating new names) so the colorants are in the */
9399
        /* same order as the target device.                                        */
9400
3.24k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9401
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9402
0
            if (code < 0)
9403
0
                return code;
9404
0
        }
9405
        /* UsePlanarBuffer is true in case this is CMYKspot */
9406
3.24k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9407
3.24k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9408
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9409
0
            goto no_clist_accum;
9410
0
        }
9411
        /* Do the initial fillpage into the pdf14-accum device we just created */
9412
3.24k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9413
3.24k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9414
3.24k
                                            &pconc_white,
9415
3.24k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9416
3.24k
                                            dev_profile)) < 0)
9417
0
            goto no_clist_accum;
9418
9419
3.24k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9420
3.24k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9421
3.24k
        if (code < 0)
9422
0
            goto no_clist_accum;
9423
9424
3.24k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9425
3.24k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9426
3.24k
    }
9427
1.01M
    return code;
9428
9429
0
no_clist_accum:
9430
        /* FIXME: We allocated a really small p14dev, but that won't work */
9431
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9432
1.01M
}
9433
9434
/*
9435
 * In a modest violation of good coding practice, the gs_composite_common
9436
 * fields are "known" to be simple (contain no pointers to garbage
9437
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9438
 * to be simple, so we just create a trivial structure descriptor for the
9439
 * entire gs_pdf14trans_s structure.
9440
 */
9441
#define private_st_gs_pdf14trans_t()\
9442
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9443
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9444
9445
/* GC descriptor for gs_pdf14trans_t */
9446
private_st_gs_pdf14trans_t();
9447
9448
/*
9449
 * Check for equality of two PDF 1.4 transparency compositor objects.
9450
 *
9451
 * We are currently always indicating that PDF 1.4 transparency compositors are
9452
 * equal.  Two transparency compositors may have teh same data but still
9453
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9454
 * operations in a row mean that we are creating a group inside of a group.
9455
 */
9456
static  bool
9457
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9458
0
{
9459
0
    return false;
9460
0
}
9461
9462
#ifdef DEBUG
9463
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9464
#endif
9465
9466
#define put_value(dp, value)\
9467
6.07M
    BEGIN\
9468
6.07M
        memcpy(dp, &value, sizeof(value));\
9469
6.07M
        dp += sizeof(value);\
9470
6.07M
    END
9471
9472
static inline int
9473
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9474
745k
{
9475
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9476
       because clist writer may skip this command for some bands.
9477
       For a better result we need individual CTM for each band.
9478
     */
9479
745k
    byte *pbuf = *ppbuf;
9480
745k
    int len, code;
9481
9482
745k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9483
745k
    pbuf--; /* For cmd_write_ctm. */
9484
745k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9485
745k
    if (code < 0)
9486
0
        return code;
9487
745k
    pbuf += len + 1;
9488
745k
    *ppbuf = pbuf;
9489
745k
    return 0;
9490
745k
}
9491
9492
/*
9493
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9494
 * list device. This is also where we update the pdf14_needed. When set the clist
9495
 * painting procs will update the trans_bbox state for bands that are affected.
9496
*/
9497
static  int
9498
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9499
                   gx_device_clist_writer *cdev)
9500
1.72M
{
9501
1.72M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9502
1.72M
    int need, avail = *psize;
9503
1.72M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9504
        to fit the data written below. We don't implement a dynamic check for
9505
        the buffer owerflow, assuming that the consistency is verified in the
9506
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9507
1.72M
    byte * pbuf = buf;
9508
1.72M
    int opcode = pparams->pdf14_op;
9509
1.72M
    int mask_size = 0;
9510
1.72M
    uint mask_id = 0;
9511
1.72M
    int code;
9512
1.72M
    bool found_icc;
9513
1.72M
    int64_t hashcode = 0;
9514
1.72M
    cmm_profile_t *icc_profile;
9515
1.72M
    gsicc_rendering_param_t render_cond;
9516
1.72M
    cmm_dev_profile_t *dev_profile;
9517
    /* We maintain and update working copies until we actually write the clist */
9518
1.72M
    int pdf14_needed = cdev->pdf14_needed;
9519
1.72M
    int trans_group_level = cdev->pdf14_trans_group_level;
9520
1.72M
    int smask_level = cdev->pdf14_smask_level;
9521
1.72M
    bool deep = device_is_deep((gx_device *)cdev);
9522
9523
1.72M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9524
1.72M
                                                     &dev_profile);
9525
1.72M
    if (code < 0)
9526
0
        return code;
9527
1.72M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9528
1.72M
                          &render_cond);
9529
1.72M
    *pbuf++ = opcode;     /* 1 byte */
9530
1.72M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9531
0
        return_error(gs_error_unregistered);  /* prevent spurious transparency ops (Bug 702327) */
9532
9533
1.72M
    switch (opcode) {
9534
0
        default:      /* Should not occur. */
9535
0
            break;
9536
18.0k
        case PDF14_PUSH_DEVICE:
9537
18.0k
            trans_group_level = 0;
9538
18.0k
            cdev->pdf14_smask_level = 0;
9539
18.0k
            cdev->page_pdf14_needed = false;
9540
18.0k
            put_value(pbuf, pparams->num_spot_colors);
9541
18.0k
            put_value(pbuf, pparams->num_spot_colors_int);
9542
18.0k
            put_value(pbuf, pparams->overprint_sim_push);
9543
18.0k
            put_value(pbuf, pparams->is_pattern);
9544
9545
            /* If we happen to be going to a color space like CIELAB then
9546
               we are going to do our blending in default RGB and convert
9547
               to CIELAB at the end.  To do this, we need to store the
9548
               default RGB profile in the clist so that we can grab it
9549
               later on during the clist read back and put image command */
9550
18.0k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9551
                /* Get the default RGB profile.  Set the device hash code
9552
                   so that we can extract it during the put_image operation. */
9553
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9554
0
                found_icc =
9555
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9556
0
                if (!found_icc) {
9557
                    /* Add it to the table */
9558
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9559
0
                                       pparams->iccprofile);
9560
0
                }
9561
0
            }
9562
18.0k
            break;
9563
18.0k
        case PDF14_POP_DEVICE:
9564
18.0k
            pdf14_needed = false;   /* reset pdf14_needed */
9565
18.0k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9566
18.0k
            smask_level = 0;
9567
18.0k
            put_value(pbuf, pparams->is_pattern);
9568
18.0k
            break;
9569
402k
        case PDF14_END_TRANS_GROUP:
9570
406k
        case PDF14_END_TRANS_TEXT_GROUP:
9571
406k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9572
406k
            if (smask_level == 0 && trans_group_level == 0)
9573
24.6k
                pdf14_needed = cdev->page_pdf14_needed;
9574
406k
            break;      /* No data */
9575
6.67k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9576
406k
        case PDF14_BEGIN_TRANS_GROUP:
9577
406k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9578
406k
            trans_group_level++;
9579
406k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9580
406k
            if (code < 0)
9581
0
                return code;
9582
406k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9583
406k
            *pbuf++ = pparams->blend_mode;
9584
406k
            *pbuf++ = pparams->group_color_type;
9585
406k
            *pbuf++ = pparams->page_group;
9586
406k
            put_value(pbuf, pparams->group_color_numcomps);
9587
406k
            put_value(pbuf, pparams->opacity);
9588
406k
            put_value(pbuf, pparams->shape);
9589
406k
            put_value(pbuf, pparams->bbox);
9590
406k
            put_value(pbuf, pparams->shade_group);
9591
406k
            put_value(pbuf, pparams->text_group);
9592
406k
            mask_id = pparams->mask_id;
9593
406k
            put_value(pbuf, mask_id);
9594
            /* Color space information maybe ICC based
9595
               in this case we need to store the ICC
9596
               profile or the ID if it is cached already */
9597
406k
            if (pparams->group_color_type == ICC) {
9598
                /* Check if it is already in the ICC clist table */
9599
11.1k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9600
11.1k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9601
11.1k
                if (!found_icc) {
9602
                    /* Add it to the table */
9603
3.57k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9604
3.57k
                    put_value(pbuf, hashcode);
9605
7.55k
                } else {
9606
                    /* It will be in the clist. Just write out the hashcode */
9607
7.55k
                    put_value(pbuf, hashcode);
9608
7.55k
                }
9609
395k
            } else {
9610
395k
                put_value(pbuf, hashcode);
9611
395k
            }
9612
406k
            break;
9613
339k
        case PDF14_BEGIN_TRANS_MASK:
9614
339k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9615
288k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9616
288k
                smask_level++;
9617
288k
            }
9618
339k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9619
339k
            if (code < 0)
9620
0
                return code;
9621
339k
            put_value(pbuf, pparams->subtype);
9622
339k
            *pbuf++ = pparams->group_color_type;
9623
339k
            put_value(pbuf, pparams->group_color_numcomps);
9624
339k
            *pbuf++ = pparams->replacing;
9625
339k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9626
339k
            *pbuf++ = pparams->Background_components;
9627
339k
            *pbuf++ = pparams->Matte_components;
9628
339k
            put_value(pbuf, pparams->bbox);
9629
339k
            mask_id = pparams->mask_id;
9630
339k
            put_value(pbuf, mask_id);
9631
339k
            if (pparams->Background_components) {
9632
1.22k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9633
9634
1.22k
                memcpy(pbuf, pparams->Background, l);
9635
1.22k
                pbuf += l;
9636
1.22k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9637
1.22k
                pbuf += sizeof(pparams->GrayBackground);
9638
1.22k
            }
9639
339k
            if (pparams->Matte_components) {
9640
56
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9641
9642
56
                memcpy(pbuf, pparams->Matte, m);
9643
56
                pbuf += m;
9644
56
            }
9645
339k
            if (!pparams->function_is_identity)
9646
1.27k
                mask_size = (256+deep)<<deep;
9647
            /* Color space information may be ICC based
9648
               in this case we need to store the ICC
9649
               profile or the ID if it is cached already */
9650
339k
            if (pparams->group_color_type == ICC) {
9651
                /* Check if it is already in the ICC clist table */
9652
288k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9653
288k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9654
288k
                if (!found_icc) {
9655
                    /* Add it to the table */
9656
2.36k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9657
2.36k
                    put_value(pbuf, hashcode);
9658
286k
                } else {
9659
                    /* It will be in the clist. Just write out the hashcode */
9660
286k
                    put_value(pbuf, hashcode);
9661
286k
                }
9662
288k
            } else {
9663
50.4k
                put_value(pbuf, hashcode);
9664
50.4k
            }
9665
339k
            break;
9666
288k
        case PDF14_END_TRANS_MASK:
9667
288k
            smask_level--;
9668
288k
            if (smask_level == 0 && trans_group_level == 0)
9669
7.23k
                pdf14_needed = cdev->page_pdf14_needed;
9670
288k
            break;
9671
207k
        case PDF14_SET_BLEND_PARAMS:
9672
207k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9673
0
                pparams->shape != 1.0)
9674
207k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9675
0
            else if (smask_level == 0 && trans_group_level == 0)
9676
0
                pdf14_needed = false;   /* At page level, set back to false */
9677
207k
            if (smask_level == 0 && trans_group_level == 0)
9678
75.2k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9679
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9680
207k
            put_value(pbuf, pparams->changed);
9681
207k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9682
34.3k
                *pbuf++ = pparams->blend_mode;
9683
207k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9684
17.4k
                *pbuf++ = pparams->text_knockout;
9685
207k
            if (pparams->changed & PDF14_SET_AIS)
9686
207k
                put_value(pbuf, pparams->ais);
9687
207k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9688
207k
                put_value(pbuf, pparams->overprint);
9689
207k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9690
207k
                put_value(pbuf, pparams->stroke_overprint);
9691
207k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9692
207k
                put_value(pbuf, pparams->fillconstantalpha);
9693
207k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9694
207k
                put_value(pbuf, pparams->strokeconstantalpha);
9695
207k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9696
207k
                put_value(pbuf, pparams->op_fs_state);
9697
207k
            break;
9698
0
        case PDF14_PUSH_TRANS_STATE:
9699
0
            break;
9700
43.1k
        case PDF14_POP_TRANS_STATE:
9701
43.1k
            break;
9702
0
        case PDF14_PUSH_SMASK_COLOR:
9703
0
            return 0;   /* We really should never be here */
9704
0
            break;
9705
0
        case PDF14_POP_SMASK_COLOR:
9706
0
            return 0;   /* We really should never be here */
9707
0
            break;
9708
1.72M
    }
9709
9710
    /* check for fit */
9711
1.72M
    need = (pbuf - buf) + mask_size;
9712
1.72M
    *psize = need;
9713
1.72M
    if (need > avail) {
9714
267k
        if (avail)
9715
0
            return_error(gs_error_rangecheck);
9716
267k
        else
9717
267k
            return gs_error_rangecheck;
9718
267k
    }
9719
9720
    /* If we are writing more than the maximum ever expected,
9721
     * return a rangecheck error. Second check is for Coverity
9722
     */
9723
1.46M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9724
1.46M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9725
0
        return_error(gs_error_rangecheck);
9726
9727
    /* Copy our serialized data into the output buffer */
9728
1.46M
    memcpy(data, buf, need - mask_size);
9729
1.46M
    if (mask_size)  /* Include the transfer mask data if present */
9730
974
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9731
1.46M
    if_debug3m('v', cdev->memory,
9732
1.46M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9733
1.46M
               pdf14_opcode_names[opcode], mask_id, need);
9734
1.46M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9735
1.46M
    cdev->pdf14_trans_group_level = trans_group_level;
9736
1.46M
    cdev->pdf14_smask_level = smask_level;
9737
1.46M
    return 0;
9738
1.46M
}
9739
9740
#undef put_value
9741
9742
/* Function prototypes */
9743
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9744
                const gs_pdf14trans_params_t * pparams,
9745
                gs_memory_t * mem );
9746
9747
#define read_value(dp, value)\
9748
119M
    BEGIN\
9749
119M
        memcpy(&value, dp, sizeof(value));\
9750
119M
        dp += sizeof(value);\
9751
119M
    END
9752
9753
/*
9754
 * Convert the string representation of the PDF 1.4 transparency parameter
9755
 * into the full compositor.
9756
 */
9757
static  int
9758
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9759
                                uint size, gs_memory_t * mem )
9760
35.8M
{
9761
35.8M
    gs_pdf14trans_params_t params = {0};
9762
35.8M
    const byte * start = data;
9763
35.8M
    int used, code = 0;
9764
35.8M
    bool deep;
9765
9766
35.8M
    if (size < 1)
9767
0
        return_error(gs_error_rangecheck);
9768
9769
    /* Read PDF 1.4 compositor data from the clist */
9770
35.8M
    params.pdf14_op = *data++;
9771
35.8M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9772
35.8M
               pdf14_opcode_names[params.pdf14_op], size);
9773
35.8M
    memset(&params.ctm, 0, sizeof(params.ctm));
9774
35.8M
    switch (params.pdf14_op) {
9775
0
        default:      /* Should not occur. */
9776
0
            break;
9777
1.55M
        case PDF14_PUSH_DEVICE:
9778
1.55M
            read_value(data, params.num_spot_colors);
9779
1.55M
            read_value(data, params.num_spot_colors_int);
9780
1.55M
            read_value(data, params.overprint_sim_push);
9781
1.55M
            read_value(data, params.is_pattern);
9782
1.55M
            break;
9783
0
        case PDF14_ABORT_DEVICE:
9784
0
            break;
9785
1.55M
        case PDF14_POP_DEVICE:
9786
1.55M
            read_value(data, params.is_pattern);
9787
1.55M
            break;
9788
2.16M
        case PDF14_END_TRANS_GROUP:
9789
2.59M
        case PDF14_END_TRANS_TEXT_GROUP:
9790
#ifdef DEBUG
9791
            code += 0; /* A good place for a breakpoint. */
9792
#endif
9793
2.59M
            break;      /* No data */
9794
0
        case PDF14_PUSH_TRANS_STATE:
9795
0
            break;
9796
3.07M
        case PDF14_POP_TRANS_STATE:
9797
3.07M
            break;
9798
602k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9799
2.59M
        case PDF14_BEGIN_TRANS_GROUP:
9800
            /*
9801
             * We are currently not using the bbox or the colorspace so they were
9802
             * not placed in the clist
9803
             */
9804
2.59M
            data = cmd_read_matrix(&params.ctm, data);
9805
2.59M
            params.Isolated = (*data) & 1;
9806
2.59M
            params.Knockout = (*data++ >> 1) & 1;
9807
2.59M
            params.blend_mode = *data++;
9808
2.59M
            params.group_color_type = *data++;  /* Trans group color */
9809
2.59M
            params.page_group = *data++;
9810
2.59M
            read_value(data,params.group_color_numcomps);  /* color group size */
9811
2.59M
            read_value(data, params.opacity);
9812
2.59M
            read_value(data, params.shape);
9813
2.59M
            read_value(data, params.bbox);
9814
2.59M
            read_value(data, params.shade_group);
9815
2.59M
            read_value(data, params.text_group);
9816
2.59M
            read_value(data, params.mask_id);
9817
2.59M
            read_value(data, params.icc_hash);
9818
2.59M
            break;
9819
4.57M
        case PDF14_BEGIN_TRANS_MASK:
9820
                /* This is the largest transparency parameter at this time (potentially
9821
                 * 1531 bytes in size if Background_components =
9822
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9823
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9824
                 *
9825
                 * NOTE:
9826
                 * The clist reader must be able to handle this sized device.
9827
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9828
                 * may also need to be changed correspondingly (defined in gstparam.h)
9829
                 * Also... if another compositor param should exceed this size, this
9830
                 * same condition applies.
9831
                 */
9832
4.57M
            data = cmd_read_matrix(&params.ctm, data);
9833
4.57M
            read_value(data, params.subtype);
9834
4.57M
            params.group_color_type = *data++;
9835
4.57M
            read_value(data, params.group_color_numcomps);
9836
4.57M
            params.replacing = *data++;
9837
4.57M
            params.function_is_identity = *data & 1;
9838
4.57M
            deep = (*data++)>>1;
9839
4.57M
            params.Background_components = *data++;
9840
4.57M
            params.Matte_components = *data++;
9841
4.57M
            read_value(data, params.bbox);
9842
4.57M
            read_value(data, params.mask_id);
9843
4.57M
            if (params.Background_components) {
9844
100k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9845
9846
100k
                memcpy(params.Background, data, l);
9847
100k
                data += l;
9848
100k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9849
100k
                data += sizeof(params.GrayBackground);
9850
100k
            }
9851
4.57M
            if (params.Matte_components) {
9852
4.17k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9853
9854
4.17k
                memcpy(params.Matte, data, m);
9855
4.17k
                data += m;
9856
4.17k
            }
9857
4.57M
            read_value(data, params.icc_hash);
9858
4.57M
            if (params.function_is_identity) {
9859
4.53M
                int i;
9860
9861
4.53M
                if (deep) {
9862
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9863
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9864
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9865
4.53M
                } else {
9866
1.16G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9867
1.16G
                        params.transfer_fn[i] = (byte)floor(i *
9868
1.16G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9869
1.16G
                    }
9870
4.53M
                }
9871
4.53M
            } else {
9872
35.0k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9873
35.0k
                data += (256+deep)<<deep;
9874
35.0k
            }
9875
4.57M
            break;
9876
459k
        case PDF14_END_TRANS_MASK:
9877
459k
            break;
9878
0
        case PDF14_PUSH_SMASK_COLOR:
9879
0
            return 0;
9880
0
            break;
9881
0
        case PDF14_POP_SMASK_COLOR:
9882
0
            return 0;
9883
0
            break;
9884
19.4M
        case PDF14_SET_BLEND_PARAMS:
9885
19.4M
            read_value(data, params.changed);
9886
19.4M
            if (params.changed & PDF14_SET_BLEND_MODE)
9887
3.34M
                params.blend_mode = *data++;
9888
19.4M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9889
1.50M
                params.text_knockout = *data++;
9890
19.4M
            if (params.changed & PDF14_SET_AIS)
9891
19.4M
                read_value(data, params.ais);
9892
19.4M
            if (params.changed & PDF14_SET_OVERPRINT)
9893
19.4M
                read_value(data, params.overprint);
9894
19.4M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9895
19.4M
                read_value(data, params.stroke_overprint);
9896
19.4M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9897
19.4M
                read_value(data, params.fillconstantalpha);
9898
19.4M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9899
19.4M
                read_value(data, params.strokeconstantalpha);
9900
19.4M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9901
19.4M
                read_value(data, params.op_fs_state);
9902
19.4M
            break;
9903
35.8M
    }
9904
35.8M
    code = gs_create_pdf14trans(ppct, &params, mem);
9905
35.8M
    if (code < 0)
9906
0
        return code;
9907
35.8M
    used = data - start;
9908
35.8M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9909
9910
    /* If we read more than the maximum expected, return a rangecheck error */
9911
35.8M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9912
0
        return_error(gs_error_rangecheck);
9913
35.8M
    else
9914
35.8M
        return used;
9915
35.8M
}
9916
9917
/*
9918
 * Adjust the compositor's CTM.
9919
 */
9920
static int
9921
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9922
22.0M
{
9923
22.0M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9924
22.0M
    gs_matrix mat = pct->params.ctm;
9925
9926
22.0M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9927
22.0M
               mat.xx, mat.xy, mat.yx, mat.yy,
9928
22.0M
               mat.tx, mat.ty);
9929
22.0M
    mat.tx -= x0;
9930
22.0M
    mat.ty -= y0;
9931
22.0M
    gs_gstate_setmatrix(pgs, &mat);
9932
22.0M
    return 0;
9933
22.0M
}
9934
9935
/*
9936
 * Create a PDF 1.4 transparency compositor.
9937
 *
9938
 * Note that this routine will be called only if the device is not already
9939
 * a PDF 1.4 transparency compositor.
9940
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9941
 */
9942
static  int
9943
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9944
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9945
    gs_memory_t * mem)
9946
1.03M
{
9947
1.03M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9948
1.03M
    int code = 0;
9949
9950
    /*
9951
     * We only handle the push operation.  All other operations are ignored.
9952
     * The other operations will be handled by the composite routine
9953
     * for the PDF 1.4 compositing device.
9954
     */
9955
1.03M
    switch (pdf14pct->params.pdf14_op) {
9956
1.01M
        case PDF14_PUSH_DEVICE:
9957
1.01M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9958
            /* Change (non-error) code to 1 to indicate that we created
9959
             * a device. */
9960
1.01M
            if (code >= 0)
9961
1.01M
                code = 1;
9962
1.01M
            break;
9963
19.5k
        default:
9964
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9965
19.5k
            *pp14dev = NULL;
9966
19.5k
            return_error(gs_error_unregistered);
9967
1.03M
    }
9968
1.01M
    return code;
9969
1.03M
}
9970
9971
/*
9972
 * Find an opening compositor op.
9973
 */
9974
static gs_compositor_closing_state
9975
find_opening_op(int opening_op, gs_composite_t **ppcte,
9976
                gs_compositor_closing_state return_code)
9977
2.37M
{
9978
    /* Assuming a right *BEGIN* - *END* operation balance. */
9979
2.37M
    gs_composite_t *pcte = *ppcte;
9980
9981
5.58M
    for (;;) {
9982
5.58M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9983
5.17M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9984
5.17M
            int op = pct->params.pdf14_op;
9985
9986
5.17M
            *ppcte = pcte;
9987
5.17M
            if (op == opening_op)
9988
1.48M
                return return_code;
9989
3.68M
            if (op != PDF14_SET_BLEND_PARAMS) {
9990
2.21M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9991
562
                    return COMP_ENQUEUE;
9992
2.21M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
9993
248k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
9994
229k
                        return COMP_ENQUEUE;
9995
248k
                }
9996
1.98M
                if (opening_op == PDF14_PUSH_DEVICE) {
9997
1.96M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
9998
1.93M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
9999
255k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10000
117k
                        return COMP_ENQUEUE;
10001
1.96M
                }
10002
1.98M
            }
10003
3.68M
        } else
10004
405k
            return COMP_ENQUEUE;
10005
3.33M
        pcte = pcte->prev;
10006
3.33M
        if (pcte == NULL)
10007
136k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10008
3.33M
    }
10009
2.37M
}
10010
10011
/*
10012
 * Find an opening compositor op.
10013
 */
10014
static gs_compositor_closing_state
10015
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10016
16.1M
{
10017
16.1M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10018
16.1M
    gs_composite_t *pct = *ppcte;
10019
10020
16.1M
    for (;;) {
10021
16.1M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10022
13.3M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10023
10024
13.3M
            *ppcte = pct;
10025
13.3M
            if (pct_pdf14->params.pdf14_op != my_op)
10026
3.89M
                return COMP_ENQUEUE;
10027
9.47M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10028
                /* If the new parameters completely replace the old ones
10029
                   then remove the old one from the queu */
10030
9.47M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10031
9.47M
                    pct_pdf14->params.changed) {
10032
8.70M
                    return COMP_REPLACE_CURR;
10033
8.70M
                } else {
10034
771k
                    return COMP_ENQUEUE;
10035
771k
                }
10036
9.47M
            }
10037
9.47M
        } else
10038
2.80M
            return COMP_ENQUEUE;
10039
0
        pct = pct->prev;
10040
0
        if (pct == NULL)
10041
0
            return COMP_ENQUEUE; /* Not in queue. */
10042
0
    }
10043
16.1M
}
10044
10045
/*
10046
 * Check for closing compositor.
10047
 */
10048
static gs_compositor_closing_state
10049
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10050
                        gx_device *dev)
10051
30.7M
{
10052
30.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10053
30.7M
    int op0 = pct0->params.pdf14_op;
10054
10055
30.7M
    switch (op0) {
10056
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10057
1.11M
        case PDF14_PUSH_DEVICE:
10058
1.11M
            return COMP_ENQUEUE;
10059
0
        case PDF14_ABORT_DEVICE:
10060
0
            return COMP_ENQUEUE;
10061
1.11M
        case PDF14_POP_DEVICE:
10062
1.11M
            if (*ppcte == NULL)
10063
746k
                return COMP_ENQUEUE;
10064
368k
            else {
10065
368k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10066
10067
368k
                if (state == COMP_EXEC_IDLE)
10068
103k
                    return COMP_DROP_QUEUE;
10069
265k
                return state;
10070
368k
            }
10071
448k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10072
2.24M
        case PDF14_BEGIN_TRANS_GROUP:
10073
2.24M
            return COMP_ENQUEUE;
10074
1.84M
        case PDF14_END_TRANS_GROUP:
10075
2.24M
        case PDF14_END_TRANS_TEXT_GROUP:
10076
2.24M
            if (*ppcte == NULL)
10077
390k
                return COMP_EXEC_QUEUE;
10078
1.85M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10079
3.84M
        case PDF14_BEGIN_TRANS_MASK:
10080
3.84M
            return COMP_ENQUEUE;
10081
0
        case PDF14_PUSH_TRANS_STATE:
10082
0
            return COMP_ENQUEUE;
10083
2.59M
        case PDF14_POP_TRANS_STATE:
10084
2.59M
            return COMP_ENQUEUE;
10085
0
        case PDF14_PUSH_SMASK_COLOR:
10086
0
            return COMP_ENQUEUE;
10087
0
            break;
10088
0
        case PDF14_POP_SMASK_COLOR:
10089
0
            return COMP_ENQUEUE;
10090
0
            break;
10091
402k
        case PDF14_END_TRANS_MASK:
10092
402k
            if (*ppcte == NULL)
10093
250k
                return COMP_EXEC_QUEUE;
10094
152k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10095
17.1M
        case PDF14_SET_BLEND_PARAMS:
10096
17.1M
            if (*ppcte == NULL)
10097
972k
                return COMP_ENQUEUE;
10098
            /* hack : ignore csel - here it is always zero : */
10099
16.1M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10100
30.7M
    }
10101
30.7M
}
10102
10103
/*
10104
 * Check whether a next operation is friendly to the compositor.
10105
 */
10106
static bool
10107
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10108
3.57M
{
10109
3.57M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10110
3.57M
    int op0 = pct0->params.pdf14_op;
10111
10112
3.57M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10113
2.28M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10114
        /* Halftone commands are always passed to the target printer device,
10115
           because transparency buffers are always contone.
10116
           So we're safe to execute them before queued transparency compositors. */
10117
1.30M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10118
373k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10119
619k
            return true;
10120
682k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10121
678k
            return true;
10122
682k
    }
10123
2.27M
    return false;
10124
3.57M
}
10125
10126
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10127
static composite_equal_proc(c_pdf14trans_equal);
10128
static composite_write_proc(c_pdf14trans_write);
10129
static composite_read_proc(c_pdf14trans_read);
10130
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10131
static composite_is_closing_proc(c_pdf14trans_is_closing);
10132
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10133
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10134
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10135
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10136
10137
/*
10138
 * Methods for the PDF 1.4 transparency compositor
10139
 *
10140
 * Note:  We have two set of methods.  They are the same except for the
10141
 * composite_clist_write_update method.  Once the clist write device is created,
10142
 * we use the second set of procedures.  This prevents the creation of multiple
10143
 * PDF 1.4 clist write compositor devices being chained together.
10144
 */
10145
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10146
    GX_COMPOSITOR_PDF14_TRANS,
10147
    {
10148
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10149
        c_pdf14trans_equal,                      /* procs.equal */
10150
        c_pdf14trans_write,                      /* procs.write */
10151
        c_pdf14trans_read,                       /* procs.read */
10152
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10153
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10154
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10155
                /* Create a PDF 1.4 clist write device */
10156
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10157
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10158
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10159
    }                                            /* procs */
10160
};
10161
10162
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10163
    GX_COMPOSITOR_PDF14_TRANS,
10164
    {
10165
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10166
        c_pdf14trans_equal,                      /* procs.equal */
10167
        c_pdf14trans_write,                      /* procs.write */
10168
        c_pdf14trans_read,                       /* procs.read */
10169
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10170
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10171
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10172
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10173
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10174
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10175
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10176
    }                                            /* procs */
10177
};
10178
10179
/*
10180
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10181
 */
10182
int
10183
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10184
254M
{
10185
254M
    return (pct->type == &gs_composite_pdf14trans_type
10186
197M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10187
254M
}
10188
10189
/*
10190
 * Create a PDF 1.4 transparency compositor data structure.
10191
 */
10192
static int
10193
gs_create_pdf14trans(
10194
    gs_composite_t **               ppct,
10195
    const gs_pdf14trans_params_t *  pparams,
10196
    gs_memory_t *                   mem )
10197
37.0M
{
10198
37.0M
    gs_pdf14trans_t *                pct;
10199
10200
37.0M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10201
37.0M
                             "gs_create_pdf14trans");
10202
37.0M
    if (pct == NULL)
10203
0
        return_error(gs_error_VMerror);
10204
37.0M
    pct->type = &gs_composite_pdf14trans_type;
10205
37.0M
    pct->id = gs_next_ids(mem, 1);
10206
37.0M
    pct->params = *pparams;
10207
37.0M
    pct->idle = false;
10208
37.0M
    *ppct = (gs_composite_t *)pct;
10209
37.0M
    return 0;
10210
37.0M
}
10211
10212
/*
10213
 * Send a PDF 1.4 transparency compositor action to the specified device.
10214
 */
10215
int
10216
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10217
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10218
1.10M
{
10219
1.10M
    gs_composite_t * pct = NULL;
10220
1.10M
    int code;
10221
10222
1.10M
    pparams->ctm = ctm_only(pgs);
10223
1.10M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10224
1.10M
    if (code < 0)
10225
0
        return code;
10226
1.10M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10227
1.10M
    if (code == gs_error_handled)
10228
0
        code = 0;
10229
10230
1.10M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10231
10232
1.10M
    return code;
10233
1.10M
}
10234
10235
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10236
10237
/*
10238
 * The PDF 1.4 transparency compositor device may have a different process
10239
 * color model than the output device.  If we are banding then we need to
10240
 * create two compositor devices.  The output side (clist reader) needs a
10241
 * compositor to actually composite the output.  We also need a compositor
10242
 * device before the clist writer.  This is needed to provide a process color
10243
 * model which matches the PDF 1.4 blending space.
10244
 *
10245
 * This section provides support for this device.
10246
 */
10247
10248
/*
10249
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10250
 * We actually use the same structure for both the clist writer and reader
10251
 * devices.  However we use separate names to identify the routines for each
10252
 * device.
10253
 */
10254
10255
static  dev_proc_composite(pdf14_clist_composite);
10256
static  dev_proc_composite(pdf14_clist_forward_composite);
10257
static  dev_proc_fill_path(pdf14_clist_fill_path);
10258
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10259
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10260
static  dev_proc_text_begin(pdf14_clist_text_begin);
10261
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10262
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10263
10264
static void
10265
pdf14_clist_init_procs(gx_device *dev,
10266
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10267
                       dev_proc_get_color_comp_index(get_color_comp_index))
10268
9.02k
{
10269
9.02k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10270
9.02k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10271
9.02k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10272
9.02k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10273
9.02k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10274
9.02k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10275
9.02k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10276
9.02k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10277
9.02k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10278
9.02k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10279
9.02k
    set_dev_proc(dev, put_params, pdf14_put_params);
10280
9.02k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10281
9.02k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10282
9.02k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10283
9.02k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10284
9.02k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10285
9.02k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10286
9.02k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10287
9.02k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10288
9.02k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10289
9.02k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10290
9.02k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10291
9.02k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10292
9.02k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10293
9.02k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10294
9.02k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10295
9.02k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10296
9.02k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10297
9.02k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10298
9.02k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10299
9.02k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10300
9.02k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10301
9.02k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10302
9.02k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10303
9.02k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10304
9.02k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10305
9.02k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10306
9.02k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10307
9.02k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10308
9.02k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10309
9.02k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10310
9.02k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10311
9.02k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10312
9.02k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10313
9.02k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10314
9.02k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10315
9.02k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10316
9.02k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10317
9.02k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10318
9.02k
}
10319
10320
static void
10321
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10322
3.15k
{
10323
3.15k
    pdf14_clist_init_procs(dev,
10324
3.15k
                           gx_default_DevGray_get_color_mapping_procs,
10325
3.15k
                           gx_default_DevGray_get_color_comp_index);
10326
3.15k
}
10327
10328
static void
10329
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10330
4.92k
{
10331
4.92k
    pdf14_clist_init_procs(dev,
10332
4.92k
                           gx_default_DevRGB_get_color_mapping_procs,
10333
4.92k
                           gx_default_DevRGB_get_color_comp_index);
10334
4.92k
}
10335
10336
static void
10337
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10338
13
{
10339
13
    pdf14_clist_init_procs(dev,
10340
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10341
13
                           gx_default_DevCMYK_get_color_comp_index);
10342
13
}
10343
10344
static void
10345
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10346
931
{
10347
931
    pdf14_clist_init_procs(dev,
10348
931
                           pdf14_cmykspot_get_color_mapping_procs,
10349
931
                           pdf14_cmykspot_get_color_comp_index);
10350
931
}
10351
10352
static void
10353
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10354
0
{
10355
0
    pdf14_clist_init_procs(dev,
10356
0
                           pdf14_rgbspot_get_color_mapping_procs,
10357
0
                           pdf14_rgbspot_get_color_comp_index);
10358
0
}
10359
10360
#if 0 /* NOT USED */
10361
static int
10362
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10363
{
10364
    pdf14_clist_init_procs(dev,
10365
                           pdf14_grayspot_get_color_mapping_procs,
10366
                           pdf14_grayspot_get_color_comp_index);
10367
}
10368
#endif  /* NOT USED */
10369
10370
const pdf14_clist_device pdf14_clist_Gray_device = {
10371
    std_device_color_stype_body(pdf14_clist_device,
10372
                                pdf14_clist_Gray_initialize_device_procs,
10373
                                "pdf14clistgray",
10374
                                &st_pdf14_device,
10375
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10376
    { 0 },      /* Procs */
10377
    NULL,     /* target */
10378
    { 0 },      /* devn_params - not used */
10379
    &gray_pdf14_procs,
10380
    &gray_blending_procs
10381
};
10382
10383
const pdf14_clist_device pdf14_clist_RGB_device = {
10384
    std_device_color_stype_body(pdf14_clist_device,
10385
                                pdf14_clist_RGB_initialize_device_procs,
10386
                                "pdf14clistRGB",
10387
                                &st_pdf14_device,
10388
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10389
    { 0 },      /* Procs */
10390
    NULL,     /* target */
10391
    { 0 },      /* devn_params - not used */
10392
    &rgb_pdf14_procs,
10393
    &rgb_blending_procs
10394
};
10395
10396
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10397
    std_device_part1_(pdf14_device,
10398
                      pdf14_clist_RGBspot_initialize_device_procs,
10399
                      "pdf14clistrgbspot",
10400
                      &st_pdf14_device,
10401
                      open_init_closed),
10402
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10403
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10404
    offset_margin_values(0, 0, 0, 0, 0, 0),
10405
    std_device_part3_(),
10406
    { 0 },      /* Procs */
10407
    NULL,     /* target */
10408
    /* DeviceN parameters */
10409
    { 8,      /* Not used - Bits per color */
10410
      DeviceRGBComponents,  /* Names of color model colorants */
10411
      3,      /* Number colorants for CMYK */
10412
      0,      /* MaxSeparations has not been specified */
10413
      -1,     /* PageSpotColors has not been specified */
10414
      {0},      /* SeparationNames */
10415
      0,      /* SeparationOrder names */
10416
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10417
    },
10418
    &rgbspot_pdf14_procs,
10419
    &rgb_blending_procs
10420
};
10421
10422
const pdf14_clist_device pdf14_clist_CMYK_device = {
10423
    std_device_std_color_full_body_type(pdf14_clist_device,
10424
                                        pdf14_clist_CMYK_initialize_device_procs,
10425
                                        "pdf14clistcmyk",
10426
                                        &st_pdf14_device,
10427
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10428
                                        0, 0, 0, 0, 0, 0),
10429
    { 0 },      /* Procs */
10430
    NULL,     /* target */
10431
    { 0 },      /* devn_params - not used */
10432
    &cmyk_pdf14_procs,
10433
    &cmyk_blending_procs
10434
};
10435
10436
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10437
    std_device_part1_(pdf14_device,
10438
                      pdf14_clist_CMYKspot_initialize_device_procs,
10439
                      "pdf14clistcmykspot",
10440
                      &st_pdf14_device,
10441
                      open_init_closed),
10442
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10443
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10444
    offset_margin_values(0, 0, 0, 0, 0, 0),
10445
    std_device_part3_(),
10446
    { 0 },      /* Procs */
10447
    NULL,     /* target */
10448
    /* DeviceN parameters */
10449
    { 8,      /* Not used - Bits per color */
10450
      DeviceCMYKComponents, /* Names of color model colorants */
10451
      4,      /* Number colorants for CMYK */
10452
      0,      /* MaxSeparations has not been specified */
10453
      -1,     /* PageSpotColors has not been specified */
10454
      {0},      /* SeparationNames */
10455
      0,      /* SeparationOrder names */
10456
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10457
    },
10458
    &cmykspot_pdf14_procs,
10459
    &cmyk_blending_procs
10460
};
10461
10462
const pdf14_clist_device pdf14_clist_custom_device = {
10463
    std_device_part1_(pdf14_device,
10464
                      pdf14_clist_CMYKspot_initialize_device_procs,
10465
                      "pdf14clistcustom",
10466
                      &st_pdf14_device,
10467
                      open_init_closed),
10468
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10469
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10470
    offset_margin_values(0, 0, 0, 0, 0, 0),
10471
    std_device_part3_(),
10472
    { 0 },      /* Procs */
10473
    NULL,     /* target */
10474
    /* DeviceN parameters */
10475
    { 8,      /* Not used - Bits per color */
10476
      DeviceCMYKComponents, /* Names of color model colorants */
10477
      4,      /* Number colorants for CMYK */
10478
      0,      /* MaxSeparations has not been specified */
10479
      -1,     /* PageSpotColors has not been specified */
10480
      {0},      /* SeparationNames */
10481
      0,      /* SeparationOrder names */
10482
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10483
    },
10484
    &custom_pdf14_procs,
10485
    &custom_blending_procs
10486
};
10487
10488
/*
10489
 * the PDF 1.4 transparency spec says that color space for blending
10490
 * operations can be based upon either a color space specified in the
10491
 * group or a default value based upon the output device.  We are
10492
 * currently only using a color space based upon the device.
10493
 */
10494
static  int
10495
get_pdf14_clist_device_proto(gx_device          *dev,
10496
                             pdf14_clist_device *pdevproto,
10497
                             gs_gstate          *pgs,
10498
                       const gs_pdf14trans_t    *pdf14pct,
10499
                             bool                use_pdf14_accum)
10500
9.02k
{
10501
9.02k
    pdf14_blend_cs_t blend_cs_state;
10502
9.02k
    pdf14_default_colorspace_t dev_cs =
10503
9.02k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10504
9.02k
                                                 &blend_cs_state);
10505
9.02k
    bool deep = device_is_deep(dev);
10506
9.02k
    int num_spots = pdf14pct->params.num_spot_colors;
10507
10508
    /* overprint overide */
10509
9.02k
    if (pdf14pct->params.overprint_sim_push &&
10510
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10511
10512
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10513
0
            dev_cs = PDF14_DeviceCMYKspot;
10514
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10515
0
        } else
10516
0
            dev_cs = PDF14_DeviceCMYK;
10517
0
    }
10518
10519
9.02k
    switch (dev_cs) {
10520
3.15k
        case PDF14_DeviceGray:
10521
           /* We want gray to be single channel.  Low level
10522
               initialization of gray device prototype is
10523
               peculiar in that in dci_std_color_num_components
10524
               the comment is
10525
              "A device is monochrome only if it is bi-level"
10526
              Here we want monochrome anytime we have a gray device.
10527
              To avoid breaking things elsewhere, we will overide
10528
              the prototype intialization here */
10529
3.15k
            *pdevproto = pdf14_clist_Gray_device;
10530
3.15k
            pdevproto->color_info.max_components = 1;
10531
3.15k
            pdevproto->color_info.num_components =
10532
3.15k
                                    pdevproto->color_info.max_components;
10533
3.15k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10534
3.15k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10535
3.15k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10536
3.15k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10537
3.15k
            pdevproto->color_info.depth = deep ? 16 : 8;
10538
3.15k
            pdevproto->sep_device = false;
10539
3.15k
            break;
10540
4.92k
        case PDF14_DeviceRGB:
10541
4.92k
            *pdevproto = pdf14_clist_RGB_device;
10542
4.92k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10543
4.92k
            pdevproto->sep_device = false;
10544
4.92k
            if (deep) {
10545
0
                pdevproto->color_info.depth = 3*16;
10546
0
                pdevproto->color_info.max_color = 65535;
10547
0
                pdevproto->color_info.max_gray = 65535;
10548
0
                pdevproto->color_info.dither_colors = 65536;
10549
0
                pdevproto->color_info.dither_grays = 65536;
10550
0
            }
10551
4.92k
            break;
10552
13
        case PDF14_DeviceCMYK:
10553
13
            *pdevproto = pdf14_clist_CMYK_device;
10554
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10555
13
            pdevproto->sep_device = false;
10556
13
            if (deep) {
10557
0
                pdevproto->color_info.depth = 4*16;
10558
0
                pdevproto->color_info.max_color = 65535;
10559
0
                pdevproto->color_info.max_gray = 65535;
10560
0
                pdevproto->color_info.dither_colors = 65536;
10561
0
                pdevproto->color_info.dither_grays = 65536;
10562
0
            }
10563
13
            break;
10564
931
        case PDF14_DeviceCMYKspot:
10565
931
            *pdevproto = pdf14_clist_CMYKspot_device;
10566
            /*
10567
             * The number of components for the PDF14 device is the sum
10568
             * of the process components and the number of spot colors
10569
             * for the page. If we are using an NCLR ICC profile at
10570
             * the output device, those spot colors are skipped. They
10571
             * do not appear in the transparency buffer, but appear
10572
             * during put image transform of the page group to the target
10573
             * color space.
10574
             */
10575
931
            if (num_spots >= 0) {
10576
931
                pdevproto->devn_params.page_spot_colors = num_spots;
10577
931
                pdevproto->color_info.num_components =
10578
931
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10579
931
                if (pdevproto->color_info.num_components >
10580
931
                              pdevproto->color_info.max_components)
10581
0
                    pdevproto->color_info.num_components =
10582
0
                              pdevproto->color_info.max_components;
10583
931
                pdevproto->color_info.depth =
10584
931
                              pdevproto->color_info.num_components * (8<<deep);
10585
931
            }
10586
931
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10587
931
            pdevproto->sep_device = true;
10588
931
            break;
10589
0
        case PDF14_DeviceRGBspot:
10590
0
            *pdevproto = pdf14_clist_RGBspot_device;
10591
            /*
10592
             * The number of components for the PDF14 device is the sum
10593
             * of the process components and the number of spot colors
10594
             * for the page. If we are using an NCLR ICC profile at
10595
             * the output device, those spot colors are skipped. They
10596
             * do not appear in the transparency buffer, but appear
10597
             * during put image transform of the page group to the target
10598
             * color space.
10599
             */
10600
0
            if (num_spots >= 0) {
10601
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10602
0
                pdevproto->color_info.num_components =
10603
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10604
0
                if (pdevproto->color_info.num_components >
10605
0
                    pdevproto->color_info.max_components)
10606
0
                    pdevproto->color_info.num_components =
10607
0
                        pdevproto->color_info.max_components;
10608
0
                pdevproto->color_info.depth =
10609
0
                    pdevproto->color_info.num_components * (8 << deep);
10610
0
            }
10611
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10612
0
            pdevproto->sep_device = true;
10613
0
            break;
10614
0
        case PDF14_DeviceCustom:
10615
            /*
10616
             * We are using the output device's process color model.  The
10617
             * color_info for the PDF 1.4 compositing device needs to match
10618
             * the output device.
10619
             */
10620
0
            *pdevproto = pdf14_clist_custom_device;
10621
0
            pdevproto->color_info = dev->color_info;
10622
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10623
0
            pdevproto->color_info.depth =
10624
0
                pdevproto->color_info.num_components * (8<<deep);
10625
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10626
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10627
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10628
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10629
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10630
0
            break;
10631
0
        default:      /* Should not occur */
10632
0
            return_error(gs_error_rangecheck);
10633
9.02k
    }
10634
9.02k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10635
9.02k
    pdevproto->blend_cs_state = blend_cs_state;
10636
9.02k
    return 0;
10637
9.02k
}
10638
10639
static  int
10640
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10641
                                gx_device ** ppdev, gx_device * target,
10642
                                const gs_pdf14trans_t * pdf14pct)
10643
9.02k
{
10644
9.02k
    pdf14_clist_device dev_proto;
10645
9.02k
    pdf14_clist_device * pdev;
10646
9.02k
    int code;
10647
9.02k
    bool has_tags = device_encodes_tags(target);
10648
9.02k
    cmm_profile_t *target_profile;
10649
9.02k
    gsicc_rendering_param_t render_cond;
10650
9.02k
    cmm_dev_profile_t *dev_profile;
10651
9.02k
    uchar k;
10652
9.02k
    bool deep = device_is_deep(target);
10653
9.02k
    cmm_profile_t *icc_profile;
10654
9.02k
    int nc;
10655
10656
9.02k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10657
9.02k
    if (code < 0)
10658
0
        return code;
10659
9.02k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10660
9.02k
                          &render_cond);
10661
9.02k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10662
    /* Prototypes never include tags. We add those in later. */
10663
9.02k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10664
9.02k
                                        pgs, pdf14pct, false);
10665
9.02k
    if (code < 0)
10666
0
        return code;
10667
9.02k
    code = gs_copydevice((gx_device **) &pdev,
10668
9.02k
                         (const gx_device *) &dev_proto, mem);
10669
9.02k
    if (code < 0)
10670
0
        return code;
10671
10672
9.02k
    nc = pdev->color_info.num_components;
10673
    /* If we are not using a blending color space, the number of color planes
10674
       should not exceed that of the target */
10675
9.02k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10676
9.02k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10677
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10678
9.02k
        if (pdev->color_info.max_components > target->color_info.max_components)
10679
1.00k
            pdev->color_info.max_components = target->color_info.max_components;
10680
9.02k
    }
10681
9.02k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10682
0
        nc = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10683
10684
9.02k
    pdev->color_info.num_components = nc;
10685
9.02k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10686
9.02k
    pdev->pad = target->pad;
10687
9.02k
    pdev->log2_align_mod = target->log2_align_mod;
10688
10689
9.02k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10690
10691
9.02k
    pdev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
10692
10693
9.02k
    if (deep) {
10694
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10695
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10696
0
    }
10697
    /* If we have a tag device then go ahead and do a special encoder decoder
10698
       for the pdf14 device to make sure we maintain this information in the
10699
       encoded color information.  We could use the target device's methods but
10700
       the PDF14 device has to maintain 8 bit color always and we could run
10701
       into other issues if the number of colorants became large.  If we need to
10702
       do compressed color with tags that will be a special project at that time */
10703
9.02k
    if (has_tags) {
10704
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10705
0
    }
10706
9.02k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10707
9.02k
    gx_device_fill_in_procs((gx_device *)pdev);
10708
    /* Copying the params adds the tags to the color_info if required. */
10709
9.02k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10710
9.02k
    if (target->num_planar_planes > 0)
10711
1.02k
        pdev->num_planar_planes = pdev->color_info.num_components;
10712
9.02k
    gx_device_set_target((gx_device_forward *)pdev, target);
10713
10714
    /* Components shift, etc have to be based upon 8 bit */
10715
30.7k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10716
21.7k
        pdev->color_info.comp_bits[k] = 8<<deep;
10717
21.7k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10718
21.7k
    }
10719
9.02k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10720
9.02k
    if (code < 0)
10721
0
        return code;
10722
9.02k
    pdev->pclist_device = target;
10723
10724
9.02k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10725
9.02k
    if (code < 0)
10726
0
        return code;
10727
9.02k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10728
9.02k
        &render_cond);
10729
9.02k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10730
10731
    /* Simulated overprint case.  We have to use CMYK-based profile
10732
       Also if the target profile is NCLR, we are going to use a pdf14
10733
       device that is CMYK based and do the mapping to the NCLR profile
10734
       when the put_image occurs */
10735
9.02k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10736
9.02k
         icc_profile->data_cs == gsNCHANNEL) {
10737
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10738
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10739
0
            -1, "pdf14_create_clist_device");
10740
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10741
9.02k
    } else {
10742
        /* If the target profile was CIELAB, then overide with default RGB for
10743
           proper blending.  During put_image we will convert from RGB to
10744
           CIELAB */
10745
9.02k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10746
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10747
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10748
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10749
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10750
0
        }
10751
9.02k
    }
10752
10753
9.02k
    if (pdf14pct->params.overprint_sim_push &&
10754
0
        pdf14pct->params.num_spot_colors_int > 0) {
10755
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10756
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10757
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10758
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10759
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10760
0
    }
10761
    /* if the device has separations already defined (by SeparationOrderNames) */
10762
    /* we need to copy them (allocating new names) so the colorants are in the */
10763
    /* same order as the target device.                                        */
10764
9.02k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10765
1.02k
        code = devn_copy_params(target, (gx_device *)pdev);
10766
1.02k
        if (code < 0)
10767
0
            return code;
10768
1.02k
    }
10769
9.02k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10770
9.02k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10771
9.02k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10772
9.02k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10773
9.02k
    pdev->color_info.separable_and_linear =
10774
9.02k
        target->color_info.separable_and_linear;
10775
9.02k
    *ppdev = (gx_device *) pdev;
10776
9.02k
    return code;
10777
9.02k
}
10778
10779
/*
10780
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10781
 * compositor device is never removed.  (We do not have a remove compositor
10782
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10783
 * routine implements that action.
10784
 */
10785
static  int
10786
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10787
                                gx_device * dev)
10788
9.02k
{
10789
9.02k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10790
9.02k
    gx_device * target = pdev->target;
10791
10792
9.02k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10793
10794
    /*
10795
     * To disable the action of this device, we forward all device
10796
     * procedures to the target except the composite and copy
10797
     * the target's color_info.
10798
     */
10799
9.02k
    dev->color_info = target->color_info;
10800
9.02k
    pdf14_forward_device_procs(dev);
10801
9.02k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10802
9.02k
    return 0;
10803
9.02k
}
10804
10805
/*
10806
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10807
 * compositor device is never removed.  (We do not have a remove compositor
10808
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10809
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10810
 * again.
10811
 */
10812
static  int
10813
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10814
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10815
0
{
10816
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10817
0
    gx_device * target = pdev->target;
10818
0
    pdf14_clist_device dev_proto;
10819
0
    int code;
10820
10821
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10822
    /*
10823
     * We will not use the entire prototype device but we will set the
10824
     * color related info to match the prototype.
10825
     */
10826
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10827
0
                                        pgs, pdf14pct, false);
10828
0
    if (code < 0)
10829
0
        return code;
10830
0
    pdev->color_info = dev_proto.color_info;
10831
10832
0
    if (dev_proto.initialize_device_procs != NULL)
10833
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10834
10835
0
    pdev->procs = dev_proto.procs;
10836
0
    pdev->pad = target->pad;
10837
0
    pdev->log2_align_mod = target->log2_align_mod;
10838
10839
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10840
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10841
0
    else
10842
0
        pdev->num_planar_planes = target->num_planar_planes;
10843
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10844
10845
0
    copy_tag_setup(dev, target);
10846
10847
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10848
0
    gx_device_fill_in_procs((gx_device *)pdev);
10849
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10850
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10851
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10852
0
    check_device_separable((gx_device *)pdev);
10853
0
    return code;
10854
0
}
10855
10856
/*
10857
 * devicen params
10858
 */
10859
gs_devn_params *
10860
pdf14_ret_devn_params(gx_device *pdev)
10861
2.08M
{
10862
2.08M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10863
10864
2.08M
    return &(p14dev->devn_params);
10865
2.08M
}
10866
10867
/*
10868
 * devicen params
10869
 */
10870
gs_devn_params *
10871
pdf14_accum_ret_devn_params(gx_device *pdev)
10872
0
{
10873
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10874
10875
0
    return &(p14dev->devn_params);
10876
0
}
10877
10878
static int
10879
pdf14_accum_get_color_comp_index(gx_device * dev,
10880
    const char * pname, int name_size, int component_type)
10881
0
{
10882
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10883
0
    gx_device *target = p14dev->target;
10884
0
    int colorant_number = devn_get_color_comp_index(dev,
10885
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10886
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10887
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10888
10889
0
    if (target != NULL)
10890
        /* colorant_number returned here _should_ be the same as from above */
10891
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10892
0
                              (target, (const char *)pname, name_size, component_type);
10893
0
    return colorant_number;
10894
0
}
10895
10896
/*
10897
 * The following procedures are used to map the standard color spaces into
10898
 * the separation color components for the pdf14_accum device.
10899
 */
10900
static void
10901
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10902
0
{
10903
0
    int * map =
10904
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10905
10906
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10907
0
}
10908
10909
static void
10910
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10911
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10912
0
{
10913
0
    int * map =
10914
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10915
10916
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10917
0
}
10918
10919
static void
10920
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10921
    frac c, frac m, frac y, frac k, frac out[])
10922
0
{
10923
0
    const int * map =
10924
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10925
10926
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10927
0
}
10928
10929
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10930
    pdf14_accum_gray_cs_to_cmyk_cm,
10931
    pdf14_accum_rgb_cs_to_cmyk_cm,
10932
    pdf14_accum_cmyk_cs_to_cmyk_cm
10933
};
10934
10935
static const gx_cm_color_map_procs *
10936
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10937
0
{
10938
0
    *map_dev = dev;
10939
0
    return &pdf14_accum_cm_procs;
10940
0
}
10941
10942
/*
10943
 *  Device proc for updating the equivalent CMYK color for spot colors.
10944
 */
10945
static int
10946
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10947
0
{
10948
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10949
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10950
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10951
0
                                              &pdev->equiv_cmyk_colors);
10952
10953
0
    if (code >= 0 && tdev != NULL)
10954
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10955
0
    return code;
10956
0
}
10957
10958
/* Used when doing overprint simulation and have spot colors */
10959
static int
10960
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10961
0
{
10962
0
    pdf14_device *pdev = (pdf14_device *)dev;
10963
0
    int code;
10964
10965
    /* Make sure we are not All or None */
10966
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10967
0
        pcs->params.separation.sep_type != SEP_OTHER)
10968
0
            return 0;
10969
10970
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10971
0
        &pdev->op_pequiv_cmyk_colors);
10972
0
    return code;
10973
0
}
10974
10975
/*
10976
 * Retrieve a list of spot color names for the PDF14 device.
10977
 */
10978
int
10979
put_param_pdf14_spot_names(gx_device * pdev,
10980
                gs_separations * pseparations, gs_param_list * plist)
10981
59.7k
{
10982
59.7k
    int code, num_spot_colors, i;
10983
59.7k
    gs_param_string str;
10984
10985
    /* Check if the given keyname is present. */
10986
59.7k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10987
59.7k
                                                &num_spot_colors);
10988
59.7k
    switch (code) {
10989
0
        default:
10990
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10991
0
            break;
10992
59.7k
        case 1:
10993
59.7k
            return 0;
10994
0
        case 0:
10995
0
            if (num_spot_colors < 1 ||
10996
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
10997
0
                return_error(gs_error_rangecheck);
10998
0
            for (i = 0; i < num_spot_colors; i++) {
10999
0
                char buff[20];
11000
0
                byte * sep_name;
11001
11002
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11003
0
                code = param_read_string(plist, buff, &str);
11004
0
                switch (code) {
11005
0
                    default:
11006
0
                        param_signal_error(plist, buff, code);
11007
0
                        break;
11008
0
                    case 0:
11009
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11010
0
                                str.size, "put_param_pdf14_spot_names");
11011
0
                        if (sep_name == NULL)
11012
0
                            return_error(gs_error_VMerror);
11013
11014
0
                        memcpy(sep_name, str.data, str.size);
11015
0
                        pseparations->names[i].size = str.size;
11016
0
                        pseparations->names[i].data = sep_name;
11017
0
                }
11018
0
            }
11019
0
            pseparations->num_separations = num_spot_colors;
11020
0
            break;
11021
59.7k
    }
11022
0
    return 0;;
11023
0
}
11024
11025
/*
11026
 * This procedure will have information from the PDF 1.4 clist writing
11027
 * clist compositior device.  This is information output the compressed
11028
 * color list info which is needed for the support of spot colors in
11029
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11030
 * clist reading compositor.  However this device is not created until
11031
 * the clist is read.  To get this info to that device, we have to
11032
 * temporarily store that info in the output device.  This routine saves
11033
 * that info in the output device.
11034
 */
11035
int
11036
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11037
                                        gs_param_list * plist)
11038
59.7k
{
11039
59.7k
    int code;
11040
59.7k
    code = put_param_pdf14_spot_names(pdev,
11041
59.7k
                       &pdevn_params->pdf14_separations, plist);
11042
59.7k
    return code;
11043
59.7k
}
11044
11045
/*
11046
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11047
 * when we are creating the clist.  The second is for imaging the data from
11048
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11049
 * This routine is only called once the PDF 1.4 clist write compositor already
11050
 * exists.
11051
 */
11052
static  int
11053
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11054
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11055
    gx_device *cdev)
11056
1.49M
{
11057
1.49M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11058
1.49M
    int code, is_pdf14_compositor;
11059
1.49M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11060
1.49M
    bool deep = device_is_deep(dev);
11061
11062
    /* We only handle a few PDF 1.4 transparency operations */
11063
1.49M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11064
922k
        switch (pdf14pct->params.pdf14_op) {
11065
0
            case PDF14_PUSH_DEVICE:
11066
                /* Re-activate the PDF 1.4 compositor */
11067
/*
11068
                We previously did:
11069
11070
                pdev->saved_target_color_info = pdev->target->color_info;
11071
11072
                Here, but since we already saved and modified the the color_info
11073
                of the target clist device in gs_pdf14_clist_device_push() this is
11074
                overwriting saved_target_color_info that we already saved with the
11075
                group color_info, meaning when we set it back again, it's incorrect.
11076
*/
11077
0
                pdev->target->color_info = pdev->color_info;
11078
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11079
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11080
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11081
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11082
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11083
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11084
0
                pdev->saved_target_get_color_mapping_procs =
11085
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11086
0
                pdev->saved_target_get_color_comp_index =
11087
0
                                        dev_proc(pdev->target, get_color_comp_index);
11088
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11089
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11090
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11091
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11092
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11093
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11094
0
                gx_set_cmap_procs(pgs, dev);
11095
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11096
0
                pdev->blend_mode = pdev->text_knockout = 0;
11097
0
                pdev->opacity = pdev->shape = 0.0;
11098
0
                if (code < 0)
11099
0
                    return code;
11100
                /*
11101
                 * This routine is part of the PDF 1.4 clist write device.
11102
                 * Change the compositor procs to not create another since we
11103
                 * do not need to create a chain of identical devices.
11104
                 */
11105
0
                {
11106
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11107
11108
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11109
0
                    code = dev_proc(pdev->target, composite)
11110
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11111
                    /* We should never have created a new device here. */
11112
0
                    assert(code != 1);
11113
0
                    return code;
11114
0
                }
11115
9.02k
            case PDF14_POP_DEVICE:
11116
9.02k
            {
11117
9.02k
                gx_device *clistdev = pdev->target;
11118
11119
                /* Find the clist device */
11120
9.02k
                while (1) {
11121
9.02k
                    gxdso_device_child_request req;
11122
                    /* Ignore any errors here, that's expected as non-clist
11123
                     * devices don't implement it. */
11124
9.02k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11125
9.02k
                    if (code == 1)
11126
9.02k
                        break;
11127
0
                    req.n = 0;
11128
0
                    req.target = clistdev;
11129
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11130
0
                    if (code < 0)
11131
0
                        return code;
11132
0
                    clistdev = req.target;
11133
0
                }
11134
11135
                /* If we have overprint simulation spot color information, store
11136
                   it in a pseudo-band of the clist */
11137
9.02k
                if (pdev->overprint_sim &&
11138
0
                    pdev->devn_params.page_spot_colors > 0) {
11139
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11140
0
                        &pdev->op_pequiv_cmyk_colors);
11141
0
                    if (code < 0)
11142
0
                        return code;
11143
0
                }
11144
11145
                /* If we hit an error during an SMask, we need to undo the color
11146
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11147
                 * for itself if it needs to take action.
11148
                 */
11149
9.02k
                pdf14_decrement_smask_color(pgs, dev);
11150
                /* Restore the color_info for the clist device */
11151
9.02k
                clistdev->color_info = pdev->saved_target_color_info;
11152
9.02k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11153
9.02k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11154
9.02k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11155
9.02k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11156
9.02k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11157
9.02k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11158
9.02k
                gx_set_cmap_procs(pgs, clistdev);
11159
9.02k
                gx_device_decache_colors(clistdev);
11160
                /* Disable the PDF 1.4 compositor */
11161
9.02k
                pdf14_disable_clist_device(mem, pgs, dev);
11162
                /*
11163
                 * Make sure that the transfer funtions, etc. are current.
11164
                 */
11165
9.02k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11166
9.02k
                if (code < 0)
11167
0
                    return code;
11168
9.02k
                break;
11169
9.02k
            }
11170
9.02k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11171
36.8k
            case PDF14_BEGIN_TRANS_GROUP:
11172
36.8k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11173
17.0k
                    pdev->depth_within_smask++;
11174
36.8k
                pdev->smask_constructed = 0;
11175
                /*
11176
                 * Keep track of any changes made in the blending parameters.
11177
                   These need to be written out in the same bands as the group
11178
                   information is written.  Hence the passing of the dimensions
11179
                   for the group. */
11180
36.8k
                code = pdf14_clist_update_params(pdev, pgs, true,
11181
36.8k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11182
36.8k
                if (code < 0)
11183
0
                    return code;
11184
36.8k
                if (pdf14pct->params.Background_components != 0 &&
11185
0
                    pdf14pct->params.Background_components !=
11186
0
                    pdev->color_info.num_components)
11187
0
                    return_error(gs_error_rangecheck);
11188
11189
                /* We need to update the clist writer device procs based upon the
11190
                   the group color space. This ensures the proper color data is
11191
                   written out to the device. For simplicity, the list item is
11192
                   created even if the color space did not change */
11193
36.8k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11194
36.8k
                if (code < 0)
11195
0
                    return code;
11196
11197
36.8k
                break;
11198
38.1k
            case PDF14_BEGIN_TRANS_MASK:
11199
                /* We need to update the clist writer device procs based upon the
11200
                   the group color space.  For simplicity, the list item is created
11201
                   even if the color space did not change */
11202
                /* First store the current ones */
11203
38.1k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11204
21.0k
                    break;
11205
11206
                /* Update the color settings of the clist writer.  Store information in stack */
11207
17.1k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11208
17.1k
                if (code < 0)
11209
0
                    return code;
11210
11211
                /* Also, if the BC is a value that may end up as something other
11212
                  than transparent. We must use the parent colors bounding box in
11213
                  determining the range of bands in which this mask can affect.
11214
                  So, if needed change the masks bounding box at this time */
11215
17.1k
                pdev->in_smask_construction++;
11216
17.1k
                break;
11217
366k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11218
366k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11219
17
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11220
17
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11221
17
                } else
11222
366k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11223
366k
                *pcdev = dev;
11224
366k
                return 0; /* Never put into clist. Only used during writing */
11225
369k
            case PDF14_END_TRANS_TEXT_GROUP:
11226
369k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11227
367k
                    *pcdev = dev;
11228
367k
                    return 0; /* Avoids spurious ET calls in interpreter */
11229
367k
                }
11230
2.17k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11231
2.17k
                code = pdf14_clist_pop_color_model(dev, pgs);
11232
2.17k
                if (code < 0)
11233
0
                    return code;
11234
2.17k
                break;
11235
17.1k
            case PDF14_END_TRANS_MASK:
11236
17.1k
                pdev->in_smask_construction--;
11237
17.1k
                if (pdev->in_smask_construction < 0)
11238
0
                    pdev->in_smask_construction = 0;
11239
17.1k
                if (pdev->in_smask_construction == 0)
11240
17.1k
                    pdev->smask_constructed = 1;
11241
                /* fallthrough */
11242
51.8k
            case PDF14_END_TRANS_GROUP:
11243
                /* We need to update the clist writer device procs based upon the
11244
                   the group color space. */
11245
51.8k
                code = pdf14_clist_pop_color_model(dev, pgs);
11246
51.8k
                if (pdev->depth_within_smask)
11247
17.0k
                    pdev->depth_within_smask--;
11248
51.8k
                if (code < 0)
11249
0
                    return code;
11250
51.8k
                break;
11251
51.8k
            case PDF14_PUSH_TRANS_STATE:
11252
0
                break;
11253
16.6k
            case PDF14_POP_TRANS_STATE:
11254
16.6k
                break;
11255
17.1k
            case PDF14_PUSH_SMASK_COLOR:
11256
17.1k
                code = pdf14_increment_smask_color(pgs,dev);
11257
17.1k
                *pcdev = dev;
11258
17.1k
                return code;  /* Note, this are NOT put in the clist */
11259
0
                break;
11260
17.1k
            case PDF14_POP_SMASK_COLOR:
11261
17.1k
                code = pdf14_decrement_smask_color(pgs,dev);
11262
17.1k
                *pcdev = dev;
11263
17.1k
                return code;  /* Note, this are NOT put in the clist */
11264
0
                break;
11265
0
            case PDF14_SET_BLEND_PARAMS:
11266
                /* If there is a change we go ahead and apply it to the target */
11267
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11268
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11269
0
                *pcdev = dev;
11270
0
                return code;
11271
0
                break;
11272
0
            case PDF14_ABORT_DEVICE:
11273
0
                code = gx_abort_trans_device(pgs, dev);
11274
0
                if (pdev->free_devicen) {
11275
0
                    devn_free_params(dev);
11276
0
                }
11277
0
                pdf14_disable_device(dev);
11278
0
                pdf14_close(dev);
11279
0
                *pcdev = dev;
11280
0
                return code;
11281
0
                break;
11282
0
            default:
11283
0
                break;   /* Pass remaining ops to target */
11284
922k
        }
11285
922k
    }
11286
730k
    code = dev_proc(pdev->target, composite)
11287
730k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11288
    /* If we were accumulating into a pdf14-clist-accum device, */
11289
    /* we now have to render the page into it's target device */
11290
730k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11291
9.02k
        pdev->target->stype == &st_gx_devn_accum_device) {
11292
11293
3.24k
        int i, y, rows_used;
11294
3.24k
        byte *linebuf;
11295
3.24k
        byte *actual_data;
11296
3.24k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11297
        /* get the target device we want to send the image to */
11298
3.24k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11299
3.24k
        gs_image1_t image;
11300
3.24k
        gs_color_space *pcs;
11301
3.24k
        gx_image_enum_common_t *info = NULL;
11302
3.24k
        gx_image_plane_t planes;
11303
3.24k
        gsicc_rendering_param_t render_cond;
11304
3.24k
        cmm_dev_profile_t *dev_profile;
11305
3.24k
        bool save_planar = pdev->num_planar_planes;
11306
3.24k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11307
3.24k
        int save_num_separations;
11308
3.24k
        gs_int_rect rect;
11309
11310
3.24k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11311
3.24k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11312
3.24k
        pdev->num_planar_planes = save_planar;
11313
11314
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11315
         * colors do require devn support
11316
         */
11317
3.24k
        if (tdev->color_info.num_components <= 4 ||
11318
3.24k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11319
            /*
11320
             * Set color space in preparation for sending an image.
11321
             */
11322
3.24k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11323
3.24k
            if (code < 0)
11324
0
                goto put_accum_error;
11325
11326
            /* Need to set this to avoid color management during the
11327
               image color render operation.  Exception is for the special case
11328
               when the destination was CIELAB.  Then we need to convert from
11329
               default RGB to CIELAB in the put image operation.  That will happen
11330
               here as we should have set the profile for the pdf14 device to RGB
11331
               and the target will be CIELAB */
11332
3.24k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11333
3.24k
            if (code < 0)
11334
0
                goto put_accum_error;
11335
3.24k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11336
3.24k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11337
            /* pcs takes a reference to the profile data it just retrieved. */
11338
3.24k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11339
3.24k
            if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS) {
11340
0
                code = gs_note_error(gs_error_rangecheck);
11341
0
                goto put_accum_error;
11342
0
            }
11343
3.24k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11344
3.24k
        } else {
11345
             /* DeviceN case -- need to handle spot colors */
11346
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11347
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11348
0
            if (code < 0)
11349
0
                goto put_accum_error;
11350
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11351
0
            pcs->params.device_n.use_alt_cspace = false;
11352
11353
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11354
0
                goto put_accum_error;
11355
0
            }
11356
            /* One last thing -- we need to fudge the pgs->color_component_map */
11357
0
            for (i=0; i < tdev->color_info.num_components; i++)
11358
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11359
            /* copy devn_params that were accumulated into the target device's devn_params */
11360
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11361
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11362
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11363
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11364
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11365
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11366
0
            target_devn_params->separations = tdev->devn_params.separations;
11367
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11368
0
                   sizeof(gs_separation_map));
11369
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11370
0
        }
11371
3.24k
        if (linebuf == NULL) {
11372
0
            code = gs_error_VMerror;
11373
0
            goto put_accum_error;
11374
0
        }
11375
3.24k
        gs_image_t_init_adjust(&image, pcs, false);
11376
3.24k
        image.ImageMatrix.xx = (float)pdev->width;
11377
3.24k
        image.ImageMatrix.yy = (float)pdev->height;
11378
3.24k
        image.Width = pdev->width;
11379
3.24k
        image.Height = pdev->height;
11380
3.24k
        image.BitsPerComponent = 8<<deep;
11381
3.24k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11382
3.24k
        ctm_only_writable(pgs).xy = 0;
11383
3.24k
        ctm_only_writable(pgs).yx = 0;
11384
3.24k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11385
3.24k
        ctm_only_writable(pgs).tx = 0.0;
11386
3.24k
        ctm_only_writable(pgs).ty = 0.0;
11387
3.24k
        code = dev_proc(target, begin_typed_image) (target,
11388
3.24k
                                                    pgs, NULL,
11389
3.24k
                                                    (gs_image_common_t *)&image,
11390
3.24k
                                                    NULL, NULL, NULL,
11391
3.24k
                                                    pgs->memory, &info);
11392
3.24k
        if (code < 0)
11393
0
            goto put_accum_error;
11394
3.24k
        rect.p.x = 0;
11395
3.24k
        rect.q.x = tdev->width;
11396
6.93M
        for (y=0; y < tdev->height; y++) {
11397
6.93M
            gs_get_bits_params_t params;
11398
11399
6.93M
            params.options = (GB_ALIGN_ANY |
11400
6.93M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11401
6.93M
                              GB_OFFSET_0 |
11402
6.93M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11403
6.93M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11404
6.93M
            params.x_offset = 0;
11405
6.93M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11406
6.93M
            params.data[0] = linebuf;
11407
6.93M
            rect.p.y = y;
11408
6.93M
            rect.q.y = y+1;
11409
6.93M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11410
6.93M
                                                      &rect, &params);
11411
6.93M
            if (code < 0)
11412
6
                goto put_accum_error;
11413
6.93M
            actual_data = params.data[0];
11414
6.93M
            planes.data = actual_data;
11415
6.93M
            planes.data_x = 0;
11416
6.93M
            planes.raster = tdev->width * tdev->color_info.num_components;
11417
6.93M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11418
0
                goto put_accum_error;
11419
6.93M
        }
11420
11421
3.24k
put_accum_error:
11422
3.24k
        if (info != NULL) {
11423
3.24k
            if (code < 0)
11424
6
                (void)info->procs->end_image(info, true);
11425
3.23k
            else
11426
3.23k
                code = info->procs->end_image(info, true);
11427
3.24k
        }
11428
11429
3.24k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11430
        /* This will also decrement the device profile */
11431
3.24k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11432
3.24k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11433
        /* Now unhook the clist device and hook to the original so we can clean up */
11434
3.24k
        gx_device_set_target((gx_device_forward *)pdev,
11435
3.24k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11436
3.24k
        pdev->pclist_device = pdev->target;
11437
3.24k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11438
3.24k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11439
3.24k
        if (target_devn_params != NULL) {
11440
            /* prevent devn_free_params from freeing names still in use by target device */
11441
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11442
0
            tdev->devn_params.separations.num_separations = 0;
11443
0
        }
11444
3.24k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11445
3.24k
        if (target_devn_params != NULL) {
11446
0
            target_devn_params->separations.num_separations = save_num_separations;
11447
0
        }
11448
3.24k
        return code;    /* DON'T perform set_target */
11449
3.24k
    }
11450
726k
    if (code == 1) {
11451
        /* We just wrapped pdev->target, so we need to update that.*/
11452
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11453
0
        code = 0; /* We did not wrap dev. */
11454
0
    }
11455
726k
    *pcdev = dev;
11456
726k
    return code;
11457
730k
}
11458
11459
/*
11460
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11461
 * compositor' method.  However the compositor is disabled when we are not
11462
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11463
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11464
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11465
 * to the targer.
11466
 */
11467
static  int
11468
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11469
        const gs_composite_t * pct, gs_gstate * pgs,
11470
        gs_memory_t * mem, gx_device *cdev)
11471
0
{
11472
0
    pdf14_device *pdev = (pdf14_device *)dev;
11473
0
    gx_device * tdev = pdev->target;
11474
0
    gx_device * ndev;
11475
0
    int code;
11476
11477
0
    *pcdev = dev;
11478
0
    if (gs_is_pdf14trans_compositor(pct)) {
11479
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11480
11481
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11482
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11483
0
        return 0;
11484
0
    }
11485
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11486
0
    if (code == 1) {
11487
        /* We just wrapped tdev, so update our target. */
11488
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11489
0
        code = 0; /* We did not wrap dev. */
11490
0
    }
11491
0
    return code;
11492
0
}
11493
11494
/*
11495
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11496
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11497
 */
11498
static  int
11499
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11500
                          bool crop_blend_params,
11501
                          gs_pdf14trans_params_t *group_params)
11502
3.41M
{
11503
3.41M
    gs_pdf14trans_params_t params = { 0 };
11504
3.41M
    gx_device * pcdev;
11505
3.41M
    int changed = 0;
11506
3.41M
    int code = 0;
11507
3.41M
    gs_composite_t *pct_new = NULL;
11508
11509
3.41M
    params.crop_blend_params = crop_blend_params;
11510
11511
3.41M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11512
3.41M
    if (pgs->blend_mode != pdev->blend_mode) {
11513
17.1k
        changed |= PDF14_SET_BLEND_MODE;
11514
17.1k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11515
17.1k
    }
11516
3.41M
    if (pgs->text_knockout != pdev->text_knockout) {
11517
8.70k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11518
8.70k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11519
8.70k
    }
11520
3.41M
    if (pgs->alphaisshape != pdev->ais) {
11521
1.61k
        changed |= PDF14_SET_AIS;
11522
1.61k
        params.ais = pdev->ais = pgs->alphaisshape;
11523
1.61k
    }
11524
3.41M
    if (pgs->overprint != pdev->overprint) {
11525
14.1k
        changed |= PDF14_SET_OVERPRINT;
11526
14.1k
        params.overprint = pdev->overprint = pgs->overprint;
11527
14.1k
    }
11528
3.41M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11529
14.1k
        changed |= PDF14_SET_STROKEOVERPRINT;
11530
14.1k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11531
14.1k
    }
11532
3.41M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11533
22.6k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11534
22.6k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11535
22.6k
    }
11536
3.41M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11537
16.3k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11538
16.3k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11539
16.3k
    }
11540
3.41M
    if ((pgs->is_fill_color && pdev->op_state != GS_OP_STATE_FILL)) {
11541
26.3k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11542
26.3k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_FILL;
11543
26.3k
        if_debug0m('v', pgs->memory,
11544
26.3k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_FILL \n");
11545
26.3k
    }
11546
3.41M
    if ((!pgs->is_fill_color && pdev->op_state != GS_OP_STATE_STROKE)) {
11547
27.3k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11548
27.3k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_STROKE;
11549
27.3k
        if_debug0m('v', pgs->memory,
11550
27.3k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_STROKE \n");
11551
27.3k
    }
11552
3.41M
    if (crop_blend_params) {
11553
36.8k
        params.ctm = group_params->ctm;
11554
36.8k
        params.bbox = group_params->bbox;
11555
36.8k
    }
11556
3.41M
    params.changed = changed;
11557
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11558
       now to the target.  Otherwise we send the compositor action
11559
       to the pdf14 device at this time.  This is due to the fact that we
11560
       need to often perform this operation when we are already starting to
11561
       do a compositor action */
11562
3.41M
    if (changed != 0) {
11563
103k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11564
103k
        if (code < 0)
11565
0
            return code;
11566
103k
        code = dev_proc(pdev->target, composite)
11567
103k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11568
103k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11569
103k
    }
11570
3.41M
    return code;
11571
3.41M
}
11572
11573
/*
11574
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11575
 * writing the clist.
11576
 */
11577
static  int
11578
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11579
                           gx_path *ppath, const gx_fill_params *params,
11580
                           const gx_drawing_color *pdcolor,
11581
                           const gx_clip_path *pcpath)
11582
859k
{
11583
859k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11584
859k
    gs_gstate new_pgs = *pgs;
11585
859k
    int code;
11586
859k
    gs_pattern2_instance_t *pinst = NULL;
11587
859k
    gx_device_forward * fdev = (gx_device_forward *)dev;
11588
859k
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11589
859k
    gsicc_rendering_param_t render_cond;
11590
859k
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11591
859k
    int push_group = 0;
11592
11593
859k
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11594
859k
    if (code < 0)
11595
0
        return code;
11596
859k
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11597
859k
    if (code < 0)
11598
0
        return code;
11599
11600
859k
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11601
1.15k
        check_device_separable(dev);
11602
11603
859k
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11604
859k
                          &render_cond);
11605
859k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11606
859k
                          &render_cond);
11607
11608
    /*
11609
     * Ensure that that the PDF 1.4 reading compositor will have the current
11610
     * blending parameters.  This is needed since the fill_rectangle routines
11611
     * do not have access to the gs_gstate.  Thus we have to pass any
11612
     * changes explictly.
11613
     */
11614
859k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11615
859k
    if (code < 0)
11616
0
        return code;
11617
    /* If we are doing a shading fill and we are in a transparency group of a
11618
       different color space, then we do not want to do the shading in the
11619
       device color space. It must occur in the source space.  To handle it in
11620
       the device space would require knowing all the nested transparency group
11621
       color space as well as the transparency.  Some of the shading code ignores
11622
       this, so we have to pass on the clist_writer device to enable proper
11623
       mapping to the transparency group color space. */
11624
11625
859k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11626
        /* Non-idempotent blends require a transparency
11627
         * group to be pushed because shadings might
11628
         * paint several pixels twice. */
11629
11.2k
        push_group = pgs->fillconstantalpha != 1.0 ||
11630
10.6k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11631
11.2k
        pinst =
11632
11.2k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11633
11.2k
           pinst->saved->has_transparency = true;
11634
           /* The transparency color space operations are driven by the pdf14
11635
              clist writer device.  */
11636
11.2k
           pinst->saved->trans_device = dev;
11637
11.2k
    }
11638
859k
    if (push_group) {
11639
556
        gs_fixed_rect box;
11640
556
        gs_fixed_rect dev_bbox;
11641
11642
556
        if (pcpath) {
11643
556
            gx_cpath_outer_box(pcpath, &box);
11644
556
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11645
556
            rect_intersect(box, dev_bbox);
11646
556
        } else
11647
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11648
11649
556
        if (ppath) {
11650
18
            gs_fixed_rect path_box;
11651
11652
18
            gx_path_bbox(ppath, &path_box);
11653
18
            if (box.p.x < path_box.p.x)
11654
18
                box.p.x = path_box.p.x;
11655
18
            if (box.p.y < path_box.p.y)
11656
18
                box.p.y = path_box.p.y;
11657
18
            if (box.q.x > path_box.q.x)
11658
18
                box.q.x = path_box.q.x;
11659
18
            if (box.q.y > path_box.q.y)
11660
18
                box.q.y = path_box.q.y;
11661
18
        }
11662
11663
556
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11664
            /* No need to do anything */
11665
222
            if (pinst != NULL) {
11666
222
                pinst->saved->trans_device = NULL;
11667
222
            }
11668
222
            return 0;
11669
222
        }
11670
11671
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11672
334
        code = push_shfill_group(pdev, &new_pgs, &box);
11673
334
    } else
11674
858k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11675
858k
    if (code >= 0) {
11676
858k
        new_pgs.trans_device = dev;
11677
858k
        new_pgs.has_transparency = true;
11678
858k
        if (gx_dc_is_pattern2_color(pdcolor))
11679
11.0k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11680
847k
        else
11681
847k
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11682
858k
        new_pgs.trans_device = NULL;
11683
858k
        new_pgs.has_transparency = false;
11684
858k
    }
11685
858k
    if (code >= 0 && push_group) {
11686
332
        code = pop_shfill_group(&new_pgs);
11687
332
        if (code >= 0)
11688
332
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11689
332
    }
11690
858k
    if (pinst != NULL){
11691
11.0k
        pinst->saved->trans_device = NULL;
11692
11.0k
    }
11693
858k
    return code;
11694
859k
}
11695
11696
/*
11697
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11698
 * writing the clist.
11699
 */
11700
static  int
11701
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11702
                             gx_path *ppath, const gx_stroke_params *params,
11703
                             const gx_drawing_color *pdcolor,
11704
                             const gx_clip_path *pcpath)
11705
344k
{
11706
344k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11707
344k
    gs_gstate new_pgs = *pgs;
11708
344k
    int code = 0;
11709
344k
    gs_pattern2_instance_t *pinst = NULL;
11710
344k
    int push_group = 0;
11711
11712
    /*
11713
     * Ensure that that the PDF 1.4 reading compositor will have the current
11714
     * blending parameters.  This is needed since the fill_rectangle routines
11715
     * do not have access to the gs_gstate.  Thus we have to pass any
11716
     * changes explictly.
11717
     */
11718
344k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11719
344k
    if (code < 0)
11720
0
        return code;
11721
    /* If we are doing a shading stroke and we are in a transparency group of a
11722
       different color space, then we need to get the proper device information
11723
       passed along so that we use the correct color procs and colorinfo about
11724
       the transparency device and not the final target device */
11725
344k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11726
        /* Non-idempotent blends require a transparency
11727
         * group to be pushed because shadings might
11728
         * paint several pixels twice. */
11729
60
        push_group = pgs->strokeconstantalpha != 1.0 ||
11730
60
               !blend_is_idempotent(gs_currentblendmode(pgs));
11731
60
        if (pdev->color_model_stack != NULL) {
11732
60
            pinst =
11733
60
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11734
60
            pinst->saved->has_transparency = true;
11735
            /* The transparency color space operations are driven
11736
              by the pdf14 clist writer device.  */
11737
60
            pinst->saved->trans_device = dev;
11738
60
        }
11739
60
    }
11740
344k
    if (push_group) {
11741
0
        gs_fixed_rect box;
11742
0
        if (pcpath)
11743
0
            gx_cpath_outer_box(pcpath, &box);
11744
0
        else
11745
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11746
0
        if (ppath) {
11747
0
            gs_fixed_rect path_box;
11748
0
            gs_fixed_point expansion;
11749
11750
0
            gx_path_bbox(ppath, &path_box);
11751
            /* Expand the path bounding box by the scaled line width. */
11752
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11753
                /* The expansion is so large it caused a limitcheck. */
11754
0
                path_box.p.x = path_box.p.y = min_fixed;
11755
0
                path_box.q.x = path_box.q.y = max_fixed;
11756
0
            } else {
11757
0
                expansion.x += pgs->fill_adjust.x;
11758
0
                expansion.y += pgs->fill_adjust.y;
11759
                /*
11760
                 * It's theoretically possible for the following computations to
11761
                 * overflow, so we need to check for this.
11762
                 */
11763
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11764
0
                                path_box.p.x - expansion.x);
11765
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11766
0
                                path_box.p.y - expansion.y);
11767
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11768
0
                                path_box.q.x + expansion.x);
11769
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11770
0
                                path_box.q.y + expansion.y);
11771
0
            }
11772
0
            if (box.p.x < path_box.p.x)
11773
0
                box.p.x = path_box.p.x;
11774
0
            if (box.p.y < path_box.p.y)
11775
0
                box.p.y = path_box.p.y;
11776
0
            if (box.q.x > path_box.q.x)
11777
0
                box.q.x = path_box.q.x;
11778
0
            if (box.q.y > path_box.q.y)
11779
0
                box.q.y = path_box.q.y;
11780
0
        }
11781
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11782
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11783
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11784
0
    } else
11785
344k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11786
11787
344k
    if (code >= 0) {
11788
344k
        new_pgs.trans_device = dev;
11789
344k
        new_pgs.has_transparency = true;
11790
344k
        if (gx_dc_is_pattern2_color(pdcolor))
11791
60
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11792
344k
        else
11793
344k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11794
344k
        new_pgs.trans_device = NULL;
11795
344k
        new_pgs.has_transparency = false;
11796
344k
    }
11797
344k
    if (code >= 0 && push_group) {
11798
0
        code = pop_shfill_group(&new_pgs);
11799
0
        if (code >= 0)
11800
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11801
0
    }
11802
344k
    if (pinst != NULL)
11803
60
        pinst->saved->trans_device = NULL;
11804
344k
    return code;
11805
344k
}
11806
11807
/* Set up work for doing shading patterns in fill stroke through
11808
   the clist.  We have to do all the dirty work now since we are
11809
   going through the default fill and stroke operations individually */
11810
static int
11811
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11812
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11813
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11814
    const gx_clip_path* pcpath)
11815
0
{
11816
0
    union {
11817
0
        const gs_gstate *cpgs;
11818
0
        gs_gstate *pgs;
11819
0
    } const_breaker;
11820
0
    gs_gstate *pgs;
11821
0
    int code, code2;
11822
0
    gs_transparency_group_params_t params = { 0 };
11823
0
    gs_fixed_rect clip_bbox;
11824
0
    gs_rect bbox, group_stroke_box;
11825
0
    float fill_alpha;
11826
0
    float stroke_alpha;
11827
0
    gs_blend_mode_t blend_mode;
11828
0
    gs_fixed_rect path_bbox;
11829
0
    int expansion_code;
11830
0
    gs_fixed_point expansion;
11831
11832
    /* Break const just once, neatly */
11833
0
    const_breaker.cpgs = cpgs;
11834
0
    pgs = const_breaker.pgs;
11835
11836
0
    fill_alpha = pgs->fillconstantalpha;
11837
0
    stroke_alpha = pgs->strokeconstantalpha;
11838
0
    blend_mode = pgs->blend_mode;
11839
11840
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11841
0
    if (code < 0 && code != gs_error_unknownerror)
11842
0
        return code;
11843
0
    if (code == gs_error_unknownerror) {
11844
        /* didn't get clip box from gx_curr_fixed_bbox */
11845
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11846
0
        clip_bbox.q.x = int2fixed(dev->width);
11847
0
        clip_bbox.q.y = int2fixed(dev->height);
11848
0
    }
11849
0
    if (pcpath)
11850
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11851
11852
    /* expand the ppath using stroke expansion rule, then intersect it */
11853
0
    code = gx_path_bbox(ppath, &path_bbox);
11854
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11855
0
        return 0;   /* ignore empty path */
11856
0
    if (code < 0)
11857
0
        return code;
11858
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11859
0
    if (expansion_code >= 0) {
11860
0
        path_bbox.p.x -= expansion.x;
11861
0
        path_bbox.p.y -= expansion.y;
11862
0
        path_bbox.q.x += expansion.x;
11863
0
        path_bbox.q.y += expansion.y;
11864
0
    }
11865
0
    rect_intersect(path_bbox, clip_bbox);
11866
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11867
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11868
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11869
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11870
11871
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11872
0
    if (code < 0)
11873
0
        return code;
11874
11875
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11876
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11877
0
        pgs->overprint && pgs->stroke_overprint &&
11878
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11879
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11880
11881
0
        params.Isolated = false;
11882
0
        params.group_color_type = UNKNOWN;
11883
0
        params.Knockout = false;
11884
0
        params.page_group = false;
11885
0
        params.group_opacity = fill_alpha;
11886
0
        params.group_shape = 1.0;
11887
11888
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11889
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11890
0
        if (code < 0)
11891
0
            return code;
11892
11893
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11894
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11895
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11896
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11897
11898
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11899
0
        if (code < 0)
11900
0
            goto cleanup;
11901
11902
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11903
0
        if (code < 0)
11904
0
            goto cleanup;
11905
11906
0
    } else {
11907
        /* Push a non-isolated knockout group. Do not change the alpha or
11908
           blend modes */
11909
0
        params.Isolated = false;
11910
0
        params.group_color_type = UNKNOWN;
11911
0
        params.Knockout = true;
11912
0
        params.page_group = false;
11913
0
        params.group_opacity = 1.0;
11914
0
        params.group_shape = 1.0;
11915
11916
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11917
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11918
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11919
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11920
11921
        /* restore blend mode for actual drawing in the group */
11922
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11923
11924
0
        if (fill_alpha > 0.0) {
11925
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11926
11927
            /* If we are in an overprint situation, set the blend mode to compatible
11928
               overprint */
11929
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11930
0
                pgs->overprint &&
11931
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11932
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11933
11934
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11935
0
            if (code < 0)
11936
0
                goto cleanup;
11937
11938
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11939
0
                pgs->overprint &&
11940
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11941
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11942
0
        }
11943
11944
0
        if (stroke_alpha > 0.0) {
11945
            /* Note that the stroke can end up looking like a fill here */
11946
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11947
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11948
11949
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11950
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11951
11952
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11953
0
            if (code < 0)
11954
0
                goto cleanup;
11955
11956
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11957
0
                pgs->overprint &&
11958
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11959
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11960
0
        }
11961
0
    }
11962
11963
0
cleanup:
11964
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11965
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11966
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11967
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11968
11969
    /* Restore where we were. If an error occured while in the group push
11970
       return that error code but try to do the cleanup */
11971
0
    code2 = gs_end_transparency_group(pgs);
11972
0
    if (code2 < 0) {
11973
        /* At this point things have gone very wrong. We should just shut down */
11974
0
        code = gs_abort_pdf14trans_device(pgs);
11975
0
        return code2;
11976
0
    }
11977
11978
    /* Restore if there were any changes */
11979
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11980
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11981
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11982
11983
0
    return code;
11984
0
}
11985
11986
/*
11987
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11988
 * writing the clist.
11989
 */
11990
static  int
11991
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11992
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11993
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11994
                             const gx_clip_path *pcpath)
11995
7.27k
{
11996
7.27k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11997
7.27k
    gs_gstate new_pgs = *pgs;
11998
7.27k
    int code;
11999
12000
7.27k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12001
7.21k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12002
75
        return 0;
12003
12004
    /*
12005
     * Ensure that that the PDF 1.4 reading compositor will have the current
12006
     * blending parameters.  This is needed since the fill_rectangle routines
12007
     * do not have access to the gs_gstate.  Thus we have to pass any
12008
     * changes explictly.
12009
     */
12010
7.20k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12011
7.20k
    if (code < 0)
12012
0
        return code;
12013
    /* If we are doing a shading fill or stroke, the clist can't
12014
       deal with this and end up in the pdf_fill_stroke operation.
12015
       We will need to break up the fill stroke now and do
12016
       the appropriate group pushes and set up. */
12017
12018
7.20k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12019
7.20k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12020
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12021
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12022
0
    }
12023
7.20k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12024
7.20k
    new_pgs.trans_device = dev;
12025
7.20k
    new_pgs.has_transparency = true;
12026
7.20k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12027
7.20k
                                       params_stroke, pdevc_stroke, pcpath);
12028
7.20k
    new_pgs.trans_device = NULL;
12029
7.20k
    new_pgs.has_transparency = false;
12030
7.20k
    return code;
12031
7.20k
}
12032
12033
/*
12034
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12035
 * writing the clist.
12036
 */
12037
static  int
12038
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12039
                 const gs_text_params_t * text, gs_font * font,
12040
                 const gx_clip_path * pcpath,
12041
                 gs_text_enum_t ** ppenum)
12042
2.12M
{
12043
2.12M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12044
2.12M
    gs_text_enum_t *penum;
12045
2.12M
    int code;
12046
2.12M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12047
2.12M
    float opacity = pgs->fillconstantalpha;
12048
2.12M
    float shape = 1.0;
12049
2.12M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12050
2.12M
    bool draw = !(text->operation & TEXT_DO_NONE);
12051
2.12M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12052
2.12M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12053
2.12M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12054
12055
2.12M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12056
    /*
12057
     * Ensure that that the PDF 1.4 reading compositor will have the current
12058
     * blending parameters.  This is needed since the fill_rectangle routines
12059
     * do not have access to the gs_gstate.  Thus we have to pass any
12060
     * changes explictly.
12061
     */
12062
2.12M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12063
2.12M
    if (code < 0)
12064
0
        return code;
12065
    /* Pass text_begin to the target */
12066
2.12M
    code = gx_forward_text_begin(dev, pgs, text, font,
12067
2.12M
                                 pcpath, &penum);
12068
2.12M
    if (code < 0)
12069
713
        return code;
12070
12071
   /* Catch case where we already pushed a group and are trying to push another one.
12072
   In that case, we will pop the current one first, as we don't want to be left
12073
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12074
   will not be caught until we do the put_image and notice that the stack is not
12075
   empty. */
12076
2.12M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12077
2
        code = gs_end_transparency_group(pgs);
12078
2
        if (code < 0)
12079
0
            return code;
12080
2
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12081
2
    }
12082
12083
    /* We may need to push a non-isolated transparency group if the following
12084
    is true.
12085
    1) We are not currently in one that we pushed for text.  This is
12086
    is determined by looking at the pdf14 device.
12087
    2) The blend mode is not Normal or the opacity is not 1.0
12088
    3) Text knockout is set to true
12089
    4) And we are actually drawing text
12090
    */
12091
12092
2.12M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12093
2.12M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12094
2.11M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12095
10.4k
        text_mode != 3 && /* don't bother with invisible text */
12096
10.4k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12097
2.20k
        if (draw) {
12098
2.20k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12099
2.20k
            if (code == 0)
12100
2.20k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12101
2.20k
        }
12102
2.20k
    }
12103
2.12M
    *ppenum = (gs_text_enum_t *)penum;
12104
2.12M
    return code;
12105
2.12M
}
12106
12107
static  int
12108
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12109
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12110
                           const gs_int_rect * prect,
12111
                           const gx_drawing_color * pdcolor,
12112
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12113
                           gx_image_enum_common_t ** pinfo)
12114
38.4k
{
12115
38.4k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12116
38.4k
    int code;
12117
38.4k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12118
38.4k
    const gs_image_t *pim = (const gs_image_t *)pic;
12119
38.4k
    gx_image_enum *penum;
12120
38.4k
    gx_color_tile *ptile;
12121
38.4k
    gs_rect bbox_in, bbox_out;
12122
38.4k
    gs_transparency_group_params_t tgp;
12123
    /*
12124
     * Ensure that that the PDF 1.4 reading compositor will have the current
12125
     * blending parameters.  This is needed since the fill_rectangle routines
12126
     * do not have access to the gs_gstate.  Thus we have to pass any
12127
     * changes explictly.
12128
     */
12129
38.4k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12130
38.4k
    if (code < 0)
12131
0
        return code;
12132
    /* Pass image to the target */
12133
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12134
       case the clist writer cannot handle this image itself.  In such a case,
12135
       we want to make sure we dont use the target device.  I don't necc. like
12136
       doing it this way.  Probably need to go back and do something a bit
12137
       more elegant. */
12138
38.4k
    pgs_noconst->has_transparency = true;
12139
38.4k
    pgs_noconst->trans_device = dev;
12140
12141
    /* If we are filling an image mask with a pattern that has a transparency
12142
       then we need to do some special handling */
12143
38.4k
    if (pim->ImageMask) {
12144
73
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12145
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12146
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12147
0
                    ptile = pdcolor->colors.pattern.p_tile;
12148
                    /* Set up things in the ptile so that we get the proper
12149
                       blending etc */
12150
                    /* Set the blending procs and the is_additive setting based
12151
                       upon the number of channels */
12152
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12153
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12154
0
                        ptile->ttrans->is_additive = true;
12155
0
                    } else {
12156
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12157
0
                        ptile->ttrans->is_additive = false;
12158
0
                    }
12159
                    /* Set the blending mode in the ptile based upon the current
12160
                       setting in the gs_gstate */
12161
0
                    ptile->blending_mode = pgs->blend_mode;
12162
                    /* Set the procs so that we use the proper filling method. */
12163
                    /* Let the imaging stuff get set up */
12164
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12165
0
                                                        prect, pdcolor,
12166
0
                                                        pcpath, mem, pinfo);
12167
0
                    if (code < 0)
12168
0
                        return code;
12169
12170
0
                    penum = (gx_image_enum *) *pinfo;
12171
                    /* Apply inverse of the image matrix to our
12172
                       image size to get our bounding box. */
12173
0
                    bbox_in.p.x = 0;
12174
0
                    bbox_in.p.y = 0;
12175
0
                    bbox_in.q.x = pim->Width;
12176
0
                    bbox_in.q.y = pim->Height;
12177
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12178
0
                                                     &bbox_out);
12179
0
                    if (code < 0)
12180
0
                        return code;
12181
                    /* Set up a compositor action for pushing the group */
12182
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12183
0
                    tgp.Isolated = true;
12184
0
                    tgp.Knockout = false;
12185
0
                    tgp.page_group = false;
12186
0
                    tgp.mask_id = 0;
12187
0
                    tgp.image_with_SMask = false;
12188
0
                    tgp.idle = false;
12189
0
                    tgp.iccprofile = NULL;
12190
0
                    tgp.icc_hashcode = 0;
12191
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12192
0
                    tgp.ColorSpace = NULL;
12193
0
                    tgp.text_group = 0;
12194
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12195
0
                    tgp.group_shape = 1.0;
12196
                    /* This will handle the compositor command */
12197
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12198
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12199
0
                    ptile->ttrans->image_render = penum->render;
12200
0
                    penum->render = &pdf14_pattern_trans_render;
12201
0
                    ptile->trans_group_popped = false;
12202
0
                    pgs_noconst->has_transparency = false;
12203
0
                    pgs_noconst->trans_device = NULL;
12204
0
                    return code;
12205
0
                }
12206
0
            }
12207
21
        }
12208
73
    }
12209
    /* This basically tries high level images for clist. If that fails
12210
       then we do the default */
12211
38.4k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12212
38.4k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12213
38.4k
    if (code < 0){
12214
10.3k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12215
10.3k
                                        pdcolor, pcpath, mem, pinfo);
12216
10.3k
        pgs_noconst->has_transparency = false;
12217
10.3k
        pgs_noconst->trans_device = NULL;
12218
10.3k
        return code;
12219
28.1k
    } else {
12220
28.1k
        pgs_noconst->has_transparency = false;
12221
28.1k
        pgs_noconst->trans_device = NULL;
12222
28.1k
        return code;
12223
28.1k
    }
12224
38.4k
}
12225
12226
static int
12227
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12228
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12229
2.45k
{
12230
2.45k
    int code;
12231
12232
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12233
2.45k
                                  x, y, w, h, plane_height);
12234
2.45k
    return code;
12235
2.45k
}
12236
12237
static int
12238
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12239
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12240
9.02k
{
12241
9.02k
    int code;
12242
9.02k
    pdf14_clist_device *p14dev;
12243
9.02k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12244
12245
9.02k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12246
9.02k
    if (code < 0)
12247
0
        return code;
12248
    /*
12249
     * Set the color_info of the clist device to match the compositing
12250
     * device.  We will restore it when the compositor is popped.
12251
     * See pdf14_clist_composite for the restore.  Do the
12252
     * same with the gs_gstate's get_cmap_procs.  We do not want
12253
     * the gs_gstate to use transfer functions on our color values.
12254
     * The transfer functions will be applied at the end after we
12255
     * have done our PDF 1.4 blend operations.
12256
     */
12257
9.02k
    p14dev = (pdf14_clist_device *)(*pcdev);
12258
9.02k
    p14dev->saved_target_color_info = dev->color_info;
12259
9.02k
    dev->color_info = (*pcdev)->color_info;
12260
    /* Make sure that we keep the anti-alias information though */
12261
9.02k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12262
9.02k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12263
12264
    /* adjust the clist_color_info now */
12265
9.02k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12266
9.02k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12267
9.02k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12268
9.02k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12269
9.02k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12270
12271
9.02k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12272
9.02k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12273
9.02k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12274
9.02k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12275
9.02k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12276
9.02k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12277
9.02k
    p14dev->saved_target_get_color_mapping_procs =
12278
9.02k
                              dev_proc(dev, get_color_mapping_procs);
12279
9.02k
    p14dev->saved_target_get_color_comp_index =
12280
9.02k
                              dev_proc(dev, get_color_comp_index);
12281
9.02k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12282
9.02k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12283
9.02k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12284
9.02k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12285
9.02k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12286
9.02k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12287
9.02k
    gx_set_cmap_procs(pgs, dev);
12288
9.02k
    return code;
12289
9.02k
}
12290
/*
12291
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12292
 * to create a compositing device for clist writing.  The primary purpose of
12293
 * this device is to provide support for the process color model in which
12294
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12295
 * model of the output device.)  The actual work of compositing the image is
12296
 * done on the output (reader) side of the clist.
12297
 */
12298
static  int
12299
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12300
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12301
267k
{
12302
267k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12303
267k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12304
267k
    int code = 0;
12305
12306
    /* We only handle the push/pop operations */
12307
267k
    switch (pdf14pct->params.pdf14_op) {
12308
9.02k
        case PDF14_PUSH_DEVICE:
12309
9.02k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12310
            /* Change (non-error) code to 1 to indicate that we created
12311
             * a device. */
12312
9.02k
            if (code >= 0)
12313
9.02k
                code = 1;
12314
9.02k
            return code;
12315
12316
9.02k
        case PDF14_POP_DEVICE:
12317
9.02k
            code = clist_writer_check_empty_cropping_stack(cdev);
12318
9.02k
            break;
12319
12320
3.33k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12321
36.8k
        case PDF14_BEGIN_TRANS_GROUP:
12322
36.8k
            { /* HACK: store mask_id into our params for subsequent
12323
                   calls of c_pdf14trans_write. To do this we must
12324
                   break const. */
12325
36.8k
                gs_pdf14trans_t * pdf14pct_noconst;
12326
12327
36.8k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12328
                /* What ever the current mask ID is, that is the
12329
                   softmask group through which this transparency
12330
                   group must be rendered. Store it now. */
12331
36.8k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12332
36.8k
                if_debug1m('v', pgs->memory,
12333
36.8k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12334
36.8k
                           cdev->mask_id);
12335
36.8k
            }
12336
36.8k
            break;
12337
34.6k
        case PDF14_END_TRANS_GROUP:
12338
36.8k
        case PDF14_END_TRANS_TEXT_GROUP:
12339
36.8k
            code = 0; /* A place for breakpoint. */
12340
36.8k
            break;
12341
38.1k
        case PDF14_BEGIN_TRANS_MASK:
12342
            /* A new mask has been started */
12343
38.1k
            cdev->mask_id = ++cdev->mask_id_count;
12344
            /* replacing is set everytime that we
12345
               have a zpushtransparencymaskgroup */
12346
38.1k
            { /* HACK: store mask_id into our params for subsequent
12347
                   calls of c_pdf14trans_write. To do this we must
12348
                   break const. */
12349
38.1k
                gs_pdf14trans_t * pdf14pct_noconst;
12350
12351
38.1k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12352
38.1k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12353
38.1k
                if_debug1m('v', pgs->memory,
12354
38.1k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12355
38.1k
                           cdev->mask_id);
12356
38.1k
            }
12357
38.1k
            break;
12358
17.1k
        case PDF14_END_TRANS_MASK:
12359
17.1k
            code = 0; /* A place for breakpoint. */
12360
17.1k
            break;
12361
0
        case PDF14_PUSH_TRANS_STATE:
12362
0
            code = 0; /* A place for breakpoint. */
12363
0
            break;
12364
16.6k
        case PDF14_POP_TRANS_STATE:
12365
16.6k
            code = 0; /* A place for breakpoint. */
12366
16.6k
            break;
12367
0
        case PDF14_ABORT_DEVICE:
12368
0
            code = 0;
12369
0
            break;
12370
0
        case PDF14_PUSH_SMASK_COLOR:
12371
0
            *pcdev = dev;
12372
0
            return 0;
12373
0
            break;
12374
0
        case PDF14_POP_SMASK_COLOR:
12375
0
            *pcdev = dev;
12376
0
            return 0;
12377
0
            break;
12378
103k
        default:
12379
103k
            break;   /* do nothing for remaining ops */
12380
267k
    }
12381
258k
    *pcdev = dev;
12382
258k
    if (code < 0)
12383
0
        return code;
12384
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12385
       apply_composite. */
12386
258k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12387
    /* Wrote an extra ctm. */
12388
258k
    cmd_clear_known(cdev, ctm_known);
12389
12390
258k
    return code;
12391
258k
}
12392
12393
/*
12394
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12395
 * device color_info data match the compositing device.  We need to do this
12396
 * since the PDF 1.4 transparency compositing device may use a different
12397
 * process color model than the output device.  We do not need to modify the
12398
 * color related device procs since the compositing device has its own.  We
12399
 * restore the color_info data when the transparency device is popped.
12400
 */
12401
static  int
12402
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12403
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12404
21.4M
{
12405
21.4M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12406
21.4M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12407
21.4M
    gs_devn_params * pclist_devn_params;
12408
21.4M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12409
21.4M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12410
21.4M
    gsicc_rendering_param_t render_cond;
12411
21.4M
    cmm_dev_profile_t *dev_profile;
12412
12413
21.4M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12414
21.4M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12415
21.4M
                          &render_cond);
12416
12417
    /* If we are using the blending color space, then be sure to use that. */
12418
21.4M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12419
0
        dev_profile->blend_profile != NULL)
12420
0
        cl_icc_profile = dev_profile->blend_profile;
12421
21.4M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12422
0
        dev_profile->oi_profile != NULL)
12423
0
        cl_icc_profile = dev_profile->oi_profile;
12424
12425
21.4M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12426
21.4M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12427
21.4M
                          &render_cond);
12428
    /*
12429
     * We only handle the push/pop operations. Save and restore the color_info
12430
     * field for the clist device.  This is needed since the process color
12431
     * model of the clist device needs to match the PDF 1.4 compositing
12432
     * device.
12433
     */
12434
21.4M
    switch (pdf14pct->params.pdf14_op) {
12435
1.01M
    case PDF14_PUSH_DEVICE:
12436
        /* Overprint simulation sets the profile at prototype creation, as does
12437
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12438
1.01M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12439
1.01M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12440
1.01M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12441
1.01M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12442
1.01M
                -1, "c_pdf14trans_clist_read_update");
12443
1.01M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12444
1.01M
        }
12445
            /*
12446
             * If we are blending using spot colors (i.e. the output device
12447
             * supports spot colors) then we need to transfer
12448
             * color info from the clist PDF 1.4 compositing reader device
12449
             * to the clist writer PDF 1.4 compositing device.
12450
             * This info was transfered from that device to the output
12451
             * device as a set of device parameters.  However the clist
12452
             * reader PDF 1.4 compositing device did not exist when the
12453
             * device parameters were read from the clist.  So that info
12454
             * was buffered into the output device.
12455
             */
12456
1.01M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12457
1.01M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12458
541
                int num_comp = p14dev->color_info.num_components;
12459
541
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12460
                /*
12461
                 * The number of components for the PDF14 device is the sum
12462
                 * of the process components and the number of spot colors
12463
                 * for the page.  If the color capabilities of the parent
12464
                 * device (which coming into this are the same as the p14dev)
12465
                 * are smaller than the number of page spot colors then
12466
                 * use that for the number of components. Otherwise use
12467
                 * the page_spot_colors.  The exception is, if we had used
12468
                 * the sICCOutputColors setting, then just use that, which
12469
                 * should be already baked into num_comp. With clist patterns,
12470
                 * cdev->icc_struct may be null.
12471
                 */
12472
12473
541
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12474
541
                    p14dev->devn_params.page_spot_colors =
12475
541
                        pclist_devn_params->page_spot_colors;
12476
541
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12477
0
                        if (p14dev->num_planar_planes > 0)
12478
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12479
0
                        p14dev->color_info.num_components = num_comp;
12480
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12481
541
                    } else {
12482
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12483
541
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12484
541
                            int n = p14dev->num_std_colorants +
12485
541
                                    p14dev->devn_params.page_spot_colors + has_tags;
12486
541
                            if (p14dev->num_planar_planes > 0)
12487
541
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12488
541
                            p14dev->color_info.num_components = n;
12489
541
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12490
541
                        }
12491
541
                    }
12492
541
                }
12493
                /* limit the num_components to the max. */
12494
541
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12495
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12496
                /* Transfer the data for the spot color names
12497
                   But we have to free what may be there before we do this */
12498
541
                devn_free_params((gx_device*) p14dev);
12499
541
                p14dev->devn_params.separations =
12500
541
                    pclist_devn_params->pdf14_separations;
12501
541
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12502
541
                if (num_comp != p14dev->color_info.num_components) {
12503
                    /* Historically, there has been a comment here:
12504
                       "When the pdf14 device is opened it creates a context and some
12505
                       soft mask related objects.  The push device compositor action
12506
                       will have already created these but they are the wrong size.
12507
                       We must destroy them though before reopening the device."
12508
                       I can't see why this is the case, and testing in the cluster
12509
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12510
                       shows that this freeing/NULLing the ctx here causes problems
12511
                       when the freed ctx is reinserted at the end of clist pattern
12512
                       files. Accordingly, I'm removing the freeing/NULLing for now
12513
                       at least. */
12514
0
                    int code = dev_proc(tdev, open_device) (tdev);
12515
0
                    if (code < 0)
12516
0
                        return code;
12517
0
                }
12518
541
            }
12519
            /* Check if we need to swap out the ICC profile for the pdf14
12520
               device.  This will occur if our source profile for our device
12521
               happens to be something like CIELAB.  Then we will blend in
12522
               RGB (unless a trans group is specified) */
12523
1.01M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12524
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12525
0
                                        -1, "c_pdf14trans_clist_read_update");
12526
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12527
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12528
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12529
                /* Keep a pointer to the clist device */
12530
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12531
0
            }
12532
1.01M
            break;
12533
12534
1.01M
        case PDF14_POP_DEVICE:
12535
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12536
                    the clist playback. This code is not executed while clist
12537
                    writing. */
12538
            cdev->color_info = p14dev->saved_target_color_info;
12539
#     endif
12540
1.01M
           break;
12541
12542
19.4M
        default:
12543
19.4M
            break;   /* do nothing for remaining ops */
12544
21.4M
    }
12545
12546
21.4M
    return 0;
12547
21.4M
}
12548
12549
/*
12550
 * Get cropping for the compositor command.
12551
 */
12552
static  int
12553
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12554
                          int cropping_min, int cropping_max)
12555
267k
{
12556
267k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12557
267k
    switch (pdf14pct->params.pdf14_op) {
12558
9.02k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12559
9.02k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12560
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12561
3.33k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12562
36.8k
        case PDF14_BEGIN_TRANS_GROUP:
12563
36.8k
            { gs_int_rect rect;
12564
12565
                /* Text group always uses parents size*/
12566
36.8k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12567
2.20k
                    *ry = cropping_min;
12568
2.20k
                    *rheight = cropping_max - *ry;
12569
34.6k
                } else {
12570
34.6k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12571
34.6k
                        &pdf14pct->params.bbox, &rect);
12572
                    /* We have to crop this by the parent object.   */
12573
34.6k
                    *ry = max(rect.p.y, cropping_min);
12574
34.6k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12575
34.6k
                }
12576
36.8k
                return PUSHCROP; /* Push cropping. */
12577
3.33k
            }
12578
38.1k
        case PDF14_BEGIN_TRANS_MASK:
12579
38.1k
            { gs_int_rect rect;
12580
12581
38.1k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12582
38.1k
                                                    &pdf14pct->params.bbox, &rect);
12583
                /* We have to crop this by the parent object and worry about the BC outside
12584
                   the range, except for image SMask which don't affect areas outside the image.
12585
                   The presence of a transfer function opens the possibility of issues with this */
12586
38.1k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12587
16.0k
                      pdf14pct->params.function_is_identity)) {
12588
                    /* In this case there will not be a background effect to
12589
                       worry about.  The mask will not have any effect outside
12590
                       the bounding box.  This is NOT the default or common case. */
12591
16.0k
                    *ry = max(rect.p.y, cropping_min);
12592
16.0k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12593
16.0k
                    return PUSHCROP; /* Push cropping. */
12594
22.1k
                }  else {
12595
                    /* We need to make the soft mask range as large as the parent
12596
                       due to the fact that the background color can have an impact
12597
                       OUTSIDE the bounding box of the soft mask */
12598
22.1k
                    *ry = cropping_min;
12599
22.1k
                    *rheight = cropping_max - cropping_min;
12600
22.1k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12601
21.0k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12602
1.16k
                    else
12603
1.16k
                        return PUSHCROP; /* Push cropping. */
12604
22.1k
                }
12605
38.1k
            }
12606
34.6k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12607
2.17k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12608
17.1k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12609
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12610
16.6k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12611
103k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12612
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12613
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12614
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12615
267k
    }
12616
0
    return ALLBANDS;
12617
267k
}
12618
12619
/*
12620
 * This routine will check to see if the color component name matches those
12621
 * that are available amoung the current device's color components.  If the
12622
 * color name is known to the output device then we add it to the list of
12623
 * colorants for the PDF 1.4 transparency compositor.
12624
 *
12625
 * Notes:  There are currently three different versions of The PDF 1.4
12626
 * transparency compositor device.  The choice of which one is being used
12627
 * depends upon the process color model of the output device.  This procedure
12628
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12629
 * plus spot color process color model.
12630
 *
12631
 * Parameters:
12632
 *   dev - pointer to device data structure.
12633
 *   pname - pointer to name (zero termination not required)
12634
 *   nlength - length of the name
12635
 *   number of process colorants (either 1, 3, or 4)
12636
 *
12637
 * This routine returns a positive value (0 to n) which is the device colorant
12638
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12639
 * the colorant is not being used due to a SeparationOrder device parameter.
12640
 * It returns a negative value if not found.
12641
 */
12642
static int
12643
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12644
    int name_size, int component_type, int num_process_colors, int cmyk)
12645
7.08k
{
12646
7.08k
    pdf14_device *pdev = (pdf14_device *)dev;
12647
7.08k
    gx_device *tdev = pdev->target;
12648
7.08k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12649
7.08k
    gs_separations *pseparations;
12650
7.08k
    int comp_index;
12651
7.08k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12652
7.08k
    int offset;
12653
12654
7.08k
    while (tdev->child) {
12655
0
        tdev = tdev->child;
12656
0
    }
12657
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12658
    /* get the devn_params from the target to avoid accessing using the wrong  */
12659
    /* pointer. Bug 696372.                                                    */
12660
7.08k
    if (tdev == (gx_device *)pdev)
12661
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12662
7.08k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12663
7.08k
    pseparations = &pdevn_params->separations;
12664
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12665
     * where we are in a blend color space that is RGB or Gray based and we
12666
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12667
     * Yellow or Black, then we should use the alternate tint transform */
12668
7.08k
    if (num_process_colors < 4) {
12669
488
        int k;
12670
2.44k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12671
1.95k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12672
0
                return -1;
12673
1.95k
        }
12674
488
    }
12675
12676
7.08k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12677
12678
    /* The pdf14_clist_composite may have set the color procs.
12679
       We need the real target procs. */
12680
7.08k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12681
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12682
7.08k
        target_get_color_comp_index =
12683
7.08k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12684
    /*
12685
    * If this is not a separation name then simply forward it to the target
12686
    * device or return -1 if we are doing overprint simulation.
12687
    * The halftone setup expects this.
12688
    */
12689
7.08k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12690
7.08k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12691
6.22k
            if (target_get_color_comp_index != NULL)
12692
6.22k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12693
0
            else
12694
0
                return -1;
12695
6.22k
    }
12696
869
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12697
0
        return -1;
12698
0
    }
12699
12700
    /*
12701
    * Check if the component is in either the process color model list
12702
    * or in the SeparationNames list.
12703
    */
12704
869
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12705
869
        name_size, component_type);
12706
12707
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12708
     * This is a decision we take here to avoid problems with PDFI not
12709
     * counting such colorants as spots. */
12710
869
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12711
27
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12712
0
            return -1;
12713
27
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12714
0
            return -1;
12715
27
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12716
0
            return -1;
12717
27
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12718
0
            return -1;
12719
27
    }
12720
    /* A psdrgb device, with simulate overprint will have become a cmyk
12721
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12722
     * either, but we need to return real numbers for them as the underlying
12723
     * routine won't know about these. */
12724
869
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12725
1
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12726
0
            return 3;
12727
1
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12728
0
            return 0;
12729
1
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12730
0
            return 1;
12731
1
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12732
0
            return 2;
12733
1
    }
12734
12735
    /*
12736
    * Return the colorant number if we know this name.  Note adjustment for
12737
    * compensating of blend color space.
12738
    */
12739
869
    if (comp_index >= 0)
12740
841
        return comp_index - offset;
12741
12742
    /* Only worry about the target if we are not doing an overprint simulation */
12743
28
    if (!pdev->overprint_sim) {
12744
        /*
12745
        * If we do not know this color, check if the output (target) device does.
12746
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12747
        * the colorant so we will only get < 0 returned when we hit the max. for
12748
        * the target device.
12749
        */
12750
28
        if (target_get_color_comp_index != NULL)
12751
28
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12752
0
        else
12753
0
            return -1;
12754
        /*
12755
        * Ignore color if unknown to the output device or if color is not being
12756
        * imaged due to the SeparationOrder device parameter.
12757
        */
12758
28
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12759
0
            return comp_index - offset;
12760
28
    }
12761
12762
    /*
12763
    * This is a new colorant.  Add it to our list of colorants.
12764
    * The limit accounts for the number of process colors (at least 4).
12765
    */
12766
28
    if ((pseparations->num_separations + 1) <
12767
28
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12768
28
        int sep_num = pseparations->num_separations++;
12769
28
        int color_component_number;
12770
28
        byte * sep_name;
12771
12772
28
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12773
28
            name_size, "pdf14_spot_get_color_comp_index");
12774
28
        if (sep_name == NULL) {
12775
0
            pseparations->num_separations--;  /* we didn't add it */
12776
0
            return -1;
12777
0
        }
12778
28
        memcpy(sep_name, pname, name_size);
12779
28
        pseparations->names[sep_num].size = name_size;
12780
28
        pseparations->names[sep_num].data = sep_name;
12781
28
        color_component_number = sep_num + num_process_colors;
12782
28
        if (color_component_number >= dev->color_info.max_components)
12783
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12784
28
        else
12785
28
            pdevn_params->separation_order_map[color_component_number] =
12786
28
            color_component_number;
12787
12788
        /* Indicate that we need to find equivalent CMYK color. */
12789
28
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12790
28
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12791
12792
        /* If we're doing an overprint simulation, then the target device
12793
         * (for instance) might not know about this colorant. This is annoying
12794
         * as the target can't then output the correct names. Call the target
12795
         * get_color_comp_index routine and ignore the result to give it a
12796
         * chance to stash it. */
12797
28
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12798
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12799
12800
28
        return color_component_number;
12801
28
    }
12802
12803
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12804
28
}
12805
12806
12807
/* CMYK process + spots */
12808
static int
12809
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12810
    int name_size, int component_type)
12811
6.60k
{
12812
6.60k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12813
6.60k
}
12814
12815
/* RGB process + spots */
12816
static int
12817
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12818
    int name_size, int component_type)
12819
488
{
12820
488
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12821
488
}
12822
12823
/* Gray process + spots */
12824
static int
12825
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12826
    int name_size, int component_type)
12827
0
{
12828
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12829
0
}
12830
12831
/* These functions keep track of when we are dealing with soft masks.
12832
   In such a case, we set the default color profiles to ones that ensure
12833
   proper soft mask rendering. */
12834
static int
12835
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12836
21.4k
{
12837
21.4k
    pdf14_device * pdev = (pdf14_device *) dev;
12838
21.4k
    pdf14_smaskcolor_t *result;
12839
21.4k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12840
21.4k
    int k;
12841
12842
    /* See if we have profiles already in place.   Note we also have to
12843
       worry about a corner case where this device does not have a
12844
       smaskcolor stucture to store the profiles AND the profiles were
12845
       already swapped out in the icc_manager.  This can occur when we
12846
       pushed a transparency mask and then inside the mask we have a pattern
12847
       which also has a transparency mask.   The state of the icc_manager
12848
       is that it already has done the swap and there is no need to fool
12849
       with any of this while dealing with the soft mask within the pattern */
12850
21.4k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12851
21.4k
        pgs->icc_manager->smask_profiles->swapped) {
12852
0
            return 0;
12853
0
    }
12854
21.4k
    if (pdev->smaskcolor != NULL) {
12855
16
        pdev->smaskcolor->ref_count++;
12856
16
        if_debug1m(gs_debug_flag_icc, dev->memory,
12857
16
                   "[icc] Increment smask color now %d\n",
12858
16
                   pdev->smaskcolor->ref_count);
12859
21.4k
    } else {
12860
        /* Allocate and swap out the current profiles.  The softmask
12861
           profiles should already be in place */
12862
21.4k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12863
21.4k
                                &st_pdf14_smaskcolor,
12864
21.4k
                                "pdf14_increment_smask_color");
12865
21.4k
        if (result == NULL)
12866
0
            return gs_error_VMerror;
12867
12868
21.4k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12869
21.4k
        if (result->profiles == NULL)
12870
0
            return gs_error_VMerror;
12871
12872
21.4k
        pdev->smaskcolor = result;
12873
12874
21.4k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12875
21.4k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12876
21.4k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12877
21.4k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12878
21.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12879
21.4k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12880
21.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12881
21.4k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12882
21.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12883
21.4k
        pgs->icc_manager->smask_profiles->swapped = true;
12884
21.4k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12885
21.4k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12886
21.4k
        pdev->smaskcolor->ref_count = 1;
12887
        /* We also need to update the profile that is currently in the
12888
           color spaces of the graphic state.  Otherwise this can be
12889
           referenced, which will result in a mismatch.  What we want to do
12890
           is see if it was the original default and only swap in that case. */
12891
64.2k
        for (k = 0; k < 2; k++) {
12892
42.8k
            gs_color_space *pcs     = pgs->color[k].color_space;
12893
42.8k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12894
42.8k
            if (profile != NULL) {
12895
41.3k
                switch(profile->data_cs) {
12896
23.5k
                    case gsGRAY:
12897
23.5k
                        if (profile->hashcode ==
12898
23.5k
                            result->profiles->smask_gray->hashcode) {
12899
21.9k
                                profile = pgs->icc_manager->default_gray;
12900
21.9k
                        }
12901
23.5k
                        break;
12902
17.5k
                    case gsRGB:
12903
17.5k
                        if (profile->hashcode ==
12904
17.5k
                            result->profiles->smask_rgb->hashcode) {
12905
10.0k
                                profile = pgs->icc_manager->default_rgb;
12906
10.0k
                        }
12907
17.5k
                        break;
12908
233
                    case gsCMYK:
12909
233
                        if (profile->hashcode ==
12910
233
                            result->profiles->smask_cmyk->hashcode) {
12911
233
                                profile = pgs->icc_manager->default_cmyk;
12912
233
                        }
12913
233
                        break;
12914
0
                    default:
12915
12916
0
                        break;
12917
41.3k
                }
12918
41.3k
                if (pcs->cmm_icc_profile_data != profile) {
12919
32.2k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12920
32.2k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12921
32.2k
                    pcs->cmm_icc_profile_data = profile;
12922
32.2k
                }
12923
41.3k
            }
12924
42.8k
        }
12925
21.4k
    }
12926
21.4k
    return 0;
12927
21.4k
}
12928
12929
static int
12930
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12931
30.4k
{
12932
30.4k
    pdf14_device * pdev = (pdf14_device *) dev;
12933
30.4k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12934
30.4k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12935
30.4k
    int k;
12936
12937
    /* See comment in pdf14_increment_smask_color to understand this one */
12938
30.4k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12939
3.72k
        pgs->icc_manager->smask_profiles->swapped) {
12940
0
            return 0;
12941
0
    }
12942
30.4k
    if (smaskcolor != NULL) {
12943
21.4k
        smaskcolor->ref_count--;
12944
21.4k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12945
21.4k
                   "[icc] Decrement smask color.  Now %d\n",
12946
21.4k
                   smaskcolor->ref_count);
12947
21.4k
        if (smaskcolor->ref_count == 0) {
12948
21.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12949
            /* Lets return the profiles and clean up */
12950
            /* First see if we need to "reset" the profiles that are in
12951
               the graphic state */
12952
21.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12953
64.2k
            for (k = 0; k < 2; k++) {
12954
42.8k
                gs_color_space *pcs = pgs->color[k].color_space;
12955
42.8k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12956
42.8k
                if (profile != NULL) {
12957
41.3k
                    switch(profile->data_cs) {
12958
23.5k
                        case gsGRAY:
12959
23.5k
                            if (profile->hashcode ==
12960
23.5k
                                pgs->icc_manager->default_gray->hashcode) {
12961
21.9k
                                    profile =
12962
21.9k
                                        smaskcolor->profiles->smask_gray;
12963
21.9k
                            }
12964
23.5k
                            break;
12965
17.5k
                        case gsRGB:
12966
17.5k
                            if (profile->hashcode ==
12967
17.5k
                                pgs->icc_manager->default_rgb->hashcode) {
12968
10.0k
                                    profile =
12969
10.0k
                                        smaskcolor->profiles->smask_rgb;
12970
10.0k
                            }
12971
17.5k
                            break;
12972
233
                        case gsCMYK:
12973
233
                            if (profile->hashcode ==
12974
233
                                pgs->icc_manager->default_cmyk->hashcode) {
12975
233
                                    profile =
12976
233
                                        smaskcolor->profiles->smask_cmyk;
12977
233
                            }
12978
233
                            break;
12979
0
                        default:
12980
12981
0
                            break;
12982
41.3k
                    }
12983
41.3k
                    if (pcs->cmm_icc_profile_data != profile) {
12984
32.2k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12985
32.2k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12986
32.2k
                        pcs->cmm_icc_profile_data = profile;
12987
32.2k
                    }
12988
41.3k
                }
12989
42.8k
            }
12990
12991
21.4k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12992
21.4k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12993
21.4k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12994
21.4k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12995
21.4k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
12996
21.4k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
12997
21.4k
            icc_manager->smask_profiles->swapped = false;
12998
            /* We didn't increment the reference count when we assigned these
12999
             * so NULL them to avoid decrementing when smaskcolor is freed
13000
             */
13001
21.4k
            smaskcolor->profiles->smask_gray =
13002
21.4k
              smaskcolor->profiles->smask_rgb =
13003
21.4k
              smaskcolor->profiles->smask_cmyk = NULL;
13004
13005
21.4k
            pdf14_free_smask_color(pdev);
13006
21.4k
        }
13007
21.4k
    }
13008
30.4k
    return 0;
13009
30.4k
}
13010
13011
static void
13012
pdf14_free_smask_color(pdf14_device * pdev)
13013
21.4k
{
13014
21.4k
    if (pdev->smaskcolor != NULL) {
13015
21.4k
        if ( pdev->smaskcolor->profiles != NULL) {
13016
            /* Do not decrement the profiles - the references were moved
13017
               here and moved back again, so the ref counts don't change
13018
             */
13019
21.4k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13020
21.4k
                        "pdf14_free_smask_color");
13021
21.4k
        }
13022
21.4k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13023
21.4k
        pdev->smaskcolor = NULL;
13024
21.4k
    }
13025
21.4k
}
13026
13027
static void
13028
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13029
1.02M
{
13030
1.02M
    gx_device * const dev = (gx_device *)vptr;
13031
1.02M
    pdf14_device * pdev = (pdf14_device *)dev;
13032
1.02M
    int k;
13033
13034
1.02M
    pdf14_cleanup_group_color_profiles (pdev);
13035
13036
1.02M
    if (pdev->ctx) {
13037
31
        pdf14_ctx_free(pdev->ctx);
13038
31
        pdev->ctx = NULL;
13039
31
    }
13040
13041
1.02M
    while (pdev->color_model_stack) {
13042
29
        pdf14_pop_group_color(dev, NULL);
13043
29
    }
13044
13045
1.02M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13046
28
        if (pdev->devn_params.separations.names[k].data) {
13047
28
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13048
28
            pdev->devn_params.separations.names[k].data = NULL;
13049
28
        }
13050
28
    }
13051
13052
1.02M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13053
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13054
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13055
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13056
0
        }
13057
0
    }
13058
13059
1.02M
    gx_device_finalize(cmem, vptr);
13060
1.02M
}
13061
13062
#if DUMP_MASK_STACK
13063
13064
static void
13065
dump_mask_stack(pdf14_mask_t *mask_stack)
13066
{
13067
    pdf14_mask_t *curr_mask = mask_stack;
13068
    int level = 0;
13069
13070
    while (curr_mask != NULL) {
13071
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13072
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13073
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13074
        level++;
13075
        curr_mask = curr_mask->previous;
13076
    }
13077
}
13078
13079
/* A function to display the current state of the mask stack */
13080
static void
13081
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13082
{
13083
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13084
    if (ctx->mask_stack != NULL) {
13085
        dump_mask_stack(ctx->mask_stack);
13086
    }
13087
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13088
    if (ctx->stack != NULL) {
13089
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13090
        if (ctx->stack->mask_stack != NULL) {
13091
            dump_mask_stack(ctx->stack->mask_stack);
13092
        }
13093
    }
13094
}
13095
13096
#else
13097
13098
#ifdef DEBUG
13099
static void
13100
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13101
{
13102
    return;
13103
}
13104
#endif
13105
13106
#endif /* DUMP_MASK_STACK */