Coverage Report

Created: 2025-06-10 07:27

/src/ghostpdl/base/gdevp14.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2025 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
74
#if RAW_DUMP
75
unsigned int global_index = 0;
76
unsigned int clist_band_count = 0;
77
#endif
78
79
#define DUMP_MASK_STACK 0
80
81
/* Static prototypes */
82
/* Used for filling rects when we are doing a fill with a pattern that
83
   has transparency */
84
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
85
                                   gx_path * ppath, const gx_fill_params * params,
86
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
87
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
88
static void pdf14_free_smask_color(pdf14_device * pdev);
89
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
90
                                         const gs_rect *pbbox, gs_gstate *pgs);
91
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
92
                                     const gs_gstate * pgs,
93
                                     bool crop_blend_params,
94
                                     gs_pdf14trans_params_t *group_params);
95
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
96
                                               int w, int h, gx_color_index color,
97
                                               const gx_device_color *pdc,
98
                                               bool devn);
99
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
100
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
101
                                  gx_color_index color, const gx_device_color *pdc,
102
                                  int depth, bool devn);
103
104
/* Functions for dealing with soft mask color */
105
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
106
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
107
108
/*
109
 * We chose the blending color space based upon the process color model of the
110
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
111
 * usually simple.  For other devices or if the user is doing custom color
112
 * processing then the user may want to control this choice.
113
 */
114
#define AUTO_USE_CUSTOM_BLENDING 0
115
#define ALWAYS_USE_CUSTOM_BLENDING 1
116
#define DO_NOT_USE_CUSTOM_BLENDING 2
117
118
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
119
120
# define INCR(v) DO_NOTHING
121
122
/* Forward prototypes */
123
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
124
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
125
                                gx_device ** pdev, gx_device * target,
126
                                const gs_pdf14trans_t * pdf14pct);
127
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
128
                                      gx_device ** pdev, gx_device * target,
129
                                      const gs_pdf14trans_t * pdf14pct);
130
static int pdf14_tile_pattern_fill(gx_device * pdev,
131
                const gs_gstate * pgs, gx_path * ppath,
132
                const gx_fill_params * params,
133
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
134
static pdf14_mask_t * pdf14_mask_element_new(gs_memory_t * memory);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    rc_mask, previous);
169
170
gs_private_st_ptrs1(st_pdf14_rcmask, pdf14_rcmask_t, "pdf_rcmask",
171
                    pdf14_rcmask_enum_ptrs, pdf14_rcmask_reloc_ptrs,
172
                    mask_buf);
173
174
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
175
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
176
                    profiles);
177
178
/* ------ The device descriptors ------ */
179
180
/*
181
 * Default X and Y resolution.
182
 */
183
#define X_DPI 72
184
#define Y_DPI 72
185
186
static int pdf14_initialize_device(gx_device *dev);
187
188
static  int pdf14_open(gx_device * pdev);
189
static  dev_proc_close_device(pdf14_close);
190
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
191
static  dev_proc_put_params(pdf14_put_params);
192
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
193
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
194
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
195
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
196
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
197
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
198
dev_proc_encode_color(pdf14_encode_color);
199
dev_proc_encode_color(pdf14_encode_color_tag);
200
dev_proc_decode_color(pdf14_decode_color);
201
dev_proc_encode_color(pdf14_encode_color16);
202
dev_proc_encode_color(pdf14_encode_color16_tag);
203
dev_proc_decode_color(pdf14_decode_color16);
204
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
205
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
206
static  dev_proc_fill_path(pdf14_fill_path);
207
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
208
static  dev_proc_copy_mono(pdf14_copy_mono);
209
static  dev_proc_fill_mask(pdf14_fill_mask);
210
static  dev_proc_stroke_path(pdf14_stroke_path);
211
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
212
static  dev_proc_text_begin(pdf14_text_begin);
213
static  dev_proc_composite(pdf14_composite);
214
static  dev_proc_composite(pdf14_forward_composite);
215
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
216
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
217
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
218
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
219
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
220
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
221
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
222
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
223
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
224
static  dev_proc_copy_alpha(pdf14_copy_alpha);
225
static  dev_proc_copy_planes(pdf14_copy_planes);
226
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
227
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
228
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
229
static  const gx_color_map_procs *
230
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
231
232
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
233
#define YSIZE (int)(11 * Y_DPI)
234
235
/* 24-bit color. */
236
237
static void
238
pdf14_procs_initialize(gx_device *dev,
239
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
240
                       dev_proc_get_color_comp_index(get_color_comp_index),
241
                       dev_proc_encode_color(encode_color),
242
                       dev_proc_decode_color(decode_color))
243
7.13M
{
244
7.13M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
245
7.13M
    set_dev_proc(dev, open_device, pdf14_open);
246
7.13M
    set_dev_proc(dev, output_page, pdf14_output_page);
247
7.13M
    set_dev_proc(dev, close_device, pdf14_close);
248
7.13M
    set_dev_proc(dev, map_rgb_color, encode_color);
249
7.13M
    set_dev_proc(dev, map_color_rgb, decode_color);
250
7.13M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
251
7.13M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
252
7.13M
    set_dev_proc(dev, get_params, gx_forward_get_params);
253
7.13M
    set_dev_proc(dev, put_params, pdf14_put_params);
254
7.13M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
255
7.13M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
256
7.13M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
257
7.13M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
258
7.13M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
259
7.13M
    set_dev_proc(dev, composite, pdf14_composite);
260
7.13M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
261
7.13M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
262
7.13M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
263
7.13M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
264
7.13M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
265
7.13M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
266
7.13M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
267
7.13M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
268
7.13M
    set_dev_proc(dev, encode_color, encode_color);
269
7.13M
    set_dev_proc(dev, decode_color, decode_color);
270
7.13M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
271
7.13M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
272
7.13M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
273
7.13M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
274
7.13M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
275
7.13M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
276
7.13M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
277
7.13M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
278
7.13M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
279
7.13M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
280
7.13M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
281
7.13M
}
282
283
static void
284
pdf14_Gray_initialize_device_procs(gx_device *dev)
285
1.83M
{
286
1.83M
    pdf14_procs_initialize(dev,
287
1.83M
                           gx_default_DevGray_get_color_mapping_procs,
288
1.83M
                           gx_default_DevGray_get_color_comp_index,
289
1.83M
                           pdf14_encode_color,
290
1.83M
                           pdf14_decode_color);
291
1.83M
}
292
293
static void
294
pdf14_RGB_initialize_device_procs(gx_device *dev)
295
4.13M
{
296
4.13M
    pdf14_procs_initialize(dev,
297
4.13M
                           gx_default_DevRGB_get_color_mapping_procs,
298
4.13M
                           gx_default_DevRGB_get_color_comp_index,
299
4.13M
                           pdf14_encode_color,
300
4.13M
                           pdf14_decode_color);
301
4.13M
}
302
303
static void
304
pdf14_CMYK_initialize_device_procs(gx_device *dev)
305
840k
{
306
840k
    pdf14_procs_initialize(dev,
307
840k
                           gx_default_DevCMYK_get_color_mapping_procs,
308
840k
                           gx_default_DevCMYK_get_color_comp_index,
309
840k
                           pdf14_encode_color,
310
840k
                           pdf14_decode_color);
311
840k
}
312
313
static void
314
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
315
264k
{
316
264k
    pdf14_procs_initialize(dev,
317
264k
                           pdf14_cmykspot_get_color_mapping_procs,
318
264k
                           pdf14_cmykspot_get_color_comp_index,
319
264k
                           pdf14_encode_color,
320
264k
                           pdf14_decode_color);
321
264k
}
322
323
static void
324
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
325
62.5k
{
326
62.5k
    pdf14_procs_initialize(dev,
327
62.5k
                           pdf14_rgbspot_get_color_mapping_procs,
328
62.5k
                           pdf14_rgbspot_get_color_comp_index,
329
62.5k
                           pdf14_encode_color,
330
62.5k
                           pdf14_decode_color);
331
62.5k
}
332
333
static void
334
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
335
0
{
336
0
    pdf14_procs_initialize(dev,
337
0
                           pdf14_grayspot_get_color_mapping_procs,
338
0
                           pdf14_grayspot_get_color_comp_index,
339
0
                           pdf14_encode_color,
340
0
                           pdf14_decode_color);
341
0
}
342
343
static void
344
pdf14_custom_initialize_device_procs(gx_device *dev)
345
0
{
346
0
    pdf14_procs_initialize(dev,
347
0
                           gx_forward_get_color_mapping_procs,
348
0
                           gx_forward_get_color_comp_index,
349
0
                           gx_forward_encode_color,
350
0
                           gx_forward_decode_color);
351
0
}
352
353
static struct_proc_finalize(pdf14_device_finalize);
354
355
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
356
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
357
                          pdf14_device_finalize);
358
359
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
362
                                                        gx_device * target);
363
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
364
                                                        gx_device * target);
365
366
/* Alter pdf14 device color model based upon group or softmask. This occurs
367
   post clist or in immediate rendering case. Data stored with buffer */
368
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
369
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
370
                              cmm_profile_t *iccprofile, bool is_mask);
371
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
372
373
/* Alter clist writer device color model based upon group or softmask. Data
374
   stored in the device color model stack */
375
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
376
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
377
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
378
379
/* Used for cleaning up the stack if things go wrong */
380
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
381
382
static const pdf14_procs_t gray_pdf14_procs = {
383
    pdf14_unpack_additive,
384
    pdf14_put_image,
385
    pdf14_unpack16_additive
386
};
387
388
static const pdf14_procs_t rgb_pdf14_procs = {
389
    pdf14_unpack_additive,
390
    pdf14_put_image,
391
    pdf14_unpack16_additive
392
};
393
394
static const pdf14_procs_t cmyk_pdf14_procs = {
395
    pdf14_unpack_subtractive,
396
    pdf14_put_image,
397
    pdf14_unpack16_subtractive
398
};
399
400
static const pdf14_procs_t cmykspot_pdf14_procs = {
401
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
402
    pdf14_cmykspot_put_image,
403
    pdf14_unpack16_custom /* should never be used since we will use devn values */
404
};
405
406
static const pdf14_procs_t rgbspot_pdf14_procs = {
407
    pdf14_unpack_rgb_mix,
408
    pdf14_cmykspot_put_image,
409
    pdf14_unpack16_rgb_mix
410
};
411
412
static const pdf14_procs_t grayspot_pdf14_procs = {
413
    pdf14_unpack_gray_mix,
414
    pdf14_cmykspot_put_image,
415
    pdf14_unpack16_gray_mix
416
};
417
418
static const pdf14_procs_t custom_pdf14_procs = {
419
    pdf14_unpack_custom,
420
    pdf14_custom_put_image,
421
    pdf14_unpack16_custom
422
};
423
424
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
425
    art_blend_luminosity_custom_8,
426
    art_blend_saturation_custom_8,
427
    art_blend_luminosity_custom_16,
428
    art_blend_saturation_custom_16
429
};
430
431
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
432
    art_blend_luminosity_rgb_8,
433
    art_blend_saturation_rgb_8,
434
    art_blend_luminosity_rgb_16,
435
    art_blend_saturation_rgb_16
436
};
437
438
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
439
    art_blend_luminosity_cmyk_8,
440
    art_blend_saturation_cmyk_8,
441
    art_blend_luminosity_cmyk_16,
442
    art_blend_saturation_cmyk_16
443
};
444
445
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
446
    art_blend_luminosity_rgb_8,
447
    art_blend_saturation_rgb_8,
448
    art_blend_luminosity_rgb_16,
449
    art_blend_saturation_rgb_16
450
};
451
452
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
453
    art_blend_luminosity_custom_8,
454
    art_blend_saturation_custom_8,
455
    art_blend_luminosity_custom_16,
456
    art_blend_saturation_custom_16
457
};
458
459
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
460
    art_blend_luminosity_custom_8,
461
    art_blend_saturation_custom_8,
462
    art_blend_luminosity_custom_16,
463
    art_blend_saturation_custom_16
464
};
465
466
const pdf14_device gs_pdf14_Gray_device = {
467
    std_device_std_color_full_body_type(pdf14_device,
468
                                        pdf14_Gray_initialize_device_procs,
469
                                        "pdf14gray",
470
                                        &st_pdf14_device,
471
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
472
                                        0, 0, 0, 0, 0, 0),
473
    { 0 },      /* Procs */
474
    NULL,     /* target */
475
    { 0 },      /* devn_params - not used */
476
    &gray_pdf14_procs,
477
    &gray_blending_procs,
478
    1
479
};
480
481
const pdf14_device gs_pdf14_RGB_device = {
482
    std_device_color_stype_body(pdf14_device,
483
                                pdf14_RGB_initialize_device_procs,
484
                                "pdf14RGB",
485
                                &st_pdf14_device,
486
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
487
    { 0 },      /* Procs */
488
    NULL,     /* target */
489
    { 0 },      /* devn_params - not used */
490
    &rgb_pdf14_procs,
491
    &rgb_blending_procs,
492
    3
493
};
494
495
const pdf14_device gs_pdf14_CMYK_device = {
496
    std_device_std_color_full_body_type(pdf14_device,
497
                                        pdf14_CMYK_initialize_device_procs,
498
                                        "pdf14cmyk",
499
                                        &st_pdf14_device,
500
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
501
                                        0, 0, 0, 0, 0, 0),
502
    { 0 },      /* Procs */
503
    NULL,     /* target */
504
    { 0 },      /* devn_params - not used */
505
    &cmyk_pdf14_procs,
506
    &cmyk_blending_procs,
507
    4
508
};
509
510
const pdf14_device gs_pdf14_CMYKspot_device = {
511
    std_device_part1_(pdf14_device,
512
                      pdf14_CMYKspot_initialize_device_procs,
513
                      "pdf14cmykspot",
514
                      &st_pdf14_device,
515
                      open_init_closed),
516
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
517
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
518
    offset_margin_values(0, 0, 0, 0, 0, 0),
519
    std_device_part3_(),
520
    { 0 },      /* Procs */
521
    NULL,     /* target */
522
    /* DeviceN parameters */
523
    { 8,      /* Not used - Bits per color */
524
      DeviceCMYKComponents, /* Names of color model colorants */
525
      4,      /* Number colorants for CMYK */
526
      0,      /* MaxSeparations has not been specified */
527
      -1,     /* PageSpotColors has not been specified */
528
      {0},      /* SeparationNames */
529
      0,      /* SeparationOrder names */
530
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
531
    },
532
    &cmykspot_pdf14_procs,
533
    &cmyk_blending_procs,
534
    4
535
};
536
537
const pdf14_device gs_pdf14_RGBspot_device = {
538
    std_device_part1_(pdf14_device,
539
                      pdf14_RGBspot_initialize_device_procs,
540
                      "pdf14rgbspot",
541
                      &st_pdf14_device,
542
                      open_init_closed),
543
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
544
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
545
    offset_margin_values(0, 0, 0, 0, 0, 0),
546
    std_device_part3_(),
547
    { 0 },      /* Procs */
548
    NULL,     /* target */
549
                    /* DeviceN parameters */
550
    { 8,      /* Not used - Bits per color */
551
    0,              /* Names of color model colorants */
552
    3,          /* Number colorants for RGB */
553
    0,          /* MaxSeparations has not been specified */
554
    -1,         /* PageSpotColors has not been specified */
555
    { 0 },      /* SeparationNames */
556
    0,          /* SeparationOrder names */
557
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
558
    },
559
    &rgbspot_pdf14_procs,
560
    &rgbspot_blending_procs,
561
    3
562
};
563
564
const pdf14_device gs_pdf14_Grayspot_device = {
565
    std_device_part1_(pdf14_device,
566
                      pdf14_Grayspot_initialize_device_procs,
567
                      "pdf14grayspot",
568
                      &st_pdf14_device,
569
                      open_init_closed),
570
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
571
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
572
    offset_margin_values(0, 0, 0, 0, 0, 0),
573
    std_device_part3_(),
574
    { 0 },      /* Procs */
575
    NULL,     /* target */
576
                    /* DeviceN parameters */
577
    { 8,      /* Not used - Bits per color */
578
    0,              /* Names of color model colorants */
579
    3,          /* Number colorants for RGB */
580
    0,          /* MaxSeparations has not been specified */
581
    -1,         /* PageSpotColors has not been specified */
582
    { 0 },      /* SeparationNames */
583
    0,          /* SeparationOrder names */
584
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
585
    },
586
    &grayspot_pdf14_procs,
587
    &grayspot_blending_procs,
588
    1
589
};
590
591
/*
592
 * The 'custom' PDF 1.4 compositor device is for working with those devices
593
 * which support spot colors but do not have a CMYK process color model.
594
 *
595
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
596
 * blending modes.  These blending modes are 'non separable' and depend upon
597
 * knowing the details of the blending color space.  However we use the
598
 * process color model of the output device for our blending color space.
599
 * With an unknown process color model, we have to fall back to some 'guesses'
600
 * about how to treat these blending modes.
601
 */
602
const pdf14_device gs_pdf14_custom_device = {
603
    std_device_part1_(pdf14_device,
604
                      pdf14_custom_initialize_device_procs,
605
                      "pdf14custom",
606
                      &st_pdf14_device,
607
                      open_init_closed),
608
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
609
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
610
    offset_margin_values(0, 0, 0, 0, 0, 0),
611
    std_device_part3_(),
612
    { 0 },      /* Procs */
613
    NULL,     /* target */
614
    /* DeviceN parameters */
615
    { 8,      /* Not used - Bits per color */
616
      DeviceCMYKComponents, /* Names of color model colorants */
617
      4,      /* Number colorants for CMYK */
618
      0,      /* MaxSeparations has not been specified */
619
      -1,     /* PageSpotColors has not been specified */
620
      {0},      /* SeparationNames */
621
      0,      /* SeparationOrder names */
622
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
623
    },
624
    &custom_pdf14_procs,
625
    &custom_blending_procs,
626
    4
627
};
628
629
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
630
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
631
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
632
633
static dev_proc_print_page(no_print_page);
634
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
635
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
636
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
637
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
638
639
static int
640
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
641
0
{
642
0
    return_error(gs_error_unknownerror);
643
0
}
644
645
struct gx_device_pdf14_accum_s {
646
    gx_devn_prn_device_common;
647
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
648
};
649
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
650
651
int
652
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
653
22.3M
{
654
22.3M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
655
656
22.3M
    if (dev_spec_op == gxdso_device_child) {
657
3.12k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
658
3.12k
        if (size < sizeof(*req))
659
0
            return gs_error_unknownerror;
660
3.12k
        req->target = adev->save_p14dev;
661
3.12k
        req->n = 0;
662
3.12k
        return 0;
663
3.12k
    }
664
665
22.3M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
666
22.3M
}
667
668
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
669
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
670
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
671
672
static void
673
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
674
1.03k
{
675
1.03k
    gdev_prn_initialize_device_procs_gray8(dev);
676
677
1.03k
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
678
1.03k
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
679
1.03k
}
680
681
const gx_device_pdf14_accum pdf14_accum_Gray = {
682
    prn_device_stype_body(gx_device_pdf14_accum,
683
                          pdf14_accum_Gray_initialize_device_procs,
684
                          "pdf14-accum-Gray",
685
                          &st_gx_devn_accum_device,
686
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
687
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
688
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
689
                          256/*dither_grays*/, 0/*dither_colors*/,
690
                          no_print_page),
691
    { 0 },      /* devn_params - not used */
692
    { 0 },      /* equivalent_cmyk_color_params - not used */
693
    0/*save_p14dev*/
694
};
695
696
static void
697
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
698
4.67k
{
699
4.67k
    gdev_prn_initialize_device_procs_rgb(dev);
700
4.67k
}
701
702
const gx_device_pdf14_accum pdf14_accum_RGB = {
703
    prn_device_stype_body(gx_device_pdf14_accum,
704
                          pdf14_accum_RGB_initialize_device_procs,
705
                          "pdf14-accum-RGB",
706
                          &st_gx_devn_accum_device,
707
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
708
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
709
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
710
                          1/*dither_grays*/, 256/*dither_colors*/,
711
                          no_print_page),
712
    { 0 },      /* devn_params - not used */
713
    { 0 },      /* equivalent_cmyk_color_params - not used */
714
    0/*save_p14dev*/
715
};
716
717
static void
718
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
719
0
{
720
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
721
722
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
723
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
724
0
}
725
726
const gx_device_pdf14_accum pdf14_accum_CMYK = {
727
    prn_device_stype_body(gx_device_pdf14_accum,
728
                          pdf14_accum_CMYK_initialize_device_procs,
729
                          "pdf14-accum-CMYK",
730
                          &st_gx_devn_accum_device,
731
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
732
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
733
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
734
                          256/*dither_grays*/, 256/*dither_colors*/,
735
                          no_print_page),
736
    { 0 },      /* devn_params - not used */
737
    { 0 },      /* equivalent_cmyk_color_params - not used */
738
    0/*save_p14dev*/
739
};
740
741
static void
742
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
743
0
{
744
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
745
746
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
747
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
748
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
749
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
750
0
}
751
752
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
753
    prn_device_stype_body(gx_device_pdf14_accum,
754
                          pdf14_accum_initialize_device_procs_cmykspot,
755
                          "pdf14-accum-CMYKspot",
756
                          &st_gx_devn_accum_device,
757
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
758
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
759
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
760
                          256/*dither_grays*/, 256/*dither_colors*/,
761
                          no_print_page),
762
    /* DeviceN parameters */
763
    { 8,      /* Not used - Bits per color */
764
      DeviceCMYKComponents, /* Names of color model colorants */
765
      4,      /* Number colorants for CMYK */
766
      0,      /* MaxSeparations has not been specified */
767
      -1,     /* PageSpotColors has not been specified */
768
      { 0 },      /* SeparationNames */
769
      0,      /* SeparationOrder names */
770
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
771
    },
772
    { true },     /* equivalent_cmyk_color_params */
773
    0/*save_p14dev*/
774
};
775
776
/* GC procedures */
777
static
778
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
779
0
{
780
0
    index -= 5;
781
0
    if (index < pdev->devn_params.separations.num_separations)
782
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
783
0
    index -= pdev->devn_params.separations.num_separations;
784
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
785
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
786
0
    return 0;
787
0
}
788
0
case 0: return ENUM_OBJ(pdev->ctx);
789
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
790
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
791
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
792
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
793
0
ENUM_PTRS_END
794
795
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
796
0
{
797
0
    {
798
0
        int i;
799
800
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
801
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
802
0
        }
803
0
    }
804
0
    RELOC_VAR(pdev->ctx);
805
0
    RELOC_VAR(pdev->smaskcolor);
806
0
    RELOC_VAR(pdev->color_model_stack);
807
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
808
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
809
0
}
810
0
RELOC_PTRS_END
811
812
/* ------ Private definitions ------ */
813
814
static void
815
resolve_matte(pdf14_buf *maskbuf, byte *src_data, int src_planestride, int src_rowstride,
816
              int width, int height, cmm_profile_t *src_profile, int deep)
817
1.04k
{
818
1.04k
    if (deep) {
819
0
        int x, y, i;
820
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
821
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
822
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
823
824
0
        src_planestride >>= 1;
825
0
        src_rowstride >>= 1;
826
827
0
        for (y = 0; y < height; y++) {
828
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
829
0
            uint16_t *src_curr_ptr = src_row_ptr;
830
0
            for (x = 0; x < width; x++) {
831
0
                uint16_t idx = *mask_curr_ptr;
832
0
                byte     top = idx>>8;
833
0
                uint16_t a   = mask_tr_fn[top];
834
0
                int      b   = mask_tr_fn[top+1]-a;
835
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
836
837
                /* matte's happen rarely enough that we allow ourselves to
838
                 * resort to 64bit here. */
839
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
840
0
                    for (i = 0; i < src_profile->num_comps; i++) {
841
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
842
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
843
844
                        /* clip */
845
0
                        if (temp > 0xffff)
846
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
847
0
                        else if (temp < 0)
848
0
                            src_curr_ptr[i * src_planestride] = 0;
849
0
                        else
850
0
                            src_curr_ptr[i * src_planestride] = temp;
851
0
                    }
852
0
                }
853
0
                mask_curr_ptr++;
854
0
                src_curr_ptr++;
855
0
            }
856
0
            src_row_ptr += src_rowstride;
857
0
            mask_row_ptr += (maskbuf->rowstride>>1);
858
0
        }
859
1.04k
    } else {
860
1.04k
        int x, y, i;
861
1.04k
        byte *mask_row_ptr  = maskbuf->data;
862
1.04k
        byte *src_row_ptr   = src_data;
863
1.04k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
864
865
13.4k
        for (y = 0; y < height; y++) {
866
12.3k
            byte *mask_curr_ptr = mask_row_ptr;
867
12.3k
            byte *src_curr_ptr = src_row_ptr;
868
15.6M
            for (x = 0; x < width; x++) {
869
15.6M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
870
15.6M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
871
7.85M
                    for (i = 0; i < src_profile->num_comps; i++) {
872
5.89M
                        byte matte = maskbuf->matte[i]>>8;
873
5.89M
                        int val = src_curr_ptr[i * src_planestride] - matte;
874
5.89M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
875
876
                        /* clip */
877
5.89M
                        if (temp > 0xff)
878
4.29M
                            src_curr_ptr[i * src_planestride] = 0xff;
879
1.59M
                        else if (temp < 0)
880
0
                            src_curr_ptr[i * src_planestride] = 0;
881
1.59M
                        else
882
1.59M
                            src_curr_ptr[i * src_planestride] = temp;
883
5.89M
                    }
884
1.96M
                }
885
15.6M
                mask_curr_ptr++;
886
15.6M
                src_curr_ptr++;
887
15.6M
            }
888
12.3k
            src_row_ptr += src_rowstride;
889
12.3k
            mask_row_ptr += maskbuf->rowstride;
890
12.3k
        }
891
1.04k
    }
892
1.04k
}
893
894
/* Transform of color data and copy noncolor data.  Used in
895
   group pop and during the pdf14 put image calls when the blend color space
896
   is different than the target device color space.  The function will try do
897
   in-place conversion if possible.  If not, it will do an allocation.  The
898
   put_image call needs to know if an allocation was made so that it can adjust
899
   for the fact that we likely don't have a full page any longer and we don't
900
   need to do the offset to our data in the buffer. Bug 700686: If we are in
901
   a softmask that includes a matte entry, then we need to undo the matte
902
   entry here at this time in the image's native color space not the parent
903
   color space.   The endian_swap term here is only set to true if the data
904
   has been baked as BE during the put_image blending operation and we are
905
   on a LE machine.  */
906
static forceinline pdf14_buf*
907
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
908
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
909
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
910
    bool has_matte, bool deep, bool endian_swap)
911
17.6k
{
912
17.6k
    gsicc_rendering_param_t rendering_params;
913
17.6k
    gsicc_link_t *icc_link;
914
17.6k
    gsicc_bufferdesc_t src_buff_desc;
915
17.6k
    gsicc_bufferdesc_t des_buff_desc;
916
17.6k
    int src_planestride = src_buf->planestride;
917
17.6k
    int src_rowstride = src_buf->rowstride;
918
17.6k
    int src_n_planes = src_buf->n_planes;
919
17.6k
    int src_n_chan = src_buf->n_chan;
920
17.6k
    int des_planestride = src_planestride;
921
17.6k
    int des_rowstride = src_rowstride;
922
17.6k
    int des_n_planes = src_n_planes;
923
17.6k
    int des_n_chan = src_n_chan;
924
17.6k
    int diff;
925
17.6k
    int k, j;
926
17.6k
    byte *des_data = NULL;
927
17.6k
    pdf14_buf *output = src_buf;
928
17.6k
    pdf14_mask_t *mask_stack;
929
17.6k
    pdf14_buf *maskbuf;
930
17.6k
    int code;
931
932
17.6k
    *did_alloc = false;
933
934
    /* Same profile */
935
17.6k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
936
0
        return src_buf;
937
938
    /* Define the rendering intent get the link */
939
17.6k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
940
17.6k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
941
17.6k
    rendering_params.override_icc = false;
942
17.6k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
943
17.6k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
944
17.6k
    rendering_params.cmm = gsCMM_DEFAULT;
945
17.6k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
946
17.6k
        &rendering_params, pgs->memory, false);
947
17.6k
    if (icc_link == NULL)
948
0
        return NULL;
949
950
    /* If different data sizes, we have to do an allocation */
951
17.6k
    diff = des_profile->num_comps - src_profile->num_comps;
952
17.6k
    if (diff != 0) {
953
17.2k
        byte *src_ptr;
954
17.2k
        byte *des_ptr;
955
956
17.2k
        *did_alloc = true;
957
17.2k
        des_rowstride = ((width + 3) & -4)<<deep;
958
17.2k
        des_planestride = height * des_rowstride;
959
17.2k
        des_n_planes = src_n_planes + diff;
960
17.2k
        des_n_chan = src_n_chan + diff;
961
17.2k
        des_data = gs_alloc_bytes(ctx->memory,
962
17.2k
                                  (size_t)des_planestride * des_n_planes + CAL_SLOP,
963
17.2k
                                  "pdf14_transform_color_buffer");
964
17.2k
        if (des_data == NULL)
965
0
            return NULL;
966
967
        /* Copy over the noncolor planes. May only be a dirty part, so have
968
           to copy row by row */
969
17.2k
        src_ptr = src_data;
970
17.2k
        des_ptr = des_data;
971
192k
        for (j = 0; j < height; j++) {
972
349k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
973
175k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps),
974
175k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
975
175k
                       width<<deep);
976
175k
            }
977
174k
            src_ptr += src_rowstride;
978
174k
            des_ptr += des_rowstride;
979
174k
        }
980
17.2k
    } else
981
348
        des_data = src_data;
982
983
    /* Set up the buffer descriptors. */
984
17.6k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
985
17.6k
                      false, true, src_planestride, src_rowstride, height, width);
986
17.6k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
987
17.6k
                      false, true, des_planestride, des_rowstride, height, width);
988
989
17.6k
    src_buff_desc.endian_swap = endian_swap;
990
17.6k
    des_buff_desc.endian_swap = endian_swap;
991
992
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
993
       context to ensure that this is not done again during the group
994
       composition */
995
17.6k
    if (has_matte &&
996
        /* Should always happen, but check for safety */
997
17.6k
        ((mask_stack = ctx->mask_stack) != NULL) &&
998
17.6k
        ((maskbuf = mask_stack->rc_mask->mask_buf) != NULL) &&
999
17.6k
         (maskbuf->data != NULL))
1000
1.04k
    {
1001
1.04k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
1002
1.04k
    }
1003
1004
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1005
       Gray buffers, this transform does not need to worry about the cmap procs
1006
       of the target device. */
1007
17.6k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1008
17.6k
        src_data, des_data);
1009
17.6k
    gsicc_release_link(icc_link);
1010
17.6k
    if (code < 0)
1011
0
        return NULL;
1012
1013
17.6k
    output->planestride = des_planestride;
1014
17.6k
    output->rowstride = des_rowstride;
1015
17.6k
    output->n_planes = des_n_planes;
1016
17.6k
    output->n_chan = des_n_chan;
1017
    /* If not in-place conversion, then release. */
1018
17.6k
    if (des_data != src_data) {
1019
17.2k
        gs_free_object(ctx->memory, output->data,
1020
17.2k
            "pdf14_transform_color_buffer");
1021
17.2k
        output->data = des_data;
1022
        /* Note, this is needed for case where we did a put image, as the
1023
           resulting transformed buffer may not be a full page. */
1024
17.2k
        output->rect.p.x = x0;
1025
17.2k
        output->rect.p.y = y0;
1026
17.2k
        output->rect.q.x = x0 + width;
1027
17.2k
        output->rect.q.y = y0 + height;
1028
17.2k
    }
1029
17.6k
    return output;
1030
17.6k
}
1031
1032
/* This is a routine to do memset's but with 16 bit values.
1033
 * Note, that we still take bytes, NOT "num values to set".
1034
 * We assume dest is 16 bit aligned. We assume that bytes is
1035
 * a multiple of 2. */
1036
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1037
0
{
1038
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1039
0
    uint32_t v;
1040
0
    if (bytes < 0)
1041
0
        return;
1042
0
    if (((intptr_t)dest) & 2) {
1043
0
        *dest++ = value;
1044
0
        bytes--;
1045
0
        if (bytes == 0)
1046
0
            return;
1047
0
    }
1048
0
    v = value | (value<<16);
1049
0
    bytes -= 2;
1050
0
    while (bytes > 0) {
1051
0
        *(uint32_t *)dest = v;
1052
0
        dest += 2;
1053
0
        bytes -= 4;
1054
0
    }
1055
0
    bytes += 2;
1056
0
    if (bytes & 2) {
1057
0
        *dest = value;
1058
0
    }
1059
0
}
1060
1061
static pdf14_buf*
1062
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1063
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1064
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1065
    bool deep, bool endian_swap)
1066
16.2k
{
1067
16.2k
    if (deep)
1068
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1069
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap);
1070
16.2k
    else
1071
16.2k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1072
16.2k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap);
1073
16.2k
}
1074
1075
static pdf14_buf*
1076
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1077
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1078
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1079
    bool deep, bool endian_swap)
1080
1.35k
{
1081
1.35k
    if (deep)
1082
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1083
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap);
1084
1.35k
    else
1085
1.35k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1086
1.35k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap);
1087
1.35k
}
1088
1089
/**
1090
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1091
 * @n_chan: Number of pixel channels including alpha, but not including
1092
 * shape, group alpha, or tags.
1093
 *
1094
 * Return value: Newly allocated buffer, or NULL on failure.
1095
 **/
1096
static  pdf14_buf *
1097
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1098
              bool has_shape, bool idle, int n_chan, int num_spots,
1099
              gs_memory_t *memory, bool deep)
1100
4.75M
{
1101
1102
    /* Note that alpha_g is the alpha for the GROUP */
1103
    /* This is distinct from the alpha that may also exist */
1104
    /* for the objects within the group.  Hence it can introduce */
1105
    /* yet another plane */
1106
1107
4.75M
    pdf14_buf *result;
1108
4.75M
    int rowstride = ((rect->q.x - rect->p.x + 3) & -4)<<deep;
1109
4.75M
    int height = (rect->q.y - rect->p.y);
1110
4.75M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1111
4.75M
                   (has_tags ? 1 : 0);
1112
4.75M
    int planestride;
1113
4.75M
    double dsize = (((double) rowstride) * height) * n_planes;
1114
1115
4.75M
    if (dsize > (double)max_uint)
1116
0
      return NULL;
1117
1118
4.75M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1119
4.75M
                             "pdf14_buf_new");
1120
4.75M
    if (result == NULL)
1121
0
        return result;
1122
1123
4.75M
    result->memory = memory;
1124
4.75M
    result->backdrop = NULL;
1125
4.75M
    result->saved = NULL;
1126
4.75M
    result->isolated = false;
1127
4.75M
    result->knockout = false;
1128
4.75M
    result->has_alpha_g = has_alpha_g;
1129
4.75M
    result->has_shape = has_shape;
1130
4.75M
    result->has_tags = has_tags;
1131
4.75M
    result->rect = *rect;
1132
4.75M
    result->n_chan = n_chan;
1133
4.75M
    result->n_planes = n_planes;
1134
4.75M
    result->rowstride = rowstride;
1135
4.75M
    result->transfer_fn = NULL;
1136
4.75M
    result->is_ident = true;
1137
4.75M
    result->matte_num_comps = 0;
1138
4.75M
    result->matte = NULL;
1139
4.75M
    result->mask_stack = NULL;
1140
4.75M
    result->idle = idle;
1141
4.75M
    result->mask_id = 0;
1142
4.75M
    result->num_spots = num_spots;
1143
4.75M
    result->deep = deep;
1144
4.75M
    result->page_group = false;
1145
4.75M
    result->group_color_info = NULL;
1146
4.75M
    result->group_popped = false;
1147
1148
4.75M
    if (idle || height <= 0) {
1149
        /* Empty clipping - will skip all drawings. */
1150
2.25M
        result->planestride = 0;
1151
2.25M
        result->data = 0;
1152
2.49M
    } else {
1153
2.49M
        planestride = rowstride * height;
1154
2.49M
        result->planestride = planestride;
1155
2.49M
        result->data = gs_alloc_bytes(memory,
1156
2.49M
                                      (size_t)planestride * n_planes + CAL_SLOP,
1157
2.49M
                                      "pdf14_buf_new");
1158
2.49M
        if (result->data == NULL) {
1159
0
            gs_free_object(memory, result, "pdf14_buf_new");
1160
0
            return NULL;
1161
0
        }
1162
2.49M
        if (has_alpha_g) {
1163
443k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1164
            /* Memsetting by 0, so this copes with the deep case too */
1165
443k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1166
443k
        }
1167
2.49M
        if (has_tags) {
1168
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1169
            /* Memsetting by 0, so this copes with the deep case too */
1170
0
            memset (result->data + tags_plane * planestride,
1171
0
                    GS_UNTOUCHED_TAG, planestride);
1172
0
        }
1173
2.49M
    }
1174
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1175
     * Any future drawing will make it valid again, so we won't blend back
1176
     * more than we need. */
1177
4.75M
    result->dirty.p.x = rect->q.x;
1178
4.75M
    result->dirty.p.y = rect->q.y;
1179
4.75M
    result->dirty.q.x = rect->p.x;
1180
4.75M
    result->dirty.q.y = rect->p.y;
1181
4.75M
    return result;
1182
4.75M
}
1183
1184
static  void
1185
pdf14_buf_free(pdf14_buf *buf)
1186
4.75M
{
1187
4.75M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1188
4.75M
    gs_memory_t *memory = buf->memory;
1189
1190
4.75M
    if (buf->mask_stack && buf->mask_stack->rc_mask)
1191
4.75M
        rc_decrement(buf->mask_stack->rc_mask, "pdf14_buf_free");
1192
1193
4.75M
    gs_free_object(memory, buf->mask_stack, "pdf14_buf_free");
1194
4.75M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1195
4.75M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1196
4.75M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1197
1198
9.50M
    while (group_color_info) {
1199
4.75M
       if (group_color_info->icc_profile != NULL) {
1200
4.75M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1201
4.75M
       }
1202
4.75M
       buf->group_color_info = group_color_info->previous;
1203
4.75M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1204
4.75M
       group_color_info = buf->group_color_info;
1205
4.75M
    }
1206
1207
4.75M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1208
4.75M
    gs_free_object(memory, buf, "pdf14_buf_free");
1209
4.75M
}
1210
1211
static void
1212
rc_pdf14_maskbuf_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
1213
2.26M
{
1214
    /* Ending the mask buffer. */
1215
2.26M
    pdf14_rcmask_t *rcmask = (pdf14_rcmask_t * ) ptr_in;
1216
    /* free the pdf14 buffer. */
1217
2.26M
    if ( rcmask->mask_buf != NULL ){
1218
244k
        pdf14_buf_free(rcmask->mask_buf);
1219
244k
    }
1220
2.26M
    gs_free_object(mem, rcmask, "rc_pdf14_maskbuf_free");
1221
2.26M
}
1222
1223
static  pdf14_rcmask_t *
1224
pdf14_rcmask_new(gs_memory_t *memory)
1225
2.26M
{
1226
2.26M
    pdf14_rcmask_t *result;
1227
1228
2.26M
    result = gs_alloc_struct(memory, pdf14_rcmask_t, &st_pdf14_rcmask,
1229
2.26M
                             "pdf14_maskbuf_new");
1230
2.26M
    if (result == NULL)
1231
0
        return NULL;
1232
2.26M
    rc_init_free(result, memory, 1, rc_pdf14_maskbuf_free);
1233
2.26M
    result->mask_buf = NULL;
1234
2.26M
    result->memory = memory;
1235
2.26M
    return result;
1236
2.26M
}
1237
1238
static  pdf14_ctx *
1239
pdf14_ctx_new(gx_device *dev, bool deep)
1240
1.56M
{
1241
1.56M
    pdf14_ctx *result;
1242
1.56M
    gs_memory_t *memory = dev->memory->stable_memory;
1243
1244
1.56M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1245
1.56M
    if (result == NULL)
1246
0
        return result;
1247
1.56M
    result->stack = NULL;
1248
1.56M
    result->mask_stack = pdf14_mask_element_new(memory);
1249
1.56M
    result->mask_stack->rc_mask = pdf14_rcmask_new(memory);
1250
1.56M
    result->memory = memory;
1251
1.56M
    result->smask_depth = 0;
1252
1.56M
    result->smask_blend = false;
1253
1.56M
    result->deep = deep;
1254
1.56M
    result->base_color = NULL;
1255
1.56M
    return result;
1256
1.56M
}
1257
1258
static  void
1259
pdf14_ctx_free(pdf14_ctx *ctx)
1260
1.56M
{
1261
1.56M
    pdf14_buf *buf, *next;
1262
1263
1.56M
    if (ctx->base_color) {
1264
835k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1265
835k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1266
835k
    }
1267
1.56M
    if (ctx->mask_stack) {
1268
        /* A mask was created but was not used in this band. */
1269
679k
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_ctx_free");
1270
679k
        gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_ctx_free");
1271
679k
    }
1272
2.93M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1273
1.37M
        next = buf->saved;
1274
1.37M
        pdf14_buf_free(buf);
1275
1.37M
    }
1276
1.56M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1277
1.56M
}
1278
1279
/**
1280
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1281
 *
1282
 * Return value: Backdrop buffer for current group operation, or NULL
1283
 * if backdrop is fully transparent.
1284
 **/
1285
static  pdf14_buf *
1286
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1287
1.37M
{
1288
    /* Our new buffer is buf */
1289
1.37M
    pdf14_buf *buf = ctx->stack;
1290
1291
1.37M
    *is_backdrop = false;
1292
1293
1.37M
    if (buf != NULL) {
1294
        /* If the new buffer is isolated there is no backdrop */
1295
1.37M
        if (buf->isolated) return NULL;
1296
1297
        /* If the previous buffer is a knockout group
1298
           then we need to use its backdrop as the backdrop. If
1299
           it was isolated then that back drop was NULL */
1300
443k
        if (buf->saved != NULL && buf->saved->knockout) {
1301
            /* Per the spec, if we have a non-isolated group
1302
               in a knockout group the non-isolated group
1303
               uses the backdrop of its parent group (the knockout group)
1304
               as its own backdrop.  The non-isolated group must
1305
               go through the standard re-composition operation
1306
               to avoid the double application of the backdrop */
1307
28
            *is_backdrop = true;
1308
28
            return buf->saved;
1309
28
        }
1310
        /* This should be the non-isolated case where its parent is
1311
           not a knockout */
1312
443k
        if (buf->saved != NULL) {
1313
443k
            return buf->saved;
1314
443k
        }
1315
443k
    }
1316
0
    return NULL;
1317
1.37M
}
1318
1319
static pdf14_group_color_t*
1320
pdf14_make_base_group_color(gx_device* dev)
1321
835k
{
1322
835k
    pdf14_device* pdev = (pdf14_device*)dev;
1323
835k
    pdf14_group_color_t* group_color;
1324
835k
    bool deep = pdev->ctx->deep;
1325
835k
    bool has_tags = device_encodes_tags(dev);
1326
1327
835k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1328
1329
835k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1330
835k
        pdf14_group_color_t, &st_pdf14_clr,
1331
835k
        "pdf14_make_base_group_color");
1332
1333
835k
    if (group_color == NULL)
1334
0
        return NULL;
1335
835k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1336
1337
835k
    group_color->num_std_colorants = pdev->num_std_colorants;
1338
835k
    group_color->blend_procs = pdev->blend_procs;
1339
835k
    group_color->polarity = pdev->color_info.polarity;
1340
835k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1341
835k
    group_color->isadditive = pdev->ctx->additive;
1342
835k
    group_color->unpack_procs = pdev->pdf14_procs;
1343
835k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1344
835k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1345
835k
    group_color->depth = pdev->color_info.depth;
1346
835k
    group_color->decode = dev_proc(pdev, decode_color);
1347
835k
    group_color->encode = dev_proc(pdev, encode_color);
1348
835k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1349
835k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1350
835k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1351
835k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1352
835k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1353
835k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1354
835k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1355
835k
    group_color->icc_profile =
1356
835k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1357
835k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1358
1359
835k
    return group_color;
1360
835k
}
1361
1362
/* This wil create the first buffer when we have
1363
   either the first drawing operation or transparency
1364
   group push.  At that time, the color space in which
1365
   we are going to be doing the alpha blend will be known. */
1366
static int
1367
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1368
812M
{
1369
812M
    pdf14_device *pdev = (pdf14_device *)dev;
1370
812M
    bool has_tags = device_encodes_tags(dev);
1371
812M
    int n_chan = pdev->color_info.num_components - has_tags;
1372
812M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1373
812M
    int num_spots = pdev->ctx->num_spots;
1374
812M
    pdf14_buf* buf;
1375
812M
    gs_memory_t* memory = dev->memory->stable_memory;
1376
1377
    /* Check for a blank idle group as a base group */
1378
812M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1379
812M
        pdev->ctx->stack->idle) {
1380
0
        pdf14_buf_free(pdev->ctx->stack);
1381
0
        pdev->ctx->stack = NULL;
1382
0
    }
1383
1384
812M
    if (pdev->ctx->stack != NULL)
1385
811M
        return 0;
1386
1387
812M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1388
724k
        dev->width, dev->height);
1389
1390
724k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1391
724k
        num_spots, memory, pdev->ctx->deep);
1392
724k
    if (buf == NULL) {
1393
0
        return gs_error_VMerror;
1394
0
    }
1395
724k
    if_debug5m('v', memory,
1396
724k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1397
724k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1398
1399
724k
    memset(buf->data, 0, (size_t)buf->planestride * (buf->n_planes - !!has_tags));
1400
724k
    buf->saved = NULL;
1401
724k
    pdev->ctx->stack = buf;
1402
724k
    pdev->ctx->additive = additive;
1403
1404
    /* Every buffer needs group color information including the base
1405
       one that is created for when we have no group */
1406
724k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1407
724k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1408
724k
    if (buf->group_color_info == NULL)
1409
0
        return gs_error_VMerror;
1410
1411
724k
    if (pgs != NULL)
1412
358k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1413
366k
    else
1414
366k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1415
1416
724k
    buf->group_color_info->group_color_mapping_procs =
1417
724k
        dev_proc(pdev, get_color_mapping_procs);
1418
724k
    buf->group_color_info->group_color_comp_index =
1419
724k
        dev_proc(pdev, get_color_comp_index);
1420
724k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1421
724k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1422
724k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1423
724k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1424
724k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1425
724k
    buf->group_color_info->depth = pdev->color_info.depth;
1426
724k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1427
724k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1428
724k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1429
724k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1430
724k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1431
724k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1432
724k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1433
724k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1434
724k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1435
724k
    buf->group_color_info->icc_profile =
1436
724k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1437
724k
    if (buf->group_color_info->icc_profile != NULL)
1438
724k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1439
1440
724k
    return 0;
1441
724k
}
1442
1443
static pdf14_group_color_t*
1444
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1445
41.6k
{
1446
41.6k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1447
41.6k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1448
41.6k
    if (des == NULL)
1449
0
        return NULL;
1450
1451
41.6k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1452
41.6k
    if (des->icc_profile != NULL)
1453
41.6k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1454
41.6k
    des->previous = NULL;  /* used during clist writing for state stack */
1455
1456
41.6k
    return des;
1457
41.6k
}
1458
1459
static  int
1460
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1461
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1462
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1463
                              int numcomps, bool cm_back_drop, bool shade_group,
1464
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1465
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1466
                              gx_device *dev)
1467
3.31M
{
1468
3.31M
    pdf14_buf *tos = ctx->stack;
1469
3.31M
    pdf14_buf *buf, * pdf14_backdrop;
1470
3.31M
    bool has_shape = false;
1471
3.31M
    bool is_backdrop;
1472
3.31M
    int num_spots;
1473
1474
3.31M
    if_debug1m('v', ctx->memory,
1475
3.31M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1476
1477
3.31M
    if (tos != NULL)
1478
2.66M
        has_shape = tos->has_shape || tos->knockout;
1479
1480
3.31M
    if (ctx->smask_depth > 0)
1481
4.42k
        num_spots = 0;
1482
3.30M
    else
1483
3.30M
        num_spots = ctx->num_spots;
1484
1485
1486
3.31M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1487
3.31M
                        num_spots, ctx->memory, ctx->deep);
1488
3.31M
    if (buf == NULL)
1489
0
        return_error(gs_error_VMerror);
1490
1491
3.31M
    if_debug4m('v', ctx->memory,
1492
3.31M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1493
3.31M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1494
3.31M
    buf->isolated = isolated;
1495
3.31M
    buf->knockout = knockout;
1496
3.31M
    buf->alpha = alpha;
1497
3.31M
    buf->shape = shape;
1498
3.31M
    buf->opacity = opacity;
1499
3.31M
    buf->blend_mode = blend_mode;
1500
3.31M
    buf->mask_id = mask_id;
1501
3.31M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1502
                                          set up another (nested) mask. */
1503
3.31M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1504
                            See pdf14_pop_transparency_group how to handle it. */
1505
3.31M
    buf->saved = tos;
1506
3.31M
    buf->group_color_info = group_color;
1507
1508
3.31M
    if (tos == NULL)
1509
652k
        buf->page_group = true;
1510
1511
3.31M
    ctx->stack = buf;
1512
3.31M
    if (buf->data == NULL)
1513
1.94M
        return 0;
1514
1.37M
    if (idle)
1515
0
        return 0;
1516
1.37M
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1517
1518
    /* Initializes buf->data with the backdrop or as opaque */
1519
1.37M
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1520
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1521
        /* Memsetting by 0, so this copes with the deep case too */
1522
926k
        memset(buf->data, 0, (size_t)buf->planestride *
1523
926k
                                          (buf->n_chan +
1524
926k
                                           (buf->has_shape ? 1 : 0) +
1525
926k
                                           (buf->has_alpha_g ? 1 : 0)));
1526
926k
    } else {
1527
443k
        if (!cm_back_drop) {
1528
443k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1529
#if RAW_DUMP
1530
                                    , ctx->memory
1531
#endif
1532
443k
                                    );
1533
443k
        } else {
1534
            /* We must have an non-isolated group with a mismatch in color spaces.
1535
                In this case, we can't just copy the buffer but must CM it */
1536
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1537
0
                                        ctx->memory, pgs, dev, is_backdrop);
1538
0
        }
1539
443k
    }
1540
1541
    /* If our new group is a non-isolated knockout group, we have to maintain
1542
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1543
       knockout group. They have to always blend with the groups backdrop
1544
       not what is currently drawn in the group. Selection of the backdrop
1545
       depends upon the properties of the parent group. For example, if
1546
       the parent itself is a knockout group we actually
1547
       need to blend with its backdrop. This could be NULL if the parent was
1548
       an isolated knockout group. */
1549
1.37M
    if (buf->knockout && pdf14_backdrop != NULL) {
1550
48.3k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1551
48.3k
                                       (size_t)buf->planestride * buf->n_planes + CAL_SLOP,
1552
48.3k
                                       "pdf14_push_transparency_group");
1553
48.3k
        if (buf->backdrop == NULL) {
1554
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1555
0
        }
1556
1557
48.3k
        memcpy(buf->backdrop, buf->data,
1558
48.3k
               (size_t)buf->planestride * buf->n_planes);
1559
1560
#if RAW_DUMP
1561
        /* Dump the current buffer to see what we have. */
1562
        dump_raw_buffer(ctx->memory,
1563
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1564
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1565
            ctx->stack->planestride, ctx->stack->rowstride,
1566
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1567
        global_index++;
1568
#endif
1569
48.3k
    }
1570
#if RAW_DUMP
1571
    /* Dump the current buffer to see what we have. */
1572
    dump_raw_buffer(ctx->memory,
1573
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1574
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1575
                    ctx->stack->planestride, ctx->stack->rowstride,
1576
                    "TransGroupPush", ctx->stack->data, buf->deep);
1577
    global_index++;
1578
#endif
1579
1.37M
    return 0;
1580
1.37M
}
1581
1582
static  int
1583
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1584
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1585
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1586
3.31M
{
1587
3.31M
    pdf14_buf *tos = ctx->stack;
1588
3.31M
    pdf14_buf *nos = tos->saved;
1589
3.31M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1590
3.31M
    pdf14_buf *maskbuf;
1591
3.31M
    int x0, x1, y0, y1;
1592
3.31M
    int nos_num_color_comp;
1593
3.31M
    bool no_icc_match;
1594
3.31M
    pdf14_device *pdev = (pdf14_device *)dev;
1595
3.31M
    bool overprint = pdev->overprint;
1596
3.31M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1597
3.31M
    bool has_matte = false;
1598
3.31M
    int code = 0;
1599
1600
#ifdef DEBUG
1601
    pdf14_debug_mask_stack_state(ctx);
1602
#endif
1603
3.31M
    if (mask_stack == NULL) {
1604
1.69M
        maskbuf = NULL;
1605
1.69M
    }
1606
1.61M
    else {
1607
1.61M
        maskbuf = mask_stack->rc_mask->mask_buf;
1608
1.61M
    }
1609
1610
3.31M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1611
4.73k
        has_matte = true;
1612
1613
    /* Check if this is our last buffer, if yes, there is nothing to
1614
       compose to.  Keep this buffer until we have the put image.
1615
       If we have another group push, this group must be destroyed.
1616
       This only occurs sometimes when at clist creation time
1617
       push_shfill_group occured and nothing was drawn in this group.
1618
       There is also the complication if we have a softmask.  There
1619
       are two approaches to this problem.  Apply the softmask during
1620
       the put image or handle it now.  I choose the later as the
1621
       put_image code is already way to complicated. */
1622
3.31M
    if (nos == NULL && maskbuf == NULL) {
1623
650k
        tos->group_popped = true;
1624
650k
        return 0;
1625
650k
    }
1626
1627
    /* Here is the case with the soft mask.  Go ahead and create a new
1628
       target buffer (nos) with the same color information etc, but blank
1629
       and go ahead and do the blend with the softmask so that it gets applied. */
1630
2.66M
    if (nos == NULL && maskbuf != NULL) {
1631
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1632
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1633
0
        if (nos == NULL) {
1634
0
            code = gs_error_VMerror;
1635
0
            goto exit;
1636
0
        }
1637
1638
0
        if_debug4m('v', ctx->memory,
1639
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1640
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1641
1642
0
        nos->dirty = tos->dirty;
1643
0
        nos->isolated = tos->isolated;
1644
0
        nos->knockout = tos->knockout;
1645
0
        nos->alpha = 65535;
1646
0
        nos->shape = 65535;
1647
0
        nos->opacity = 65535;
1648
0
        nos->blend_mode = tos->blend_mode;
1649
0
        nos->mask_id = tos->mask_id;
1650
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1651
1652
0
        if (nos->data != NULL)
1653
0
            memset(nos->data, 0,
1654
0
                   (size_t)nos->planestride *
1655
0
                                          (nos->n_chan +
1656
0
                                           (nos->has_shape ? 1 : 0) +
1657
0
                                           (nos->has_alpha_g ? 1 : 0)));
1658
0
    }
1659
1660
    /* Before we get started, lets see if we have somehow gotten into
1661
       what should be an impossible situation where the group color
1662
       information does not match the buffer color information. This
1663
       can occur is there were memory issues that have perhaps blown
1664
       away information, or in the example of Bug 705197 the PDF interpreter
1665
       reuses a pattern during a circular reference causing an aliasing
1666
       of two nested patterns, one of which has a softmask. The change in
1667
       the buffer size of the inner one blows away the buffer of the
1668
       outer one leading to a mismatch of color spaces. Here
1669
       we can at least catch the case when the color space sizes have
1670
       changed and avoid buffer over-runs that would occur when we try
1671
       to do the group composition */
1672
2.66M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1673
2.66M
        tos->n_chan - 1 != tos_num_color_comp)
1674
0
        return_error(gs_error_Fatal);
1675
1676
2.66M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1677
2.66M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1678
1679
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1680
     * have made them overly large. */
1681
2.66M
    rect_intersect(tos->dirty, tos->rect);
1682
2.66M
    rect_intersect(nos->dirty, nos->rect);
1683
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1684
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1685
2.66M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1686
2.66M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1687
2.66M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1688
2.66M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1689
2.66M
    if (ctx->mask_stack) {
1690
        /* This can occur when we have a situation where we are ending out of
1691
           a group that has internal to it a soft mask and another group.
1692
           The soft mask left over from the previous trans group pop is put
1693
           into ctx->masbuf, since it is still active if another trans group
1694
           push occurs to use it.  If one does not occur, but instead we find
1695
           ourselves popping from a parent group, then this softmask is no
1696
           longer needed.  We will rc_decrement and set it to NULL. */
1697
66
        rc_decrement(ctx->mask_stack->rc_mask, "pdf14_pop_transparency_group");
1698
66
        if (ctx->mask_stack->rc_mask == NULL ){
1699
66
            gs_free_object(ctx->memory, ctx->mask_stack, "pdf14_pop_transparency_group");
1700
66
        }
1701
66
        ctx->mask_stack = NULL;
1702
66
    }
1703
2.66M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1704
2.66M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1705
2.66M
    if (tos->idle)
1706
1.90M
        goto exit;
1707
751k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1708
0
        goto exit;
1709
1710
#if RAW_DUMP
1711
    /* Dump the current buffer to see what we have. */
1712
    dump_raw_buffer(ctx->memory,
1713
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1714
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1715
                    ctx->stack->planestride, ctx->stack->rowstride,
1716
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1717
    global_index++;
1718
#endif
1719
/* Note currently if a pattern space has transparency, the ICC profile is not used
1720
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1721
   This is partially due to the fact that pdf14_pop_transparency_group and
1722
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1723
   operations called in the tile transparency code.  Instead we may want to
1724
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1725
   is where all the ICC information is handled.  We will return to look at that later */
1726
751k
    if (nos->group_color_info->icc_profile != NULL) {
1727
751k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1728
751k
    } else {
1729
        /* Let the other tests make the decision if we need to transform */
1730
0
        no_icc_match = false;
1731
0
    }
1732
    /* If the color spaces are different and we actually did do a swap of
1733
       the procs for color */
1734
751k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1735
751k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1736
8.02k
        if (x0 < x1 && y0 < y1) {
1737
6.50k
            pdf14_buf *result;
1738
6.50k
            bool did_alloc; /* We don't care here */
1739
1740
6.50k
            if (has_matte) {
1741
1.35k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1742
1.35k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1743
1.35k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1744
1.35k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1745
1.35k
                has_matte = false;
1746
5.14k
            } else {
1747
5.14k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1748
5.14k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1749
5.14k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1750
5.14k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1751
5.14k
            }
1752
6.50k
            if (result == NULL) {
1753
                /* Clean up and return error code */
1754
0
                code = gs_error_unknownerror;
1755
0
                goto exit;
1756
0
            }
1757
1758
#if RAW_DUMP
1759
            /* Dump the current buffer to see what we have. */
1760
            dump_raw_buffer(ctx->memory,
1761
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1762
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1763
                            ctx->stack->planestride, ctx->stack->rowstride,
1764
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1765
                            ctx->stack->deep);
1766
#endif
1767
             /* compose. never do overprint in this case */
1768
6.50k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1769
6.50k
                 nos->group_color_info->isadditive,
1770
6.50k
                 nos->group_color_info->blend_procs,
1771
6.50k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1772
6.50k
        }
1773
743k
    } else {
1774
        /* Group color spaces are the same.  No color conversions needed */
1775
743k
        if (x0 < x1 && y0 < y1)
1776
493k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1777
493k
                                ctx->additive, pblend_procs, has_matte, overprint,
1778
493k
                                drawn_comps, ctx->memory, dev);
1779
743k
    }
1780
2.66M
exit:
1781
2.66M
    ctx->stack = nos;
1782
    /* We want to detect the cases where we have luminosity soft masks embedded
1783
       within one another.  The "alpha" channel really needs to be merged into
1784
       the luminosity channel in this case.  This will occur during the mask pop */
1785
2.66M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1786
        /* Set the trigger so that we will blend if not alpha. Since
1787
           we have softmasks embedded in softmasks */
1788
1.19k
        ctx->smask_blend = true;
1789
1.19k
    }
1790
2.66M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1791
2.66M
    pdf14_buf_free(tos);
1792
2.66M
    if (code < 0)
1793
0
        return_error(code);
1794
2.66M
    return 0;
1795
2.66M
}
1796
1797
/*
1798
 * Create a transparency mask that will be used as the mask for
1799
 * the next transparency group that is created afterwards.
1800
 * The sequence of calls is:
1801
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1802
 */
1803
static  int
1804
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1805
                             byte *transfer_fn, bool is_ident, bool idle,
1806
                             bool replacing, uint mask_id,
1807
                             gs_transparency_mask_subtype_t subtype,
1808
                             int numcomps, int Background_components,
1809
                             const float Background[], int Matte_components,
1810
                             const float Matte[], const float GrayBackground,
1811
                             pdf14_group_color_t* group_color)
1812
713k
{
1813
713k
    pdf14_buf *buf;
1814
713k
    int i;
1815
1816
713k
    if_debug2m('v', ctx->memory,
1817
713k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1818
713k
               idle, replacing);
1819
713k
    ctx->smask_depth += 1;
1820
1821
713k
    if (ctx->stack == NULL) {
1822
0
        return_error(gs_error_VMerror);
1823
0
    }
1824
1825
    /* An optimization to consider is that if the SubType is Alpha
1826
       then we really should only be allocating the alpha band and
1827
       only draw with that channel.  Current architecture makes that
1828
       a bit tricky.  We need to create this based upon the size of
1829
       the color space + an alpha channel. NOT the device size
1830
       or the previous ctx size */
1831
    /* A mask doesn't worry about tags */
1832
713k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1833
713k
                        ctx->memory, ctx->deep);
1834
713k
    if (buf == NULL)
1835
0
        return_error(gs_error_VMerror);
1836
713k
    buf->alpha = bg_alpha;
1837
713k
    buf->is_ident = is_ident;
1838
    /* fill in, but these values aren't really used */
1839
713k
    buf->isolated = true;
1840
713k
    buf->knockout = false;
1841
713k
    buf->shape = 0xffff;
1842
713k
    buf->blend_mode = BLEND_MODE_Normal;
1843
713k
    buf->transfer_fn = transfer_fn;
1844
713k
    buf->matte_num_comps = Matte_components;
1845
713k
    buf->group_color_info = group_color;
1846
1847
713k
    if (Matte_components) {
1848
4.73k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1849
4.73k
                                                "pdf14_push_transparency_mask");
1850
4.73k
        if (buf->matte == NULL)
1851
0
            return_error(gs_error_VMerror);
1852
18.9k
        for (i = 0; i < Matte_components; i++) {
1853
14.2k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1854
14.2k
        }
1855
4.73k
    }
1856
713k
    buf->mask_id = mask_id;
1857
    /* If replacing=false, we start the mask for an image with SMask.
1858
       In this case the image's SMask temporary replaces the
1859
       mask of the containing group. Save the containing droup's mask
1860
       in buf->mask_stack */
1861
713k
    buf->mask_stack = ctx->mask_stack;
1862
713k
    if (buf->mask_stack){
1863
168k
        rc_increment(buf->mask_stack->rc_mask);
1864
168k
    }
1865
#if RAW_DUMP
1866
    /* Dump the current buffer to see what we have. */
1867
    if (ctx->stack->planestride > 0 ){
1868
        dump_raw_buffer(ctx->memory,
1869
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1870
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1871
                        ctx->stack->planestride, ctx->stack->rowstride,
1872
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1873
        global_index++;
1874
    }
1875
#endif
1876
713k
    buf->saved = ctx->stack;
1877
713k
    ctx->stack = buf;
1878
    /* Soft Mask related information so we know how to
1879
       compute luminosity when we pop the soft mask */
1880
713k
    buf->SMask_SubType = subtype;
1881
713k
    if (buf->data != NULL) {
1882
        /* We need to initialize it to the BC if it existed */
1883
        /* According to the spec, the CS has to be the same */
1884
        /* If the back ground component is black, then don't bother
1885
           with this.  Since we are forcing the rendering to gray
1886
           earlier now, go ahead and just use the GrayBackGround color
1887
           directly. */
1888
403k
        if ( Background_components && GrayBackground != 0.0 ) {
1889
126
            if (buf->deep) {
1890
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1891
0
                gs_memset16(buf->data, gray, buf->planestride);
1892
                /* If we have a background component that was not black, then we
1893
                   need to set the alpha for this mask as if we had drawn in the
1894
                   entire soft mask buffer */
1895
0
                gs_memset16(buf->data + buf->planestride, 65535,
1896
0
                            buf->planestride *(buf->n_chan - 1));
1897
126
            } else {
1898
126
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1899
126
                memset(buf->data, gray, buf->planestride);
1900
                /* If we have a background component that was not black, then we
1901
                   need to set the alpha for this mask as if we had drawn in the
1902
                   entire soft mask buffer */
1903
126
                memset(buf->data + buf->planestride, 255,
1904
126
                       (size_t)buf->planestride * (buf->n_chan - 1));
1905
126
            }
1906
403k
        } else {
1907
            /* Compose mask with opaque background */
1908
403k
            memset(buf->data, 0, (size_t)buf->planestride * buf->n_chan);
1909
403k
        }
1910
403k
    }
1911
713k
    return 0;
1912
713k
}
1913
1914
static void pdf14_free_mask_stack(pdf14_ctx *ctx, gs_memory_t *memory)
1915
169k
{
1916
169k
    pdf14_mask_t *mask_stack = ctx->mask_stack;
1917
1918
169k
    if (mask_stack->rc_mask != NULL) {
1919
1.15k
        pdf14_mask_t *curr_mask = mask_stack;
1920
1.15k
        pdf14_mask_t *old_mask;
1921
2.31k
        while (curr_mask != NULL) {
1922
            /* Force to decrement until free */
1923
2.50k
            while (curr_mask->rc_mask != NULL)
1924
1.34k
                rc_decrement(curr_mask->rc_mask, "pdf14_free_mask_stack");
1925
1.15k
            old_mask = curr_mask;
1926
1.15k
            curr_mask = curr_mask->previous;
1927
1.15k
            gs_free_object(old_mask->memory, old_mask, "pdf14_free_mask_stack");
1928
1.15k
        }
1929
167k
    } else {
1930
167k
        gs_free_object(memory, mask_stack, "pdf14_free_mask_stack");
1931
167k
    }
1932
169k
    ctx->mask_stack = NULL;
1933
169k
}
1934
1935
static  int
1936
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1937
713k
{
1938
713k
    pdf14_buf* tos = ctx->stack;
1939
713k
    pdf14_buf* nos = tos->saved;
1940
713k
    byte *new_data_buf;
1941
713k
    int icc_match;
1942
713k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1943
713k
    cmm_profile_t *src_profile;
1944
713k
    gsicc_rendering_param_t rendering_params;
1945
713k
    gsicc_link_t *icc_link;
1946
713k
    gsicc_rendering_param_t render_cond;
1947
713k
    cmm_dev_profile_t *dev_profile;
1948
713k
    int code = 0;
1949
1950
713k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1951
713k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1952
713k
                          &render_cond);
1953
713k
    ctx->smask_depth -= 1;
1954
    /* icc_match == -1 means old non-icc code.
1955
       icc_match == 0 means use icc code
1956
       icc_match == 1 mean no conversion needed */
1957
713k
    if (des_profile != NULL && src_profile != NULL ) {
1958
713k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1959
713k
    } else {
1960
0
        icc_match = -1;
1961
0
    }
1962
713k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1963
713k
               tos->idle);
1964
713k
    ctx->stack = tos->saved;
1965
713k
    tos->saved = NULL;  /* To avoid issues with GC */
1966
713k
    if (tos->mask_stack) {
1967
        /* During the soft mask push, the mask_stack was copied (not moved) from
1968
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1969
           just set to NULL.  However, before we do that we must perform
1970
           rc decrement to match the increment that occured was made.  Also,
1971
           if this is the last ref count of the rc_mask, we should free the
1972
           buffer now since no other groups need it. */
1973
168k
        rc_decrement(tos->mask_stack->rc_mask,
1974
168k
                     "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1975
168k
        if (tos->mask_stack->rc_mask) {
1976
168k
            if (tos->mask_stack->rc_mask->rc.ref_count == 1){
1977
167k
                rc_decrement(tos->mask_stack->rc_mask,
1978
167k
                            "pdf14_pop_transparency_mask(tos->mask_stack->rc_mask)");
1979
167k
            }
1980
168k
        }
1981
168k
        tos->mask_stack = NULL;
1982
168k
    }
1983
713k
    if (tos->data == NULL ) {
1984
        /* This can occur in clist rendering if the soft mask does
1985
           not intersect the current band.  It would be nice to
1986
           catch this earlier and just avoid creating the structure
1987
           to begin with.  For now we need to delete the structure
1988
           that was created.  Only delete if the alpha value is 65535 */
1989
309k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1990
309k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1991
5.32k
            pdf14_buf_free(tos);
1992
5.32k
            if (ctx->mask_stack != NULL) {
1993
2.99k
                pdf14_free_mask_stack(ctx, ctx->memory);
1994
2.99k
            }
1995
304k
        } else {
1996
            /* Assign as mask buffer */
1997
304k
            if (ctx->mask_stack != NULL) {
1998
79.8k
                pdf14_free_mask_stack(ctx, ctx->memory);
1999
79.8k
            }
2000
304k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2001
304k
            ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2002
304k
            ctx->mask_stack->rc_mask->mask_buf = tos;
2003
304k
        }
2004
309k
        ctx->smask_blend = false;  /* just in case */
2005
403k
    } else {
2006
        /* If we are already in the source space then there is no reason
2007
           to do the transformation */
2008
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
2009
        /* This will reduce our memory.  We won't reuse the existing one, due */
2010
        /* Due to the fact that on certain systems we may have issues recovering */
2011
        /* the data after a resize */
2012
403k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
2013
403k
                                        "pdf14_pop_transparency_mask");
2014
403k
        if (new_data_buf == NULL)
2015
0
            return_error(gs_error_VMerror);
2016
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
2017
           we won't be filling everything during the remap if it had not been
2018
           written into by the PDF14 fill rect */
2019
403k
        memset(new_data_buf, 0, tos->planestride);
2020
        /* If the subtype was alpha, then just grab the alpha channel now
2021
           and we are all done */
2022
403k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
2023
36.9k
            ctx->smask_blend = false;  /* not used in this case */
2024
36.9k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
2025
36.9k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2026
36.9k
                       tos->rowstride,
2027
36.9k
                       (tos->data)+tos->planestride, new_data_buf);
2028
#if RAW_DUMP
2029
            /* Dump the current buffer to see what we have. */
2030
            dump_raw_buffer(ctx->memory,
2031
                            tos->rect.q.y-tos->rect.p.y,
2032
                            tos->rowstride>>tos->deep, 1,
2033
                            tos->planestride, tos->rowstride,
2034
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
2035
                            tos->deep);
2036
            global_index++;
2037
#endif
2038
366k
        } else {
2039
366k
            if (icc_match == 1 || tos->n_chan == 2) {
2040
#if RAW_DUMP
2041
                /* Dump the current buffer to see what we have. */
2042
                dump_raw_buffer(ctx->memory,
2043
                                tos->rect.q.y-tos->rect.p.y,
2044
                                tos->rowstride>>tos->deep, tos->n_planes,
2045
                                tos->planestride, tos->rowstride,
2046
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
2047
                                tos->deep);
2048
                global_index++;
2049
#endif
2050
                /* There is no need to color convert.  Data is already gray scale.
2051
                   We just need to copy the gray plane.  However it is
2052
                   possible that the soft mask could have a soft mask which
2053
                   would end us up with some alpha blending information
2054
                   (Bug691803). In fact, according to the spec, the alpha
2055
                   blending has to occur.  See FTS test fts_26_2601.pdf
2056
                   for an example of this.  Softmask buffer is intialized
2057
                   with BG values.  It would be nice to keep track if buffer
2058
                   ever has a alpha value not 1 so that we could detect and
2059
                   avoid this blend if not needed. */
2060
366k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
2061
366k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
2062
366k
                            tos->planestride, tos->deep);
2063
#if RAW_DUMP
2064
                /* Dump the current buffer to see what we have. */
2065
                dump_raw_buffer(ctx->memory,
2066
                                tos->rect.q.y-tos->rect.p.y,
2067
                                tos->rowstride>>tos->deep, 1,
2068
                                tos->planestride, tos->rowstride,
2069
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2070
                                tos->deep);
2071
                global_index++;
2072
#endif
2073
366k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2074
366k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2075
366k
                           tos->rowstride, tos->data, new_data_buf);
2076
366k
            } else {
2077
0
                if ( icc_match == -1 ) {
2078
                    /* The slow old fashioned way */
2079
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2080
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2081
0
                        tos->rowstride, tos->planestride,
2082
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2083
0
                        tos->deep
2084
#if RAW_DUMP
2085
                        , ctx->memory
2086
#endif
2087
0
                        );
2088
0
                } else {
2089
                    /* ICC case where we use the CMM */
2090
                    /* Request the ICC link for the transform that we will need to use */
2091
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2092
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2093
0
                    rendering_params.override_icc = false;
2094
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2095
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2096
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2097
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2098
0
                        src_profile, &rendering_params, pgs->memory, false);
2099
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2100
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2101
0
                              tos->rowstride, tos->planestride,
2102
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2103
                    /* Release the link */
2104
0
                    gsicc_release_link(icc_link);
2105
0
                }
2106
0
            }
2107
366k
        }
2108
        /* Free the old object, NULL test was above */
2109
403k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2110
403k
        tos->data = new_data_buf;
2111
        /* Data is single channel now */
2112
403k
        tos->n_chan = 1;
2113
403k
        tos->n_planes = 1;
2114
        /* Assign as reference counted mask buffer */
2115
403k
        if (ctx->mask_stack != NULL) {
2116
            /* In this case, the source file is wacky as it already had a
2117
               softmask and now is getting a replacement. We need to clean
2118
               up the softmask stack before doing this free and creating
2119
               a new stack. Bug 693312 */
2120
86.3k
            pdf14_free_mask_stack(ctx, ctx->memory);
2121
86.3k
        }
2122
403k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2123
403k
        if (ctx->mask_stack == NULL)
2124
0
            return gs_note_error(gs_error_VMerror);
2125
403k
        ctx->mask_stack->rc_mask = pdf14_rcmask_new(ctx->memory);
2126
403k
        if (ctx->mask_stack->rc_mask == NULL)
2127
0
            return gs_note_error(gs_error_VMerror);
2128
403k
        ctx->mask_stack->rc_mask->mask_buf = tos;
2129
403k
    }
2130
713k
    return code;
2131
713k
}
2132
2133
static pdf14_mask_t *
2134
pdf14_mask_element_new(gs_memory_t *memory)
2135
2.26M
{
2136
2.26M
    pdf14_mask_t *result;
2137
2138
2.26M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2139
2.26M
                             "pdf14_mask_element_new");
2140
2.26M
    if (result == NULL)
2141
0
        return NULL;
2142
    /* Get the reference counted mask */
2143
2.26M
    result->rc_mask = NULL;
2144
2.26M
    result->previous = NULL;
2145
2.26M
    result->memory = memory;
2146
2.26M
    return result;
2147
2.26M
}
2148
2149
static int
2150
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2151
0
{
2152
    /* We need to push the current soft mask.  We need to
2153
       be able to recover it if we draw a new one and
2154
       then obtain a Q operation ( a pop ) */
2155
2156
0
    pdf14_device *pdev = (pdf14_device *)dev;
2157
0
    pdf14_ctx *ctx = pdev->ctx;
2158
0
    pdf14_mask_t *new_mask;
2159
2160
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2161
    /* We need to push the current mask buffer   */
2162
    /* Allocate a new element for the stack.
2163
       Don't do anything if there is no mask present.*/
2164
0
    if (ctx->mask_stack != NULL) {
2165
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2166
        /* Duplicate and make the link */
2167
0
        new_mask->rc_mask = ctx->mask_stack->rc_mask;
2168
0
        rc_increment(new_mask->rc_mask);
2169
0
        new_mask->previous = ctx->mask_stack;
2170
0
        ctx->mask_stack = new_mask;
2171
0
    }
2172
#ifdef DEBUG
2173
    pdf14_debug_mask_stack_state(pdev->ctx);
2174
#endif
2175
0
    return 0;
2176
0
}
2177
2178
static int
2179
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2180
4.27M
{
2181
    /* Pop the soft mask.  It is no longer needed. Likely due to
2182
       a Q that has occurred. */
2183
4.27M
    pdf14_device *pdev = (pdf14_device *)dev;
2184
4.27M
    pdf14_ctx *ctx = pdev->ctx;
2185
4.27M
    pdf14_mask_t *old_mask;
2186
2187
4.27M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2188
    /* rc decrement the current link after we break it from
2189
       the list, then free the stack element.  Don't do
2190
       anything if there is no mask present. */
2191
4.27M
    if (ctx->mask_stack != NULL) {
2192
768k
        old_mask = ctx->mask_stack;
2193
768k
        ctx->mask_stack = ctx->mask_stack->previous;
2194
768k
        if (old_mask->rc_mask) {
2195
768k
            rc_decrement(old_mask->rc_mask, "pdf14_pop_transparency_state");
2196
768k
        }
2197
768k
        gs_free_object(old_mask->memory, old_mask, "pdf14_pop_transparency_state");
2198
        /* We need to have some special handling here for when we have nested
2199
           soft masks.  There may be a copy in the stack that we may need to
2200
           adjust. */
2201
768k
        if (ctx->smask_depth > 0) {
2202
407
            if (ctx->stack != NULL && ctx->stack->mask_stack != NULL) {
2203
286
                ctx->stack->mask_stack = ctx->mask_stack;
2204
286
            }
2205
407
        }
2206
768k
    }
2207
#ifdef DEBUG
2208
    pdf14_debug_mask_stack_state(pdev->ctx);
2209
#endif
2210
4.27M
    return 0;
2211
4.27M
}
2212
2213
static  int
2214
pdf14_open(gx_device *dev)
2215
1.56M
{
2216
1.56M
    pdf14_device *pdev = (pdf14_device *)dev;
2217
2218
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2219
1.56M
    if (pdev->ctx == NULL) {
2220
1.56M
        bool has_tags = device_encodes_tags(dev);
2221
1.56M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2222
1.56M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2223
1.56M
        if (pdev->ctx == NULL)
2224
0
            return_error(gs_error_VMerror);
2225
2226
1.56M
        pdev->ctx->rect.p.x = 0;
2227
1.56M
        pdev->ctx->rect.p.y = 0;
2228
1.56M
        pdev->ctx->rect.q.x = dev->width;
2229
1.56M
        pdev->ctx->rect.q.y = dev->height;
2230
1.56M
        pdev->ctx->has_tags = has_tags;
2231
1.56M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2232
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2233
         * is. I am not sure how to fix that. */
2234
1.56M
        if (pdev->ctx->num_spots < 0)
2235
0
            pdev->ctx->num_spots = 0;
2236
1.56M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2237
1.56M
    }
2238
1.56M
    pdev->free_devicen = true;
2239
1.56M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2240
1.56M
    return 0;
2241
1.56M
}
2242
2243
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2244
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2245
};
2246
2247
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2248
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2249
};
2250
2251
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2252
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2253
};
2254
2255
static const gx_cm_color_map_procs *
2256
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2257
7.20M
{
2258
7.20M
    *tdev = dev;
2259
7.20M
    return &pdf14_DeviceCMYKspot_procs;
2260
7.20M
}
2261
2262
static const gx_cm_color_map_procs *
2263
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2264
5.91M
{
2265
5.91M
    *tdev = dev;
2266
5.91M
    return &pdf14_DeviceRGBspot_procs;
2267
5.91M
}
2268
2269
static const gx_cm_color_map_procs *
2270
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2271
0
{
2272
0
    *tdev = dev;
2273
0
    return &pdf14_DeviceGrayspot_procs;
2274
0
}
2275
2276
static void
2277
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2278
0
{
2279
0
    for (; n != 0; n--) {
2280
0
        uint16_t in = *src++;
2281
0
        ((byte *)dst)[0] = in>>8;
2282
0
        ((byte *)dst)[1] = in;
2283
0
        dst++;
2284
0
    }
2285
0
}
2286
2287
/* Used to pass along information about the buffer created by the
2288
   pdf14 device.  This is used by the pattern accumulator when the
2289
   pattern contains transparency.  Note that if free_device is true then
2290
   we need to go ahead and get the buffer data copied and free up the
2291
   device.  This only occurs at the end of a pattern accumulation operation */
2292
int
2293
pdf14_get_buffer_information(const gx_device * dev,
2294
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2295
                             bool free_device)
2296
57.1k
{
2297
57.1k
    const pdf14_device * pdev = (pdf14_device *)dev;
2298
57.1k
    pdf14_buf *buf;
2299
57.1k
    gs_int_rect rect;
2300
57.1k
    int x1,y1,width,height;
2301
2302
57.1k
    if ( pdev->ctx == NULL){
2303
0
        return 0;  /* this can occur if the pattern is a clist */
2304
0
    }
2305
#ifdef DEBUG
2306
    pdf14_debug_mask_stack_state(pdev->ctx);
2307
#endif
2308
57.1k
    buf = pdev->ctx->stack;
2309
57.1k
    rect = buf->rect;
2310
57.1k
    transbuff->buf = (free_device ? NULL : buf);
2311
57.1k
    x1 = min(pdev->width, rect.q.x);
2312
57.1k
    y1 = min(pdev->height, rect.q.y);
2313
57.1k
    width = x1 - rect.p.x;
2314
57.1k
    height = y1 - rect.p.y;
2315
2316
57.1k
    transbuff->n_chan    = buf->n_chan;
2317
57.1k
    transbuff->has_tags  = buf->has_tags;
2318
57.1k
    transbuff->has_shape = buf->has_shape;
2319
57.1k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2320
57.1k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2321
57.1k
    transbuff->deep      = buf->deep;
2322
2323
57.1k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2324
10.3k
        transbuff->planestride = 0;
2325
10.3k
        transbuff->rowstride = 0;
2326
10.3k
        return 0;
2327
10.3k
    }
2328
2329
46.8k
    if (free_device) {
2330
15.5k
        transbuff->pdev14 = NULL;
2331
15.5k
        transbuff->rect = rect;
2332
15.5k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2333
            /* If the bbox is smaller than the whole buffer than go ahead and
2334
               create a new one to use.  This can occur if we drew in a smaller
2335
               area than was specified by the transparency group rect. */
2336
0
            int rowstride = ((width + 3) & -4)<<buf->deep;
2337
0
            int planestride = rowstride * height;
2338
0
            int k, j;
2339
0
            byte *buff_ptr_src, *buff_ptr_des;
2340
2341
0
            transbuff->planestride = planestride;
2342
0
            transbuff->rowstride = rowstride;
2343
0
            transbuff->transbytes =
2344
0
                         gs_alloc_bytes(mem,
2345
0
                                        (size_t)planestride *
2346
0
                                                (buf->n_chan +
2347
0
                                                 buf->has_tags ? 1 : 0) + CAL_SLOP,
2348
0
                                        "pdf14_get_buffer_information");
2349
0
            if (transbuff->transbytes == NULL)
2350
0
                return gs_error_VMerror;
2351
2352
0
            transbuff->mem = mem;
2353
0
            if (transbuff->deep) {
2354
0
                for (j = 0; j < transbuff->n_chan; j++) {
2355
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2356
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2357
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2358
0
                    for (k = 0; k < height; k++) {
2359
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2360
0
                        buff_ptr_des += rowstride;
2361
0
                        buff_ptr_src += buf->rowstride;
2362
0
                    }
2363
0
                }
2364
0
            } else {
2365
0
                for (j = 0; j < transbuff->n_chan; j++) {
2366
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2367
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2368
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2369
0
                    for (k = 0; k < height; k++) {
2370
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2371
0
                        buff_ptr_des += rowstride;
2372
0
                        buff_ptr_src += buf->rowstride;
2373
0
                    }
2374
0
                }
2375
0
            }
2376
2377
15.5k
        } else {
2378
            /* The entire buffer is used.  Go ahead and grab the pointer and
2379
               clear the pointer in the pdf14 device data buffer so it is not
2380
               freed when we close the device */
2381
15.5k
            transbuff->planestride = buf->planestride;
2382
15.5k
            transbuff->rowstride = buf->rowstride;
2383
15.5k
            transbuff->transbytes = buf->data;
2384
15.5k
            transbuff->mem = buf->memory;
2385
15.5k
            buf->data = NULL;  /* So that the buffer is not freed */
2386
15.5k
            if (transbuff->deep) {
2387
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2388
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2389
0
                uint16_t *buff_ptr;
2390
0
                int j, k, z;
2391
0
                int rowstride = transbuff->rowstride>>1;
2392
0
                int planestride = transbuff->planestride;
2393
0
                for (j = 0; j < transbuff->n_chan; j++) {
2394
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2395
0
                    for (k = 0; k < height; k++) {
2396
0
                        for (z = 0; z < width; z++) {
2397
0
                            uint16_t in = buff_ptr[z];
2398
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2399
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2400
0
                        }
2401
0
                        buff_ptr += rowstride;
2402
0
                    }
2403
0
                }
2404
0
            }
2405
15.5k
        }
2406
#if RAW_DUMP
2407
        /* Dump the buffer that should be going into the pattern */;
2408
        dump_raw_buffer_be(buf->memory,
2409
                           height, width, transbuff->n_chan,
2410
                           transbuff->planestride, transbuff->rowstride,
2411
                           "pdf14_pattern_buff", transbuff->transbytes,
2412
                           transbuff->deep);
2413
        global_index++;
2414
#endif
2415
        /* Go ahead and free up the pdf14 device */
2416
15.5k
        dev_proc(dev, close_device)((gx_device *)dev);
2417
31.3k
    } else {
2418
        /* Here we are coming from one of the fill image / pattern / mask
2419
           operations */
2420
31.3k
        transbuff->pdev14 = dev;
2421
31.3k
        transbuff->planestride = buf->planestride;
2422
31.3k
        transbuff->rowstride = buf->rowstride;
2423
31.3k
        transbuff->transbytes = buf->data;
2424
31.3k
        transbuff->mem = buf->memory;
2425
31.3k
        transbuff->rect = rect;
2426
#if RAW_DUMP
2427
    /* Dump the buffer that should be going into the pattern */;
2428
        dump_raw_buffer(buf->memory,
2429
                        height, width, buf->n_chan,
2430
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2431
                        "pdf14_pattern_buff",
2432
                        buf->data,
2433
                        transbuff->deep);
2434
        global_index++;
2435
#endif
2436
31.3k
    }
2437
46.8k
    return 0;
2438
46.8k
}
2439
2440
typedef void(*blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2441
    int planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2442
2443
2444
static int
2445
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2446
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2447
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height)
2448
11.1k
{
2449
11.1k
    pdf14_buf* cm_result = NULL;
2450
11.1k
    cmm_profile_t* des_profile;
2451
11.1k
    gsicc_rendering_param_t render_cond;
2452
11.1k
    bool did_alloc;
2453
11.1k
    bool endian_swap;
2454
2455
11.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2456
11.1k
        &render_cond);
2457
2458
#if RAW_DUMP
2459
    dump_raw_buffer(dev->ctx->memory,
2460
        height, width, (*buf)->n_planes, (*buf)->planestride,
2461
        (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2462
    global_index++;
2463
#endif
2464
2465
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2466
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2467
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2468
       will need to know if it is dealing with native or BE data. */
2469
11.1k
    if (was_blended && (*buf)->deep) {
2470
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2471
           color conversion */
2472
#if ARCH_IS_BIG_ENDIAN
2473
        endian_swap = false;
2474
#else
2475
0
        endian_swap = true;
2476
0
#endif
2477
11.1k
    } else {
2478
        /* Data is in native format. No swap needed for CMM */
2479
11.1k
        endian_swap = false;
2480
11.1k
    }
2481
2482
11.1k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2483
11.1k
        *buf_ptr, src_profile, des_profile, x, y, width,
2484
11.1k
        height, &did_alloc, (*buf)->deep, endian_swap);
2485
2486
11.1k
    if (cm_result == NULL)
2487
0
        return_error(gs_error_VMerror);
2488
2489
    /* Update */
2490
11.1k
    *buf = cm_result;
2491
2492
    /* Make sure our buf_ptr is pointing to the proper location */
2493
11.1k
    if (did_alloc)
2494
11.1k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2495
2496
#if RAW_DUMP
2497
    dump_raw_buffer(dev->ctx->memory,
2498
        height, width, (*buf)->n_planes, (*buf)->planestride,
2499
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2500
    global_index++;
2501
#endif
2502
11.1k
    return 0;
2503
11.1k
}
2504
2505
/**
2506
 * pdf14_put_image: Put rendered image to target device.
2507
 * @pdev: The PDF 1.4 rendering device.
2508
 * @pgs: State for image draw operation.
2509
 * @target: The target device.
2510
 *
2511
 * Puts the rendered image in @pdev's buffer to @target. This is called
2512
 * as part of the sequence of popping the PDF 1.4 device filter.
2513
 *
2514
 * Return code: negative on error.
2515
 **/
2516
static  int
2517
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2518
1.43M
{
2519
1.43M
    const pdf14_device * pdev = (pdf14_device *)dev;
2520
1.43M
    int code;
2521
1.43M
    gs_image1_t image;
2522
1.43M
    gx_image_enum_common_t *info;
2523
1.43M
    pdf14_buf *buf = pdev->ctx->stack;
2524
1.43M
    gs_int_rect rect;
2525
1.43M
    int y;
2526
1.43M
    int num_comp;
2527
1.43M
    byte *linebuf, *linebuf_unaligned;
2528
1.43M
    gs_color_space *pcs;
2529
1.43M
    int x1, y1, width, height;
2530
1.43M
    byte *buf_ptr;
2531
1.43M
    int num_rows_left;
2532
1.43M
    cmm_profile_t* src_profile = NULL;
2533
1.43M
    cmm_profile_t* des_profile = NULL;
2534
1.43M
    cmm_dev_profile_t *pdf14dev_profile;
2535
1.43M
    cmm_dev_profile_t *dev_target_profile;
2536
1.43M
    uint16_t bg;
2537
1.43M
    bool has_tags = device_encodes_tags(dev);
2538
1.43M
    bool deep = pdev->ctx->deep;
2539
1.43M
    int planestride;
2540
1.43M
    int rowstride;
2541
1.43M
    blend_image_row_proc_t blend_row;
2542
1.43M
    bool color_mismatch = false;
2543
1.43M
    bool supports_alpha = false;
2544
1.43M
    int i;
2545
1.43M
    int alpha_offset, tag_offset;
2546
1.43M
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2547
1.43M
    int rendering_intent_saved;
2548
1.43M
    int additive;
2549
2550
    /* Nothing was ever drawn. */
2551
1.43M
    if (buf == NULL)
2552
144k
        return 0;
2553
2554
1.29M
    additive = buf->group_color_info->isadditive;
2555
2556
1.29M
    src_profile = buf->group_color_info->icc_profile;
2557
2558
1.29M
    num_comp = buf->n_chan - 1;
2559
1.29M
    rect = buf->rect;
2560
1.29M
    planestride = buf->planestride;
2561
1.29M
    rowstride = buf->rowstride;
2562
2563
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2564
       potential problem. Bug 694190 */
2565
1.29M
    if (buf->saved != NULL) {
2566
8
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2567
8
    }
2568
1.29M
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2569
1.29M
    rect_intersect(rect, buf->dirty);
2570
1.29M
    x1 = min(pdev->width, rect.q.x);
2571
1.29M
    y1 = min(pdev->height, rect.q.y);
2572
1.29M
    width = x1 - rect.p.x;
2573
1.29M
    height = y1 - rect.p.y;
2574
#ifdef DUMP_TO_PNG
2575
    dump_planar_rgba(pdev->memory, buf);
2576
#endif
2577
1.29M
    if (width <= 0 || height <= 0 || buf->data == NULL)
2578
249k
        return 0;
2579
1.04M
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2580
2581
    /* Check that target is OK.  From fuzzing results the target could have been
2582
       destroyed, for e.g if it were a pattern accumulator that was closed
2583
       prematurely (Bug 694154).  We should always be able to to get an ICC
2584
       profile from the target. */
2585
1.04M
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2586
1.04M
    if (code < 0)
2587
0
        return code;
2588
1.04M
    if (dev_target_profile == NULL)
2589
0
        return gs_throw_code(gs_error_Fatal);
2590
2591
1.04M
    if (src_profile == NULL) {
2592
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2593
0
        if (code < 0) {
2594
0
            return code;
2595
0
        }
2596
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2597
0
    }
2598
2599
    /* Check if we have a color conversion issue */
2600
1.04M
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2601
1.04M
    if (!gsicc_profiles_equal(des_profile, src_profile))
2602
166k
        color_mismatch = true;
2603
2604
    /* Check if target supports alpha */
2605
1.04M
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2606
1.04M
    code = 0;
2607
2608
#if RAW_DUMP
2609
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2610
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2611
        "pre_final_blend", buf_ptr, deep);
2612
#endif
2613
2614
    /* Note. The logic below will need a little rework if we ever
2615
       have a device that has tags and alpha support */
2616
1.04M
    if (supports_alpha) {
2617
0
        if (!color_mismatch) {
2618
0
            alpha_offset = num_comp;
2619
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2620
2621
0
            for (i = 0; i < buf->n_planes; i++)
2622
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2623
0
            for (; i < target->color_info.num_components; i++)
2624
0
                buf_ptrs[i] = 0;
2625
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2626
0
                rect.p.x, rect.p.y, width, height,
2627
0
                rowstride, alpha_offset,
2628
0
                tag_offset);
2629
            /* Right now code has number of rows written */
2630
0
        } else {
2631
            /* In this case, just color convert and maintain alpha.  This is a case
2632
               where we either either blend in the right color space and have no
2633
               alpha for the output device or hand back the wrong color space with
2634
               alpha data.  We choose the later. */
2635
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2636
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2637
0
                width, height);
2638
0
            if (code < 0)
2639
0
                return code;
2640
2641
            /* reset */
2642
0
            rowstride = buf->rowstride;
2643
0
            planestride = buf->planestride;
2644
0
            num_comp = buf->n_chan - 1;
2645
0
            alpha_offset = num_comp;
2646
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2647
2648
            /* And then out */
2649
0
            for (i = 0; i < buf->n_planes; i++)
2650
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2651
0
            for (; i < target->color_info.num_components; i++)
2652
0
                buf_ptrs[i] = 0;
2653
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2654
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2655
0
                tag_offset);
2656
            /* Right now code has number of rows written */
2657
0
        }
2658
1.04M
    } else if (has_tags) {
2659
        /* We are going out to a device that supports tags */
2660
0
        if (deep) {
2661
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2662
0
                buf->planestride, num_comp, additive, false);
2663
0
        } else {
2664
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2665
0
                buf->planestride, num_comp, additive);
2666
0
        }
2667
2668
#if RAW_DUMP
2669
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2670
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2671
            "post_final_blend", buf_ptr, deep);
2672
#endif
2673
2674
        /* Take care of color issues */
2675
0
        if (color_mismatch) {
2676
            /* In this case, just color convert and maintain alpha.  This is a case
2677
               where we either either blend in the right color space and have no
2678
               alpha for the output device or hand back the wrong color space with
2679
               alpha data.  We choose the later. */
2680
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2681
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
2682
0
            if (code < 0)
2683
0
                return code;
2684
2685
#if RAW_DUMP
2686
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2687
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2688
                "final_color_manage", buf_ptr, deep);
2689
            global_index++;
2690
#endif
2691
0
        }
2692
2693
        /* reset */
2694
0
        rowstride = buf->rowstride;
2695
0
        planestride = buf->planestride;
2696
0
        num_comp = buf->n_chan - 1;
2697
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2698
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2699
2700
        /* And then out */
2701
0
        for (i = 0; i < buf->n_planes; i++)
2702
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2703
0
        for (; i < target->color_info.num_components; i++)
2704
0
            buf_ptrs[i] = 0;
2705
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2706
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2707
0
            tag_offset);
2708
        /* Right now code has number of rows written */
2709
2710
0
    }
2711
2712
    /* If code > 0 then put image worked.  Let it finish and then exit */
2713
1.04M
    if (code > 0) {
2714
        /* We processed some or all of the rows.  Continue until we are done */
2715
0
        num_rows_left = height - code;
2716
0
        while (num_rows_left > 0) {
2717
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2718
0
                                                rect.p.x, rect.p.y + code, width,
2719
0
                                                num_rows_left, rowstride,
2720
0
                                                alpha_offset, tag_offset);
2721
0
            num_rows_left = num_rows_left - code;
2722
0
        }
2723
0
        return 0;
2724
0
    }
2725
2726
    /* Target device did not support alpha or tags.
2727
     * Set color space in preparation for sending an image.
2728
     * color conversion will occur after blending with through
2729
     * the begin typed image work flow.
2730
     */
2731
2732
1.04M
    planestride = buf->planestride;
2733
1.04M
    rowstride = buf->rowstride;
2734
1.04M
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2735
1.04M
    if (code < 0)
2736
0
        return code;
2737
    /* Need to set this to avoid color management during the image color render
2738
       operation.  Exception is for the special case when the destination was
2739
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2740
       image operation.  That will happen here as we should have set the profile
2741
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2742
       the case when we have a blend color space that is different than the
2743
       target device color space */
2744
1.04M
    pcs->cmm_icc_profile_data = src_profile;
2745
2746
    /* pcs takes a reference to the profile data it just retrieved. */
2747
1.04M
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2748
1.04M
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2749
1.04M
    gs_image_t_init_adjust(&image, pcs, false);
2750
1.04M
    image.ImageMatrix.xx = (float)width;
2751
1.04M
    image.ImageMatrix.yy = (float)height;
2752
1.04M
    image.Width = width;
2753
1.04M
    image.Height = height;
2754
1.04M
    image.BitsPerComponent = deep ? 16 : 8;
2755
1.04M
    image.ColorSpace = pcs;
2756
1.04M
    ctm_only_writable(pgs).xx = (float)width;
2757
1.04M
    ctm_only_writable(pgs).xy = 0;
2758
1.04M
    ctm_only_writable(pgs).yx = 0;
2759
1.04M
    ctm_only_writable(pgs).yy = (float)height;
2760
1.04M
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2761
1.04M
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2762
    /* Make sure that the relative colorimetric rendering intent is
2763
       used for this image. */
2764
1.04M
    rendering_intent_saved = pgs->renderingintent;
2765
1.04M
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2766
1.04M
    code = dev_proc(target, begin_typed_image) (target,
2767
1.04M
                                                pgs, NULL,
2768
1.04M
                                                (gs_image_common_t *)&image,
2769
1.04M
                                                NULL, NULL, NULL,
2770
1.04M
                                                pgs->memory, &info);
2771
1.04M
    pgs->renderingintent = rendering_intent_saved;
2772
1.04M
    if (code < 0) {
2773
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2774
0
        return code;
2775
0
    }
2776
#if RAW_DUMP
2777
    /* Dump the current buffer to see what we have. */
2778
    dump_raw_buffer(pdev->ctx->memory,
2779
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2780
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2781
                    pdev->ctx->stack->n_planes,
2782
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2783
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2784
    dump_raw_buffer(pdev->ctx->memory,
2785
                    height, width, buf->n_planes,
2786
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2787
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2788
    global_index++;
2789
    clist_band_count++;
2790
#endif
2791
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2792
    /* 28 byte overflow for AVX CMYK case. */
2793
1.04M
#define SSE_ALIGN 32
2794
1.04M
#define SSE_OVERFLOW 28
2795
1.04M
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2796
1.04M
    if (linebuf_unaligned == NULL)
2797
0
        return gs_error_VMerror;
2798
1.04M
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2799
2800
1.04M
    blend_row = deep ? gx_build_blended_image_row16 :
2801
1.04M
                       gx_build_blended_image_row;
2802
#ifdef WITH_CAL
2803
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2804
                                  blend_row, num_comp, deep);
2805
#endif
2806
2807
1.04M
    bg = additive ? (deep ? 65535 : 255) : 0;
2808
11.6M
    for (y = 0; y < height; y++) {
2809
10.6M
        gx_image_plane_t planes;
2810
10.6M
        int rows_used;
2811
2812
10.6M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2813
10.6M
        planes.data = linebuf;
2814
10.6M
        planes.data_x = 0;
2815
10.6M
        planes.raster = width * num_comp;
2816
10.6M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2817
        /* todo: check return value */
2818
10.6M
        buf_ptr += buf->rowstride;
2819
10.6M
    }
2820
1.04M
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2821
1.04M
    info->procs->end_image(info, true);
2822
    /* This will also decrement the device profile */
2823
1.04M
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2824
1.04M
    return code;
2825
1.04M
}
2826
2827
/* Overprint simulation with spots.  Collapse to CMYK */
2828
static void
2829
template_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride,
2830
    int planestride, int num_comp, int spot_start, int tag_offset,
2831
    cmyk_composite_map *map, bool keep_alpha)
2832
0
{
2833
0
    int comp_num;
2834
0
    uint cyan, magenta, yellow, black;
2835
0
    cmyk_composite_map *cmyk_map_entry;
2836
0
    int x, y;
2837
0
    int position;
2838
0
    byte comp, a;
2839
2840
0
    for (y = 0; y < height; y++) {
2841
0
        position = y * rowstride;
2842
0
        for (x = 0; x < width; x++) {
2843
0
            a = buf_ptr[position + planestride * num_comp];
2844
0
            if (a != 0) {
2845
0
                cyan = buf_ptr[position] * frac_1;
2846
0
                magenta = buf_ptr[position + planestride] * frac_1;
2847
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2848
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2849
0
                cmyk_map_entry = &(map[4]);
2850
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2851
0
                    comp = buf_ptr[position + planestride * comp_num];
2852
0
                    cyan += cmyk_map_entry->c * comp;
2853
0
                    magenta += cmyk_map_entry->m * comp;
2854
0
                    yellow += cmyk_map_entry->y * comp;
2855
0
                    black += cmyk_map_entry->k * comp;
2856
0
                    cmyk_map_entry++;
2857
0
                }
2858
0
                cyan /= frac_1;
2859
0
                magenta /= frac_1;
2860
0
                yellow /= frac_1;
2861
0
                black /= frac_1;
2862
2863
0
                if (cyan > 255)
2864
0
                    cyan = 255;
2865
0
                if (magenta > 255)
2866
0
                    magenta = 255;
2867
0
                if (yellow > 255)
2868
0
                    yellow = 255;
2869
0
                if (black > 255)
2870
0
                    black = 255;
2871
2872
0
                buf_ptr[position] = cyan;
2873
0
                buf_ptr[position + planestride] = magenta;
2874
0
                buf_ptr[position + planestride * 2] = yellow;
2875
0
                buf_ptr[position + planestride * 3] = black;
2876
0
            }
2877
0
            if (keep_alpha) {
2878
                /* Move the alpha and tag data */
2879
0
                buf_ptr[position + planestride * 4] = a;
2880
0
                if (tag_offset > 0) {
2881
0
                    buf_ptr[position + planestride * 5] =
2882
0
                        buf_ptr[position + planestride * tag_offset];
2883
0
                }
2884
0
            } else {
2885
                /* Remove alpha but keep tags */
2886
0
                if (tag_offset > 0) {
2887
0
                    buf_ptr[position + planestride * 4] =
2888
0
                        buf_ptr[position + planestride * tag_offset];
2889
0
                }
2890
2891
0
            }
2892
0
            position += 1;
2893
0
        }
2894
0
    }
2895
0
}
2896
2897
static void
2898
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, int rowstride,
2899
    int planestride, int num_comp, int spot_start, int tag_offset,
2900
    cmyk_composite_map *map, bool keep_alpha)
2901
0
{
2902
0
    int comp_num;
2903
0
    ulong cyan, magenta, yellow, black;
2904
0
    cmyk_composite_map *cmyk_map_entry;
2905
0
    int x, y;
2906
0
    int position;
2907
0
    ulong comp, a;
2908
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2909
2910
    /* planestride and rowstride are in bytes, and we want them in shorts */
2911
0
    planestride >>= 1;
2912
0
    rowstride >>= 1;
2913
2914
0
    for (y = 0; y < height; y++) {
2915
0
        position = y * rowstride;
2916
0
        for (x = 0; x < width; x++) {
2917
0
            a = buf_ptr[position + planestride * num_comp];
2918
0
            if (a != 0) {
2919
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2920
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2921
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2922
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2923
0
                cmyk_map_entry = &(map[4]);
2924
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2925
0
                    comp = buf_ptr[position + planestride * comp_num];
2926
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2927
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2928
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2929
0
                    black += (ulong)cmyk_map_entry->k * comp;
2930
0
                    cmyk_map_entry++;
2931
0
                }
2932
0
                cyan /= frac_1_long;
2933
0
                magenta /= frac_1_long;
2934
0
                yellow /= frac_1_long;
2935
0
                black /= frac_1_long;
2936
2937
0
                if (cyan > 65535)
2938
0
                    cyan = 65535;
2939
0
                if (magenta > 65535)
2940
0
                    magenta = 65535;
2941
0
                if (yellow > 65535)
2942
0
                    yellow = 65535;
2943
0
                if (black > 65535)
2944
0
                    black = 65535;
2945
2946
#if ARCH_IS_BIG_ENDIAN
2947
                buf_ptr[position] = cyan;
2948
                buf_ptr[position + planestride] = magenta;
2949
                buf_ptr[position + planestride * 2] = yellow;
2950
                buf_ptr[position + planestride * 3] = black;
2951
#else
2952
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2953
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2954
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2955
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2956
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2957
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2958
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2959
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2960
0
#endif
2961
0
            }
2962
            /* Move the alpha and tag data */
2963
#if ARCH_IS_BIG_ENDIAN
2964
            if (keep_alpha) {
2965
                buf_ptr[position + planestride * 4] = a;
2966
                if (tag_offset > 0) {
2967
                    buf_ptr[position + planestride * 5] =
2968
                        buf_ptr[position + planestride * tag_offset];
2969
                }
2970
            } else {
2971
                if (tag_offset > 0) {
2972
                    buf_ptr[position + planestride * 4] =
2973
                        buf_ptr[position + planestride * tag_offset];
2974
                }
2975
            }
2976
#else
2977
0
            if (keep_alpha) {
2978
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2979
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2980
0
                if (tag_offset > 0) {
2981
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2982
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2983
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2984
0
                        buf_ptr[position + planestride * tag_offset];
2985
0
                }
2986
0
            } else {
2987
0
                if (tag_offset > 0) {
2988
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2989
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2990
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2991
0
                        buf_ptr[position + planestride * tag_offset];
2992
0
                }
2993
0
            }
2994
0
#endif
2995
0
            position += 1;
2996
0
        }
2997
0
    }
2998
0
}
2999
3000
static void
3001
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, int rowstride,
3002
    int planestride, int num_comp, int spot_start, int tag_offset,
3003
    cmyk_composite_map *map, bool keep_alpha, bool deep)
3004
0
{
3005
0
    if (deep) {
3006
0
        if (keep_alpha) {
3007
0
            if (tag_offset > 0) {
3008
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3009
0
                    planestride, num_comp, spot_start, tag_offset,
3010
0
                    map, true);
3011
0
            } else {
3012
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3013
0
                    planestride, num_comp, spot_start, 0,
3014
0
                    map, true);
3015
0
            }
3016
0
        } else {
3017
0
            if (tag_offset > 0) {
3018
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3019
0
                    planestride, num_comp, spot_start, tag_offset,
3020
0
                    map, false);
3021
0
            } else {
3022
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
3023
0
                    planestride, num_comp, spot_start, 0,
3024
0
                    map, false);
3025
0
            }
3026
0
        }
3027
0
    } else {
3028
0
        if (keep_alpha) {
3029
0
            if (tag_offset > 0) {
3030
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3031
0
                    planestride, num_comp, spot_start, tag_offset,
3032
0
                    map, true);
3033
0
            } else {
3034
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3035
0
                    planestride, num_comp, spot_start, 0,
3036
0
                    map, true);
3037
0
            }
3038
0
        } else {
3039
0
            if (tag_offset > 0) {
3040
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3041
0
                    planestride, num_comp, spot_start, tag_offset,
3042
0
                    map, false);
3043
0
            } else {
3044
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3045
0
                    planestride, num_comp, spot_start, 0,
3046
0
                    map, false);
3047
0
            }
3048
0
        }
3049
0
    }
3050
0
}
3051
3052
/* This is for the case where we have mixture of spots and additive color.
3053
   For example, RGB + spots or Gray + spots */
3054
static void
3055
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, int rowstride,
3056
    int planestride, int num_comp, int spot_start)
3057
11.1k
{
3058
11.1k
    int x, y;
3059
11.1k
    int position;
3060
11.1k
    byte comp, a;
3061
11.1k
    int tmp, comp_num;
3062
3063
120k
    for (y = 0; y < height; y++) {
3064
109k
        position = y * rowstride;
3065
117M
        for (x = 0; x < width; x++) {
3066
117M
            a = buf_ptr[position + planestride * num_comp];
3067
117M
            if ((a + 1) & 0xfe) {
3068
6.10M
                a ^= 0xff;
3069
24.4M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3070
18.3M
                    comp = buf_ptr[position + planestride * comp_num];
3071
18.3M
                    tmp = ((0xff - comp) * a) + 0x80;
3072
18.3M
                    comp += (tmp + (tmp >> 8)) >> 8;
3073
18.3M
                    buf_ptr[position + planestride * comp_num] = comp;
3074
18.3M
                }
3075
6.10M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3076
0
                    comp = buf_ptr[position + planestride * comp_num];
3077
0
                    tmp = ((-comp) * a) + 0x80;
3078
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3079
0
                    buf_ptr[position + planestride * comp_num] = comp;
3080
0
                }
3081
110M
            } else if (a == 0) {
3082
56.6M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3083
42.4M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3084
42.4M
                }
3085
14.2M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3086
50.8k
                    buf_ptr[position + planestride * comp_num] = 0;
3087
50.8k
                }
3088
14.1M
            }
3089
117M
            position += 1;
3090
117M
        }
3091
109k
    }
3092
11.1k
}
3093
3094
static void
3095
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, int rowstride,
3096
    int planestride, int num_comp, int spot_start)
3097
0
{
3098
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3099
0
    int x, y;
3100
0
    int position;
3101
0
    int comp, a;
3102
0
    int tmp, comp_num;
3103
3104
    /* planestride and rowstride are in bytes, and we want them in shorts */
3105
0
    planestride >>= 1;
3106
0
    rowstride >>= 1;
3107
3108
    /* Note that the input here is native endian, and the output must be in big endian! */
3109
0
    for (y = 0; y < height; y++) {
3110
0
        position = y * rowstride;
3111
0
        for (x = 0; x < width; x++) {
3112
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3113
0
            a = buf_ptr[position + planestride * num_comp];
3114
0
            if (a == 0) {
3115
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3116
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3117
0
                }
3118
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3119
0
                    buf_ptr[position + planestride * comp_num] = 0;
3120
0
                }
3121
0
            } else if (a == 0xffff) {
3122
#if ARCH_IS_BIG_ENDIAN
3123
#else
3124
                /* Convert from native -> big endian */
3125
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3126
0
                    comp = buf_ptr[position + planestride * comp_num];
3127
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3128
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3129
0
                }
3130
0
#endif
3131
0
            } else {
3132
0
                a ^= 0xffff;
3133
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3134
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3135
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3136
0
                    comp = buf_ptr[position + planestride * comp_num];
3137
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3138
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3139
                    /* Store as big endian */
3140
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3141
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3142
0
                }
3143
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3144
0
                    comp = buf_ptr[position + planestride * comp_num];
3145
0
                    tmp = ((0 - comp) * a) + 0x4000;
3146
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3147
                    /* Store as big endian */
3148
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3149
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3150
0
                }
3151
0
            }
3152
0
            position += 1;
3153
0
        }
3154
0
    }
3155
0
}
3156
3157
static int
3158
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3159
    gs_gstate* pgs, pdf14_buf* buf, int planestride_in,
3160
    int rowstride_in, int x0, int y0, int width, int height,
3161
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3162
    gs_separations* pseparations, bool deep)
3163
46.5k
{
3164
46.5k
    pdf14_device* pdev = (pdf14_device*)dev;
3165
46.5k
    int code = 0;
3166
46.5k
    int y;
3167
46.5k
    int num_rows_left;
3168
46.5k
    int i;
3169
46.5k
    gs_int_rect rect = rect_in;
3170
46.5k
    int planestride = planestride_in;
3171
46.5k
    int rowstride = rowstride_in;
3172
46.5k
    byte* buf_ptr = NULL;
3173
46.5k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3174
46.5k
    cmm_profile_t* des_profile = NULL;
3175
46.5k
    cmm_dev_profile_t* dev_target_profile;
3176
46.5k
    cmm_dev_profile_t* pdf14dev_profile;
3177
46.5k
    bool color_mismatch = false;
3178
46.5k
    bool supports_alpha = false;
3179
46.5k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3180
46.5k
    int alpha_offset = num_comp;
3181
46.5k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3182
46.5k
    gs_color_space *pcs;
3183
46.5k
    gs_image1_t image;
3184
46.5k
    gx_image_enum_common_t *info;
3185
46.5k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3186
46.5k
    pdf14_buf *cm_result = NULL;
3187
46.5k
    bool did_alloc;
3188
46.5k
    bool target_sep_device = dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0);
3189
46.5k
    bool has_spots = pdev->ctx->num_spots > 0;
3190
46.5k
    bool blend_spots = !target_sep_device && has_spots;
3191
3192
    /* Check if group color space is CMYK based */
3193
46.5k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3194
46.5k
    if (code < 0)
3195
0
        return code;
3196
46.5k
    if (dev_target_profile == NULL)
3197
0
        return gs_throw_code(gs_error_Fatal);
3198
3199
46.5k
    if (src_profile == NULL) {
3200
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3201
0
        if (code < 0) {
3202
0
            return code;
3203
0
        }
3204
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3205
0
    }
3206
3207
    /* If the target device does not support spot colors and we have spot colors
3208
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3209
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3210
46.5k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3211
3212
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3213
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3214
0
            buf->rect.q.y, &did_alloc, buf->deep, false);
3215
0
        if (cm_result == NULL)
3216
0
            return_error(gs_error_VMerror);
3217
3218
        /* Update */
3219
0
        buf = cm_result;
3220
0
        src_profile = pgs->icc_manager->default_cmyk;
3221
0
        num_comp = buf->n_chan - 1;
3222
0
        additive = 0;
3223
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3224
0
        alpha_offset = num_comp;
3225
3226
#if RAW_DUMP
3227
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3228
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3229
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3230
        global_index++;
3231
#endif
3232
0
    }
3233
3234
    /* Fix order map if needed */
3235
221k
    for (i = 0; i < num_comp; i++) {
3236
175k
        pdev->devn_params.separation_order_map[i] = i;
3237
175k
    }
3238
3239
    /* Check if we have a color conversion issue */
3240
46.5k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3241
46.5k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3242
11.1k
        color_mismatch = true;
3243
3244
    /* Check if target supports alpha */
3245
46.5k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
3246
46.5k
    code = 0;
3247
3248
46.5k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3249
3250
    /* Note. The logic below will need a little rework if we ever
3251
       have a device that has tags and alpha support */
3252
46.5k
    if (supports_alpha) {
3253
3254
        /* If doing simulated overprint, Bring the spot color channels into
3255
           CMYK. Data is planar and 16 bit data in native format. */
3256
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3257
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3258
3259
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3260
0
            if (pdev->pclist_device != NULL) {
3261
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3262
3263
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3264
0
                if (code < 0)
3265
0
                    return code;
3266
0
            }
3267
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3268
3269
            /* Now we go to big endian */
3270
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3271
0
                planestride, num_comp, src_profile->num_comps,
3272
0
                tag_offset, cmyk_map, true, deep);
3273
3274
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3275
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3276
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3277
0
            buf->num_spots = 0;
3278
0
            num_comp = buf->n_chan - 1;
3279
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3280
0
        }
3281
3282
0
        if (!color_mismatch) {
3283
0
            for (i = 0; i < buf->n_planes; i++)
3284
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3285
0
            for (; i < target->color_info.num_components; i++)
3286
0
                buf_ptrs[i] = 0;
3287
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3288
0
                rect.p.x, rect.p.y, width, height,
3289
0
                rowstride, alpha_offset, tag_offset);
3290
            /* Right now code has number of rows written */
3291
0
        } else {
3292
            /* In this case, just color convert and maintain alpha.
3293
               This is a case where we either either blend in the
3294
               right color space and have no alpha for the output
3295
               device or hand back the wrong color space with
3296
               alpha data.  We choose the later. */
3297
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3298
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3299
0
                        rect.p.y, width, height);
3300
0
            if (code < 0)
3301
0
                return code;
3302
3303
            /* reset */
3304
0
            rowstride = buf->rowstride;
3305
0
            planestride = buf->planestride;
3306
0
            num_comp = buf->n_chan - 1;
3307
0
            alpha_offset = num_comp;
3308
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3309
3310
            /* And then out */
3311
0
            for (i = 0; i < buf->n_planes; i++)
3312
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3313
0
            for (; i < target->color_info.num_components; i++)
3314
0
                buf_ptrs[i] = 0;
3315
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3316
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3317
0
                tag_offset);
3318
            /* Right now code has number of rows written.  Writing continues below */
3319
0
        }
3320
46.5k
    } else {
3321
        /* Device could not handle the alpha data (we actually don't have
3322
           a device that does spot colorants and has an alpha channel so
3323
           the above code is untested.  Go ahead and preblend now and then
3324
           color convert if needed */
3325
#if RAW_DUMP
3326
           /* Dump before and after the blend to make sure we are doing that ok */
3327
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3328
            "pre_put_image_blend_image", buf_ptr, deep);
3329
        global_index++;
3330
#endif
3331
3332
46.5k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3333
11.1k
            if (deep) {
3334
            /* In this case, we are NOT going to bring the spots into the CMYK
3335
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3336
               16 bit data will be converted now from native endian to big endian during
3337
               the blending process */
3338
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3339
0
                    planestride, num_comp, src_profile->num_comps);
3340
11.1k
            } else {
3341
11.1k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3342
11.1k
                    planestride, num_comp, src_profile->num_comps);
3343
11.1k
            }
3344
35.4k
        } else {
3345
35.4k
            if (deep) {
3346
            /* In this case, if blend_spots == true, we will shortly be bringing
3347
               the spot colors to CMYK equivalent colors. It is at that time that
3348
               we will convert from native endian to big endian. In all other
3349
               cases this blending will due to conversion from native to BE */
3350
0
                bool keep_native = (blend_spots == true);
3351
3352
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3353
0
                    planestride, num_comp, additive, keep_native);
3354
35.4k
            } else {
3355
35.4k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3356
35.4k
                    planestride, num_comp, additive);
3357
35.4k
            }
3358
35.4k
        }
3359
3360
46.5k
        if (deep && has_tags)
3361
0
        {
3362
            /* We still need to convert the tags from Native to BE */
3363
#if ARCH_IS_BIG_ENDIAN
3364
#else
3365
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3366
0
            int i, j;
3367
0
            for (j = 0; j < height; j++)
3368
0
            {
3369
0
                for (i = 0; i < width; i++)
3370
0
                {
3371
0
                    uint16_t tag = *tags++;
3372
0
                    ((byte *)tags)[-2] = tag >> 8;
3373
0
                    ((byte *)tags)[-1] = tag;
3374
0
                }
3375
0
                tags += (buf->rowstride>>1) - width;
3376
0
            }
3377
0
#endif
3378
0
        }
3379
3380
#if RAW_DUMP
3381
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3382
            "post_put_image_blend_image", buf_ptr, deep);
3383
        global_index++;
3384
#endif
3385
3386
        /* If doing simulated overprint and we are not going to a sep device and
3387
           we have spot colors, then bring the spot color channels into CMYK
3388
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3389
           At this point, data is planar and 16 bit data is still in native format. It is
3390
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3391
           above during the alpha blend operation. */
3392
46.5k
        if (blend_spots) {
3393
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3394
3395
            /* In the clist case, we need to get equiv spots out of the
3396
               pseudo-band. */
3397
0
            if (pdev->pclist_device != NULL) {
3398
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3399
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3400
0
                if (code < 0)
3401
0
                    return code;
3402
0
            }
3403
3404
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3405
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3406
0
                planestride, num_comp, src_profile->num_comps,
3407
0
                tag_offset, cmyk_map, false, deep);
3408
3409
            /* Reset buffer information. We have CMYK and maybe tags */
3410
0
            num_comp = 4;
3411
0
            alpha_offset = 0;
3412
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3413
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3414
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3415
0
            buf->num_spots = 0;
3416
3417
#if RAW_DUMP
3418
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3419
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3420
            global_index++;
3421
#endif
3422
0
        }
3423
3424
        /* Map to the destination color space */
3425
46.5k
        if (color_mismatch) {
3426
11.1k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3427
11.1k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height);
3428
11.1k
            if (code < 0)
3429
0
                return code;
3430
3431
            /* reset */
3432
11.1k
            rowstride = buf->rowstride;
3433
11.1k
            planestride = buf->planestride;
3434
11.1k
            num_comp = buf->n_chan;
3435
11.1k
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3436
11.1k
        }
3437
3438
#if RAW_DUMP
3439
        /* Dump after the CS transform */
3440
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3441
            "post_put_image_color_convert", buf_ptr, deep);
3442
        global_index++;
3443
        /* clist_band_count++; */
3444
#endif
3445
3446
        /* Try put_image again. This can occur if the
3447
           target, like psdcmyk and tiffsep, support put_image */
3448
46.5k
        alpha_offset = 0;
3449
279k
        for (i = 0; i < buf->n_planes; i++)
3450
233k
            buf_ptrs[i] = buf_ptr + i * planestride;
3451
46.5k
        for (; i < target->color_info.num_components; i++)
3452
0
            buf_ptrs[i] = 0;
3453
46.5k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3454
46.5k
            rect.p.x, rect.p.y, width, height,
3455
46.5k
            rowstride, alpha_offset, tag_offset);
3456
46.5k
    }
3457
3458
    /* Put image was succesful.  We processed some or all of the rows.
3459
       Continue until we are done */
3460
46.5k
    if (code > 0) {
3461
93
        num_rows_left = height - code;
3462
93
        while (num_rows_left > 0) {
3463
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3464
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3465
0
                alpha_offset, tag_offset);
3466
0
            if (code < 0) {
3467
0
                return code;
3468
0
            }
3469
0
            num_rows_left = num_rows_left - code;
3470
0
        }
3471
93
        return 0;
3472
93
    }
3473
3474
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3475
       as well as those devices that support alpha (pngalpha,
3476
       png16malpha). If we are here, then we are doing an
3477
       overprint simulation on some other device. Image data
3478
       is aleady blended and in device color space. */
3479
46.4k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3480
46.4k
    if (code < 0)
3481
0
        return code;
3482
3483
    /* Already in destination CS */
3484
46.4k
    pcs->cmm_icc_profile_data = des_profile;
3485
3486
    /* pcs takes a reference to the profile data it just retrieved. */
3487
46.4k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3488
46.4k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3489
3490
    /* If we have more components to write out than are in the des_profile,
3491
     * then just using a PCS based on des_profile, will result in us dropping
3492
     * the spot colors.
3493
     * So, if our target supports devn colors, we instead construct a
3494
     * DevN device space with colors names taken from the devn_params, and
3495
     * use that instead. */
3496
46.4k
    if (des_profile->num_comps != target->color_info.num_components &&
3497
46.4k
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0))
3498
29
    {
3499
29
        int num_std;
3500
29
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3501
29
        gs_color_space *pcs2 = pcs;
3502
29
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3503
29
                                     pcs2, pgs->memory->non_gc_memory);
3504
29
        if (code < 0)
3505
0
            return code;
3506
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3507
29
        pcs->params.device_n.use_alt_cspace = false;
3508
29
        num_std = devn_params->num_std_colorant_names;
3509
145
        for (i = 0; i < num_std; i++) {
3510
116
            const char *name = devn_params->std_colorant_names[i];
3511
116
            size_t len = strlen(name);
3512
116
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3513
116
            if (pcs->params.device_n.names[i] == NULL) {
3514
0
                int j = 0;
3515
0
                for (j = 0;j < i; j++) {
3516
0
                    if (pcs->params.device_n.names[j] != NULL)
3517
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3518
0
                    pcs->params.device_n.names[j] = NULL;
3519
0
                }
3520
0
                return_error(gs_error_VMerror);
3521
0
            }
3522
116
            strcpy(pcs->params.device_n.names[i], name);
3523
116
        }
3524
29
        for (; i < devn_params->separations.num_separations; i++) {
3525
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3526
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");
3527
0
            if (pcs->params.device_n.names[i] == NULL) {
3528
0
                int j = 0;
3529
0
                for (j = 0;j < i; j++) {
3530
0
                    if (pcs->params.device_n.names[j] != NULL)
3531
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3532
0
                    pcs->params.device_n.names[j] = NULL;
3533
0
                }
3534
0
                return_error(gs_error_VMerror);
3535
0
            }
3536
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3537
0
            pcs->params.device_n.names[i][name->size] = 0;
3538
0
        }
3539
29
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3540
0
            return code;
3541
0
        }
3542
        /* One last thing -- we need to fudge the pgs->color_component_map */
3543
174
        for (i=0; i < dev->color_info.num_components; i++)
3544
145
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3545
29
    }
3546
3547
46.4k
    gs_image_t_init_adjust(&image, pcs, false);
3548
46.4k
    image.ImageMatrix.xx = (float)width;
3549
46.4k
    image.ImageMatrix.yy = (float)height;
3550
46.4k
    image.Width = width;
3551
46.4k
    image.Height = height;
3552
46.4k
    image.BitsPerComponent = deep ? 16 : 8;
3553
46.4k
    image.ColorSpace = pcs;
3554
46.4k
    image.format = gs_image_format_component_planar;
3555
3556
46.4k
    ctm_only_writable(pgs).xx = (float)width;
3557
46.4k
    ctm_only_writable(pgs).xy = 0;
3558
46.4k
    ctm_only_writable(pgs).yx = 0;
3559
46.4k
    ctm_only_writable(pgs).yy = (float)height;
3560
46.4k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3561
46.4k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3562
46.4k
    code = dev_proc(target, begin_typed_image) (target,
3563
46.4k
        pgs, NULL, (gs_image_common_t *)&image,
3564
46.4k
        NULL, NULL, NULL, pgs->memory, &info);
3565
46.4k
    if (code < 0) {
3566
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3567
0
        return code;
3568
0
    }
3569
#if RAW_DUMP
3570
    /* Dump the current buffer to see what we have. */
3571
    dump_raw_buffer(pdev->ctx->memory,
3572
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3573
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3574
        pdev->ctx->stack->n_planes,
3575
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3576
        "put_image_final_big", pdev->ctx->stack->data, deep);
3577
    dump_raw_buffer(pdev->ctx->memory,
3578
        height, width, buf->n_planes,
3579
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3580
        "put_image_final_small", buf_ptr, deep);
3581
    global_index++;
3582
    clist_band_count++;
3583
#endif
3584
3585
243k
    for (i = 0; i < num_comp; i++) {
3586
197k
        planes[i].data = buf_ptr + i * planestride;
3587
197k
        planes[i].data_x = 0;
3588
197k
        planes[i].raster = buf->rowstride;
3589
197k
    }
3590
3591
516k
    for (y = 0; y < height; y++) {
3592
470k
        int rows_used;
3593
3594
470k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3595
3596
2.46M
        for (i = 0; i < num_comp; i++) {
3597
1.99M
            planes[i].data += buf->rowstride;
3598
1.99M
        }
3599
470k
    }
3600
46.4k
    info->procs->end_image(info, true);
3601
3602
    /* This will also decrement the profile */
3603
46.4k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3604
46.4k
    return code;
3605
46.4k
}
3606
3607
/**
3608
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3609
 * @pdev: The PDF 1.4 rendering device.
3610
 * @pgs: State for image draw operation.
3611
 * @target: The target device.
3612
 *
3613
 * Puts the rendered image in @pdev's buffer to @target. This is called
3614
 * as part of the sequence of popping the PDF 1.4 device filter.
3615
 *
3616
 * Return code: negative on error.
3617
 **/
3618
static  int
3619
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3620
99.1k
{
3621
99.1k
    pdf14_device *pdev = (pdf14_device *)dev;
3622
99.1k
    pdf14_buf *buf = pdev->ctx->stack;
3623
99.1k
    gs_int_rect rect;
3624
99.1k
    int x1, y1, width, height;
3625
99.1k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3626
99.1k
    gs_separations *pseparations = &pdevn_params->separations;
3627
99.1k
    int planestride;
3628
99.1k
    int rowstride;
3629
99.1k
    bool deep = pdev->ctx->deep;
3630
99.1k
    int num_comp;
3631
3632
    /* Nothing was ever drawn. */
3633
99.1k
    if (buf == NULL)
3634
34.0k
        return 0;
3635
3636
65.0k
    num_comp = buf->n_chan - 1;
3637
65.0k
    rect = buf->rect;
3638
65.0k
    planestride = buf->planestride;
3639
65.0k
    rowstride = buf->rowstride;
3640
3641
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3642
       potential problem. Bug 694190 */
3643
65.0k
    if (buf->saved != NULL) {
3644
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3645
0
    }
3646
65.0k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3647
65.0k
    rect_intersect(rect, buf->dirty);
3648
65.0k
    x1 = min(pdev->width, rect.q.x);
3649
65.0k
    y1 = min(pdev->height, rect.q.y);
3650
65.0k
    width = x1 - rect.p.x;
3651
65.0k
    height = y1 - rect.p.y;
3652
65.0k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3653
18.5k
        return 0;
3654
3655
#if RAW_DUMP
3656
    /* Dump the current buffer to see what we have. */
3657
    dump_raw_buffer(pdev->ctx->memory,
3658
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3659
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3660
                    pdev->ctx->stack->n_planes,
3661
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3662
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3663
                    pdev->ctx->stack->deep);
3664
3665
    global_index++;
3666
    clist_band_count++;
3667
#endif
3668
3669
46.5k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3670
46.5k
                      buf, planestride, rowstride,
3671
46.5k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3672
46.5k
                      buf->has_tags, rect, pseparations, deep);
3673
65.0k
}
3674
3675
/**
3676
 * pdf14_custom_put_image: Put rendered image to target device.
3677
 * @pdev: The PDF 1.4 rendering device.
3678
 * @pgs: State for image draw operation.
3679
 * @target: The target device.
3680
 *
3681
 * Puts the rendered image in @pdev's buffer to @target. This is called
3682
 * as part of the sequence of popping the PDF 1.4 device filter.
3683
 *
3684
 * Return code: negative on error.
3685
 **/
3686
static  int
3687
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3688
0
{
3689
0
    pdf14_device * pdev = (pdf14_device *)dev;
3690
0
    pdf14_buf *buf = pdev->ctx->stack;
3691
0
    bool deep = pdev->ctx->deep;
3692
0
    gs_int_rect rect;
3693
0
    int x0, y0;
3694
0
    int planestride;
3695
0
    int rowstride;
3696
0
    int num_comp;
3697
0
    uint16_t bg;
3698
0
    int x1, y1, width, height;
3699
0
    byte *buf_ptr;
3700
3701
    /* Nothing was ever drawn. */
3702
0
    if (buf == NULL)
3703
0
        return 0;
3704
3705
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3706
0
    num_comp = buf->n_chan - 1;
3707
0
    rect = buf->rect;
3708
0
    x0 = rect.p.x;
3709
0
    y0 = rect.p.y;
3710
0
    planestride = buf->planestride;
3711
0
    rowstride = buf->rowstride;
3712
3713
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3714
       potential problem. Bug 694190 */
3715
0
    if (buf->saved != NULL) {
3716
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3717
0
    }
3718
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3719
0
    rect_intersect(rect, buf->dirty);
3720
0
    x1 = min(pdev->width, rect.q.x);
3721
0
    y1 = min(pdev->height, rect.q.y);
3722
0
    width = x1 - rect.p.x;
3723
0
    height = y1 - rect.p.y;
3724
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3725
0
        return 0;
3726
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3727
3728
0
    return gx_put_blended_image_custom(target, buf_ptr,
3729
0
                      planestride, rowstride,
3730
0
                      x0, y0, width, height, num_comp, bg, deep);
3731
0
}
3732
3733
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3734
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3735
 * putting everything back how it was, and cleaning up the reference counts.
3736
 */
3737
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3738
3.15M
{
3739
3.15M
    if (pdev->ctx && pdev->ctx->stack) {
3740
1.37M
        pdf14_buf *buf, *next;
3741
3742
1.37M
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3743
8
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3744
8
            next = buf->saved;
3745
16
            while (group_color_info) {
3746
8
               if (group_color_info->icc_profile != NULL) {
3747
8
                   cmm_profile_t *group_profile;
3748
8
                   gsicc_rendering_param_t render_cond;
3749
8
                   cmm_dev_profile_t *dev_profile;
3750
8
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3751
3752
8
                   if (code >= 0) {
3753
8
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3754
8
                                             &render_cond);
3755
3756
8
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3757
8
                                               -1, "pdf14_end_transparency_group");
3758
8
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3759
8
                           group_color_info->icc_profile;
3760
8
                       group_color_info->icc_profile = NULL;
3761
8
                   }
3762
8
               }
3763
3764
8
               group_color_info = group_color_info->previous;
3765
8
            }
3766
8
        }
3767
1.37M
    }
3768
3.15M
}
3769
3770
static  int
3771
pdf14_close(gx_device *dev)
3772
1.57M
{
3773
1.57M
    pdf14_device *pdev = (pdf14_device *)dev;
3774
3775
1.57M
    pdf14_cleanup_group_color_profiles(pdev);
3776
3777
1.57M
    if (pdev->ctx) {
3778
1.56M
        pdf14_ctx_free(pdev->ctx);
3779
1.56M
        pdev->ctx = NULL;
3780
1.56M
    }
3781
1.57M
    return 0;
3782
1.57M
}
3783
3784
/* This is called when something has gone wrong and the interpreter received a
3785
   stop while in the middle of doing something with the PDF14 device.  We need
3786
   to clean up and end this in a graceful manner */
3787
static int
3788
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3789
0
{
3790
0
    pdf14_device *pdev = (pdf14_device *)dev;
3791
    /* The things that need to be cleaned up */
3792
0
    pdf14_ctx *ctx = pdev->ctx;
3793
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3794
0
    pdf14_group_color_t *group_color = pdev->color_model_stack;
3795
3796
    /* Free up the smask color */
3797
0
    if (smaskcolor != NULL) {
3798
0
        smaskcolor->ref_count = 1;
3799
0
        pdf14_decrement_smask_color(pgs, dev);
3800
0
        pdev->smaskcolor = NULL;
3801
0
    }
3802
3803
    /* Free up the nested color procs and decrement the profiles */
3804
0
    if (group_color != NULL) {
3805
0
        while (group_color->previous != NULL)
3806
0
            pdf14_pop_group_color(dev, pgs);
3807
0
        gs_free_object(dev->memory->stable_memory, group_color, "pdf14_discard_trans_layer");
3808
0
        pdev->color_model_stack = NULL;
3809
0
    }
3810
3811
    /* Start the context clean up */
3812
0
    if (ctx != NULL) {
3813
0
        pdf14_buf *buf, *next;
3814
0
        pdf14_group_color_t *procs, *prev_procs;
3815
3816
0
        if (ctx->mask_stack != NULL) {
3817
0
            pdf14_free_mask_stack(ctx, ctx->memory);
3818
0
        }
3819
3820
        /* Now the stack of buffers */
3821
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3822
0
            next = buf->saved;
3823
3824
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3825
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3826
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3827
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3828
            /* During the soft mask push, the mask_stack was copied (not moved) from
3829
               the ctx to the tos mask_stack. We are done with this now so it is safe
3830
               to free this one object */
3831
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3832
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3833
0
                prev_procs = procs->previous;
3834
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3835
0
            }
3836
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3837
0
        }
3838
        /* Finally the context itself */
3839
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3840
0
        pdev->ctx = NULL;
3841
0
    }
3842
0
    return 0;
3843
0
}
3844
3845
static  int
3846
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3847
0
{
3848
0
    pdf14_device * pdev = (pdf14_device *)dev;
3849
3850
0
    if (pdev->target != NULL)
3851
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3852
0
    return 0;
3853
0
}
3854
3855
12.6M
#define COPY_PARAM(p) dev->p = target->p
3856
7.89M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3857
3858
static void
3859
copy_tag_setup(gx_device *dev, const gx_device *target)
3860
1.57M
{
3861
1.57M
    bool deep = device_is_deep(target);
3862
1.57M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3863
1.57M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3864
1.57M
    COPY_PARAM(graphics_type_tag);
3865
1.57M
    if (had_tags && !has_tags)
3866
0
    {
3867
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3868
0
        dev->color_info.num_components--;
3869
0
        dev->color_info.depth -= deep ? 16 : 8;
3870
0
    }
3871
1.57M
    else if (!had_tags && has_tags)
3872
0
    {
3873
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3874
0
        dev->color_info.num_components++;
3875
0
        dev->color_info.depth += deep ? 16 : 8;
3876
0
    }
3877
1.57M
}
3878
3879
/*
3880
 * Copy device parameters back from a target.  This copies all standard
3881
 * parameters related to page size and resolution, but not any of the
3882
 * color-related parameters, as the pdf14 device retains its own color
3883
 * handling. This routine is parallel to gx_device_copy_params().
3884
 * Note that it DOES copy the devn_params since these are required to
3885
 * keep agreement with colorant name->number mapping, and don't change
3886
 * with the pdf14 color handling.
3887
 */
3888
static  int
3889
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3890
1.57M
{
3891
1.57M
    cmm_dev_profile_t *profile_targ;
3892
1.57M
    cmm_dev_profile_t *profile_dev14;
3893
1.57M
    pdf14_device *pdev = (pdf14_device*) dev;
3894
1.57M
    cmm_profile_t *blend_profile = NULL;
3895
1.57M
    int k;
3896
3897
1.57M
    COPY_PARAM(width);
3898
1.57M
    COPY_PARAM(height);
3899
1.57M
    COPY_ARRAY_PARAM(MediaSize);
3900
1.57M
    COPY_ARRAY_PARAM(ImagingBBox);
3901
1.57M
    COPY_PARAM(ImagingBBox_set);
3902
1.57M
    COPY_ARRAY_PARAM(HWResolution);
3903
1.57M
    COPY_ARRAY_PARAM(Margins);
3904
1.57M
    COPY_ARRAY_PARAM(HWMargins);
3905
1.57M
    COPY_PARAM(PageCount);
3906
1.57M
    COPY_PARAM(MaxPatternBitmap);
3907
3908
3909
    /* Supposedly this function isn't supposed to change the color setup of dev.
3910
     * BUT... if we change the tags value, we have to change the color setup to
3911
     * keep it valid. This is because num_components and depth include tags. */
3912
1.57M
    copy_tag_setup(dev, target);
3913
1.57M
    COPY_PARAM(interpolate_control);
3914
1.57M
    COPY_PARAM(non_strict_bounds);
3915
1.57M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3916
3917
1.57M
    if (dev->icc_struct == NULL) {
3918
1.57M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3919
1.57M
        if (dev->icc_struct == NULL)
3920
0
            return_error(gs_error_VMerror);
3921
1.57M
        profile_dev14 = dev->icc_struct;
3922
1.57M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3923
1.57M
                                          &(profile_targ));
3924
3925
7.89M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3926
6.31M
            if (profile_targ->device_profile[k] != NULL) {
3927
1.57M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3928
1.57M
            }
3929
6.31M
            if (profile_dev14->device_profile[k] != NULL) {
3930
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3931
0
            }
3932
6.31M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3933
6.31M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3934
6.31M
        }
3935
3936
1.57M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3937
1.57M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3938
1.57M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3939
1.57M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3940
1.57M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3941
1.57M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3942
1.57M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3943
1.57M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3944
1.57M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3945
3946
1.57M
        switch (pdev->blend_cs_state) {
3947
1.57M
            case PDF14_BLEND_CS_UNSPECIFIED:
3948
1.57M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3949
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3950
                   during the device push, when we have
3951
                   access to the pgs */
3952
1.57M
                break;
3953
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3954
0
                blend_profile = profile_targ->oi_profile;
3955
0
                break;
3956
0
            case PDF14_BLEND_CS_SPECIFIED:
3957
0
                blend_profile = profile_targ->blend_profile;
3958
0
                break;
3959
0
            default:
3960
0
                break;
3961
1.57M
        }
3962
3963
1.57M
        if (blend_profile != NULL) {
3964
            /* Set the device profile to the blend profile. Note only default profile is set */
3965
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3966
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3967
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3968
0
        }
3969
3970
1.57M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3971
1.57M
    }
3972
1.57M
#undef COPY_ARRAY_PARAM
3973
1.57M
#undef COPY_PARAM
3974
1.57M
    return 0;
3975
1.57M
}
3976
3977
/*
3978
 * This is a forwarding version of the put_params device proc.  It is only
3979
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3980
 * check if the target device has closed and, if so, close itself.  The routine
3981
 * also sync the device parameters.
3982
 */
3983
static  int
3984
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3985
0
{
3986
0
    pdf14_device * pdev = (pdf14_device *)dev;
3987
0
    gx_device * tdev = pdev->target;
3988
0
    bool was_open = tdev->is_open;
3989
0
    int code = 0;
3990
3991
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3992
0
        gx_device_decache_colors(dev);
3993
0
        if (!tdev->is_open) {
3994
0
            code = gs_closedevice(dev);
3995
0
            if (code == 0)
3996
0
                code = was_open ? 1 : 0;   /* target device closed */
3997
0
        }
3998
0
        gx_device_copy_params(dev, tdev);
3999
0
    }
4000
0
    return code;
4001
0
}
4002
4003
/* Function prototypes */
4004
int put_param_pdf14_spot_names(gx_device * pdev,
4005
                gs_separations * pseparations, gs_param_list * plist);
4006
55.1k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
4007
4008
/*
4009
 * The put_params method for the PDF 1.4 device will check if the
4010
 * target device has closed and, if so, close itself.  Note:  This routine is
4011
 * currently being used by both the pdf14_clist_device and the pdf_device.
4012
 * Please make sure that any changes are either applicable to both devices
4013
 * or clone the routine for each device.
4014
 */
4015
static  int
4016
pdf14_put_params(gx_device * dev, gs_param_list * plist)
4017
0
{
4018
0
    pdf14_device * pdev = (pdf14_device *)dev;
4019
0
    gx_device * tdev = pdev->target;
4020
0
    bool was_open = tdev->is_open;
4021
0
    int code = 0, code2 = 0;
4022
4023
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4024
0
        gx_device_decache_colors(dev);
4025
0
        if (!tdev->is_open) {
4026
0
            code = gs_closedevice(dev);
4027
0
            if (code == 0)
4028
0
                code = was_open ? 1 : 0;   /* target device closed */
4029
0
        }
4030
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4031
0
        if (code2 < 0)
4032
0
            code = code2;
4033
0
    }
4034
0
    return code;
4035
0
}
4036
4037
/*
4038
 * Copy marking related parameters into the PDF 1.4 device structure for use
4039
 * by pdf14_fill_rectangle.
4040
 */
4041
static  void
4042
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4043
49.8M
{
4044
49.8M
    pdf14_device * pdev = (pdf14_device *)dev;
4045
4046
49.8M
    if (pgs->alphaisshape) {
4047
897k
        pdev->opacity = 1.0;
4048
897k
        if (pgs->is_fill_color) {
4049
853k
            pdev->shape = pgs->fillconstantalpha;
4050
853k
        } else {
4051
43.7k
            pdev->shape = pgs->strokeconstantalpha;
4052
43.7k
        }
4053
48.9M
    } else {
4054
48.9M
        pdev->shape = 1.0;
4055
48.9M
        if (pgs->is_fill_color) {
4056
20.5M
            pdev->opacity = pgs->fillconstantalpha;
4057
28.4M
        } else {
4058
28.4M
            pdev->opacity = pgs->strokeconstantalpha;
4059
28.4M
        }
4060
48.9M
    }
4061
49.8M
    pdev->alpha = pdev->opacity * pdev->shape;
4062
49.8M
    pdev->blend_mode = pgs->blend_mode;
4063
49.8M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4064
49.8M
        pdev->overprint = pgs->overprint;
4065
49.8M
        pdev->stroke_overprint = pgs->stroke_overprint;
4066
49.8M
    } else {
4067
0
        pdev->overprint = false;
4068
0
        pdev->stroke_overprint = false;
4069
0
    }
4070
4071
49.8M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4072
49.8M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4073
4074
49.8M
    if (pgs->is_fill_color)
4075
21.3M
        pdev->op_state = PDF14_OP_STATE_FILL;
4076
28.4M
    else
4077
28.4M
        pdev->op_state = PDF14_OP_STATE_STROKE;
4078
4079
49.8M
    if_debug6m('v', dev->memory,
4080
49.8M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4081
49.8M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4082
49.8M
               pdev->stroke_effective_op_mode);
4083
49.8M
}
4084
4085
static  void
4086
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4087
35.4M
{
4088
35.4M
    bool hastrans = false;
4089
4090
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4091
     * makes other operations much slower. We have no option however, if the
4092
     * current colour involves transparency, or if it's anything other than
4093
     * a completely solid (or transparent) operation in the normal blend mode.
4094
     */
4095
35.4M
    if (pdcolor != NULL)
4096
35.4M
    {
4097
35.4M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4098
35.4M
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4099
15.6k
            hastrans = true;
4100
35.4M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4101
            /* FIXME: Here we assume that ALL type 2 patterns are
4102
             * transparent - this test could be better. */
4103
50.9k
            hastrans = true;
4104
50.9k
        }
4105
35.4M
    }
4106
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4107
       This appears to be the only place where this test is done so
4108
       not adding a is_idempotent method */
4109
35.4M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4110
35.4M
        pgs->blend_mode != BLEND_MODE_Darken &&
4111
35.4M
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4112
35.4M
        (pgs->fillconstantalpha != 1.0) ||
4113
35.4M
        (pgs->strokeconstantalpha != 1.0) ||
4114
35.4M
        (hastrans))
4115
984k
    {
4116
        /*
4117
         * The blend operations are not idempotent.  Force non-idempotent
4118
         * filling and stroking operations.
4119
         */
4120
984k
        pgs->log_op |= lop_pdf14;
4121
984k
    }
4122
35.4M
}
4123
4124
static int
4125
push_shfill_group(pdf14_clist_device *pdev,
4126
                  gs_gstate *pgs,
4127
                  gs_fixed_rect *box)
4128
1.98k
{
4129
1.98k
    gs_transparency_group_params_t params = { 0 };
4130
1.98k
    int code;
4131
1.98k
    gs_rect cb;
4132
1.98k
    gs_gstate fudged_pgs = *pgs;
4133
4134
1.98k
    params.shade_group = true;
4135
4136
    /* gs_begin_transparency_group takes a bbox that it then
4137
     * transforms by ctm. Our bbox has already been transformed,
4138
     * so clear out the ctm. */
4139
1.98k
    fudged_pgs.ctm.xx = 1.0;
4140
1.98k
    fudged_pgs.ctm.xy = 0;
4141
1.98k
    fudged_pgs.ctm.yx = 0;
4142
1.98k
    fudged_pgs.ctm.yy = 1.0;
4143
1.98k
    fudged_pgs.ctm.tx = 0;
4144
1.98k
    fudged_pgs.ctm.ty = 0;
4145
1.98k
    cb.p.x = fixed2int_pixround(box->p.x);
4146
1.98k
    cb.p.y = fixed2int_pixround(box->p.y);
4147
1.98k
    cb.q.x = fixed2int_pixround(box->q.x);
4148
1.98k
    cb.q.y = fixed2int_pixround(box->q.y);
4149
4150
1.98k
    params.Isolated = false;
4151
1.98k
    params.Knockout = true;
4152
1.98k
    params.page_group = false;
4153
1.98k
    params.group_opacity = fudged_pgs.fillconstantalpha;
4154
1.98k
    params.group_shape = 1.0;
4155
1.98k
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4156
4157
    /* We have the group handle the blendmode and the opacity,
4158
     * and continue with the existing graphics state reset
4159
     * to normal, opaque operation. We could do it the other
4160
     * way around, but this way means that if we push a knockout
4161
     * group for a stroke, and then the code calls back into
4162
     * the fill operation as part of doing the stroking, we don't
4163
     * push another one. */
4164
1.98k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4165
1.98k
    gs_setfillconstantalpha(pgs, 1.0);
4166
1.98k
    gs_setstrokeconstantalpha(pgs, 1.0);
4167
1.98k
    if (pdev) {
4168
1.98k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4169
1.98k
        if (code < 0)
4170
0
            return code;
4171
1.98k
    }
4172
4173
1.98k
    return code;
4174
1.98k
}
4175
4176
static int
4177
pop_shfill_group(gs_gstate *pgs)
4178
1.98k
{
4179
1.98k
     return gs_end_transparency_group(pgs);
4180
1.98k
}
4181
4182
static int
4183
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4184
                           gx_path *ppath, const gx_fill_params *params,
4185
                           const gx_drawing_color *pdcolor,
4186
                           const gx_clip_path *pcpath)
4187
29.0M
{
4188
29.0M
    gs_gstate new_pgs = *pgs;
4189
29.0M
    int code = 0;
4190
29.0M
    gs_pattern2_instance_t *pinst = NULL;
4191
29.0M
    int push_group = 0;
4192
4193
29.0M
    code = pdf14_initialize_ctx(dev, pgs);
4194
29.0M
    if (code < 0)
4195
0
        return code;
4196
4197
29.0M
    if (pdcolor == NULL)
4198
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4199
29.0M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_STROKE;
4200
29.0M
    if (gx_dc_is_pattern1_color(pdcolor)){
4201
727k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4202
727k
            gx_pattern1_clist_has_trans(pdcolor) ){
4203
            /* In this case, we need to push a transparency group
4204
               and tile the pattern color, which is stored in
4205
               a pdf14 device buffer in the ctile object memember
4206
               variable ttrans */
4207
#if RAW_DUMP
4208
            /* Since we do not get a put_image to view what
4209
               we have do it now */
4210
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4211
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4212
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4213
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4214
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4215
                        ppatdev14->ctx->stack->rect.p.y *
4216
                        ppatdev14->ctx->stack->rowstride +
4217
                        ppatdev14->ctx->stack->rect.p.x;
4218
                    dump_raw_buffer(ppatdev14->ctx->memory,
4219
                                    (ppatdev14->ctx->stack->rect.q.y -
4220
                                     ppatdev14->ctx->stack->rect.p.y),
4221
                                    (ppatdev14->ctx->stack->rect.q.x -
4222
                                     ppatdev14->ctx->stack->rect.p.x),
4223
                                    ppatdev14->ctx->stack->n_planes,
4224
                                    ppatdev14->ctx->stack->planestride,
4225
                                    ppatdev14->ctx->stack->rowstride,
4226
                                    "Pattern_Fill", buf_ptr,
4227
                                    ppatdev14->ctx->stack->deep);
4228
                    global_index++;
4229
                } else {
4230
                     gx_pattern_trans_t *patt_trans =
4231
                                        pdcolor->colors.pattern.p_tile->ttrans;
4232
                     dump_raw_buffer(patt_trans->mem,
4233
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4234
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4235
                                     patt_trans->n_chan,
4236
                                     patt_trans->planestride, patt_trans->rowstride,
4237
                                     "Pattern_Fill_clist",
4238
                                     patt_trans->transbytes +
4239
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4240
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4241
                                     patt_trans->deep);
4242
                    global_index++;
4243
                }
4244
            }
4245
#endif
4246
96.4k
            pdf14_set_marking_params(dev, &new_pgs);
4247
96.4k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4248
96.4k
                params, pdcolor, pcpath);
4249
96.4k
            new_pgs.trans_device = NULL;
4250
96.4k
            new_pgs.has_transparency = false;
4251
96.4k
            return code;
4252
96.4k
        }
4253
727k
    }
4254
28.9M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4255
28.9M
        pdcolor->type == &gx_dc_devn_masked) {
4256
        /* Non-idempotent blends require a transparency
4257
         * group to be pushed because shadings might
4258
         * paint several pixels twice. */
4259
47
        push_group = pgs->fillconstantalpha != 1.0 ||
4260
47
               !blend_is_idempotent(gs_currentblendmode(pgs));
4261
47
        pinst =
4262
47
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4263
47
        pinst->saved->has_transparency = true;
4264
        /* The transparency color space operations are driven
4265
           by the pdf14 clist writer device.  */
4266
47
        pinst->saved->trans_device = dev;
4267
47
    }
4268
28.9M
    if (push_group) {
4269
0
        gs_fixed_rect box;
4270
0
        if (pcpath)
4271
0
            gx_cpath_outer_box(pcpath, &box);
4272
0
        else
4273
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4274
0
        if (ppath) {
4275
0
            gs_fixed_rect path_box;
4276
4277
0
            gx_path_bbox(ppath, &path_box);
4278
0
            if (box.p.x < path_box.p.x)
4279
0
                box.p.x = path_box.p.x;
4280
0
            if (box.p.y < path_box.p.y)
4281
0
                box.p.y = path_box.p.y;
4282
0
            if (box.q.x > path_box.q.x)
4283
0
                box.q.x = path_box.q.x;
4284
0
            if (box.q.y > path_box.q.y)
4285
0
                box.q.y = path_box.q.y;
4286
0
        }
4287
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4288
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4289
0
    } else
4290
28.9M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4291
28.9M
    pdf14_set_marking_params(dev, &new_pgs);
4292
28.9M
    if (code >= 0) {
4293
28.9M
        new_pgs.trans_device = dev;
4294
28.9M
        new_pgs.has_transparency = true;
4295
        /* ppath can permissibly be NULL here, if we want to have a
4296
         * shading or a pattern fill the clipping path. This upsets
4297
         * coverity, which is not smart enough to realise that the
4298
         * validity of a NULL ppath depends on the type of pdcolor.
4299
         * We'll mark it as a false positive. */
4300
28.9M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4301
28.9M
        new_pgs.trans_device = NULL;
4302
28.9M
        new_pgs.has_transparency = false;
4303
28.9M
    }
4304
28.9M
    if (code >= 0 && push_group) {
4305
0
        code = pop_shfill_group(&new_pgs);
4306
0
        pdf14_set_marking_params(dev, pgs);
4307
0
    }
4308
28.9M
    if (pinst != NULL){
4309
47
        pinst->saved->trans_device = NULL;
4310
47
    }
4311
28.9M
    return code;
4312
29.0M
}
4313
4314
static  int
4315
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4316
                             gx_path *ppath, const gx_stroke_params *params,
4317
                             const gx_drawing_color *pdcolor,
4318
                             const gx_clip_path *pcpath)
4319
3.97M
{
4320
3.97M
    gs_gstate new_pgs = *pgs;
4321
3.97M
    int push_group = 0;
4322
3.97M
    int code = 0;
4323
4324
3.97M
    if (pdcolor == NULL)
4325
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4326
4327
3.97M
    code = pdf14_initialize_ctx(dev, pgs);
4328
3.97M
    if (code < 0)
4329
0
        return code;
4330
4331
3.97M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4332
        /* Non-idempotent blends require a transparency
4333
         * group to be pushed because shadings might
4334
         * paint several pixels twice. */
4335
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4336
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4337
0
    }
4338
3.97M
    if (push_group) {
4339
0
        gs_fixed_rect box;
4340
0
        if (pcpath)
4341
0
            gx_cpath_outer_box(pcpath, &box);
4342
0
        else
4343
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4344
4345
        /* For fill_path, we accept ppath == NULL to mean
4346
         * fill the entire clipping region. That makes no
4347
         * sense for stroke_path, hence ppath is always non
4348
         * NULL here. */
4349
0
        {
4350
0
            gs_fixed_rect path_box;
4351
0
            gs_fixed_point expansion;
4352
4353
0
            gx_path_bbox(ppath, &path_box);
4354
            /* Expand the path bounding box by the scaled line width. */
4355
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4356
                /* The expansion is so large it caused a limitcheck. */
4357
0
                path_box.p.x = path_box.p.y = min_fixed;
4358
0
                path_box.q.x = path_box.q.y = max_fixed;
4359
0
            } else {
4360
0
                expansion.x += pgs->fill_adjust.x;
4361
0
                expansion.y += pgs->fill_adjust.y;
4362
                /*
4363
                 * It's theoretically possible for the following computations to
4364
                 * overflow, so we need to check for this.
4365
                 */
4366
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4367
0
                                path_box.p.x - expansion.x);
4368
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4369
0
                                path_box.p.y - expansion.y);
4370
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4371
0
                                path_box.q.x + expansion.x);
4372
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4373
0
                                path_box.q.y + expansion.y);
4374
0
            }
4375
0
            if (box.p.x < path_box.p.x)
4376
0
                box.p.x = path_box.p.x;
4377
0
            if (box.p.y < path_box.p.y)
4378
0
                box.p.y = path_box.p.y;
4379
0
            if (box.q.x > path_box.q.x)
4380
0
                box.q.x = path_box.q.x;
4381
0
            if (box.q.y > path_box.q.y)
4382
0
                box.q.y = path_box.q.y;
4383
0
        }
4384
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4385
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4386
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4387
0
    } else
4388
3.97M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4389
3.97M
    pdf14_set_marking_params(dev, &new_pgs);
4390
3.97M
    if (code >= 0) {
4391
3.97M
        PDF14_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4392
4393
3.97M
        ((pdf14_device*)dev)->op_state = PDF14_OP_STATE_STROKE;
4394
3.97M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4395
3.97M
        ((pdf14_device*)dev)->op_state = save_op_state;
4396
3.97M
    }
4397
3.97M
    if (code >= 0 && push_group) {
4398
0
        code = pop_shfill_group(&new_pgs);
4399
0
        pdf14_set_marking_params(dev, pgs);
4400
0
    }
4401
4402
3.97M
    return code;
4403
3.97M
}
4404
4405
/* Pull out steps of transparency updates for fill/stroke
4406
   so that they can be invoked elsewhere (e.g.
4407
   when the abuf device is handling the stroke/fill */
4408
4409
/* Set-up prior to fill operation in fill-stroke */
4410
static int
4411
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4412
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4413
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4414
65.6k
{
4415
65.6k
    int code = 0;
4416
65.6k
    gs_transparency_group_params_t params = { 0 };
4417
65.6k
    gs_fixed_rect clip_bbox;
4418
65.6k
    gs_rect bbox, group_stroke_box;
4419
65.6k
    gs_fixed_rect path_bbox;
4420
65.6k
    int expansion_code;
4421
65.6k
    gs_fixed_point expansion;
4422
65.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4423
4424
65.6k
    *path_empty = false;
4425
4426
65.6k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4427
65.6k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4428
48
        return 0;
4429
4430
    /* The clip box returned here is scaled up by path_log2scale, so we need
4431
     * to scale down by this later. */
4432
65.6k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4433
65.6k
    if (code < 0 && code != gs_error_unknownerror)
4434
0
        return code;
4435
4436
65.6k
    if (code == gs_error_unknownerror) {
4437
        /* didn't get clip box from gx_curr_fixed_bbox */
4438
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4439
         * scaling down by this in a moment. */
4440
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4441
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4442
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4443
0
    }
4444
    /* pcpath->outer_box is scaled by path_log2scale too. */
4445
65.6k
    if (pcpath)
4446
65.6k
        rect_intersect(clip_bbox, pcpath->outer_box);
4447
4448
    /* expand the ppath using stroke expansion rule, then intersect it */
4449
65.6k
    code = gx_path_bbox(ppath, &path_bbox);
4450
4451
    /* If we are coming from the abuf device, the path has been scaled
4452
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4453
       on the path_bbox so that we get the proper bounding box for our group. */
4454
65.6k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4455
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4456
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4457
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4458
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4459
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4460
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4461
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4462
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4463
0
    }
4464
4465
65.6k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4466
40.1k
        *path_empty = true;
4467
40.1k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4468
                     there are simply too many return cases that I can't account for. */
4469
40.1k
    }
4470
25.4k
    if (code < 0)
4471
0
        return code;
4472
4473
25.4k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4474
25.4k
    if (expansion_code >= 0) {
4475
22.4k
        path_bbox.p.x -= expansion.x;
4476
22.4k
        path_bbox.p.y -= expansion.y;
4477
22.4k
        path_bbox.q.x += expansion.x;
4478
22.4k
        path_bbox.q.y += expansion.y;
4479
22.4k
    }
4480
25.4k
    rect_intersect(path_bbox, clip_bbox);
4481
25.4k
    bbox.p.x = fixed2float(path_bbox.p.x);
4482
25.4k
    bbox.p.y = fixed2float(path_bbox.p.y);
4483
25.4k
    bbox.q.x = fixed2float(path_bbox.q.x);
4484
25.4k
    bbox.q.y = fixed2float(path_bbox.q.y);
4485
4486
25.4k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4487
25.4k
    if (code < 0)
4488
3
        return code;
4489
4490
25.4k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4491
0
        p14dev->overprint = pgs->overprint;
4492
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4493
0
    }
4494
4495
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4496
25.4k
    if (fill_alpha == stroke_alpha &&
4497
25.4k
        p14dev->overprint && p14dev->stroke_overprint &&
4498
25.4k
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4499
4500
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4501
           compatible overprint mode.  Group will be composited with
4502
           original alpha and blend mode */
4503
0
        *op_ca_eq_CA = true;
4504
0
        params.Isolated = false;
4505
0
        params.group_color_type = UNKNOWN;
4506
0
        params.Knockout = false;
4507
0
        params.page_group = false;
4508
0
        params.group_opacity = 1.0;
4509
0
        params.group_shape = fill_alpha;
4510
4511
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4512
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4513
0
        if (code < 0)
4514
0
            return code;
4515
4516
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4517
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4518
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4519
4520
25.4k
    } else {
4521
        /* Push a non-isolated knockout group. Do not change the alpha or
4522
            blend modes. Note: we need to draw those that have alpha = 0 */
4523
25.4k
        *op_ca_eq_CA = false;
4524
25.4k
        params.Isolated = false;
4525
25.4k
        params.group_color_type = UNKNOWN;
4526
25.4k
        params.Knockout = true;
4527
25.4k
        params.page_group = false;
4528
25.4k
        params.group_shape = 1.0;
4529
25.4k
        params.group_opacity = 1.0;
4530
4531
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4532
25.4k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4533
25.4k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4534
25.4k
        if (code < 0)
4535
0
            return code;
4536
4537
        /* restore blend mode for actual drawing in the group */
4538
25.4k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4539
4540
        /* If we are in an overprint situation, set the blend mode to compatible
4541
            overprint */
4542
25.4k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4543
25.4k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4544
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4545
25.4k
    }
4546
25.4k
    p14dev->op_state = PDF14_OP_STATE_FILL;
4547
25.4k
    return code;
4548
25.4k
}
4549
4550
/* Set-up prior to stroke operation in fill-stroke */
4551
static void
4552
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4553
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4554
25.4k
{
4555
25.4k
    pdf14_device* p14dev = (pdf14_device*)dev;
4556
4557
25.4k
    if (op_ca_eq_CA) {
4558
48
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4559
25.4k
    } else {
4560
25.4k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4561
25.4k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4562
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4563
4564
        /* Note that the stroke can end up doing fill methods */
4565
25.4k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4566
4567
25.4k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4568
25.4k
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4569
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4570
25.4k
    }
4571
25.4k
    p14dev->op_state = PDF14_OP_STATE_STROKE;
4572
25.4k
}
4573
4574
/* Cleanup after the stroke in fill-stroke  */
4575
static int
4576
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4577
25.4k
{
4578
25.4k
    int code;
4579
4580
25.4k
    if (!op_ca_eq_CA) {
4581
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4582
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4583
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4584
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4585
          * We therefore need to make sure it is set according to the current fill state.
4586
          */
4587
25.4k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4588
25.4k
        code = gs_update_trans_marking_params(pgs);
4589
25.4k
        if (code < 0)
4590
0
            return code;
4591
25.4k
        pdf14_set_marking_params(dev, pgs);
4592
25.4k
    }
4593
4594
25.4k
    return 0;
4595
25.4k
}
4596
4597
/* cleanup in fill-stroke  */
4598
static int
4599
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4600
    gs_blend_mode_t blend_mode, PDF14_OP_FS_STATE save_op_state)
4601
25.4k
{
4602
25.4k
    pdf14_device* p14dev = (pdf14_device*)dev;
4603
25.4k
    int code2;
4604
25.4k
    int code = 0;
4605
4606
    /* Restore the state */
4607
25.4k
    p14dev->op_state = save_op_state;
4608
25.4k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4609
25.4k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4610
25.4k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4611
4612
25.4k
    code2 = gs_end_transparency_group(pgs);
4613
25.4k
    if (code2 < 0) {
4614
        /* At this point things have gone very wrong. We should just shut down */
4615
0
        code = gs_abort_pdf14trans_device(pgs);
4616
0
        return code2;
4617
0
    }
4618
25.4k
    return code;
4619
25.4k
}
4620
4621
static int
4622
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4623
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4624
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4625
    const gx_clip_path *pcpath)
4626
236k
{
4627
236k
    bool op_ca_eq_CA;
4628
236k
    bool path_empty;
4629
236k
    int code;
4630
236k
    float stroke_alpha = cpgs->strokeconstantalpha;
4631
236k
    float fill_alpha = cpgs->fillconstantalpha;
4632
236k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4633
236k
    pdf14_device* p14dev = (pdf14_device*)dev;
4634
236k
    PDF14_OP_FS_STATE save_op_state = p14dev->op_state;
4635
236k
    gs_log2_scale_point path_log2scale;
4636
236k
    bool group_needed = true;
4637
236k
    gx_device* curr_pgs_dev = cpgs->device;
4638
4639
236k
    union {
4640
236k
        const gs_gstate* cpgs;
4641
236k
        gs_gstate* pgs;
4642
236k
    } const_breaker;
4643
236k
    gs_gstate* pgs;
4644
4645
    /* Break const just once, neatly */
4646
236k
    const_breaker.cpgs = cpgs;
4647
236k
    pgs = const_breaker.pgs;
4648
236k
    path_log2scale.x = 0;
4649
236k
    path_log2scale.y = 0;
4650
4651
236k
    code = pdf14_initialize_ctx(dev, pgs);
4652
236k
    if (code < 0)
4653
0
        return code;
4654
4655
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4656
     * blend is normal we don't do a group push. Just do the stroke
4657
     * and the fill, even with overprint */
4658
236k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4659
170k
        group_needed = false;
4660
4661
236k
    if (group_needed) {
4662
65.6k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4663
                              can be called on the clist writer side when dealing
4664
                              with the abuf/pdf14 interaction. Those calls have to
4665
                              go through the gs_trans API not the gx_trans or pdf14
4666
                              methods.  Perhaps these methods should have a different
4667
                              suffix, but they are static methods here in the pdf14
4668
                              file. */
4669
65.6k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4670
65.6k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4671
65.6k
        pgs->device = curr_pgs_dev;
4672
65.6k
        if (code < 0)
4673
3
            goto cleanup;
4674
65.6k
        if (path_empty)
4675
40.1k
            return 0;
4676
65.6k
    }
4677
4678
196k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4679
196k
    if (code < 0)
4680
0
        goto cleanup;
4681
4682
196k
    if (group_needed)
4683
25.4k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4684
196k
    gs_swapcolors_quick(pgs);
4685
4686
4687
#if RAW_DUMP
4688
    /* Dump the current buffer to see what we have. */
4689
    dump_raw_buffer(p14dev->ctx->memory,
4690
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4691
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4692
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4693
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4694
    global_index++;
4695
#endif
4696
4697
196k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4698
196k
    gs_swapcolors_quick(pgs);
4699
196k
    if (code < 0) {
4700
0
        goto cleanup;
4701
0
    }
4702
4703
#if RAW_DUMP
4704
    /* Dump the current buffer to see what we have. */
4705
    dump_raw_buffer(p14dev->ctx->memory,
4706
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4707
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4708
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4709
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4710
    global_index++;
4711
#endif
4712
196k
    if (group_needed)
4713
25.4k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4714
4715
196k
cleanup:
4716
196k
    if (group_needed) {
4717
25.4k
        int code1;
4718
25.4k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4719
25.4k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4720
25.4k
            save_op_state);
4721
25.4k
        if (code1 < 0)
4722
0
            code = code1;
4723
25.4k
        pgs->device = curr_pgs_dev;
4724
25.4k
    }
4725
196k
    return code;
4726
196k
}
4727
4728
static int
4729
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4730
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4731
                      gx_color_index color, int depth)
4732
0
{
4733
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4734
0
                                  color, NULL, depth, false);
4735
0
}
4736
4737
static int
4738
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4739
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4740
                      const gx_drawing_color *pdcolor, int depth)
4741
0
{
4742
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4743
0
                                  0, pdcolor, depth, true);
4744
0
}
4745
4746
static int
4747
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4748
                          int aa_raster, gx_bitmap_id id, int x, int y,
4749
                          int w, int h, gx_color_index color,
4750
                          const gx_device_color *pdc, int depth, bool devn)
4751
0
{
4752
0
    const byte *aa_row;
4753
0
    pdf14_device *pdev = (pdf14_device *)dev;
4754
0
    pdf14_buf *buf = pdev->ctx->stack;
4755
0
    int i, j, k;
4756
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4757
0
    byte src[PDF14_MAX_PLANES];
4758
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4759
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4760
0
    bool additive = pdev->ctx->additive;
4761
0
    int rowstride = buf->rowstride;
4762
0
    int planestride = buf->planestride;
4763
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4764
0
    bool has_alpha_g = buf->has_alpha_g;
4765
0
    bool has_shape = buf->has_shape;
4766
0
    bool has_tags = buf->has_tags;
4767
0
    bool knockout = buf->knockout;
4768
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4769
0
        blend_mode == BLEND_MODE_Compatible ||
4770
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4771
0
    int num_chan = buf->n_chan;
4772
0
    int num_comp = num_chan - 1;
4773
0
    int shape_off = num_chan * planestride;
4774
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
4775
0
    int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4776
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4777
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4778
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4779
0
    gx_color_index comps;
4780
0
    byte shape = 0; /* Quiet compiler. */
4781
0
    byte src_alpha;
4782
0
    int alpha2_aa, alpha_aa, sx;
4783
0
    int alpha_aa_act;
4784
0
    int xoff;
4785
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4786
0
    int shift = 8;
4787
0
    bool has_backdrop = buf->backdrop != NULL;
4788
4789
0
    if (buf->data == NULL)
4790
0
        return 0;
4791
0
    aa_row = data;
4792
0
    if (has_tags) {
4793
0
        if (devn)
4794
0
            curr_tag = pdc->tag;
4795
0
        else
4796
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4797
0
    }
4798
4799
0
    if (devn) {
4800
0
        if (additive) {
4801
0
            for (j = 0; j < num_comp; j++) {
4802
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4803
0
            }
4804
0
        } else {
4805
0
            for (j = 0; j < num_comp; j++) {
4806
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4807
0
            }
4808
0
        }
4809
0
    } else
4810
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4811
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4812
0
    if (has_shape)
4813
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4814
    /* Limit the area we write to the bounding rectangle for this buffer */
4815
0
    if (x < buf->rect.p.x) {
4816
0
        xoff = data_x + buf->rect.p.x - x;
4817
0
        w += x - buf->rect.p.x;
4818
0
        x = buf->rect.p.x;
4819
0
    } else {
4820
0
        xoff = data_x;
4821
0
    }
4822
0
    if (y < buf->rect.p.y) {
4823
0
      h += y - buf->rect.p.y;
4824
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4825
0
      y = buf->rect.p.y;
4826
0
    }
4827
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4828
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4829
    /* Update the dirty rectangle. */
4830
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4831
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4832
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4833
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4834
4835
    /* composite with backdrop only. */
4836
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4837
0
    if (knockout && has_backdrop)
4838
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4839
0
    else
4840
0
        bline = line;
4841
4842
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4843
0
        back_ptr = bline;
4844
0
        dst_ptr = line;
4845
0
        sx = xoff;
4846
0
        for (i = 0; i < w; ++i, ++sx) {
4847
            /* Complement the components for subtractive color spaces */
4848
0
            if (additive) {
4849
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4850
0
                    dst[k] = back_ptr[k * planestride];
4851
0
            } else { /* Complement the components for subtractive color spaces */
4852
0
                for (k = 0; k < num_comp; ++k)
4853
0
                    dst[k] = 255 - back_ptr[k * planestride];
4854
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4855
0
            }
4856
            /* Get the aa alpha from the buffer */
4857
0
            switch(depth)
4858
0
            {
4859
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4860
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4861
0
                break;
4862
0
            case 4:
4863
0
                alpha2_aa = aa_row[sx >> 1];
4864
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4865
0
                break;
4866
0
            case 8:
4867
0
                alpha_aa = aa_row[sx];
4868
0
                break;
4869
0
            default:
4870
0
                return_error(gs_error_rangecheck);
4871
0
            }
4872
0
            if (alpha_aa != 0) {  /* This does happen */
4873
0
                if (alpha_aa != 255) {
4874
                    /* We have an alpha value from aa */
4875
0
                    alpha_aa_act = alpha_aa;
4876
0
                    if (src_alpha != 255) {
4877
                        /* Need to combine it with the existing alpha */
4878
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4879
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4880
0
                    }
4881
                    /* Set our source alpha value appropriately */
4882
0
                    src[num_comp] = alpha_aa_act;
4883
0
                } else {
4884
                    /* We may have to reset this is it was changed as we
4885
                       moved across the row */
4886
0
                    src[num_comp] = src_alpha;
4887
0
                }
4888
0
                if (knockout) {
4889
0
                    if (buf->isolated) {
4890
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4891
0
                    } else {
4892
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4893
0
                            blend_mode, pdev->blend_procs, pdev);
4894
0
                    }
4895
0
                } else {
4896
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4897
0
                                                    pdev->blend_procs, pdev);
4898
0
                }
4899
                /* Complement the results for subtractive color spaces */
4900
0
                if (additive) {
4901
0
                    for (k = 0; k < num_chan; ++k)
4902
0
                        dst_ptr[k * planestride] = dst[k];
4903
0
                } else {
4904
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4905
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4906
0
                                ++k, comps >>= 1) {
4907
0
                            if ((comps & 0x1) != 0) {
4908
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4909
0
                            }
4910
0
                        }
4911
                        /* The alpha channel */
4912
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4913
0
                    } else {
4914
0
                        for (k = 0; k < num_comp; ++k)
4915
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4916
                        /* The alpha channel */
4917
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4918
0
                    }
4919
0
                }
4920
0
                if (has_alpha_g) {
4921
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4922
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4923
0
                }
4924
0
                if (has_shape) {
4925
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4926
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4927
0
                }
4928
0
                if (has_tags) {
4929
                    /* If alpha is 100% then set to curr_tag, else or */
4930
                    /* other than Normal BM, we always OR */
4931
0
                    if (src[num_comp] == 255 && tag_blend) {
4932
0
                        dst_ptr[tag_off] = curr_tag;
4933
0
                    } else {
4934
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4935
0
                    }
4936
0
                }
4937
0
            }
4938
0
            ++dst_ptr;
4939
0
            ++back_ptr;
4940
0
        }
4941
0
        line += rowstride;
4942
0
        bline += rowstride;
4943
0
    }
4944
0
    return 0;
4945
0
}
4946
4947
static int
4948
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4949
                             int aa_raster, gx_bitmap_id id, int x, int y,
4950
                             int w, int h, gx_color_index color,
4951
                             const gx_device_color *pdc, int depth, bool devn)
4952
0
{
4953
0
    const byte *aa_row;
4954
0
    pdf14_device *pdev = (pdf14_device *)dev;
4955
0
    pdf14_buf *buf = pdev->ctx->stack;
4956
0
    int i, j, k;
4957
0
    byte *bline, *line;
4958
0
    uint16_t *dst_ptr, *back_ptr;
4959
0
    uint16_t src[PDF14_MAX_PLANES];
4960
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4961
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4962
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4963
0
        blend_mode == BLEND_MODE_Compatible ||
4964
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4965
0
    bool additive = pdev->ctx->additive;
4966
0
    int rowstride = buf->rowstride;
4967
0
    int planestride = buf->planestride;
4968
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4969
0
    bool has_alpha_g = buf->has_alpha_g;
4970
0
    bool has_shape = buf->has_shape;
4971
0
    bool has_tags = buf->has_tags;
4972
0
    bool knockout = buf->knockout;
4973
0
    int num_chan = buf->n_chan;
4974
0
    int num_comp = num_chan - 1;
4975
0
    int shape_off = num_chan * planestride;
4976
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
4977
0
    int tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4978
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4979
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
4980
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4981
0
    gx_color_index comps;
4982
0
    uint16_t shape = 0; /* Quiet compiler. */
4983
0
    uint16_t src_alpha;
4984
0
    int alpha2_aa, alpha_aa, sx;
4985
0
    int alpha_aa_act;
4986
0
    int xoff;
4987
0
    bool has_backdrop = buf->backdrop != NULL;
4988
4989
0
    if (buf->data == NULL)
4990
0
        return 0;
4991
0
    aa_row = data;
4992
0
    if (has_tags) {
4993
0
        if (devn)
4994
0
            curr_tag = pdc->tag;
4995
0
        else
4996
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4997
0
    }
4998
4999
0
    if (devn) {
5000
0
        if (additive) {
5001
0
            for (j = 0; j < num_comp; j++) {
5002
0
                src[j] = pdc->colors.devn.values[j];
5003
0
            }
5004
0
        } else {
5005
0
            for (j = 0; j < num_comp; j++) {
5006
0
                src[j] = 65535 - pdc->colors.devn.values[j];
5007
0
            }
5008
0
        }
5009
0
    } else
5010
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
5011
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
5012
0
    if (has_shape)
5013
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
5014
    /* Limit the area we write to the bounding rectangle for this buffer */
5015
0
    if (x < buf->rect.p.x) {
5016
0
        xoff = data_x + buf->rect.p.x - x;
5017
0
        w += x - buf->rect.p.x;
5018
0
        x = buf->rect.p.x;
5019
0
    } else {
5020
0
        xoff = data_x;
5021
0
    }
5022
0
    if (y < buf->rect.p.y) {
5023
0
      h += y - buf->rect.p.y;
5024
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5025
0
      y = buf->rect.p.y;
5026
0
    }
5027
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5028
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5029
    /* Update the dirty rectangle. */
5030
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5031
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5032
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5033
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5034
5035
    /* composite with backdrop only. */
5036
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5037
0
    if (knockout && has_backdrop)
5038
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5039
0
    else
5040
0
        bline = line;
5041
5042
0
    planestride >>= 1;
5043
0
    rowstride   >>= 1;
5044
0
    alpha_g_off >>= 1;
5045
0
    shape_off   >>= 1;
5046
0
    tag_off     >>= 1;
5047
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5048
0
        back_ptr = (uint16_t *)(void *)bline;
5049
0
        dst_ptr = (uint16_t *)(void *)line;
5050
0
        sx = xoff;
5051
0
        for (i = 0; i < w; ++i, ++sx) {
5052
            /* Complement the components for subtractive color spaces */
5053
0
            if (additive) {
5054
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5055
0
                    dst[k] = back_ptr[k * planestride];
5056
0
            } else { /* Complement the components for subtractive color spaces */
5057
0
                for (k = 0; k < num_comp; ++k)
5058
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5059
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5060
0
            }
5061
            /* Get the aa alpha from the buffer */
5062
0
            switch(depth)
5063
0
            {
5064
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5065
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5066
0
                break;
5067
0
            case 4:
5068
0
                alpha2_aa = aa_row[sx >> 1];
5069
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5070
0
                break;
5071
0
            case 8:
5072
0
                alpha_aa = aa_row[sx];
5073
0
                break;
5074
0
            default:
5075
0
                return_error(gs_error_rangecheck);
5076
0
            }
5077
0
            if (alpha_aa != 0) {  /* This does happen */
5078
0
                if (alpha_aa != 255) {
5079
                    /* We have an alpha value from aa */
5080
0
                    alpha_aa_act = alpha_aa * 0x101;
5081
0
                    if (src_alpha != 65535) {
5082
                        /* Need to combine it with the existing alpha */
5083
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5084
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5085
0
                    }
5086
                    /* Set our source alpha value appropriately */
5087
0
                    src[num_comp] = alpha_aa_act;
5088
0
                } else {
5089
                    /* We may have to reset this is it was changed as we
5090
                       moved across the row */
5091
0
                    src[num_comp] = src_alpha;
5092
0
                }
5093
0
                if (knockout) {
5094
0
                    if (buf->isolated) {
5095
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5096
0
                    } else {
5097
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5098
0
                            blend_mode, pdev->blend_procs, pdev);
5099
0
                    }
5100
0
                } else {
5101
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5102
0
                                                     pdev->blend_procs, pdev);
5103
0
                }
5104
                /* Complement the results for subtractive color spaces */
5105
0
                if (additive) {
5106
0
                    for (k = 0; k < num_chan; ++k)
5107
0
                        dst_ptr[k * planestride] = dst[k];
5108
0
                } else {
5109
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5110
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5111
0
                                ++k, comps >>= 1) {
5112
0
                            if ((comps & 0x1) != 0) {
5113
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5114
0
                            }
5115
0
                        }
5116
                        /* The alpha channel */
5117
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5118
0
                    } else {
5119
0
                        for (k = 0; k < num_comp; ++k)
5120
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5121
                        /* The alpha channel */
5122
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5123
0
                    }
5124
0
                }
5125
0
                if (has_alpha_g) {
5126
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5127
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5128
0
                }
5129
0
                if (has_shape) {
5130
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5131
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5132
0
                }
5133
0
                if (has_tags) {
5134
                    /* If alpha is 100% then set to curr_tag, else or */
5135
                    /* other than Normal BM, we always OR */
5136
0
                    if (src[num_comp] == 65535 && tag_blend) {
5137
0
                        dst_ptr[tag_off] = curr_tag;
5138
0
                    } else {
5139
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5140
0
                    }
5141
0
                }
5142
0
            }
5143
0
            ++dst_ptr;
5144
0
            ++back_ptr;
5145
0
        }
5146
0
        line += rowstride;
5147
0
        bline += rowstride;
5148
0
    }
5149
0
    return 0;
5150
0
}
5151
5152
static int
5153
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5154
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5155
                      gx_color_index color, const gx_device_color *pdc,
5156
                      int depth, bool devn)
5157
0
{
5158
0
    bool deep = device_is_deep(dev);
5159
0
    int code;
5160
5161
0
    code = pdf14_initialize_ctx(dev, NULL);
5162
0
    if (code < 0)
5163
0
        return code;
5164
5165
0
    if (deep)
5166
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5167
0
                                            id, x, y, w, h,
5168
0
                                            color, pdc, depth, devn);
5169
0
    else
5170
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5171
0
                                         id, x, y, w, h,
5172
0
                                         color, pdc, depth, devn);
5173
0
}
5174
5175
static  int
5176
pdf14_fill_mask(gx_device * orig_dev,
5177
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5178
                     int x, int y, int w, int h,
5179
                     const gx_drawing_color * pdcolor, int depth,
5180
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5181
25.4M
{
5182
25.4M
    gx_device *dev;
5183
25.4M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5184
25.4M
    gx_device_clip cdev;
5185
25.4M
    gx_color_tile *ptile = NULL;
5186
25.4M
    int code = 0;
5187
25.4M
    gs_int_rect group_rect;
5188
25.4M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5189
25.4M
    bool has_pattern_trans = false;
5190
25.4M
    cmm_dev_profile_t *dev_profile;
5191
5192
25.4M
    if (pdcolor == NULL)
5193
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5194
5195
25.4M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5196
25.4M
    if (code < 0)
5197
0
        return code;
5198
5199
    /* If we are doing a fill with a pattern that has a transparency then
5200
       go ahead and do a push and a pop of the transparency group */
5201
25.4M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5202
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5203
0
            ptile = pdcolor->colors.pattern.p_tile;
5204
            /* Set up things in the ptile so that we get the proper
5205
               blending etc */
5206
            /* Set the blending procs and the is_additive setting based
5207
               upon the number of channels */
5208
0
            if (ptile->ttrans->n_chan-1 < 4) {
5209
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5210
0
                ptile->ttrans->is_additive = true;
5211
0
            } else {
5212
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5213
0
                ptile->ttrans->is_additive = false;
5214
0
            }
5215
            /* Set the procs so that we use the proper filling method. */
5216
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5217
            /* Based upon if the tiles overlap pick the type of rect
5218
               fill that we will want to use */
5219
0
            if (ptile->has_overlap) {
5220
                /* This one does blending since there is tile overlap */
5221
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5222
0
            } else {
5223
                /* This one does no blending since there is no tile overlap */
5224
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5225
0
            }
5226
            /* Push the group */
5227
0
            group_rect.p.x = x;
5228
0
            group_rect.p.y = max(0,y);
5229
0
            group_rect.q.x = x + w;
5230
0
            group_rect.q.y = y + h;
5231
0
            if (!(w <= 0 || h <= 0)) {
5232
5233
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5234
0
                if (group_color_info == NULL)
5235
0
                    return_error(gs_error_VMerror);
5236
5237
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5238
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5239
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5240
0
                     group_color_info, NULL, NULL);
5241
0
                if (code < 0)
5242
0
                    return code;
5243
                /* Set up the output buffer information now that we have
5244
                   pushed the group */
5245
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5246
0
                if (fill_trans_buffer == NULL)
5247
0
                    return_error(gs_error_VMerror);
5248
5249
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5250
0
                                              fill_trans_buffer, NULL, false);
5251
                /* Store this in the appropriate place in pdcolor.  This
5252
                   is released later after the mask fill */
5253
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5254
0
                has_pattern_trans = true;
5255
0
            }
5256
0
        }
5257
0
    }
5258
25.4M
    if (pcpath != 0) {
5259
3.21M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5260
3.21M
        dev = (gx_device *) & cdev;
5261
3.21M
    } else
5262
22.2M
        dev = orig_dev;
5263
25.4M
    if (depth > 1) {
5264
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5265
0
        code = (*dev_proc(dev, copy_alpha))
5266
0
            (dev, data, dx, raster, id, x, y, w, h,
5267
0
             gx_dc_pure_color(pdcolor), depth);
5268
25.4M
    } else {
5269
25.4M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5270
25.4M
                                          x, y, w, h, dev, lop, false);
5271
25.4M
    }
5272
25.4M
    if (has_pattern_trans) {
5273
0
        bool has_tags = device_encodes_tags(dev);
5274
0
        if (code >= 0)
5275
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5276
0
        if (code >= 0)
5277
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5278
0
                                                p14dev->blend_procs,
5279
0
                                                p14dev->color_info.num_components - has_tags,
5280
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5281
0
                                                orig_dev);
5282
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5283
0
                       "pdf14_fill_mask");
5284
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5285
0
    }
5286
25.4M
    if (pcpath != 0)
5287
3.21M
        gx_destroy_clip_device_on_stack(&cdev);
5288
25.4M
    return code;
5289
25.4M
}
5290
5291
5292
5293
/* Used for filling rects when we are doing a fill with a pattern that
5294
   has transparency */
5295
static  int
5296
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5297
                        gx_path * ppath, const gx_fill_params * params,
5298
                        const gx_device_color * pdevc,
5299
                        const gx_clip_path * pcpath)
5300
96.4k
{
5301
96.4k
    int code;
5302
96.4k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5303
96.4k
    gs_fixed_rect clip_box;
5304
96.4k
    gs_fixed_rect outer_box;
5305
96.4k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5306
96.4k
    gs_int_rect rect;
5307
96.4k
    gx_clip_rect *curr_clip_rect;
5308
96.4k
    gx_color_tile *ptile = NULL;
5309
96.4k
    int k;
5310
96.4k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5311
96.4k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5312
96.4k
    int n_chan_tile;
5313
96.4k
    gx_clip_path cpath_intersection;
5314
96.4k
    gx_path path_ttrans;
5315
96.4k
    pdf14_group_color_t *group_color_info;
5316
96.4k
    bool has_tags = device_encodes_tags(pdev);
5317
5318
96.4k
    if (ppath == NULL)
5319
0
        return_error(gs_error_unknownerror);  /* should not happen */
5320
96.4k
    if (pcpath != NULL) {
5321
91.7k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5322
91.7k
    } else {
5323
4.74k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5324
4.74k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5325
4.74k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5326
4.74k
    }
5327
96.4k
    if (code < 0)
5328
0
        return code;
5329
96.4k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5330
96.4k
                                          params->rule, pgs_noconst, params);
5331
96.4k
    if (code < 0)
5332
0
        return code;
5333
    /* One (common) case worth optimising for is where we have a pattern that
5334
     * is positioned such that only one repeat of the tile is actually
5335
     * visible. In this case, we can restrict the size of the blending group
5336
     * we need to produce to be that of the actual area of the tile that is
5337
     * used. */
5338
96.4k
    ptile = pdevc->colors.pattern.p_tile;
5339
96.4k
    if (ptile->ttrans != NULL)
5340
41.6k
    {
5341
41.6k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5342
41.6k
            (cpath_intersection.outer_box.p.y < 0) ||
5343
41.6k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5344
41.6k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5345
28.7k
        {
5346
            /* More than one repeat of the tile would be visible, so we can't
5347
             * use the optimisation here. (Actually, this test isn't quite
5348
             * right - it actually tests whether more than the '0th' repeat
5349
             * of the tile is visible. A better test would test if just one
5350
             * repeat of the tile was visible, irrespective of which one.
5351
             * This is (hopefully) relatively rare, and would make the code
5352
             * below more complex too, so we're ignoring that for now. If it
5353
             * becomes evident that it's a case that matters we can revisit
5354
             * it.) */
5355
28.7k
        } else {
5356
            /* Only the 0th repeat is visible. Restrict the size further to
5357
             * just the used area of that patch. */
5358
12.8k
            gx_path_init_local(&path_ttrans, ppath->memory);
5359
12.8k
            code = gx_path_add_rectangle(&path_ttrans,
5360
12.8k
                                         int2fixed(ptile->ttrans->rect.p.x),
5361
12.8k
                                         int2fixed(ptile->ttrans->rect.p.y),
5362
12.8k
                                         int2fixed(ptile->ttrans->rect.q.x),
5363
12.8k
                                         int2fixed(ptile->ttrans->rect.q.y));
5364
12.8k
            if (code < 0)
5365
0
                return code;
5366
12.8k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5367
12.8k
                                      params->rule, pgs_noconst);
5368
12.8k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5369
12.8k
            if (code < 0)
5370
0
                return code;
5371
12.8k
        }
5372
41.6k
    }
5373
    /* Now let us push a transparency group into which we are
5374
     * going to tile the pattern.  */
5375
96.4k
    if (ppath != NULL) {
5376
96.4k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5377
5378
96.4k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5379
96.4k
        rect.p.x = fixed2int(outer_box.p.x);
5380
96.4k
        rect.p.y = fixed2int(outer_box.p.y);
5381
96.4k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5382
96.4k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5383
5384
        /* The color space of this group must be the same as that of the
5385
           tile.  Then when we pop the group, if there is a mismatch between
5386
           the tile color space and the current context we will do the proper
5387
           conversion.  In this way, we ensure that if the tile has any overlapping
5388
           occuring it will be blended in the proper manner i.e in the tile
5389
           underlying color space. */
5390
96.4k
        if (ptile->cdev == NULL) {
5391
41.6k
            if (ptile->ttrans == NULL)
5392
0
                return_error(gs_error_unknownerror);  /* should not happen */
5393
41.6k
            n_chan_tile = ptile->ttrans->n_chan;
5394
54.8k
        } else {
5395
54.8k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5396
54.8k
        }
5397
96.4k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5398
5399
        /* Transparency handling with patterns confuses me, so some notes...
5400
         *
5401
         * For simple, non-transparent patterns, like you'd get in PS, we've
5402
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5403
         * times. To cope with unmarked pixels, we have a "transparency" plane
5404
         * (simple on/off) that says whether a pixel is marked or not.
5405
         *
5406
         * For patterns with transparency (but not blending), we can create an
5407
         * isolated transparency group, tile all the bitmap tiles into that, and
5408
         * then blend that back with the required alpha at the end. This works
5409
         * because the alpha values of the individual objects within the tile are
5410
         * recorded in that group.
5411
         *
5412
         * We can't do that for groups that use blending though, as each object
5413
         * in the pattern might use a different blend, and we don't (can't) record
5414
         * the blending mode. An isolated group doesn't even allow us to actually
5415
         * do the blending at all. So, for such patterns (any patterns that sets (or
5416
         * just has a resource that mentions) a non-normal blend mode), we use
5417
         * a pattern clist.
5418
         */
5419
96.4k
        if (ptile->cdev == NULL) {
5420
41.6k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5421
41.6k
            if (group_color_info == NULL)
5422
0
                return gs_error_VMerror;
5423
5424
41.6k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5425
41.6k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5426
41.6k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5427
41.6k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5428
41.6k
            if (code < 0)
5429
0
                return code;
5430
41.6k
        }
5431
5432
        /* Set the blending procs and the is_additive setting based
5433
           upon the number of channels */
5434
96.4k
        if (ptile->cdev == NULL) {
5435
41.6k
            if (n_chan_tile-1 < 4) {
5436
40.0k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5437
40.0k
                ptile->ttrans->is_additive = true;
5438
40.0k
            } else {
5439
1.57k
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5440
1.57k
                ptile->ttrans->is_additive = false;
5441
1.57k
            }
5442
41.6k
        }
5443
        /* Now lets go through the rect list and fill with the pattern */
5444
        /* First get the buffer that we will be filling */
5445
96.4k
        if (ptile->cdev == NULL) {
5446
41.6k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5447
41.6k
            if (fill_trans_buffer == NULL) {
5448
0
                p14dev->pclist_device = NULL;
5449
0
                return_error(gs_error_VMerror);
5450
0
            }
5451
41.6k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5452
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5453
               want to use */
5454
41.6k
            if (ptile->has_overlap) {
5455
                /* This one does blending since there is tile overlap */
5456
1.81k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5457
39.8k
            } else {
5458
                /* This one does no blending since there is no tile overlap */
5459
39.8k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5460
39.8k
            }
5461
            /* fill the rectangles */
5462
41.6k
            phase.x = pdevc->phase.x;
5463
41.6k
            phase.y = pdevc->phase.y;
5464
41.6k
            if (cpath_intersection.rect_list->list.head != NULL){
5465
996
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5466
16.5k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5467
15.5k
                    if_debug5m('v', pgs->memory,
5468
15.5k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5469
15.5k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5470
15.5k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5471
15.5k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5472
15.5k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5473
15.5k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5474
15.5k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5475
15.5k
                    curr_clip_rect = curr_clip_rect->next;
5476
15.5k
                }
5477
40.6k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5478
                /* The case when there is just a single rect */
5479
40.6k
                if_debug5m('v', pgs->memory,
5480
40.6k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5481
40.6k
                           cpath_intersection.rect_list->list.single.xmin,
5482
40.6k
                           cpath_intersection.rect_list->list.single.ymin,
5483
40.6k
                           cpath_intersection.rect_list->list.single.xmax-
5484
40.6k
                              cpath_intersection.rect_list->list.single.xmin,
5485
40.6k
                           cpath_intersection.rect_list->list.single.ymax-
5486
40.6k
                              cpath_intersection.rect_list->list.single.ymin,
5487
40.6k
                           (int)ptile->id);
5488
40.6k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5489
40.6k
                                                  cpath_intersection.rect_list->list.single.ymin,
5490
40.6k
                                                  cpath_intersection.rect_list->list.single.xmax,
5491
40.6k
                                                  cpath_intersection.rect_list->list.single.ymax,
5492
40.6k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5493
40.6k
            }
5494
54.8k
        } else {
5495
            /* Clist pattern with transparency.  Create a clip device from our
5496
               cpath_intersection.  The above non-clist case could probably be
5497
               done this way too, which will reduce the amount of code here.
5498
               That is for another day though due to time constraints*/
5499
54.8k
            gx_device *dev;
5500
54.8k
            gx_device_clip clipdev;
5501
5502
54.8k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5503
54.8k
            dev = (gx_device *)&clipdev;
5504
54.8k
            phase.x = pdevc->phase.x;
5505
54.8k
            phase.y = pdevc->phase.y;
5506
54.8k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5507
54.8k
                                              ptile, fill_trans_buffer, phase,
5508
54.8k
                                              dev, pdevc, 1);
5509
54.8k
            gx_destroy_clip_device_on_stack(&clipdev);
5510
54.8k
        }
5511
        /* We're done drawing with the pattern, remove the reference to the
5512
         * pattern device
5513
         */
5514
96.4k
        p14dev->pclist_device = NULL;
5515
96.4k
        if (code < 0)
5516
0
            return code;
5517
5518
        /* free our buffer object */
5519
96.4k
        if (fill_trans_buffer != NULL) {
5520
41.6k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5521
41.6k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5522
41.6k
        }
5523
96.4k
        if (ptile->cdev == NULL) {
5524
            /* pop our transparency group which will force the blending.
5525
               This was all needed for Bug 693498 */
5526
41.6k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5527
41.6k
                                                p14dev->blend_procs,
5528
41.6k
                                                p14dev->color_info.num_components - has_tags,
5529
41.6k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5530
41.6k
                                                pdev);
5531
41.6k
        }
5532
96.4k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5533
96.4k
        p14dev->pclist_device = NULL;
5534
96.4k
    }
5535
96.4k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5536
96.4k
    return code;
5537
96.4k
}
5538
5539
/* Useful function that should probably go elsewhere.
5540
 * Call this function to find the topmost pdf14 device in the device chain,
5541
 * or NULL if there is not one.
5542
 */
5543
static pdf14_device *find_pdf14_device(gx_device *dev)
5544
0
{
5545
0
    pdf14_device *pdev;
5546
5547
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5548
0
        return NULL;
5549
0
    return pdev;
5550
0
}
5551
5552
/* Imager render for pattern transparency filling.  This is just here to catch
5553
   the final flush, at which time we will pop the group and reset a few items */
5554
static  int
5555
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5556
                    uint w, int h, gx_device * dev)
5557
0
{
5558
0
    int code;
5559
0
    pdf14_device * p14dev;
5560
0
    const gs_gstate * pgs = penum->pgs;
5561
0
    gx_device_color * pdcolor = (penum->icolor1);
5562
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5563
0
    bool has_tags = device_encodes_tags(dev);
5564
5565
    /* Pass along to the original renderer */
5566
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5567
0
    if (code < 0)
5568
0
        return code;
5569
    /* On our final time through here, go ahead and pop the transparency
5570
       group and reset the procs in the device color. And free the fill
5571
       trans buffer object */
5572
0
    if (h == 0 && ptile->trans_group_popped == false) {
5573
0
        p14dev = find_pdf14_device(dev);
5574
5575
0
        if (p14dev->pclist_device == NULL) {
5576
            /* Used if we are on clist writing phase.  Would only
5577
               occur if we somehow failed in high level clist
5578
               image writing */
5579
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5580
0
        } else {
5581
            /* Used if we are on clist reading phase.  If we had high level
5582
               image in clist */
5583
0
            cmm_dev_profile_t *dev_profile;
5584
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5585
0
            if (code < 0)
5586
0
                return code;
5587
5588
0
            if_debug2m('v', p14dev->ctx->memory,
5589
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5590
0
                       ptile->uid.id, ptile->id);
5591
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5592
0
                    p14dev->color_info.num_components - has_tags,
5593
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5594
0
                    (gx_device *) p14dev);
5595
0
        }
5596
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5597
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5598
0
                       "pdf14_pattern_trans_render");
5599
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5600
0
    }
5601
0
    return code;
5602
0
}
5603
5604
/* This function is used to get things in place for filling a mask image
5605
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5606
   and pdf14_clist_begin_type_image */
5607
static int
5608
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5609
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5610
                           const gs_int_rect * prect,
5611
                           const gx_drawing_color * pdcolor,
5612
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5613
                           gx_image_enum_common_t ** pinfo)
5614
0
{
5615
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5616
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5617
0
    gx_color_tile *ptile;
5618
0
    int code;
5619
0
    gs_int_rect group_rect;
5620
0
    gx_image_enum *penum;
5621
0
    gs_rect bbox_in, bbox_out;
5622
0
    gx_pattern_trans_t *fill_trans_buffer;
5623
5624
0
    ptile = pdcolor->colors.pattern.p_tile;
5625
    /* Set up things in the ptile so that we get the proper
5626
       blending etc */
5627
    /* Set the blending procs and the is_additive setting based
5628
       upon the number of channels */
5629
0
    if (ptile->ttrans->n_chan-1 < 4) {
5630
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5631
0
        ptile->ttrans->is_additive = true;
5632
0
    } else {
5633
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5634
0
        ptile->ttrans->is_additive = false;
5635
0
    }
5636
    /* Set the blending mode in the ptile based upon the current
5637
       setting in the gs_gstate */
5638
0
    ptile->blending_mode = pgs->blend_mode;
5639
    /* Based upon if the tiles overlap pick the type of rect
5640
       fill that we will want to use */
5641
0
    if (ptile->has_overlap) {
5642
        /* This one does blending since there is tile overlap */
5643
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5644
0
    } else {
5645
        /* This one does no blending since there is no tile overlap */
5646
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5647
0
    }
5648
    /* Set the procs so that we use the proper filling method. */
5649
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5650
    /* Let the imaging stuff get set up */
5651
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5652
0
                            prect, pdcolor,pcpath, mem, pinfo);
5653
0
    if (code < 0)
5654
0
        return code;
5655
    /* Now Push the group */
5656
    /* First apply the inverse of the image matrix to our
5657
       image size to get our bounding box. */
5658
0
    bbox_in.p.x = 0;
5659
0
    bbox_in.p.y = 0;
5660
0
    bbox_in.q.x = pim->Width;
5661
0
    bbox_in.q.y = pim->Height;
5662
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5663
0
                                &bbox_out);
5664
0
    if (code < 0)
5665
0
        return code;
5666
    /* That in turn will get hit by the matrix in the gs_gstate */
5667
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5668
0
                                            &bbox_out, (gs_gstate *)pgs);
5669
0
    if (code < 0)
5670
0
        return code;
5671
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5672
0
        if_debug2m('v', p14dev->ctx->memory,
5673
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5674
0
                   ptile->uid.id, ptile->id);
5675
5676
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5677
0
                                             65535, pgs->blend_mode, 0, 0,
5678
0
                                             ptile->ttrans->n_chan-1, false, false,
5679
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5680
5681
        /* Set up the output buffer information now that we have
5682
           pushed the group */
5683
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5684
0
        if (fill_trans_buffer == NULL)
5685
0
            return_error(gs_error_VMerror);
5686
5687
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5688
5689
        /* Store this in the appropriate place in pdcolor.  This
5690
           is released later in pdf14_pattern_trans_render when
5691
           we are all done with the mask fill */
5692
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5693
5694
        /* Change the renderer to handle this case so we can catch the
5695
           end.  We will then pop the group and reset the pdcolor proc.
5696
           Keep the base renderer also. */
5697
0
        penum = (gx_image_enum *) *pinfo;
5698
0
        ptile->ttrans->image_render = penum->render;
5699
0
        penum->render = &pdf14_pattern_trans_render;
5700
0
        ptile->trans_group_popped = false;
5701
0
    }
5702
0
    return code;
5703
0
}
5704
5705
static  int
5706
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5707
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5708
                           const gs_int_rect * prect,
5709
                           const gx_drawing_color * pdcolor,
5710
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5711
                           gx_image_enum_common_t ** pinfo)
5712
592k
{
5713
592k
    const gs_image_t *pim = (const gs_image_t *)pic;
5714
592k
    int code;
5715
5716
592k
    code = pdf14_initialize_ctx(dev, pgs);
5717
592k
    if (code < 0)
5718
0
        return code;
5719
5720
    /* If we are filling an image mask with a pattern that has a transparency
5721
       then we need to do some special handling */
5722
592k
    if (pim->ImageMask) {
5723
84
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5724
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5725
                /* If we are in a final run through here for this case then
5726
                   go ahead and push the transparency group.   Also, update
5727
                   the proc for the pattern color so that we used the
5728
                   appropriate fill operation.  Note that the group
5729
                   is popped and the proc will be reset when we flush the
5730
                   image data.  This is handled in a special pdf14 image
5731
                   renderer which will end up installed for this case.
5732
                   Detect setting of begin_image to gx_no_begin_image.
5733
                   (final recursive call) */
5734
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5735
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5736
0
                                                prect, pdcolor, pcpath, mem,
5737
0
                                                pinfo);
5738
0
                    return code;
5739
0
                }
5740
0
            }
5741
0
        }
5742
84
    }
5743
592k
    pdf14_set_marking_params(dev, pgs);
5744
592k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5745
592k
                                        pcpath, mem, pinfo);
5746
592k
}
5747
5748
static  void
5749
pdf14_set_params(gs_gstate * pgs,
5750
                 gx_device * dev,
5751
                 const gs_pdf14trans_params_t * pparams)
5752
14.6M
{
5753
14.6M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5754
14.6M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5755
2.75M
        pgs->blend_mode = pparams->blend_mode;
5756
14.6M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5757
1.54M
        pgs->text_knockout = pparams->text_knockout;
5758
14.6M
    if (pparams->changed & PDF14_SET_AIS)
5759
703k
        pgs->alphaisshape = pparams->ais;
5760
14.6M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5761
4.03M
        pgs->overprint = pparams->overprint;
5762
14.6M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5763
4.02M
        pgs->stroke_overprint = pparams->stroke_overprint;
5764
14.6M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5765
4.59M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5766
14.6M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5767
3.91M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5768
14.6M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5769
4.30M
        gs_swapcolors_quick(pgs);
5770
4.30M
        if (pparams->op_fs_state == PDF14_OP_STATE_STROKE)
5771
1.47M
            pgs->is_fill_color = false;
5772
2.82M
        else
5773
2.82M
            pgs->is_fill_color = true;
5774
4.30M
    }
5775
14.6M
    pdf14_set_marking_params(dev, pgs);
5776
14.6M
}
5777
5778
/*
5779
 * This open_device method for the PDF 1.4 compositor devices is only used
5780
 * when these devices are disabled.  This routine is about as close to
5781
 * a pure "forwarding" open_device operation as is possible. Its only
5782
 * significant function is to ensure that the is_open field of the
5783
 * PDF 1.4 compositor devices matches that of the target device.
5784
 *
5785
 * We assume this procedure is called only if the device is not already
5786
 * open, and that gs_opendevice will take care of the is_open flag.
5787
 */
5788
static  int
5789
pdf14_forward_open_device(gx_device * dev)
5790
0
{
5791
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5792
0
    gx_device * tdev = pdev->target;
5793
0
    int code;
5794
5795
    /* The PDF 1.4 compositing devices must have a target */
5796
0
    if (tdev == 0)
5797
0
        return_error(gs_error_unknownerror);
5798
0
    if ((code = gs_opendevice(tdev)) >= 0)
5799
0
        gx_device_copy_params(dev, tdev);
5800
0
    return code;
5801
0
}
5802
5803
/*
5804
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5805
 * for setting any device procs that should not be forwarded.
5806
 */
5807
static  void
5808
pdf14_forward_device_procs(gx_device * dev)
5809
1.55M
{
5810
1.55M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5811
1.55M
    pdf14_device *p14dev = (pdf14_device*)dev;
5812
5813
    /* If doing simulated overprint with spot colors
5814
       then makes sure to reset devn setting */
5815
1.55M
    if (p14dev->overprint_sim &&
5816
1.55M
        p14dev->color_info.num_components > 4)
5817
0
        p14dev->icc_struct->supports_devn =
5818
0
            p14dev->target_support_devn;
5819
5820
    /*
5821
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5822
     * This will ensure that any new device procs are also set.  However that
5823
     * routine only changes procs which are NULL.  Thus we start by setting all
5824
     * procs to NULL.
5825
     */
5826
1.55M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5827
1.55M
    gx_device_forward_fill_in_procs(pdev);
5828
    /*
5829
     * gx_device_forward_fill_in_procs does not forward all procs.
5830
     * Set the remainding procs to also forward.
5831
     */
5832
1.55M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5833
1.55M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5834
1.55M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5835
1.55M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5836
1.55M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5837
1.55M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5838
1.55M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5839
1.55M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5840
1.55M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5841
1.55M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5842
    /* These are forwarding devices with minor tweaks. */
5843
1.55M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5844
1.55M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5845
1.55M
}
5846
5847
/*
5848
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5849
 * compositor device is never removed.  (We do not have a remove compositor
5850
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5851
 * routine implements that action.
5852
 */
5853
int
5854
pdf14_disable_device(gx_device * dev)
5855
1.54M
{
5856
1.54M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5857
5858
1.54M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5859
1.54M
    dev->color_info = pdev->target->color_info;
5860
1.54M
    pdf14_forward_device_procs(dev);
5861
1.54M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5862
1.54M
    return 0;
5863
1.54M
}
5864
5865
/*
5866
 * The default color space for PDF 1.4 blend modes is based upon the process
5867
 * color model of the output device.
5868
 */
5869
static  pdf14_default_colorspace_t
5870
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5871
                                 pdf14_blend_cs_t *blend_cs_state)
5872
4.38M
{
5873
    /* If a blend color space was specified, then go ahead and use that to
5874
       define the default color space for the blend modes.  Only Gray, RGB
5875
       or CMYK blend color spaces are allowed.  Note we do not allow this
5876
       setting if we are dealing with a separation device. */
5877
4.38M
    cmm_dev_profile_t *dev_profile;
5878
4.38M
    cmm_profile_t *blend_profile = NULL;
5879
4.38M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5880
4.38M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5881
4.38M
    bool valid_blend_cs = false;
5882
4.38M
    int has_tags = device_encodes_tags(pdev);
5883
5884
4.38M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5885
5886
    /* Are we using a blend color space or the output intent color space? Also
5887
       is there a conflict in the settings. i.e. has someone set a blend color
5888
       space and tried to use the output intent with simulate overprint setting.
5889
    */
5890
4.38M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5891
4.38M
        dev_profile->oi_profile != NULL &&
5892
4.38M
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5893
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5894
           possible conflicting command line settings and we will err on using the blend profile
5895
           if one was specified. */
5896
0
        if (dev_profile->blend_profile != NULL &&
5897
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5898
0
            blend_profile = dev_profile->blend_profile;
5899
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5900
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5901
0
        } else {
5902
            /* All good, use the output intent profile as we have one
5903
               and are doing simulate overprint with a different device
5904
               profile set. */
5905
0
            blend_profile = dev_profile->oi_profile;
5906
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5907
0
        }
5908
4.38M
    } else if (dev_profile->blend_profile != NULL &&
5909
4.38M
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5910
        /* Blend profile is different than device profile */
5911
0
        blend_profile = dev_profile->blend_profile;
5912
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5913
0
    }
5914
5915
    /* Make sure any blend color space is valid along with other cond */
5916
4.38M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5917
0
        if (!blend_profile->isdevlink &&
5918
0
            !blend_profile->islab &&
5919
0
            (blend_profile->data_cs == gsGRAY ||
5920
0
             blend_profile->data_cs == gsRGB ||
5921
0
             blend_profile->data_cs == gsCMYK)) {
5922
            /* Also, do not allow the use of the blend space when we are pushing
5923
               a pattern pdf14 device.  Those should inherit from the parent */
5924
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5925
0
                  gx_device_is_pattern_accum(pdev))) {
5926
0
                valid_blend_cs = true;
5927
0
            }
5928
0
        }
5929
0
    }
5930
5931
    /* If num components is one, just go ahead and use gray.  This avoids
5932
       issues with additive/subtractive mono color devices  */
5933
4.38M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5934
4.38M
        pdev->color_info.num_components == 1) {
5935
        /*
5936
        * Note:  We do not allow the SeparationOrder device parameter for
5937
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5938
        * and 3 colorants for DeviceRGB.
5939
        */
5940
4.08M
        if (valid_blend_cs) {
5941
0
            *blend_cs_state = temp_cs_state;
5942
0
            switch (blend_profile->num_comps) {
5943
0
            case 1:
5944
0
                return PDF14_DeviceGray;
5945
0
            case 3:
5946
0
                return PDF14_DeviceRGB;
5947
0
            case 4:
5948
0
                return PDF14_DeviceCMYK;
5949
0
            }
5950
0
        }
5951
4.08M
        if (pdev->color_info.num_components - has_tags == 1)
5952
1.24M
            return PDF14_DeviceGray;
5953
2.83M
        else if (pdev->color_info.num_components - has_tags == 3)
5954
2.83M
            return PDF14_DeviceRGB;
5955
0
        else
5956
0
            return PDF14_DeviceRGBspot;
5957
4.08M
    } else {
5958
        /*
5959
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5960
         * the CMYK plus spot colors will not support the blend color space
5961
         */
5962
298k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5963
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5964
        return PDF14_DeviceCustom;
5965
#endif
5966
        /*
5967
         * Count the number of CMYK process components supported by the output
5968
         * device.
5969
         */
5970
1.49M
        for (i = 0; i < 4; i++) {
5971
1.19M
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5972
5973
1.19M
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5974
1.19M
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5975
1.19M
            if (output_comp_num >= 0) {
5976
1.19M
                num_cmyk++;
5977
1.19M
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5978
1.19M
                    num_cmyk_used++;
5979
1.19M
            }
5980
1.19M
        }
5981
        /*
5982
         * Check if the device supports only CMYK.  Otherewise we assume that
5983
         * the output device supports spot colors.  Note:  This algorithm can
5984
         * be fooled if the SeparationOrder device parameter is being used by
5985
         * the output device device to only select CMYK.
5986
         */
5987
298k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5988
298k
            && pdev->color_info.max_components == 4) {
5989
53.3k
            if (valid_blend_cs) {
5990
0
                *blend_cs_state = temp_cs_state;
5991
0
                switch (blend_profile->num_comps) {
5992
0
                case 1:
5993
0
                    return PDF14_DeviceGray;
5994
0
                case 3:
5995
0
                    return PDF14_DeviceRGB;
5996
0
                case 4:
5997
0
                    return PDF14_DeviceCMYK;
5998
0
                }
5999
0
            }
6000
53.3k
            return PDF14_DeviceCMYK;
6001
53.3k
        }
6002
        /*
6003
         * Check if we should use the 'custom' PDF 1.4 compositor device.
6004
         * This device is only needed for those devices which do not support
6005
         * a basic CMYK process color model.
6006
         */
6007
245k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
6008
245k
        if (num_cmyk != 4)
6009
0
            return PDF14_DeviceCustom;
6010
245k
#endif
6011
        /*
6012
         * Otherewise we use a CMYK plus spot colors for blending.
6013
         */
6014
245k
        if (valid_blend_cs)
6015
0
            *blend_cs_state = temp_cs_state;
6016
245k
        return PDF14_DeviceCMYKspot;
6017
245k
    }
6018
4.38M
}
6019
6020
/*
6021
 * the PDF 1.4 transparency spec says that color space for blending
6022
 * operations can be based upon either a color space specified in the
6023
 * group or a default value based upon the output device.  We are
6024
 * currently only using a color space based upon the device.
6025
 */
6026
static  int
6027
get_pdf14_device_proto(gx_device       *dev,
6028
                       pdf14_device    *pdevproto,
6029
                       gs_gstate       *pgs,
6030
                 const gs_pdf14trans_t *pdf14pct,
6031
                       bool             use_pdf14_accum)
6032
1.56M
{
6033
1.56M
    pdf14_blend_cs_t blend_cs_state;
6034
1.56M
    pdf14_default_colorspace_t dev_cs =
6035
1.56M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6036
1.56M
                                                 &blend_cs_state);
6037
1.56M
    bool deep = device_is_deep(dev);
6038
1.56M
    int num_spots = pdf14pct->params.num_spot_colors;
6039
6040
    /* overprint overide */
6041
1.56M
    if (pdf14pct->params.overprint_sim_push &&
6042
1.56M
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6043
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6044
0
            dev_cs = PDF14_DeviceCMYKspot;
6045
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6046
0
        } else
6047
0
            dev_cs = PDF14_DeviceCMYK;
6048
0
    }
6049
6050
1.56M
    switch (dev_cs) {
6051
464k
        case PDF14_DeviceGray:
6052
464k
            *pdevproto = gs_pdf14_Gray_device;
6053
464k
            pdevproto->color_info.max_components = 1;
6054
464k
            pdevproto->color_info.num_components =
6055
464k
                                    pdevproto->color_info.max_components;
6056
464k
            pdevproto->color_info.depth = 8<<deep;
6057
464k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6058
464k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6059
464k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6060
464k
            pdevproto->sep_device = false;
6061
464k
            break;
6062
992k
        case PDF14_DeviceRGB:
6063
992k
            *pdevproto = gs_pdf14_RGB_device;
6064
992k
            pdevproto->color_info.depth = 24<<deep;
6065
992k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6066
992k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6067
992k
            pdevproto->sep_device = false;
6068
992k
            break;
6069
2.39k
        case PDF14_DeviceCMYK:
6070
2.39k
            *pdevproto = gs_pdf14_CMYK_device;
6071
2.39k
            pdevproto->color_info.depth = 32<<deep;
6072
2.39k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6073
2.39k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6074
2.39k
            pdevproto->sep_device = false;
6075
2.39k
            break;
6076
101k
        case PDF14_DeviceCMYKspot:
6077
101k
            *pdevproto = gs_pdf14_CMYKspot_device;
6078
            /* Need to figure out how we want to handle the device profile
6079
               for this case */
6080
            /*
6081
             * The number of components for the PDF14 device is the sum
6082
             * of the process components and the number of spot colors
6083
             * for the page.
6084
             */
6085
101k
            if (num_spots >= 0) {
6086
101k
                pdevproto->color_info.num_components =
6087
101k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
6088
101k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6089
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6090
101k
                pdevproto->color_info.depth =
6091
101k
                                    pdevproto->color_info.num_components * (8<<deep);
6092
101k
                pdevproto->sep_device = true;
6093
101k
            }
6094
101k
            break;
6095
0
        case PDF14_DeviceRGBspot:
6096
0
            *pdevproto = gs_pdf14_RGBspot_device;
6097
            /* Need to figure out how we want to handle the device profile
6098
               for this case */
6099
            /*
6100
             * The number of components for the PDF14 device is the sum
6101
             * of the process components and the number of spot colors
6102
             * for the page.
6103
             */
6104
0
            if (num_spots >= 0) {
6105
0
                pdevproto->color_info.num_components =
6106
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
6107
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6108
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6109
0
                pdevproto->color_info.depth =
6110
0
                    pdevproto->color_info.num_components * (8 << deep);
6111
0
                pdevproto->sep_device = true;
6112
0
            }
6113
0
            break;
6114
0
        case PDF14_DeviceCustom:
6115
            /*
6116
             * We are using the output device's process color model.  The
6117
             * color_info for the PDF 1.4 compositing device needs to match
6118
             * the output device.
6119
             */
6120
0
            *pdevproto = gs_pdf14_custom_device;
6121
0
            pdevproto->color_info = dev->color_info;
6122
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6123
0
            pdevproto->color_info.depth =
6124
0
                       pdevproto->color_info.num_components * (8<<deep);
6125
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6126
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6127
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6128
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6129
0
            break;
6130
0
        default:      /* Should not occur */
6131
0
            return_error(gs_error_rangecheck);
6132
1.56M
    }
6133
1.56M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6134
1.56M
    pdevproto->blend_cs_state = blend_cs_state;
6135
1.56M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6136
1.56M
    return 0;
6137
1.56M
}
6138
6139
/* When playing back the clist, we need to know if the buffer device is compatible */
6140
/* with the pdf14 compositor that was used when writing the clist. Colorspace and  */
6141
/* depth are critical since these must match when reading back colors.             */
6142
bool
6143
pdf14_ok_to_optimize(gx_device *dev)
6144
2.80M
{
6145
2.80M
    pdf14_blend_cs_t blend_cs_state;
6146
2.80M
    pdf14_default_colorspace_t pdf14_cs =
6147
2.80M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6148
2.80M
    gsicc_colorbuffer_t dev_icc_cs;
6149
2.80M
    bool ok = false;
6150
2.80M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6151
2.80M
    cmm_dev_profile_t *dev_profile;
6152
2.80M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6153
2.80M
    bool deep = device_is_deep(dev);
6154
6155
2.80M
    if (code < 0)
6156
0
        return false;
6157
6158
2.80M
    check_device_compatible_encoding(dev);
6159
6160
2.80M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6161
1.08M
        return false;
6162
6163
1.72M
    dev_icc_cs = dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->data_cs;
6164
    /* If the outputprofile is not "standard" then colors converted to device color */
6165
    /* during clist writing won't match the colors written for the pdf14 clist dev  */
6166
1.72M
    if (!(dev_icc_cs == gsGRAY || dev_icc_cs == gsRGB || dev_icc_cs == gsCMYK))
6167
0
        return false;                           /* can't handle funky output profiles */
6168
6169
1.72M
    switch (pdf14_cs) {
6170
442k
        case PDF14_DeviceGray:
6171
442k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6172
442k
            break;
6173
1.14M
        case PDF14_DeviceRGB:
6174
1.14M
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6175
1.14M
            break;
6176
0
        case PDF14_DeviceCMYK:
6177
0
            ok = dev->color_info.max_color == (deep ? 65535 : 255) && dev->color_info.depth == (32<<deep) + tag_depth;
6178
0
            break;
6179
142k
        case PDF14_DeviceCMYKspot:
6180
142k
            ok = false;     /* punt for this case */
6181
142k
            break;
6182
0
        case PDF14_DeviceRGBspot:
6183
0
            ok = false;     /* punt for this case */
6184
0
            break;
6185
0
        case PDF14_DeviceCustom:
6186
            /*
6187
             * We are using the output device's process color model.  The
6188
             * color_info for the PDF 1.4 compositing device needs to match
6189
             * the output device, but it may not have been contone.
6190
             */
6191
0
            ok = dev->color_info.depth == dev->color_info.num_components * (8<<deep) + tag_depth;
6192
0
            break;
6193
0
        default:      /* Should not occur */
6194
0
            ok = false;
6195
1.72M
    }
6196
1.72M
    return ok;
6197
1.72M
}
6198
6199
/*
6200
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6201
 * compositor device is never removed.  (We do not have a remove compositor
6202
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6203
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6204
 * again.
6205
 */
6206
static  int
6207
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6208
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6209
0
{
6210
0
    pdf14_device * pdev = (pdf14_device *)dev;
6211
0
    gx_device * target = pdev->target;
6212
0
    pdf14_device dev_proto;
6213
0
    bool has_tags = device_encodes_tags(dev);
6214
0
    int code;
6215
0
    bool deep = device_is_deep(dev);
6216
6217
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6218
6219
    /*
6220
     * We will not use the entire prototype device but we will set the
6221
     * color related info and the device procs to match the prototype.
6222
     */
6223
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6224
0
                                  pdf14pct, false);
6225
0
    if (code < 0)
6226
0
        return code;
6227
0
    pdev->color_info = dev_proto.color_info;
6228
0
    pdev->pad = target->pad;
6229
0
    pdev->log2_align_mod = target->log2_align_mod;
6230
6231
    /* The prototype has the color setup without tags. If we are
6232
     * using tags, then we need to extend num_components and depth.
6233
     */
6234
0
    if (has_tags) {
6235
0
        pdev->color_info.num_components++;
6236
0
        pdev->color_info.depth = pdev->color_info.num_components * (deep ? 16 : 8);
6237
0
    }
6238
6239
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
6240
0
        pdev->num_planar_planes = dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
6241
0
    else
6242
0
        pdev->num_planar_planes = target->num_planar_planes;
6243
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6244
6245
0
    pdev->procs = dev_proto.procs;
6246
0
    if (deep) {
6247
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6248
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6249
0
    }
6250
0
    if (has_tags) {
6251
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6252
0
    }
6253
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6254
0
    gx_device_fill_in_procs((gx_device *)pdev);
6255
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6256
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6257
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6258
0
    check_device_separable(dev);
6259
0
    return dev_proc(pdev, open_device)(dev);
6260
0
}
6261
6262
/*
6263
 * Implement the various operations that can be specified via the PDF 1.4
6264
 * create compositor request.
6265
 */
6266
static  int
6267
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6268
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6269
34.1M
{
6270
34.1M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6271
34.1M
    gs_pdf14trans_params_t params = pdf14pct->params;
6272
34.1M
    int code = 0;
6273
6274
34.1M
    params.idle = pdf14pct->idle;
6275
34.1M
    switch (params.pdf14_op) {
6276
0
        default:      /* Should not occur. */
6277
0
            break;
6278
13.9k
        case PDF14_PUSH_DEVICE:
6279
13.9k
            if (!(params.is_pattern)) {
6280
0
                p14dev->blend_mode = 0;
6281
0
                p14dev->opacity = p14dev->shape = 0.0;
6282
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6283
0
            }
6284
13.9k
            break;
6285
0
        case PDF14_ABORT_DEVICE:
6286
            /* Something has gone very wrong.  Let transparency device clean up
6287
               what ever it has allocated and then we are shutting it down */
6288
0
            code = gx_abort_trans_device(pgs, pdev);
6289
0
            if (p14dev->free_devicen) {
6290
0
                devn_free_params(pdev);
6291
0
            }
6292
0
            pdf14_disable_device(pdev);
6293
0
            pdf14_close(pdev);
6294
0
            break;
6295
1.55M
        case PDF14_POP_DEVICE:
6296
1.55M
            if (!(params.is_pattern)) {
6297
1.53M
                if_debug0m('v', pdev->memory,
6298
1.53M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6299
1.53M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6300
1.53M
                gx_set_cmap_procs(pgs, p14dev->target);
6301
                /* Send image out raster data to output device */
6302
1.53M
                {
6303
                    /* Make a copy so we can change the ROP */
6304
1.53M
                    gs_gstate new_pgs = *pgs;
6305
6306
                    /* We don't use the gs_gstate log_op since this is for the */
6307
                    /* clist playback. Putting the image (band in the case of the */
6308
                    /* clist) only needs to use the default ROP to copy the data  */
6309
1.53M
                    new_pgs.log_op = rop3_default;
6310
1.53M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6311
1.53M
                }
6312
                /* Before we disable the device release any deviceN structures.
6313
                    free_devicen is set if the pdf14 device had inherited its
6314
                    deviceN parameters from the target clist device.  In this
6315
                    case they should not be freed */
6316
1.53M
                if (p14dev->free_devicen) {
6317
1.53M
                    devn_free_params(pdev);
6318
1.53M
                }
6319
1.53M
                pdf14_disable_device(pdev);
6320
1.53M
                pdf14_close(pdev);
6321
1.53M
            }
6322
1.55M
            break;
6323
652k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6324
3.27M
        case PDF14_BEGIN_TRANS_GROUP:
6325
3.27M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6326
508k
                p14dev->depth_within_smask++;
6327
3.27M
            p14dev->smask_constructed = 0;
6328
3.27M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6329
3.27M
            break;
6330
2.86M
        case PDF14_END_TRANS_GROUP:
6331
2.86M
            code = gx_end_transparency_group(pgs, pdev);
6332
2.86M
            if (p14dev->depth_within_smask)
6333
508k
                p14dev->depth_within_smask--;
6334
2.86M
            break;
6335
121
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6336
121
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6337
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6338
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6339
0
            } else
6340
121
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6341
121
            break;
6342
403k
        case PDF14_END_TRANS_TEXT_GROUP:
6343
403k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6344
403k
                code = gx_end_transparency_group(pgs, pdev);
6345
403k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6346
403k
            break;
6347
6.39M
        case PDF14_BEGIN_TRANS_MASK:
6348
6.39M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6349
6.39M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6350
713k
                p14dev->in_smask_construction++;
6351
6.39M
            break;
6352
713k
        case PDF14_END_TRANS_MASK:
6353
713k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6354
713k
            if (code >= 0) {
6355
713k
                p14dev->in_smask_construction--;
6356
713k
                if (p14dev->in_smask_construction < 0)
6357
0
                    p14dev->in_smask_construction = 0;
6358
713k
                if (p14dev->in_smask_construction == 0)
6359
712k
                    p14dev->smask_constructed = 1;
6360
713k
            }
6361
713k
            break;
6362
14.6M
        case PDF14_SET_BLEND_PARAMS:
6363
14.6M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6364
14.6M
            break;
6365
0
        case PDF14_PUSH_TRANS_STATE:
6366
0
            code = gx_push_transparency_state(pgs, pdev);
6367
0
            break;
6368
4.27M
        case PDF14_POP_TRANS_STATE:
6369
4.27M
            code = gx_pop_transparency_state(pgs, pdev);
6370
4.27M
            break;
6371
14.0k
        case PDF14_PUSH_SMASK_COLOR:
6372
14.0k
            code = pdf14_increment_smask_color(pgs, pdev);
6373
14.0k
            break;
6374
14.0k
        case PDF14_POP_SMASK_COLOR:
6375
14.0k
            code = pdf14_decrement_smask_color(pgs, pdev);
6376
14.0k
            break;
6377
34.1M
    }
6378
34.1M
    return code;
6379
34.1M
}
6380
6381
/*
6382
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6383
 * compositor' method.  However the compositor is disabled when we are not
6384
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6385
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6386
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6387
 * to the target.
6388
 */
6389
static  int
6390
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6391
        const gs_composite_t * pct, gs_gstate * pgs,
6392
        gs_memory_t * mem, gx_device *cdev)
6393
1.11k
{
6394
1.11k
    pdf14_device *pdev = (pdf14_device *)dev;
6395
1.11k
    gx_device * tdev = pdev->target;
6396
1.11k
    int code;
6397
6398
1.11k
    *pcdev = dev;
6399
1.11k
    if (gs_is_pdf14trans_compositor(pct)) {
6400
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6401
6402
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6403
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6404
0
        return 0;
6405
0
    }
6406
1.11k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6407
1.11k
    if (code == 1) {
6408
        /* We have created a new compositor that wrapped tdev. This means
6409
         * that our target should be updated to point to that. */
6410
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6411
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6412
0
    }
6413
1.11k
    return code;
6414
1.11k
}
6415
6416
/*
6417
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6418
 * and return. Since the gs_pdf14_device only supports the high-level routines
6419
 * of the interface, don't bother trying to handle any other compositor.
6420
 */
6421
static int
6422
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6423
        const gs_composite_t * pct, gs_gstate * pgs,
6424
        gs_memory_t * mem, gx_device *cdev)
6425
189M
{
6426
189M
    pdf14_device *p14dev = (pdf14_device *)dev;
6427
189M
    if (gs_is_pdf14trans_compositor(pct)) {
6428
34.1M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6429
34.1M
        *pcdev = dev;
6430
        /* cdev, may be the clist reader device which may contain information that
6431
           we will need related to the ICC color spaces that define transparency
6432
           groups.  We want this propogated through all the pdf14 functions.  Store
6433
           a pointer to it in the pdf14 device */
6434
34.1M
        p14dev->pclist_device = cdev;
6435
34.1M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6436
155M
    } else if (gs_is_overprint_compositor(pct)) {
6437
                /* If we had an overprint compositer action, then the
6438
                   color components that were drawn should be updated.
6439
                   The overprint compositor logic and its interactions
6440
                   with the clist is a little odd as it passes uninitialized
6441
                   values around a fair amount.  Hence the forced assignement here.
6442
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6443
155M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6444
155M
                gx_color_index drawn_comps;
6445
155M
                PDF14_OP_FS_STATE curr_state = p14dev->op_state;
6446
6447
155M
                p14dev->op_state = op_pct->params.op_state;
6448
155M
                if (p14dev->op_state == PDF14_OP_STATE_NONE) {
6449
77.5M
                    if (op_pct->params.retain_any_comps) {
6450
53.0k
                        drawn_comps = op_pct->params.drawn_comps;
6451
77.5M
                    } else {
6452
                        /* Draw everything. If this parameter was not set, clist does
6453
                           not fill it in.  */
6454
77.5M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6455
77.5M
                    }
6456
6457
77.5M
                    if (op_pct->params.is_fill_color) {
6458
41.7M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6459
41.7M
                        p14dev->drawn_comps_fill = drawn_comps;
6460
41.7M
                    } else {
6461
35.8M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6462
35.8M
                        p14dev->drawn_comps_stroke = drawn_comps;
6463
35.8M
                    }
6464
                    /* We restore the NONE states as that is used just to force
6465
                       overprint settings in the overprint compositor communication */
6466
77.5M
                    p14dev->op_state = curr_state;
6467
77.5M
                }
6468
155M
                *pcdev = dev;
6469
155M
                return 0;
6470
155M
    } else
6471
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6472
189M
}
6473
6474
static int
6475
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6476
                      gs_blend_mode_t blend_mode, float opacity,
6477
                      float shape, bool is_clist)
6478
2.25k
{
6479
2.25k
    int code;
6480
2.25k
    gs_transparency_group_params_t params = { 0 };
6481
2.25k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6482
2.25k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6483
2.25k
    float alpha = pgs->fillconstantalpha;
6484
6485
    /* Push a non-isolated knock-out group making sure the opacity and blend
6486
       mode are correct */
6487
2.25k
    params.Isolated = false;
6488
2.25k
    params.Knockout = true;
6489
2.25k
    params.page_group = false;
6490
2.25k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6491
2.25k
    params.group_opacity = 1.0;
6492
2.25k
    params.group_shape = 1.0;
6493
6494
2.25k
    gs_setfillconstantalpha(pgs, 1.0);
6495
2.25k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6496
6497
2.25k
    if (is_clist) {
6498
2.25k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6499
2.25k
        if (code < 0)
6500
0
            return code;
6501
2.25k
    }
6502
6503
2.25k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6504
2.25k
    gs_setfillconstantalpha(pgs, alpha);
6505
2.25k
    gs_setblendmode(pgs, blend_mode);
6506
2.25k
    if (code < 0)
6507
0
        return code;
6508
6509
2.25k
    if (is_clist) {
6510
2.25k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6511
2.25k
    }
6512
2.25k
    return code;
6513
2.25k
}
6514
6515
static  int
6516
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6517
                 const gs_text_params_t * text, gs_font * font,
6518
                 const gx_clip_path * pcpath,
6519
                 gs_text_enum_t ** ppenum)
6520
314
{
6521
314
    int code;
6522
314
    gs_text_enum_t *penum;
6523
314
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6524
314
    float opacity = pgs->fillconstantalpha;
6525
314
    float shape = 1.0;
6526
314
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6527
314
    pdf14_device *pdev = (pdf14_device*)dev;
6528
314
    bool draw = !(text->operation & TEXT_DO_NONE);
6529
314
    uint text_mode = gs_currenttextrenderingmode(pgs);
6530
314
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6531
314
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6532
6533
314
    code = pdf14_initialize_ctx(dev, pgs);
6534
314
    if (code < 0)
6535
0
        return code;
6536
6537
314
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6538
314
    pdf14_set_marking_params(dev, pgs);
6539
314
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6540
314
    if (code < 0)
6541
0
        return code;
6542
6543
    /* We may need to push a non-isolated transparency group if the following
6544
       is true.
6545
       1) We are not currently in one that we pushed for text and we are in
6546
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6547
       2) The blend mode is not Normal or the opacity is not 1.0
6548
       3) Text knockout is set to true
6549
       4) We are actually doing a text drawing
6550
6551
       Special note:  If text-knockout is set to false while we are within a
6552
       BT ET pair, we should pop the group.  I need to create a test file for
6553
       this case.  */
6554
6555
       /* Catch case where we already pushed a group and are trying to push another one.
6556
       In that case, we will pop the current one first, as we don't want to be left
6557
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6558
       will not be caught until we do the put_image and notice that the stack is not
6559
       empty. */
6560
314
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6561
0
        code = gs_end_transparency_group(pgs);
6562
0
        if (code < 0)
6563
0
            return code;
6564
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6565
0
    }
6566
6567
314
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6568
314
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6569
314
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6570
314
         text_mode != 3 && /* don't bother with invisible text */
6571
314
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6572
1
        if (draw) {
6573
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6574
1
                false);
6575
1
        }
6576
314
    *ppenum = (gs_text_enum_t *)penum;
6577
314
    return code;
6578
314
}
6579
6580
static  int
6581
pdf14_initialize_device(gx_device *new_dev)
6582
1.56M
{
6583
1.56M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6584
6585
1.56M
    pdev->ctx = NULL;
6586
1.56M
    pdev->color_model_stack = NULL;
6587
1.56M
    pdev->smaskcolor = NULL;
6588
6589
1.56M
    return 0;
6590
1.56M
}
6591
6592
/*
6593
 * Implement copy_mono by filling lots of small rectangles.
6594
 */
6595
static int
6596
pdf14_copy_mono(gx_device * dev,
6597
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6598
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6599
25.6M
{
6600
25.6M
    const byte *sptr;
6601
25.6M
    const byte *line;
6602
25.6M
    int sbit, first_bit;
6603
25.6M
    int code, sbyte, bit, count;
6604
25.6M
    int run_length, startx, current_bit, bit_value;
6605
25.6M
    gx_color_index current_color;
6606
6607
25.6M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6608
25.6M
    line = base + (sourcex >> 3);
6609
25.6M
    sbit = sourcex & 7;
6610
25.6M
    first_bit = 7 - sbit;
6611
6612
    /* Loop through the height of the specified area. */
6613
192M
    while (h-- > 0) {
6614
        /* Set up for the start of each line of the area. */
6615
167M
        sptr = line;
6616
167M
        sbyte = *sptr++;
6617
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6618
         * the loop below so adding 1 means that we don't fall into the bit == 0
6619
         * case and incorrectly read a new byte from the source. This weirdness is because
6620
         * the original code wouold read off the end of the buffer if the number of bits in
6621
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6622
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6623
         * of the loop to the beginning meant we would not read past the end of the buffer
6624
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6625
         * reading another byte.
6626
         */
6627
167M
        bit = first_bit + 1;
6628
167M
        count = w;
6629
167M
        run_length = 0;
6630
167M
        startx = x;
6631
167M
        current_bit = 0;
6632
167M
        current_color = zero;
6633
6634
        /* Loop across each pixel of a line. */
6635
2.24G
        do {
6636
            /* Move to the next input bit. */
6637
2.24G
            if (bit == 0) {
6638
192M
                bit = 7;
6639
192M
                sbyte = *sptr++;
6640
192M
            }
6641
2.05G
            else
6642
2.05G
                bit--;
6643
2.24G
            bit_value = (sbyte >> bit) & 1;
6644
2.24G
            if (bit_value == current_bit) {
6645
                /* The value did not change, simply increment our run length */
6646
1.83G
                run_length++;
6647
1.83G
            } else {
6648
                /* The value changed, fill the current rectangle. */
6649
413M
                if (run_length != 0) {
6650
394M
                    if (current_color != gx_no_color_index) {
6651
169M
                        code = (*dev_proc(dev, fill_rectangle))
6652
169M
                                (dev, startx, y, run_length, 1, current_color);
6653
169M
                        if (code < 0)
6654
0
                            return code;
6655
169M
                    }
6656
394M
                    startx += run_length;
6657
394M
                }
6658
413M
                run_length = 1;
6659
413M
                current_color = bit_value ? one : zero;
6660
413M
                current_bit = bit_value;
6661
413M
            }
6662
2.24G
        } while (--count > 0);
6663
        /* Fill the last rectangle in the line. */
6664
167M
        if (run_length != 0 && current_color != gx_no_color_index) {
6665
73.8M
            code = (*dev_proc(dev, fill_rectangle))
6666
73.8M
                        (dev, startx, y, run_length, 1, current_color);
6667
73.8M
            if (code < 0)
6668
0
                return code;
6669
73.8M
        }
6670
        /* Move to the next line */
6671
167M
        line += sraster;
6672
167M
        y++;
6673
167M
    }
6674
25.6M
    return 0;
6675
25.6M
}
6676
6677
/* Added to avoid having to go back and forth between fixed and int
6678
   in some of the internal methods used for dealing with tiling
6679
   and devn colors */
6680
static int
6681
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6682
    const gx_drawing_color *pdcolor)
6683
962
{
6684
962
    pdf14_device *pdev = (pdf14_device *)dev;
6685
962
    pdf14_buf *buf;
6686
962
    int code;
6687
6688
962
    fit_fill_xywh(dev, x, y, w, h);
6689
962
    if (w <= 0 || h <= 0)
6690
0
        return 0;
6691
6692
962
    code = pdf14_initialize_ctx(dev, NULL);
6693
962
    if (code < 0)
6694
0
        return code;
6695
962
    buf = pdev->ctx->stack;
6696
6697
962
    if (buf->knockout)
6698
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6699
0
            true);
6700
962
    else
6701
962
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6702
962
}
6703
6704
/* Step through and do rect fills with the devn colors as
6705
   we hit each transition in the bitmap. It is possible
6706
   that one of the colors is not devn, but is pure and
6707
   is set to gx_no_color_index. This type of mix happens
6708
   for example from tile_clip_fill_rectangle_hl_color */
6709
static int
6710
pdf14_copy_mono_devn(gx_device *dev,
6711
    const byte *base, int sourcex, int sraster,
6712
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6713
    const gx_drawing_color *pdcolor1)
6714
248
{
6715
248
    const byte *sptr;
6716
248
    const byte *line;
6717
248
    int sbit, first_bit;
6718
248
    int code, sbyte, bit, count;
6719
248
    int run_length, startx, current_bit, bit_value;
6720
248
    const gx_drawing_color *current_color;
6721
6722
248
    if ((x | y) < 0) {
6723
0
        if (x < 0) {
6724
0
            w += x;
6725
0
            sourcex -= x;
6726
0
            x = 0;
6727
0
        }
6728
0
        if (y < 0) {
6729
0
            h += y;
6730
0
            base -= (int)(y * sraster);
6731
0
            y = 0;
6732
0
        }
6733
0
    }
6734
248
    if (w > (dev)->width - x)
6735
0
        w = (dev)->width - x;
6736
248
    if (h > (dev)->height - y)
6737
0
        h = (dev)->height - y;
6738
248
    if (w <= 0 || h <= 0)
6739
0
        return 0;
6740
6741
248
    line = base + (sourcex >> 3);
6742
248
    sbit = sourcex & 7;
6743
248
    first_bit = 7 - sbit;
6744
6745
    /* Loop through the height of the specified area. */
6746
815
    while (h-- > 0) {
6747
        /* Set up for the start of each line of the area. */
6748
567
        sptr = line;
6749
567
        sbyte = *sptr++;
6750
567
        bit = first_bit;
6751
567
        count = w;
6752
567
        run_length = 0;
6753
567
        startx = x;
6754
567
        current_bit = 0;
6755
567
        current_color = pdcolor0;
6756
6757
        /* Loop across each pixel of a line. */
6758
6.15k
        do {
6759
6.15k
            bit_value = (sbyte >> bit) & 1;
6760
6.15k
            if (bit_value == current_bit) {
6761
                /* The value did not change, simply increment our run length */
6762
4.47k
                run_length++;
6763
4.47k
            } else {
6764
                /* The value changed, fill the current rectangle. */
6765
1.67k
                if (run_length != 0) {
6766
1.51k
                    if (current_color->type != gx_dc_type_pure &&
6767
1.51k
                        current_color->colors.pure != gx_no_color_index) {
6768
717
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6769
717
                            run_length, 1, current_color);
6770
717
                        if (code < 0)
6771
0
                            return code;
6772
717
                    }
6773
1.51k
                    startx += run_length;
6774
1.51k
                }
6775
1.67k
                run_length = 1;
6776
1.67k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6777
1.67k
                current_bit = bit_value;
6778
1.67k
            }
6779
6780
            /* Move to the next input bit. */
6781
6.15k
            if (bit == 0) {
6782
553
                bit = 7;
6783
553
                sbyte = *sptr++;
6784
553
            } else
6785
5.60k
                bit--;
6786
6.15k
        } while (--count > 0);
6787
6788
        /* Fill the last rectangle in the line. */
6789
567
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6790
567
            current_color->colors.pure != gx_no_color_index) {
6791
245
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6792
245
                run_length, 1, current_color);
6793
245
            if (code < 0)
6794
0
                return code;
6795
245
        }
6796
        /* Move to the next line */
6797
567
        line += sraster;
6798
567
        y++;
6799
567
    }
6800
248
    return 0;
6801
248
}
6802
6803
/* Step through the tiles doing essentially copy_mono but with devn colors */
6804
static int
6805
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6806
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6807
    const gx_drawing_color *pdcolor1, int px, int py)
6808
248
{   /* Fill the rectangle in chunks. */
6809
248
    int width = tiles->size.x;
6810
248
    int height = tiles->size.y;
6811
248
    int raster = tiles->raster;
6812
248
    int rwidth = tiles->rep_width;
6813
248
    int rheight = tiles->rep_height;
6814
248
    int shift = tiles->shift;
6815
6816
248
    if (rwidth == 0 || rheight == 0)
6817
0
        return_error(gs_error_unregistered);
6818
248
    fit_fill_xy(dev, x, y, w, h);
6819
6820
248
     {
6821
248
        int xoff = (shift == 0 ? px :
6822
248
                px + (y + py) / rheight * tiles->rep_shift);
6823
248
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6824
0
            (x + xoff) & (rwidth - 1) :
6825
248
            (x + xoff) % rwidth);
6826
248
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6827
0
            (y + py) & (rheight - 1) :
6828
248
            (y + py) % rheight);
6829
248
        int icw = width - irx;
6830
248
        int ch = height - ry;
6831
248
        byte *row = tiles->data + ry * raster;
6832
248
        int code = 0;
6833
6834
248
        if (ch >= h) {      /* Shallow operation */
6835
248
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6836
248
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6837
248
                    w, h, pdcolor0, pdcolor1);
6838
248
                if (code < 0)
6839
0
                    return_error(code);
6840
248
            } else {
6841
0
                int ex = x + w;
6842
0
                int fex = ex - width;
6843
0
                int cx = x + icw;
6844
6845
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6846
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6847
0
                if (code < 0)
6848
0
                    return_error(code);
6849
6850
0
                while (cx <= fex) {
6851
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6852
0
                        width, h, pdcolor0, pdcolor1);
6853
0
                    if (code < 0)
6854
0
                        return_error(code);
6855
0
                    cx += width;
6856
0
                }
6857
0
                if (cx < ex) {
6858
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6859
0
                        ex - cx, h, pdcolor0, pdcolor1);
6860
0
                    if (code < 0)
6861
0
                        return_error(code);
6862
0
                }
6863
0
            }
6864
248
        } else if (icw >= w && shift == 0) {
6865
            /* Narrow operation, no shift */
6866
0
            int ey = y + h;
6867
0
            int fey = ey - height;
6868
0
            int cy = y + ch;
6869
6870
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6871
0
                x, y, w, ch, pdcolor0, pdcolor1);
6872
0
            if (code < 0)
6873
0
                return_error(code);
6874
0
            row = tiles->data;
6875
0
            do {
6876
0
                ch = (cy > fey ? ey - cy : height);
6877
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6878
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6879
0
                if (code < 0)
6880
0
                    return_error(code);
6881
0
            } while ((cy += ch) < ey);
6882
0
        } else {
6883
            /* Full operation.  If shift != 0, some scan lines */
6884
            /* may be narrow.  We could test shift == 0 in advance */
6885
            /* and use a slightly faster loop, but right now */
6886
            /* we don't bother. */
6887
0
            int ex = x + w, ey = y + h;
6888
0
            int fex = ex - width, fey = ey - height;
6889
0
            int cx, cy;
6890
6891
0
            for (cy = y;;) {
6892
0
                if (icw >= w) {
6893
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6894
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6895
0
                    if (code < 0)
6896
0
                        return_error(code);
6897
0
                } else {
6898
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6899
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6900
0
                    if (code < 0)
6901
0
                        return_error(code);
6902
0
                    cx = x + icw;
6903
0
                    while (cx <= fex) {
6904
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6905
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6906
0
                        if (code < 0)
6907
0
                            return_error(code);
6908
0
                        cx += width;
6909
0
                    }
6910
0
                    if (cx < ex) {
6911
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6912
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6913
0
                        if (code < 0)
6914
0
                            return_error(code);
6915
0
                    }
6916
0
                }
6917
0
                if ((cy += ch) >= ey)
6918
0
                    break;
6919
0
                ch = (cy > fey ? ey - cy : height);
6920
0
                if ((irx += shift) >= rwidth)
6921
0
                    irx -= rwidth;
6922
0
                icw = width - irx;
6923
0
                row = tiles->data;
6924
0
            }
6925
0
        }
6926
248
    }
6927
248
    return 0;
6928
248
}
6929
6930
/* pdf14 device supports devn */
6931
static int
6932
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6933
    int x, int y, int w, int h,
6934
    const gx_drawing_color *pdcolor0,
6935
    const gx_drawing_color *pdcolor1, int px, int py)
6936
248
{
6937
248
    pdf14_device *pdev = (pdf14_device *)dev;
6938
248
    pdf14_buf *buf;
6939
248
    int num_comp;
6940
248
    int k;
6941
248
    bool same = false;
6942
248
    int code;
6943
6944
248
    code = pdf14_initialize_ctx(dev, NULL);
6945
248
    if (code < 0)
6946
0
        return code;
6947
248
    buf = pdev->ctx->stack;
6948
248
    num_comp = buf->n_chan - 1;
6949
6950
    /* if color0 is identical to color1, do rect fill */
6951
248
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6952
0
        same = true;
6953
0
        for (k = 0; k < num_comp; k++) {
6954
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6955
0
                same = false;
6956
0
                break;
6957
0
            }
6958
0
        }
6959
0
    }
6960
6961
248
    if (same) {
6962
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6963
248
    } else {
6964
        /* Go through the tile stepping using code stolen from
6965
           gx_default_strip_tile_rectangle and call the rect fills
6966
           using code stolen from pdf14_copy_mono but using devn
6967
           colors */
6968
248
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6969
248
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6970
248
    }
6971
248
    return code;
6972
248
}
6973
6974
/* Used in a few odd cases where the target device is planar and we have
6975
   a planar tile (pattern) and we are copying it into place here */
6976
static int
6977
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6978
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6979
2.45k
{
6980
2.45k
    pdf14_device *pdev = (pdf14_device *)dev;
6981
2.45k
    pdf14_ctx *ctx;
6982
2.45k
    pdf14_buf *buf;
6983
2.45k
    int xo = x;
6984
2.45k
    int yo = y;
6985
2.45k
    pdf14_buf fake_tos;
6986
2.45k
    int deep;
6987
6988
2.45k
    int code = pdf14_initialize_ctx(dev, NULL);
6989
2.45k
    if (code < 0)
6990
0
        return code;
6991
6992
2.45k
    fit_fill_xywh(dev, x, y, w, h);
6993
2.45k
    if (w <= 0 || h <= 0)
6994
0
        return 0;
6995
6996
2.45k
    ctx = pdev->ctx;
6997
2.45k
    buf = ctx->stack;
6998
2.45k
    deep = ctx->deep;
6999
7000
2.45k
    fake_tos.deep = deep;
7001
2.45k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7002
2.45k
    fake_tos.backdrop = NULL;
7003
2.45k
    fake_tos.blend_mode = pdev->blend_mode;
7004
2.45k
    fake_tos.color_space = buf->color_space;
7005
2.45k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7006
2.45k
    fake_tos.dirty.p.x = x;
7007
2.45k
    fake_tos.dirty.p.y = y;
7008
2.45k
    fake_tos.dirty.q.x = x + w;
7009
2.45k
    fake_tos.dirty.q.y = y + h;
7010
2.45k
    fake_tos.has_alpha_g = 0;
7011
2.45k
    fake_tos.has_shape = 0;
7012
2.45k
    fake_tos.has_tags = 0;
7013
2.45k
    fake_tos.idle = false;
7014
2.45k
    fake_tos.isolated = false;
7015
2.45k
    fake_tos.knockout = false;
7016
2.45k
    fake_tos.mask_id = 0;
7017
2.45k
    fake_tos.mask_stack = NULL;
7018
2.45k
    fake_tos.matte = NULL;
7019
2.45k
    fake_tos.matte_num_comps = 0;
7020
2.45k
    fake_tos.memory = dev->memory;
7021
2.45k
    fake_tos.n_chan = dev->color_info.num_components;
7022
2.45k
    fake_tos.n_planes = dev->color_info.num_components;
7023
2.45k
    fake_tos.num_spots = 0;
7024
2.45k
    fake_tos.group_color_info = NULL;
7025
2.45k
    fake_tos.planestride = raster * plane_height;
7026
2.45k
    fake_tos.rect.p.x = x;
7027
2.45k
    fake_tos.rect.p.y = y;
7028
2.45k
    fake_tos.rect.q.x = x + w;
7029
2.45k
    fake_tos.rect.q.y = y + h;
7030
2.45k
    fake_tos.rowstride = raster;
7031
2.45k
    fake_tos.saved = NULL;
7032
2.45k
    fake_tos.shape = 0xffff;
7033
2.45k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7034
2.45k
    fake_tos.transfer_fn = NULL;
7035
2.45k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7036
2.45k
                                  pdev->ctx->memory, dev);
7037
2.45k
    return 0;
7038
2.45k
}
7039
7040
static int
7041
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7042
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7043
    const gx_clip_path *pcpath)
7044
23.9M
{
7045
23.9M
    pdf14_device *pdev = (pdf14_device *)dev;
7046
23.9M
    pdf14_buf* buf;
7047
23.9M
    int code;
7048
23.9M
    int x = fixed2int(rect->p.x);
7049
23.9M
    int y = fixed2int(rect->p.y);
7050
23.9M
    int w = fixed2int(rect->q.x) - x;
7051
23.9M
    int h = fixed2int(rect->q.y) - y;
7052
7053
23.9M
    fit_fill_xywh(dev, x, y, w, h);
7054
23.9M
    if (w <= 0 || h <= 0)
7055
554k
        return 0;
7056
7057
23.4M
    code = pdf14_initialize_ctx(dev, pgs);
7058
23.4M
    if (code < 0)
7059
0
        return code;
7060
23.4M
    buf = pdev->ctx->stack;
7061
7062
23.4M
    if (buf->knockout)
7063
622k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7064
622k
                                                   true);
7065
22.7M
    else
7066
22.7M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7067
23.4M
}
7068
7069
static  int
7070
pdf14_fill_rectangle(gx_device * dev,
7071
                    int x, int y, int w, int h, gx_color_index color)
7072
734M
{
7073
734M
    pdf14_device *pdev = (pdf14_device *)dev;
7074
734M
    pdf14_buf *buf;
7075
734M
    int code;
7076
7077
734M
    fit_fill_xywh(dev, x, y, w, h);
7078
734M
    if (w <= 0 || h <= 0)
7079
11.4M
        return 0;
7080
7081
723M
    code = pdf14_initialize_ctx(dev, NULL);
7082
723M
    if (code < 0)
7083
0
        return code;
7084
7085
723M
    buf = pdev->ctx->stack;
7086
7087
723M
    if (buf->knockout)
7088
4.29M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7089
4.29M
                                                   false);
7090
719M
    else
7091
719M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7092
723M
}
7093
7094
static int
7095
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7096
                                    const gs_rect *pbbox, gs_int_rect *rect)
7097
3.70M
{
7098
3.70M
    gs_rect dev_bbox;
7099
3.70M
    int code;
7100
7101
3.70M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7102
3.70M
    if (code < 0)
7103
0
        return code;
7104
3.70M
    rect->p.x = (int)floor(dev_bbox.p.x);
7105
3.70M
    rect->p.y = (int)floor(dev_bbox.p.y);
7106
3.70M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7107
3.70M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7108
    /* Sanity check rect for insane ctms */
7109
3.70M
    if (rect->p.x < 0)
7110
822k
        rect->p.x = 0;
7111
3.70M
    if (rect->q.x < rect->p.x)
7112
4.41k
        rect->q.x = rect->p.x;
7113
3.70M
    if (rect->p.y < 0)
7114
3.35M
        rect->p.y = 0;
7115
3.70M
    if (rect->q.y < rect->p.y)
7116
95.5k
        rect->q.y = rect->p.y;
7117
3.70M
    return 0;
7118
3.70M
}
7119
7120
static  int
7121
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7122
                              const gs_rect *pbbox, gs_gstate *pgs)
7123
3.58M
{
7124
3.58M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7125
7126
3.58M
    if (code < 0)
7127
0
        return code;
7128
3.58M
    rect_intersect(*rect, pdev->ctx->rect);
7129
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7130
3.58M
    if (rect->q.x < rect->p.x)
7131
16.2k
        rect->q.x = rect->p.x;
7132
3.58M
    if (rect->q.y < rect->p.y)
7133
111k
        rect->q.y = rect->p.y;
7134
3.58M
    return 0;
7135
3.58M
}
7136
7137
static  int
7138
pdf14_begin_transparency_group(gx_device* dev,
7139
    const gs_transparency_group_params_t* ptgp,
7140
    const gs_rect* pbbox,
7141
    gs_gstate* pgs, gs_memory_t* mem)
7142
3.27M
{
7143
3.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7144
3.27M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7145
3.27M
    gs_int_rect rect;
7146
3.27M
    int code;
7147
3.27M
    bool isolated = ptgp->Isolated;
7148
3.27M
    gs_transparency_color_t group_color_type;
7149
3.27M
    cmm_profile_t* group_profile;
7150
3.27M
    cmm_profile_t* tos_profile;
7151
3.27M
    gsicc_rendering_param_t render_cond;
7152
3.27M
    cmm_dev_profile_t* dev_profile;
7153
3.27M
    bool cm_back_drop = false;
7154
3.27M
    bool new_icc = false;
7155
3.27M
    pdf14_group_color_t* group_color_info;
7156
3.27M
    bool has_tags = device_encodes_tags(dev);
7157
7158
3.27M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7159
3.27M
    if (code < 0)
7160
0
        return code;
7161
3.27M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7162
7163
3.27M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7164
403k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7165
403k
    }
7166
7167
3.27M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7168
403k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7169
2.86M
    else
7170
2.86M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7171
7172
3.27M
    if (code < 0)
7173
0
        return code;
7174
3.27M
    if_debug5m('v', pdev->memory,
7175
3.27M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7176
3.27M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7177
7178
    /* If the group color is unknown then use the current device profile. */
7179
3.27M
    if (ptgp->group_color_type == UNKNOWN) {
7180
2.60M
        group_color_type = ICC;
7181
2.60M
        group_profile = tos_profile;
7182
2.60M
    }
7183
671k
    else {
7184
671k
        group_color_type = ptgp->group_color_type;
7185
671k
        group_profile = ptgp->iccprofile;
7186
671k
    }
7187
7188
    /* We have to handle case where the profile is in the clist */
7189
3.27M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7190
        /* Get the serialized data from the clist. */
7191
671k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7192
671k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7193
671k
        if (group_profile == NULL)
7194
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7195
        /* Keep a pointer to the clist device */
7196
671k
        group_profile->dev = (gx_device*)pcrdev;
7197
671k
        new_icc = true;
7198
671k
    }
7199
3.27M
    if (group_profile != NULL) {
7200
        /* If we have a non-isolated group and the color space is different,
7201
            we will need to CM the backdrop. */
7202
3.27M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7203
256k
            cm_back_drop = true;
7204
256k
        }
7205
3.27M
    }
7206
7207
    /* Always create the base color group information as it is only through
7208
       groups that we can have a color space change.  This will survive
7209
       the life of the context. */
7210
3.27M
    if (pdev->ctx->base_color == NULL) {
7211
835k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7212
835k
    }
7213
7214
    /* If this is not the page group and we don't yet have a group, we need
7215
       to create a buffer for the whole page so that we can handle stuff drawn
7216
       outside this current group (e.g. two non inclusive groups drawn independently) */
7217
3.27M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7218
69.2k
        code = pdf14_initialize_ctx(dev, NULL);
7219
69.2k
        if (code < 0)
7220
0
            return code;
7221
69.2k
        pdev->ctx->stack->isolated = true;
7222
69.2k
    }
7223
7224
3.27M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7225
3.27M
        group_profile, false);
7226
3.27M
    if (group_color_info == NULL)
7227
0
        return gs_error_VMerror;
7228
3.27M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7229
7230
3.27M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7231
3.27M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7232
3.27M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7233
3.27M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7234
3.27M
                                        pgs->blend_mode, ptgp->idle,
7235
3.27M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7236
3.27M
                                         cm_back_drop, ptgp->shade_group,
7237
3.27M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7238
3.27M
    if (new_icc)
7239
671k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7240
3.27M
    return code;
7241
3.27M
}
7242
7243
static void
7244
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7245
3.27M
{
7246
3.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7247
7248
3.27M
    if (group_color != NULL &&
7249
3.27M
        !(group_color->group_color_mapping_procs == NULL &&
7250
3.27M
            group_color->group_color_comp_index == NULL)) {
7251
3.27M
        bool has_tags = device_encodes_tags(dev);
7252
3.27M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7253
3.27M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7254
3.27M
        pdev->color_info.polarity = group_color->polarity;
7255
3.27M
        if (pdev->num_planar_planes > 0)
7256
122k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7257
3.27M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7258
3.27M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7259
3.27M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7260
3.27M
        pdev->blend_procs = group_color->blend_procs;
7261
3.27M
        pdev->ctx->additive = group_color->isadditive;
7262
3.27M
        pdev->pdf14_procs = group_color->unpack_procs;
7263
3.27M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7264
3.27M
        pdev->color_info.depth = group_color->depth;
7265
3.27M
        pdev->color_info.max_color = group_color->max_color;
7266
3.27M
        pdev->color_info.max_gray = group_color->max_gray;
7267
3.27M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7268
3.27M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7269
3.27M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7270
3.27M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7271
3.27M
        if (group_color->icc_profile != NULL) {
7272
            /* make sure to decrement the device profile.  If it was allocated
7273
               with the push then it will be freed. */
7274
3.27M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7275
3.27M
                                    -1, "pdf14_pop_color_model");
7276
3.27M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7277
3.27M
                                    group_color->icc_profile;
7278
7279
3.27M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7280
3.27M
                                    1, "pdf14_pop_color_model");
7281
3.27M
        }
7282
3.27M
        pdev->num_std_colorants = group_color->num_std_colorants;
7283
3.27M
    }
7284
3.27M
}
7285
7286
static  int
7287
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7288
3.27M
{
7289
3.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7290
3.27M
    int code;
7291
3.27M
    cmm_profile_t* group_profile;
7292
3.27M
    gsicc_rendering_param_t render_cond;
7293
3.27M
    cmm_dev_profile_t* dev_profile;
7294
3.27M
    int has_tags = device_encodes_tags(dev);
7295
7296
3.27M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7297
3.27M
    if (code < 0)
7298
0
        return code;
7299
7300
3.27M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7301
3.27M
        &render_cond);
7302
3.27M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7303
7304
3.27M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7305
3.27M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7306
3.27M
    if (code < 0)
7307
0
        return code;
7308
#ifdef DEBUG
7309
    pdf14_debug_mask_stack_state(pdev->ctx);
7310
#endif
7311
    /* If this group is the base group, then restore the color model
7312
       of the device at this time.  Note that during the actual device pop
7313
       we will need to use the profile of the buffer not the pdf14 device
7314
       as the source color space */
7315
3.27M
    if (pdev->ctx->stack->group_popped) {
7316
650k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7317
2.61M
    } else {
7318
2.61M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7319
2.61M
    }
7320
7321
3.27M
    return code;
7322
3.27M
}
7323
7324
static pdf14_group_color_t*
7325
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7326
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7327
                        bool is_mask)
7328
3.98M
{
7329
3.98M
    pdf14_device *pdevproto = NULL;
7330
3.98M
    pdf14_device *pdev = (pdf14_device *)dev;
7331
3.98M
    const pdf14_procs_t *new_14procs = NULL;
7332
3.98M
    pdf14_group_color_t *group_color;
7333
3.98M
    gx_color_polarity_t new_polarity;
7334
3.98M
    uchar new_num_comps;
7335
3.98M
    bool new_additive;
7336
3.98M
    gx_device_clist_reader *pcrdev;
7337
3.98M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7338
3.98M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7339
3.98M
    int k;
7340
3.98M
    bool has_tags = device_encodes_tags(dev);
7341
3.98M
    bool deep = pdev->ctx->deep;
7342
7343
3.98M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7344
7345
3.98M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7346
3.98M
                               pdf14_group_color_t, &st_pdf14_clr,
7347
3.98M
                               "pdf14_push_color_model");
7348
3.98M
    if (group_color == NULL)
7349
0
        return NULL;
7350
7351
3.98M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7352
7353
3.98M
    switch (group_color_type) {
7354
0
        case GRAY_SCALE:
7355
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7356
0
            new_num_comps = 1;
7357
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7358
0
            new_additive = true;
7359
0
            new_14procs = &gray_pdf14_procs;
7360
0
            break;
7361
0
        case DEVICE_RGB:
7362
0
        case CIE_XYZ:
7363
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7364
0
            new_num_comps = 3;
7365
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7366
0
            new_additive = true;
7367
0
            new_14procs = &rgb_pdf14_procs;
7368
0
            break;
7369
0
        case DEVICE_CMYK:
7370
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7371
0
            new_num_comps = 4;
7372
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7373
0
            new_additive = false;
7374
            /* This is needed due to the mismatched compressed encode decode
7375
                between the device procs and the pdf14 procs */
7376
0
            if (dev->color_info.num_components > 4){
7377
0
                new_14procs = &cmykspot_pdf14_procs;
7378
0
            } else {
7379
0
                new_14procs = &cmyk_pdf14_procs;
7380
0
            }
7381
0
            break;
7382
3.98M
        case ICC:
7383
            /* If we are coming from the clist reader, then we need to get
7384
                the ICC data now  */
7385
3.98M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7386
                /* Get the serialized data from the clist.  Not the whole
7387
                    profile. */
7388
699k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7389
699k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7390
699k
                                                    icc_hashcode);
7391
699k
                if (iccprofile == NULL)
7392
0
                    return NULL;
7393
                /* Keep a pointer to the clist device */
7394
699k
                iccprofile->dev = (gx_device *) pcrdev;
7395
3.28M
            } else {
7396
                /* Go ahead and rc increment right now.  This way when
7397
                    we pop, we will make sure to decrement and avoid a
7398
                    leak for the above profile that we just created.  This
7399
                    goes with the assignment to the device's profile.
7400
                    Note that we still do the increment for the group_color
7401
                    assignment below. */
7402
3.28M
                if (iccprofile == NULL)
7403
0
                    return NULL;
7404
3.28M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7405
3.28M
            }
7406
3.98M
            new_num_comps = iccprofile->num_comps;
7407
3.98M
            if (new_num_comps == 4) {
7408
895k
                new_additive = false;
7409
895k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7410
3.08M
            } else {
7411
3.08M
                new_additive = true;
7412
3.08M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7413
3.08M
            }
7414
3.98M
            switch (new_num_comps) {
7415
882k
                case 1:
7416
882k
                    if (pdev->sep_device && !is_mask) {
7417
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7418
0
                        new_14procs = &grayspot_pdf14_procs;
7419
882k
                    } else {
7420
882k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7421
882k
                        new_14procs = &gray_pdf14_procs;
7422
882k
                    }
7423
882k
                    break;
7424
2.20M
                case 3:
7425
2.20M
                    if (pdev->sep_device) {
7426
62.0k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7427
62.0k
                        new_14procs = &rgbspot_pdf14_procs;
7428
62.0k
                    }
7429
2.14M
                    else {
7430
2.14M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7431
2.14M
                        new_14procs = &rgb_pdf14_procs;
7432
2.14M
                    }
7433
2.20M
                    break;
7434
895k
                case 4:
7435
895k
                    if (pdev->sep_device) {
7436
60.6k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7437
60.6k
                        new_14procs = &cmykspot_pdf14_procs;
7438
835k
                    } else {
7439
835k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7440
835k
                        new_14procs = &cmyk_pdf14_procs;
7441
835k
                    }
7442
895k
                    break;
7443
0
                default:
7444
0
                    return NULL;
7445
0
                    break;
7446
3.98M
            }
7447
3.98M
            break;
7448
3.98M
        default:
7449
0
            return NULL;
7450
0
            break;
7451
3.98M
    }
7452
7453
    /* We might just have changed the colorspace of the device, which means
7454
     * the number of colorants have changed. */
7455
3.98M
    group_color->num_std_colorants = new_num_comps;
7456
3.98M
    pdev->num_std_colorants = new_num_comps;
7457
7458
3.98M
    if (has_tags)
7459
0
        new_num_comps++;
7460
7461
3.98M
    if (group_color_type == ICC && iccprofile != NULL) {
7462
3.98M
        group_color->icc_profile = iccprofile;
7463
3.98M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7464
3.98M
    }
7465
7466
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7467
       spot colorants and know how to index into them */
7468
3.98M
    if (pdev->sep_device && !is_mask) {
7469
122k
        int num_spots = dev->color_info.num_components - has_tags -
7470
122k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7471
7472
122k
        if (num_spots > 0)
7473
342
            new_num_comps += num_spots;
7474
122k
    }
7475
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7476
15.0M
    for (k = 0; k < new_num_comps; k++) {
7477
11.0M
        comp_bits[k] = 8<<deep;
7478
11.0M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7479
11.0M
    }
7480
7481
    /* Set device values now and store settings in group_color.  Then they
7482
       are available when we pop the previous group */
7483
3.98M
    if_debug2m('v', pdev->memory,
7484
3.98M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7485
3.98M
                pdev->color_info.num_components,new_num_comps);
7486
3.98M
    {
7487
3.98M
        gx_device local_device;
7488
7489
3.98M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7490
3.98M
        local_device.initialize_device_procs((gx_device *)&local_device);
7491
3.98M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7492
3.98M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7493
3.98M
    }
7494
3.98M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7495
3.98M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7496
3.98M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7497
3.98M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7498
3.98M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7499
3.98M
    if (pdev->num_planar_planes > 0)
7500
154k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7501
3.98M
    group_color->num_components = new_num_comps - has_tags;
7502
3.98M
    pdev->color_info.num_components = new_num_comps;
7503
3.98M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7504
3.98M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7505
3.98M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7506
3.98M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7507
3.98M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7508
3.98M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7509
3.98M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7510
3.98M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7511
3.98M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7512
3.98M
    group_color->depth = pdev->color_info.depth;
7513
3.98M
    group_color->decode = dev_proc(pdev, decode_color);
7514
3.98M
    group_color->encode = dev_proc(pdev, encode_color);
7515
3.98M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7516
3.98M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7517
3.98M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7518
3.98M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7519
3.98M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7520
3.98M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7521
3.98M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7522
7523
    /* If the CS was ICC based, we need to update the device ICC profile
7524
        in the ICC manager, since that is the profile that is used for the
7525
        PDF14 device */
7526
3.98M
    if (group_color_type == ICC && iccprofile != NULL) {
7527
        /* iccprofile was incremented above if we had not just created it.
7528
           When we do the pop we will decrement and if we just created it, it
7529
           will be destroyed */
7530
3.98M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7531
3.98M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7532
3.98M
    }
7533
3.98M
    return group_color;
7534
3.98M
}
7535
7536
static int
7537
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7538
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7539
                             bool is_mask)
7540
88.2k
{
7541
88.2k
    pdf14_device* pdev = (pdf14_device*)dev;
7542
88.2k
    pdf14_group_color_t* new_group_color;
7543
88.2k
    gsicc_rendering_param_t render_cond;
7544
88.2k
    cmm_dev_profile_t* dev_profile;
7545
88.2k
    pdf14_device* pdevproto;
7546
88.2k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7547
88.2k
    const pdf14_procs_t* new_14procs;
7548
88.2k
    bool update_color_info;
7549
88.2k
    gx_color_polarity_t new_polarity;
7550
88.2k
    int new_num_comps;
7551
88.2k
    bool new_additive = false;
7552
88.2k
    byte new_depth;
7553
88.2k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7554
88.2k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7555
88.2k
    int k;
7556
88.2k
    bool has_tags = device_encodes_tags(dev);
7557
88.2k
    bool deep = device_is_deep(dev);
7558
88.2k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7559
88.2k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7560
88.2k
    cmm_profile_t *old_profile = NULL;
7561
7562
88.2k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7563
88.2k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7564
88.2k
        &render_cond);
7565
88.2k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7566
7567
    /* Allocate a new one */
7568
88.2k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7569
88.2k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7570
7571
88.2k
    if (new_group_color == NULL)
7572
0
        return_error(gs_error_VMerror);
7573
7574
    /* Link to old one */
7575
88.2k
    new_group_color->previous = pdev->color_model_stack;
7576
7577
    /* Reassign new one to dev */
7578
88.2k
    pdev->color_model_stack = new_group_color;
7579
7580
    /* Initialize with values */
7581
88.2k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7582
88.2k
    new_group_color->group_color_mapping_procs =
7583
88.2k
        dev_proc(pdev, get_color_mapping_procs);
7584
88.2k
    new_group_color->group_color_comp_index =
7585
88.2k
        dev_proc(pdev, get_color_comp_index);
7586
88.2k
    new_group_color->blend_procs = pdev->blend_procs;
7587
88.2k
    new_group_color->polarity = pdev->color_info.polarity;
7588
88.2k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7589
88.2k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7590
88.2k
    new_group_color->depth = pdev->color_info.depth;
7591
88.2k
    new_group_color->max_color = pdev->color_info.max_color;
7592
88.2k
    new_group_color->max_gray = pdev->color_info.max_gray;
7593
88.2k
    new_group_color->decode = dev_proc(pdev, decode_color);
7594
88.2k
    new_group_color->encode = dev_proc(pdev, encode_color);
7595
88.2k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7596
88.2k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7597
88.2k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7598
88.2k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7599
7600
88.2k
    if (new_profile == NULL)
7601
53.6k
        new_group_color->icc_profile = NULL;
7602
7603
    /* isadditive is only used in ctx */
7604
88.2k
    if (pdev->ctx) {
7605
0
        new_group_color->isadditive = pdev->ctx->additive;
7606
0
    }
7607
7608
88.2k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7609
88.2k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7610
7611
88.2k
    if (group_color_type == ICC && new_profile == NULL)
7612
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7613
88.2k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7614
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7615
       are based upon the color space of the device.  We want to remain in the
7616
       color space defined by the color space of the soft mask or transparency
7617
       group as opposed to the device color space. Later, when we pop the softmask
7618
       we will collapse it to a single band and then compose with it to the device
7619
       color space (or the parent layer space).  In the case where we pop an
7620
       isolated transparency group, we will do the blending in the proper color
7621
       space and then transform the data when we pop the group.  Remember that only
7622
       isolated groups can have color spaces that are different than their parent. */
7623
88.2k
    update_color_info = false;
7624
88.2k
    switch (group_color_type) {
7625
0
    case GRAY_SCALE:
7626
0
        if (pdev->color_info.num_components != 1) {
7627
0
            update_color_info = true;
7628
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7629
0
            new_num_comps = 1;
7630
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7631
0
            new_additive = true;
7632
0
            new_14procs = &gray_pdf14_procs;
7633
0
            new_depth = 8 << deep;
7634
0
        }
7635
0
        break;
7636
0
    case DEVICE_RGB:
7637
0
    case CIE_XYZ:
7638
0
        if (pdev->color_info.num_components != 3) {
7639
0
            update_color_info = true;
7640
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7641
0
            new_num_comps = 3;
7642
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7643
0
            new_additive = true;
7644
0
            new_14procs = &rgb_pdf14_procs;
7645
0
            new_depth = 24 << deep;
7646
0
        }
7647
0
        break;
7648
0
    case DEVICE_CMYK:
7649
0
        if (pdev->color_info.num_components != 4) {
7650
0
            update_color_info = true;
7651
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7652
0
            new_num_comps = 4;
7653
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7654
0
            new_additive = false;
7655
            /* This is needed due to the mismatched compressed encode decode
7656
               between the device procs and the pdf14 procs */
7657
0
            if (dev->color_info.num_components > 4) {
7658
0
                new_14procs = &cmykspot_pdf14_procs;
7659
0
            }
7660
0
            else {
7661
0
                new_14procs = &cmyk_pdf14_procs;
7662
0
            }
7663
0
            new_depth = 32 << deep;
7664
0
        }
7665
0
        break;
7666
34.5k
    case ICC:
7667
        /* Check if the profile is different. */
7668
34.5k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7669
31.1k
            update_color_info = true;
7670
31.1k
            new_num_comps = new_profile->num_comps;
7671
31.1k
            new_depth = new_profile->num_comps * (8 << deep);
7672
31.1k
            switch (new_num_comps) {
7673
28.4k
            case 1:
7674
28.4k
                if (pdev->sep_device && !is_mask) {
7675
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7676
0
                    new_14procs = &grayspot_pdf14_procs;
7677
0
                }
7678
28.4k
                else {
7679
28.4k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7680
28.4k
                    new_14procs = &gray_pdf14_procs;
7681
28.4k
                }
7682
28.4k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7683
28.4k
                new_additive = true;
7684
28.4k
                break;
7685
1.91k
            case 3:
7686
1.91k
                if (pdev->sep_device) {
7687
436
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7688
436
                    new_14procs = &rgbspot_pdf14_procs;
7689
436
                }
7690
1.48k
                else {
7691
1.48k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7692
1.48k
                    new_14procs = &rgb_pdf14_procs;
7693
1.48k
                }
7694
1.91k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7695
1.91k
                new_additive = true;
7696
1.91k
                break;
7697
807
            case 4:
7698
807
                if (pdev->sep_device) {
7699
36
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7700
36
                    new_14procs = &cmykspot_pdf14_procs;
7701
36
                }
7702
771
                else {
7703
771
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7704
771
                    new_14procs = &cmyk_pdf14_procs;
7705
771
                }
7706
807
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7707
807
                new_additive = false;
7708
807
                break;
7709
0
            default:
7710
0
                return gs_throw(gs_error_undefinedresult,
7711
31.1k
                    "ICC Number of colorants illegal");
7712
31.1k
            }
7713
31.1k
        }
7714
34.5k
        break;
7715
53.6k
    case UNKNOWN:
7716
53.6k
        return 0;
7717
0
        break;
7718
0
    default:
7719
0
        return_error(gs_error_rangecheck);
7720
0
        break;
7721
88.2k
    }
7722
7723
34.5k
    if (!update_color_info) {
7724
        /* Profile not updated */
7725
3.38k
        new_group_color->icc_profile = NULL;
7726
3.38k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7727
3.38k
        return 0;
7728
3.38k
    }
7729
7730
31.1k
    if (has_tags) {
7731
0
        new_num_comps++;
7732
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7733
0
        if (pdev->num_planar_planes > 0)
7734
0
            new_depth += deep ? 16 : 8;
7735
0
        else
7736
0
            new_depth += 8;
7737
0
    }
7738
31.1k
    if (pdev->sep_device && !is_mask) {
7739
472
        int num_spots;
7740
7741
472
        if (old_profile == NULL)
7742
0
            return_error(gs_error_undefined);
7743
7744
472
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7745
7746
472
        if (num_spots > 0) {
7747
34
            new_num_comps += num_spots;
7748
34
            new_depth = (8 << deep) * new_num_comps;
7749
34
        }
7750
472
    }
7751
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7752
68.6k
    for (k = 0; k < new_num_comps; k++) {
7753
37.4k
        comp_bits[k] = 8 << deep;
7754
37.4k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7755
37.4k
    }
7756
31.1k
    if_debug2m('v', pdev->memory,
7757
31.1k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7758
31.1k
        pdev->color_info.num_components, new_num_comps);
7759
    /* Set new information in the device */
7760
31.1k
    {
7761
31.1k
        gx_device local_device;
7762
7763
31.1k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7764
31.1k
        local_device.initialize_device_procs((gx_device *)&local_device);
7765
31.1k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7766
31.1k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7767
31.1k
    }
7768
31.1k
    pdev->blend_procs = pdevproto->blend_procs;
7769
31.1k
    pdev->color_info.polarity = new_polarity;
7770
31.1k
    pdev->color_info.max_color = deep ? 65535 : 255;
7771
31.1k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7772
31.1k
    pdev->pdf14_procs = new_14procs;
7773
31.1k
    if (pdev->num_planar_planes > 0)
7774
3.53k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7775
31.1k
    pdev->color_info.num_components = new_num_comps;
7776
31.1k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7777
31.1k
    pdev->color_info.depth = new_depth;
7778
31.1k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7779
31.1k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7780
31.1k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7781
31.1k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7782
31.1k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7783
7784
    /* If we have a compressed color codec, and we are doing a soft mask
7785
       push operation then go ahead and update the color encode and
7786
       decode for the pdf14 device to not used compressed color
7787
       encoding while in the soft mask.  We will just check for gray
7788
       and compressed.  Note that we probably don't have_tags if we
7789
       are dealing with compressed color.  But is is possible so
7790
       we add it in to catch for future use. */
7791
31.1k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7792
31.1k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7793
31.1k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7794
31.1k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7795
31.1k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7796
31.1k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7797
    /* For the ICC profiles, we want to update the ICC profile for the
7798
       device.  We store the original in group_color.
7799
       That will be stored in the clist and restored during the reading phase. */
7800
31.1k
    if (group_color_type == ICC) {
7801
31.1k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7802
31.1k
        new_group_color->icc_profile =
7803
31.1k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7804
31.1k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7805
31.1k
    }
7806
31.1k
    if (pdev->ctx) {
7807
0
        pdev->ctx->additive = new_additive;
7808
0
    }
7809
31.1k
    return 1;  /* Lets us detect that we did do an update */
7810
31.1k
}
7811
7812
static int
7813
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7814
88.2k
{
7815
7816
88.2k
    pdf14_device *pdev = (pdf14_device *)dev;
7817
88.2k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7818
88.2k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7819
7820
88.2k
    if (group_color == NULL)
7821
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7822
7823
88.2k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7824
    /* The color procs are always pushed.  Simply restore them. */
7825
88.2k
    if (group_color->group_color_mapping_procs == NULL &&
7826
88.2k
        group_color->group_color_comp_index == NULL) {
7827
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7828
88.2k
    } else {
7829
88.2k
        bool has_tags = device_encodes_tags(dev);
7830
88.2k
        if_debug2m('v', pdev->memory,
7831
88.2k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7832
88.2k
                   pdev->color_info.num_components,group_color->num_components);
7833
88.2k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7834
88.2k
        gx_set_cmap_procs(pgs, dev);
7835
88.2k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7836
88.2k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7837
88.2k
        pdev->color_info.polarity = group_color->polarity;
7838
88.2k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7839
88.2k
        pdev->color_info.depth = group_color->depth;
7840
88.2k
        if (pdev->num_planar_planes > 0)
7841
8.68k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7842
88.2k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7843
88.2k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7844
88.2k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7845
88.2k
        pdev->blend_procs = group_color->blend_procs;
7846
88.2k
        pdev->pdf14_procs = group_color->unpack_procs;
7847
88.2k
        pdev->color_info.max_color = group_color->max_color;
7848
88.2k
        pdev->color_info.max_gray = group_color->max_gray;
7849
88.2k
        set_dev_proc(pdev, encode_color, group_color->encode);
7850
88.2k
        set_dev_proc(pdev, decode_color, group_color->decode);
7851
88.2k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7852
88.2k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7853
88.2k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7854
88.2k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7855
7856
        /* clist writer fill rect has no access to gs_gstate */
7857
        /* and it forwards the target device.  this information */
7858
        /* is passed along to use in this case */
7859
88.2k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7860
88.2k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7861
88.2k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7862
88.2k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7863
88.2k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7864
88.2k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7865
88.2k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7866
88.2k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7867
88.2k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7868
88.2k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7869
88.2k
        if (pdev->ctx){
7870
0
            pdev->ctx->additive = group_color->isadditive;
7871
0
        }
7872
       /* The device profile must be restored. */
7873
88.2k
        if (group_color->icc_profile != NULL) {
7874
31.1k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7875
31.1k
                                    -1, "pdf14_clist_pop_color_model");
7876
31.1k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7877
31.1k
        }
7878
88.2k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7879
88.2k
    }
7880
88.2k
   pdf14_pop_group_color(dev, pgs);
7881
88.2k
    return 0;
7882
88.2k
}
7883
7884
/* When a transparency group is popped, the parent colorprocs must be restored.
7885
   Since the color mapping procs are all based upon the device, we must have a
7886
   nested list based upon the transparency group color space.  This nesting
7887
   must be outside the nested ctx structures to allow the nesting for the
7888
   clist writer */
7889
static void
7890
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7891
88.2k
{
7892
88.2k
    pdf14_device *pdev = (pdf14_device *)dev;
7893
88.2k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7894
7895
88.2k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7896
7897
    /* Update the link */
7898
88.2k
    pdev->color_model_stack = group_color->previous;
7899
7900
    /* Free the old one */
7901
88.2k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7902
88.2k
}
7903
7904
static  int
7905
pdf14_begin_transparency_mask(gx_device *dev,
7906
                              const gx_transparency_mask_params_t *ptmp,
7907
                              const gs_rect *pbbox,
7908
                              gs_gstate *pgs, gs_memory_t *mem)
7909
6.39M
{
7910
6.39M
    pdf14_device *pdev = (pdf14_device *)dev;
7911
6.39M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7912
6.39M
    byte *transfer_fn;
7913
6.39M
    gs_int_rect rect;
7914
6.39M
    int code;
7915
6.39M
    int group_color_numcomps;
7916
6.39M
    gs_transparency_color_t group_color_type;
7917
6.39M
    bool deep = device_is_deep(dev);
7918
6.39M
    pdf14_group_color_t* group_color_info;
7919
7920
6.39M
    code = pdf14_initialize_ctx(dev, pgs);
7921
6.39M
    if (code < 0)
7922
0
        return code;
7923
7924
6.39M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7925
5.68M
        pdf14_ctx *ctx = pdev->ctx;
7926
7927
        /* free up any maskbuf on the current tos */
7928
5.68M
        if (ctx->mask_stack) {
7929
932k
            if (ctx->mask_stack->rc_mask->mask_buf != NULL ) {
7930
463k
                pdf14_buf_free(ctx->mask_stack->rc_mask->mask_buf);
7931
463k
                ctx->mask_stack->rc_mask->mask_buf = NULL;
7932
463k
            }
7933
932k
        }
7934
5.68M
        return 0;
7935
5.68M
    }
7936
713k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7937
713k
                                         "pdf14_begin_transparency_mask");
7938
713k
    if (transfer_fn == NULL)
7939
0
        return_error(gs_error_VMerror);
7940
713k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7941
713k
    if (code < 0)
7942
0
        return code;
7943
    /* If we have background components the background alpha may be nonzero */
7944
713k
    if (ptmp->Background_components)
7945
222k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7946
713k
    if_debug1m('v', dev->memory,
7947
713k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7948
713k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7949
   /* If the group color is unknown, then we must use the previous group color
7950
       space or the device process color space */
7951
713k
    if (ptmp->group_color_type == UNKNOWN){
7952
0
        if (pdev->ctx->stack){
7953
            /* Use previous group color space */
7954
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7955
0
        } else {
7956
            /* Use process color space */
7957
0
            group_color_numcomps = pdev->color_info.num_components;
7958
0
        }
7959
0
        switch (group_color_numcomps) {
7960
0
            case 1:
7961
0
                group_color_type = GRAY_SCALE;
7962
0
                break;
7963
0
            case 3:
7964
0
                group_color_type = DEVICE_RGB;
7965
0
                break;
7966
0
            case 4:
7967
0
                group_color_type = DEVICE_CMYK;
7968
0
            break;
7969
0
            default:
7970
                /* We can end up here if we are in a deviceN color space and
7971
                   we have a sep output device */
7972
0
                group_color_type = DEVICEN;
7973
0
            break;
7974
0
         }
7975
713k
    } else {
7976
713k
        group_color_type = ptmp->group_color_type;
7977
713k
        group_color_numcomps = ptmp->group_color_numcomps;
7978
713k
    }
7979
7980
713k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7981
713k
                                               ptmp->iccprofile, true);
7982
713k
    if (group_color_info == NULL)
7983
0
        return gs_error_VMerror;
7984
7985
    /* Note that the soft mask always follows the group color requirements even
7986
       when we have a separable device */
7987
713k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7988
713k
                                        transfer_fn, ptmp->function_is_identity,
7989
713k
                                        ptmp->idle, ptmp->replacing,
7990
713k
                                        ptmp->mask_id, ptmp->subtype,
7991
713k
                                        group_color_numcomps,
7992
713k
                                        ptmp->Background_components,
7993
713k
                                        ptmp->Background,
7994
713k
                                        ptmp->Matte_components,
7995
713k
                                        ptmp->Matte,
7996
713k
                                        ptmp->GrayBackground,
7997
713k
                                        group_color_info);
7998
713k
    if (code < 0)
7999
0
        return code;
8000
8001
713k
    return 0;
8002
713k
}
8003
8004
static  int
8005
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8006
713k
{
8007
713k
    pdf14_device *pdev = (pdf14_device *)dev;
8008
713k
    pdf14_group_color_t *group_color;
8009
713k
    int ok;
8010
713k
    bool has_tags = device_encodes_tags(dev);
8011
8012
713k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8013
713k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8014
#ifdef DEBUG
8015
    pdf14_debug_mask_stack_state(pdev->ctx);
8016
#endif
8017
8018
    /* May need to reset some color stuff related
8019
     * to a mismatch between the Smask color space
8020
     * and the Smask blending space */
8021
713k
    if (pdev->ctx->stack != NULL ) {
8022
713k
        group_color = pdev->ctx->stack->group_color_info;
8023
713k
        if (!(group_color->group_color_mapping_procs == NULL &&
8024
713k
            group_color->group_color_comp_index == NULL)) {
8025
713k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8026
713k
            gx_set_cmap_procs(pgs, dev);
8027
713k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8028
713k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8029
713k
            pdev->color_info.polarity = group_color->polarity;
8030
713k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8031
713k
            if (pdev->num_planar_planes > 0)
8032
31.8k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8033
713k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8034
713k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8035
713k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8036
713k
            pdev->num_std_colorants = group_color->num_std_colorants;
8037
713k
            pdev->color_info.depth = group_color->depth;
8038
713k
            pdev->blend_procs = group_color->blend_procs;
8039
713k
            pdev->ctx->additive = group_color->isadditive;
8040
713k
            pdev->pdf14_procs = group_color->unpack_procs;
8041
713k
            pdev->color_info.max_color = group_color->max_color;
8042
713k
            pdev->color_info.max_gray = group_color->max_gray;
8043
713k
            set_dev_proc(pdev, encode_color, group_color->encode);
8044
713k
            set_dev_proc(pdev, decode_color, group_color->decode);
8045
713k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8046
713k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8047
713k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8048
713k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8049
            /* Take care of the ICC profile */
8050
713k
            if (group_color->icc_profile != NULL) {
8051
713k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8052
713k
                                        -1, "pdf14_end_transparency_mask");
8053
713k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8054
713k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8055
713k
                                         1, "pdf14_end_transparency_mask");
8056
713k
            }
8057
713k
        }
8058
713k
    }
8059
713k
    return ok;
8060
713k
}
8061
8062
static  int
8063
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8064
                                 gx_color_index color,
8065
                                 const gx_device_color *pdc, bool devn)
8066
4.91M
{
8067
4.91M
    pdf14_device *pdev = (pdf14_device *)dev;
8068
4.91M
    pdf14_buf *buf = pdev->ctx->stack;
8069
4.91M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8070
4.91M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8071
4.91M
        blend_mode == BLEND_MODE_Compatible ||
8072
4.91M
        blend_mode == BLEND_MODE_CompatibleOverprint;
8073
4.91M
    int i, j, k;
8074
4.91M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8075
4.91M
    byte src[PDF14_MAX_PLANES];
8076
4.91M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8077
4.91M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8078
4.91M
    int rowstride = buf->rowstride;
8079
4.91M
    int planestride = buf->planestride;
8080
4.91M
    int num_chan = buf->n_chan;
8081
4.91M
    int num_comp = num_chan - 1;
8082
4.91M
    int shape_off = num_chan * planestride;
8083
4.91M
    bool has_shape = buf->has_shape;
8084
4.91M
    bool has_alpha_g = buf->has_alpha_g;
8085
4.91M
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
8086
4.91M
    int tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8087
4.91M
                              (has_shape ? planestride : 0);
8088
4.91M
    bool has_tags = buf->has_tags;
8089
4.91M
    bool additive = pdev->ctx->additive;
8090
4.91M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8091
4.91M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8092
4.91M
    int shift = 8;
8093
4.91M
    byte shape = 0; /* Quiet compiler. */
8094
4.91M
    byte src_alpha;
8095
4.91M
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8096
4.91M
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8097
4.52M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8098
4.91M
    gx_color_index comps;
8099
4.91M
    bool has_backdrop = buf->backdrop != NULL;
8100
8101
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8102
       subtractive) and we are doing overprint with drawn_comps == 0
8103
       then this is a no-operation */
8104
4.91M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8105
0
        return 0;
8106
8107
4.91M
    if (buf->data == NULL)
8108
0
        return 0;
8109
#if 0
8110
    if (sizeof(color) <= sizeof(ulong))
8111
        if_debug6m('v', dev->memory,
8112
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8113
                   x, y, w, h, (ulong)color, num_chan);
8114
    else
8115
        if_debug7m('v', dev->memory,
8116
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8117
                   x, y, w, h,
8118
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8119
                   num_chan);
8120
#endif
8121
    /*
8122
     * Unpack the gx_color_index values.  Complement the components for subtractive
8123
     * color spaces.
8124
     */
8125
4.91M
    if (devn) {
8126
622k
        if (has_tags) {
8127
0
            curr_tag = pdc->tag;
8128
0
        }
8129
622k
        if (additive) {
8130
1.77M
            for (j = 0; j < num_comp; j++) {
8131
1.33M
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8132
1.33M
            }
8133
443k
        } else {
8134
891k
            for (j = 0; j < num_comp; j++) {
8135
712k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8136
712k
            }
8137
178k
        }
8138
4.29M
    } else {
8139
4.29M
        if (has_tags) {
8140
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8141
0
        }
8142
4.29M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8143
4.29M
    }
8144
8145
4.91M
    if (!has_tags)
8146
4.91M
        tag_off = 0;
8147
8148
4.91M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8149
4.91M
    if (has_shape) {
8150
6.61k
        shape = (byte)floor (255 * pdev->shape + 0.5);
8151
4.90M
    } else {
8152
4.90M
        shape_off = 0;
8153
4.90M
    }
8154
8155
4.91M
    if (!has_alpha_g)
8156
0
        alpha_g_off = 0;
8157
4.91M
    src_alpha = 255 - src_alpha;
8158
4.91M
    shape = 255 - shape;
8159
8160
    /* Fit the mark into the bounds of the buffer */
8161
4.91M
    if (x < buf->rect.p.x) {
8162
0
        w += x - buf->rect.p.x;
8163
0
        x = buf->rect.p.x;
8164
0
    }
8165
4.91M
    if (y < buf->rect.p.y) {
8166
9
      h += y - buf->rect.p.y;
8167
9
      y = buf->rect.p.y;
8168
9
    }
8169
4.91M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8170
4.91M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8171
    /* Update the dirty rectangle with the mark. */
8172
4.91M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8173
4.91M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8174
4.91M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8175
4.91M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8176
8177
    /* composite with backdrop only. */
8178
4.91M
    if (has_backdrop)
8179
4.91M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8180
0
    else
8181
0
        bline = NULL;
8182
8183
4.91M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8184
8185
10.3M
    for (j = 0; j < h; ++j) {
8186
5.48M
        bg_ptr = bline;
8187
5.48M
        dst_ptr = line;
8188
234M
        for (i = 0; i < w; ++i) {
8189
            /* Complement the components for subtractive color spaces */
8190
229M
            if (has_backdrop) {
8191
229M
                if (additive) {
8192
863M
                    for (k = 0; k < num_comp; ++k)
8193
639M
                        dst[k] = bg_ptr[k * planestride];
8194
224M
                } else {
8195
25.8M
                    for (k = 0; k < num_comp; ++k)
8196
20.6M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8197
5.16M
                }
8198
229M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8199
229M
            }
8200
229M
            if (buf->isolated || !has_backdrop) {
8201
0
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8202
229M
            } else {
8203
229M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8204
229M
                                            blend_mode, pdev->blend_procs, pdev);
8205
229M
            }
8206
            /* Complement the results for subtractive color spaces */
8207
229M
            if (additive) {
8208
224M
                if (!overprint) {
8209
1.08G
                    for (k = 0; k < num_chan; ++k)
8210
863M
                        dst_ptr[k * planestride] = dst[k];
8211
224M
                } else {
8212
                    /* Hybrid additive with subtractive spots */
8213
                    /* We may have to do the compatible overprint blending */
8214
46.9k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8215
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8216
0
                            blend_mode, pdev->blend_procs, pdev);
8217
0
                    }
8218
187k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8219
140k
                        if ((comps & 0x1) != 0) {
8220
140k
                            dst_ptr[k * planestride] = dst[k];
8221
140k
                        } else {
8222
                            /* Compatible overprint blend result. */
8223
0
                            dst_ptr[k * planestride] = dst2[k];
8224
0
                        }
8225
140k
                    }
8226
46.9k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8227
46.9k
                }
8228
224M
            } else {
8229
5.16M
                if (overprint) {
8230
                    /* We may have to do the compatible overprint blending */
8231
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8232
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8233
0
                            blend_mode, pdev->blend_procs, pdev);
8234
0
                    }
8235
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8236
0
                        if ((comps & 0x1) != 0) {
8237
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8238
0
                        } else {
8239
                            /* Compatible overprint blend result. */
8240
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8241
0
                        }
8242
0
                    }
8243
5.16M
                } else {
8244
25.8M
                    for (k = 0; k < num_comp; ++k)
8245
20.6M
                        dst_ptr[k * planestride] = 255 - dst[k];
8246
5.16M
                }
8247
5.16M
                dst_ptr[num_comp * planestride] = dst[num_comp];
8248
5.16M
            }
8249
229M
            if (tag_off) {
8250
                /* If src alpha is 100% then set to curr_tag, else or */
8251
                /* other than Normal BM, we always OR */
8252
0
                if (src[num_comp] == 255 && tag_blend) {
8253
0
                    dst_ptr[tag_off] = curr_tag;
8254
0
                } else {
8255
0
                    dst_ptr[tag_off] |= curr_tag;
8256
0
                }
8257
0
            }
8258
            /* Knockout group alpha and shape too */
8259
229M
            if (alpha_g_off)
8260
229M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8261
229M
            if (shape_off)
8262
6.93k
                dst_ptr[shape_off] = 255 - shape;
8263
229M
            ++dst_ptr;
8264
229M
            if (has_backdrop)
8265
229M
                ++bg_ptr;
8266
229M
        }
8267
5.48M
        bline += rowstride;
8268
5.48M
        line += rowstride;
8269
5.48M
    }
8270
#if 0
8271
/* #if RAW_DUMP */
8272
    /* Dump the current buffer to see what we have. */
8273
    dump_raw_buffer(pdev->ctx->memory,
8274
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8275
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8276
                    pdev->ctx->stack->n_planes,
8277
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8278
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8279
                    pdev->ctx->stack->deep);
8280
    global_index++;
8281
#endif
8282
4.91M
    return 0;
8283
4.91M
}
8284
8285
static  int
8286
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8287
                                   gx_color_index color,
8288
                                   const gx_device_color *pdc, bool devn)
8289
0
{
8290
0
    pdf14_device *pdev = (pdf14_device *)dev;
8291
0
    pdf14_buf *buf = pdev->ctx->stack;
8292
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8293
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8294
0
        blend_mode == BLEND_MODE_Compatible ||
8295
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8296
0
    int i, j, k;
8297
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8298
0
    uint16_t src[PDF14_MAX_PLANES];
8299
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8300
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8301
0
    int rowstride = buf->rowstride;
8302
0
    int planestride = buf->planestride;
8303
0
    int num_chan = buf->n_chan;
8304
0
    int num_comp = num_chan - 1;
8305
0
    int shape_off = num_chan * planestride;
8306
0
    bool has_shape = buf->has_shape;
8307
0
    bool has_alpha_g = buf->has_alpha_g;
8308
0
    int alpha_g_off = shape_off + (has_shape ? planestride : 0);
8309
0
    int tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8310
0
                              (has_shape ? planestride : 0);
8311
0
    bool has_tags = buf->has_tags;
8312
0
    bool additive = pdev->ctx->additive;
8313
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8314
0
    uint16_t shape = 0; /* Quiet compiler. */
8315
0
    uint16_t src_alpha;
8316
0
    bool overprint = pdev->op_state == PDF14_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8317
0
    gx_color_index drawn_comps = pdev->op_state == PDF14_OP_STATE_FILL ?
8318
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8319
0
    gx_color_index comps;
8320
0
    bool has_backdrop = buf->backdrop != NULL;
8321
8322
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8323
       subtractive) and we are doing overprint with drawn_comps == 0
8324
       then this is a no-operation */
8325
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8326
0
        return 0;
8327
8328
0
    if (buf->data == NULL)
8329
0
        return 0;
8330
#if 0
8331
    if (sizeof(color) <= sizeof(ulong))
8332
        if_debug6m('v', dev->memory,
8333
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8334
                   x, y, w, h, (ulong)color, num_chan);
8335
    else
8336
        if_debug7m('v', dev->memory,
8337
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8338
                   x, y, w, h,
8339
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8340
                   num_chan);
8341
#endif
8342
    /*
8343
     * Unpack the gx_color_index values.  Complement the components for subtractive
8344
     * color spaces.
8345
     */
8346
0
    if (devn) {
8347
0
        if (has_tags) {
8348
0
            curr_tag = pdc->tag;
8349
0
        }
8350
0
        if (additive) {
8351
0
            for (j = 0; j < num_comp; j++) {
8352
0
                src[j] = pdc->colors.devn.values[j];
8353
0
            }
8354
0
        } else {
8355
0
            for (j = 0; j < num_comp; j++) {
8356
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8357
0
            }
8358
0
        }
8359
0
    } else {
8360
0
        if (has_tags) {
8361
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8362
0
        }
8363
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8364
0
    }
8365
8366
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8367
0
    if (has_shape) {
8368
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8369
0
    } else {
8370
0
        shape_off = 0;
8371
0
    }
8372
8373
0
    if (!has_tags) {
8374
0
        tag_off = 0;
8375
0
    }
8376
8377
0
    if (!has_alpha_g)
8378
0
        alpha_g_off = 0;
8379
0
    src_alpha = 65535 - src_alpha;
8380
0
    shape = 65535 - shape;
8381
8382
    /* Fit the mark into the bounds of the buffer */
8383
0
    if (x < buf->rect.p.x) {
8384
0
        w += x - buf->rect.p.x;
8385
0
        x = buf->rect.p.x;
8386
0
    }
8387
0
    if (y < buf->rect.p.y) {
8388
0
      h += y - buf->rect.p.y;
8389
0
      y = buf->rect.p.y;
8390
0
    }
8391
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8392
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8393
    /* Update the dirty rectangle with the mark. */
8394
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8395
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8396
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8397
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8398
8399
8400
    /* composite with backdrop only. */
8401
0
    if (has_backdrop)
8402
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8403
0
    else
8404
0
        bline = NULL;
8405
8406
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8407
0
    planestride >>= 1;
8408
0
    rowstride >>= 1;
8409
0
    alpha_g_off >>= 1;
8410
0
    shape_off >>= 1;
8411
0
    tag_off >>= 1;
8412
8413
0
    for (j = 0; j < h; ++j) {
8414
0
        bg_ptr = bline;
8415
0
        dst_ptr = line;
8416
0
        for (i = 0; i < w; ++i) {
8417
            /* Complement the components for subtractive color spaces */
8418
0
            if (has_backdrop) {
8419
0
                if (additive) {
8420
0
                    for (k = 0; k < num_comp; ++k)
8421
0
                        dst[k] = bg_ptr[k * planestride];
8422
0
                } else {
8423
0
                    for (k = 0; k < num_comp; ++k)
8424
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8425
0
                }
8426
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8427
0
            }
8428
0
            if (buf->isolated || !has_backdrop) {
8429
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8430
0
            } else {
8431
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8432
0
                                              blend_mode, pdev->blend_procs, pdev);
8433
0
            }
8434
            /* Complement the results for subtractive color spaces */
8435
0
            if (additive) {
8436
0
                if (!overprint) {
8437
0
                    for (k = 0; k < num_chan; ++k)
8438
0
                        dst_ptr[k * planestride] = dst[k];
8439
0
                } else {
8440
                    /* Hybrid additive with subtractive spots */
8441
                    /* We may have to do the compatible overprint blending */
8442
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8443
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8444
0
                            blend_mode, pdev->blend_procs, pdev);
8445
0
                    }
8446
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8447
0
                        if ((comps & 0x1) != 0) {
8448
0
                            dst_ptr[k * planestride] = dst[k];
8449
0
                        } else {
8450
                            /* Compatible overprint blend result. */
8451
0
                            dst_ptr[k * planestride] = dst2[k];
8452
0
                        }
8453
0
                    }
8454
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8455
0
                }
8456
0
            } else {
8457
0
                if (overprint) {
8458
                    /* We may have to do the compatible overprint blending */
8459
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8460
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8461
0
                            blend_mode, pdev->blend_procs, pdev);
8462
0
                    }
8463
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8464
0
                        if ((comps & 0x1) != 0) {
8465
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8466
0
                        } else {
8467
                            /* Compatible overprint blend result. */
8468
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8469
0
                        }
8470
0
                    }
8471
0
                } else {
8472
0
                    for (k = 0; k < num_comp; ++k)
8473
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8474
0
                }
8475
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8476
0
            }
8477
0
            if (tag_off) {
8478
                /* FIXME: As we are knocking out, possibly, we should be
8479
                 * always overwriting tag values here? */
8480
                /* If src alpha is 100% then set to curr_tag, else or */
8481
                /* other than Normal BM, we always OR */
8482
0
                if (src[num_comp] == 65535 && tag_blend) {
8483
0
                    dst_ptr[tag_off] = curr_tag;
8484
0
                } else {
8485
0
                    dst_ptr[tag_off] |= curr_tag;
8486
0
                }
8487
0
            }
8488
            /* Knockout group alpha and shape too */
8489
0
            if (alpha_g_off)
8490
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8491
0
            if (shape_off)
8492
0
                dst_ptr[shape_off] = 65535 - shape;
8493
0
            ++dst_ptr;
8494
0
            if (has_backdrop)
8495
0
                ++bg_ptr;
8496
0
        }
8497
0
        bline += rowstride;
8498
0
        line += rowstride;
8499
0
    }
8500
#if 0
8501
/* #if RAW_DUMP */
8502
    /* Dump the current buffer to see what we have. */
8503
    dump_raw_buffer(pdev->ctx->memory,
8504
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8505
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8506
                    pdev->ctx->stack->n_planes,
8507
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8508
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8509
                    pdev->ctx->stack->deep);
8510
    global_index++;
8511
#endif
8512
0
    return 0;
8513
0
}
8514
8515
static  int
8516
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8517
                                    gx_color_index color,
8518
                                    const gx_device_color *pdc, bool devn)
8519
4.91M
{
8520
4.91M
    pdf14_device *pdev = (pdf14_device *)dev;
8521
4.91M
    pdf14_buf *buf = pdev->ctx->stack;
8522
8523
4.91M
    if (buf->deep)
8524
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8525
4.91M
    else
8526
4.91M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8527
4.91M
}
8528
8529
/**
8530
 * Here we have logic to override the cmap_procs with versions that
8531
 * do not apply the transfer function. These copies should track the
8532
 * versions in gxcmap.c.
8533
 **/
8534
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8535
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8536
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8537
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8538
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8539
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8540
8541
static  const gx_color_map_procs pdf14_cmap_many = {
8542
     pdf14_cmap_gray_direct,
8543
     pdf14_cmap_rgb_direct,
8544
     pdf14_cmap_cmyk_direct,
8545
     pdf14_cmap_separation_direct,
8546
     pdf14_cmap_devicen_direct,
8547
     pdf14_cmap_is_halftoned
8548
    };
8549
8550
/**
8551
 * Note: copied from gxcmap.c because it's inlined.
8552
 **/
8553
static  inline void
8554
map_components_to_colorants(const frac * pcc,
8555
                            const gs_devicen_color_map * pcolor_component_map,
8556
                            frac * plist)
8557
3.82M
{
8558
3.82M
    int i = pcolor_component_map->num_colorants - 1;
8559
3.82M
    int pos;
8560
8561
    /* Clear all output colorants first */
8562
19.1M
    for (; i >= 0; i--) {
8563
15.3M
        plist[i] = frac_0;
8564
15.3M
    }
8565
    /* Map color components into output list */
8566
8.03M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8567
4.21M
        pos = pcolor_component_map->color_map[i];
8568
4.21M
        if (pos >= 0)
8569
4.21M
            plist[pos] = pcc[i];
8570
4.21M
    }
8571
3.82M
}
8572
8573
/* See Section 7.6.4 of PDF 1.7 spec */
8574
static inline bool
8575
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8576
49.1M
{
8577
49.1M
    if (pgs->fillconstantalpha != 1.0 ||
8578
49.1M
        pgs->strokeconstantalpha != 1.0 ||
8579
49.1M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8580
48.9M
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8581
299k
        return 0;
8582
8583
    /* We can only be opaque if we're not in an SMask. */
8584
48.8M
    return dev_proc(pdev, dev_spec_op)(pdev,
8585
48.8M
                                       gxdso_in_smask,
8586
48.8M
                                       NULL, 0) != 1;
8587
49.1M
}
8588
8589
static  void
8590
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8591
                       gx_device * dev, gs_color_select_t select)
8592
14.6M
{
8593
14.6M
    int i, nc, ncomps;
8594
14.6M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8595
14.6M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8596
14.6M
    gx_color_index color;
8597
14.6M
    gx_device *trans_device;
8598
14.6M
    const gx_device *map_dev;
8599
14.6M
    const gx_cm_color_map_procs *procs;
8600
8601
    /* If trans device is set, we need to use its procs. */
8602
14.6M
    if (pgs->trans_device != NULL) {
8603
4.33M
        trans_device = pgs->trans_device;
8604
10.3M
    } else {
8605
10.3M
        trans_device = dev;
8606
10.3M
    }
8607
14.6M
    ncomps = trans_device->color_info.num_components;
8608
8609
    /* map to the color model */
8610
14.6M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8611
14.6M
    procs->map_gray(map_dev, gray, cm_comps);
8612
8613
14.6M
    nc = ncomps;
8614
14.6M
    if (device_encodes_tags(trans_device))
8615
0
        nc--;
8616
14.6M
    if (pdf14_state_opaque(trans_device, pgs)) {
8617
9.35M
        for (i = 0; i < nc; i++)
8618
4.68M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8619
9.98M
    } else {
8620
19.9M
        for (i = 0; i < nc; i++)
8621
9.98M
            cv[i] = frac2cv(cm_comps[i]);
8622
9.98M
    }
8623
    /* Copy tags untransformed. */
8624
14.6M
    if (nc < ncomps)
8625
0
        cv[nc] = cm_comps[nc];
8626
8627
    /* If output device supports devn, we need to make sure we send it the
8628
       proper color type.  We now support Gray + spots as devn colors */
8629
14.6M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8630
775k
        for (i = 0; i < ncomps; i++)
8631
387k
            pdc->colors.devn.values[i] = cv[i];
8632
387k
        pdc->type = gx_dc_type_devn;
8633
14.2M
    } else {
8634
        /* encode as a color index */
8635
14.2M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8636
        /* check if the encoding was successful; we presume failure is rare */
8637
14.2M
        if (color != gx_no_color_index)
8638
14.2M
            color_set_pure(pdc, color);
8639
14.2M
    }
8640
14.6M
}
8641
8642
static  void
8643
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8644
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8645
8.88M
{
8646
8.88M
    int i, nc, ncomps;
8647
8.88M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8648
8.88M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8649
8.88M
    gx_color_index color;
8650
8.88M
    gx_device *trans_device;
8651
8.88M
    const gx_device *map_dev;
8652
8.88M
    const gx_cm_color_map_procs *procs;
8653
8654
    /* If trans device is set, we need to use its procs. */
8655
8.88M
    if (pgs->trans_device != NULL){
8656
1.98M
        trans_device = pgs->trans_device;
8657
6.89M
    } else {
8658
6.89M
        trans_device = dev;
8659
6.89M
    }
8660
8.88M
    ncomps = trans_device->color_info.num_components;
8661
    /* map to the color model */
8662
8.88M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8663
8.88M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8664
8665
8.88M
    nc = ncomps;
8666
8.88M
    if (device_encodes_tags(trans_device))
8667
0
        nc--;
8668
8.88M
    if (pdf14_state_opaque(trans_device, pgs)) {
8669
24.2M
        for (i = 0; i < nc; i++)
8670
18.1M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8671
6.05M
    } else {
8672
11.2M
        for (i = 0; i < nc; i++)
8673
8.46M
            cv[i] = frac2cv(cm_comps[i]);
8674
2.83M
    }
8675
    /* Copy tags untransformed. */
8676
8.88M
    if (nc < ncomps)
8677
0
        cv[nc] = cm_comps[nc];
8678
8679
    /* If output device supports devn, we need to make sure we send it the
8680
       proper color type.  We now support RGB + spots as devn colors */
8681
8.88M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8682
23.6M
        for (i = 0; i < ncomps; i++)
8683
17.7M
            pdc->colors.devn.values[i] = cv[i];
8684
5.90M
        pdc->type = gx_dc_type_devn;
8685
5.90M
    } else {
8686
        /* encode as a color index */
8687
2.98M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8688
        /* check if the encoding was successful; we presume failure is rare */
8689
2.98M
        if (color != gx_no_color_index)
8690
2.98M
            color_set_pure(pdc, color);
8691
2.98M
    }
8692
8.88M
}
8693
8694
static  void
8695
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8696
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8697
     const gs_color_space *pcs)
8698
25.6M
{
8699
25.6M
    int i, nc, ncomps;
8700
25.6M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8701
25.6M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8702
25.6M
    gx_color_index color;
8703
25.6M
    gx_device *trans_device;
8704
25.6M
    const gx_device *map_dev;
8705
25.6M
    const gx_cm_color_map_procs *procs;
8706
8707
8708
    /* If trans device is set, we need to use its procs. */
8709
25.6M
    if (pgs->trans_device != NULL){
8710
20.5M
        trans_device = pgs->trans_device;
8711
20.5M
    } else {
8712
5.02M
        trans_device = dev;
8713
5.02M
    }
8714
25.6M
    ncomps = trans_device->color_info.num_components;
8715
8716
    /* Map to the color model. Transfer function is only used
8717
       if we are drawing with an opaque color. */
8718
25.6M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8719
25.6M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8720
8721
25.6M
    nc = ncomps;
8722
25.6M
    if (device_encodes_tags(trans_device))
8723
0
        nc--;
8724
25.6M
    if (pdf14_state_opaque(trans_device, pgs)) {
8725
115M
        for (i = 0; i < nc; i++)
8726
92.3M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8727
23.0M
    } else {
8728
12.6M
        for (i = 0; i < nc; i++)
8729
10.1M
            cv[i] = frac2cv(cm_comps[i]);
8730
2.52M
    }
8731
    /* Copy tags untransformed. */
8732
25.6M
    if (nc < ncomps)
8733
0
        cv[nc] = cm_comps[nc];
8734
8735
    /* if output device supports devn, we need to make sure we send it the
8736
       proper color type */
8737
25.6M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8738
36.0M
        for (i = 0; i < ncomps; i++)
8739
28.8M
            pdc->colors.devn.values[i] = cv[i];
8740
7.20M
        pdc->type = gx_dc_type_devn;
8741
18.4M
    } else {
8742
        /* encode as a color index */
8743
18.4M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8744
        /* check if the encoding was successful; we presume failure is rare */
8745
18.4M
        if (color != gx_no_color_index)
8746
18.4M
            color_set_pure(pdc, color);
8747
18.4M
    }
8748
25.6M
}
8749
8750
static int
8751
pdf14_get_num_spots(gx_device * dev)
8752
3.82M
{
8753
3.82M
    cmm_dev_profile_t *dev_profile;
8754
3.82M
    cmm_profile_t *icc_profile;
8755
3.82M
    gsicc_rendering_param_t render_cond;
8756
8757
3.82M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8758
3.82M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8759
3.82M
        &render_cond);
8760
3.82M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8761
3.82M
}
8762
8763
static  void
8764
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8765
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8766
45.0k
{
8767
45.0k
    int i, nc, ncomps = dev->color_info.num_components;
8768
45.0k
    int num_spots = pdf14_get_num_spots(dev);
8769
45.0k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8770
45.0k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8771
45.0k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8772
45.0k
    gx_color_index color;
8773
8774
45.0k
    nc = ncomps;
8775
45.0k
    if (device_encodes_tags(dev))
8776
0
        nc--;
8777
8778
45.0k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8779
0
        frac comp_value = all;
8780
8781
0
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8782
0
            cm_comps[i] = comp_value;
8783
        /*
8784
         * Invert the photometric interpretation for additive
8785
         * color spaces because separations are always subtractive.
8786
         */
8787
0
        if (additive)
8788
0
            comp_value = frac_1 - comp_value;
8789
        /* Use the "all" value for all components */
8790
0
        for (; i >= 0; i--)
8791
0
            cm_comps[i] = comp_value;
8792
45.0k
    } else {
8793
45.0k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8794
8795
45.0k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8796
0
            color_set_null(pdc);
8797
0
            return;
8798
0
        }
8799
8800
        /* map to the color model */
8801
90.0k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8802
45.0k
            comp_value[i] = all;
8803
45.0k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps);
8804
45.0k
    }
8805
8806
    /* apply the transfer function(s); convert to color values */
8807
45.0k
    if (additive) {
8808
4.58k
        for (i = 0; i < nc; i++)
8809
3.66k
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8810
        /* We are in an additive mode (blend space) and drawing with a sep color
8811
        into a sep device.  Make sure we are drawing "white" with the process
8812
        colorants, but only if we are not in an ALL case */
8813
916
        if (pgs->color_component_map.sep_type != SEP_ALL)
8814
3.66k
            for (i = 0; i < nc - num_spots; i++)
8815
2.74k
                cv[i] = gx_max_color_value;
8816
916
    } else
8817
220k
        for (i = 0; i < nc; i++)
8818
176k
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8819
    /* Copy tags untransformed. */
8820
45.0k
    if (nc < ncomps)
8821
0
        cv[nc] = cm_comps[nc];
8822
8823
    /* if output device supports devn, we need to make sure we send it the
8824
       proper color type */
8825
45.0k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0)) {
8826
225k
        for (i = 0; i < ncomps; i++)
8827
180k
            pdc->colors.devn.values[i] = cv[i];
8828
45.0k
        pdc->type = gx_dc_type_devn;
8829
45.0k
    } else {
8830
        /* encode as a color index */
8831
0
        color = dev_proc(dev, encode_color)(dev, cv);
8832
        /* check if the encoding was successful; we presume failure is rare */
8833
0
        if (color != gx_no_color_index)
8834
0
            color_set_pure(pdc, color);
8835
0
    }
8836
45.0k
}
8837
8838
static  void
8839
pdf14_cmap_devicen_direct(const frac * pcc,
8840
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8841
    gs_color_select_t select, const gs_color_space *pcs)
8842
3.78M
{
8843
3.78M
    int i, nc, ncomps = dev->color_info.num_components;
8844
3.78M
    int num_spots = pdf14_get_num_spots(dev);
8845
3.78M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8846
3.78M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8847
3.78M
    gx_color_index color;
8848
3.78M
    gx_device *trans_device;
8849
8850
     /*  We may be coming from the clist writer which often forwards us the
8851
         target device. If this occurs we actually need to get to the color
8852
         space defined by the transparency group and we use the operators
8853
         defined by the transparency device to do the job.
8854
       */
8855
3.78M
    if (pgs->trans_device != NULL){
8856
3.78M
        trans_device = pgs->trans_device;
8857
3.78M
    } else {
8858
0
        trans_device = dev;
8859
0
    }
8860
3.78M
    ncomps = trans_device->color_info.num_components;
8861
    /* map to the color model */
8862
3.78M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps);
8863
8864
3.78M
    nc = ncomps;
8865
3.78M
    if (device_encodes_tags(trans_device))
8866
0
        nc--;
8867
    /* apply the transfer function(s); convert to color values */
8868
3.78M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
8869
0
        for (i = 0; i < nc; i++)
8870
0
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8871
        /* We are in an additive mode (blend space) and drawing with a sep color
8872
        into a sep device.  Make sure we are drawing "white" with the process
8873
        colorants */
8874
0
        for (i = 0; i < nc - num_spots; i++)
8875
0
            cv[i] = gx_max_color_value;
8876
0
    } else
8877
18.9M
        for (i = 0; i < nc; i++)
8878
15.1M
            cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8879
    /* Copy tags untransformed. */
8880
3.78M
    if (nc < ncomps)
8881
0
        cv[nc] = cm_comps[nc];
8882
8883
    /* if output device supports devn, we need to make sure we send it the
8884
       proper color type */
8885
3.78M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0)) {
8886
2.46M
        for (i = 0; i < ncomps; i++)
8887
1.97M
            pdc->colors.devn.values[i] = cv[i];
8888
493k
        pdc->type = gx_dc_type_devn;
8889
3.28M
    } else {
8890
    /* encode as a color index */
8891
3.28M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8892
        /* check if the encoding was successful; we presume failure is rare */
8893
3.28M
        if (color != gx_no_color_index)
8894
3.28M
            color_set_pure(pdc, color);
8895
3.28M
    }
8896
3.78M
}
8897
8898
static  bool
8899
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8900
328k
{
8901
328k
    return false;
8902
328k
}
8903
8904
static  const gx_color_map_procs *
8905
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8906
2.78M
{
8907
    /* The pdf14 marking device itself is always continuous tone. */
8908
2.78M
    return &pdf14_cmap_many;
8909
2.78M
}
8910
8911
static int
8912
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8913
                  void *data, int size)
8914
220M
{
8915
220M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8916
8917
220M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8918
1.39M
        return 1;
8919
218M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8920
52.8k
        return 1;
8921
218M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8922
854
        if (data != NULL && size == sizeof(gx_device *))
8923
386
            *(gx_device **)data = pdev;
8924
854
        return 1;
8925
854
    }
8926
218M
    if (dev_spec_op == gxdso_device_child) {
8927
3.23k
        pdf14_device *dev = (pdf14_device *)pdev;
8928
3.23k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8929
3.23k
        if (d->target == pdev) {
8930
3.23k
            d->target = dev->target;
8931
3.23k
            return 1;
8932
3.23k
        }
8933
3.23k
    }
8934
218M
    if (dev_spec_op == gxdso_supports_devn
8935
218M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8936
119M
        cmm_dev_profile_t *dev_profile;
8937
119M
        int code;
8938
119M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8939
119M
        if (code == 0) {
8940
119M
            return dev_profile->supports_devn;
8941
119M
        } else {
8942
0
            return 0;
8943
0
        }
8944
119M
    }
8945
99.0M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8946
432k
        pdf14_device* dev = (pdf14_device*)pdev;
8947
8948
432k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8949
432k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8950
125k
            return 1;
8951
307k
        return 0;
8952
432k
    }
8953
98.5M
    if (dev_spec_op == gxdso_is_encoding_direct)
8954
3.25M
        return 1;
8955
8956
    /* We don't want to pass on these spec_ops either, because the child might respond
8957
     * with an inappropriate response when the PDF14 device is active. For example; the
8958
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8959
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8960
     */
8961
95.3M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8962
609k
        return 0;
8963
94.7M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8964
2.23M
        return 0;
8965
92.4M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8966
52.7k
        return 0;
8967
92.4M
    if(dev_spec_op == gxdso_supports_hlcolor)
8968
1.45k
        return 0;
8969
92.4M
    if(dev_spec_op == gxdso_pattern_can_accum)
8970
131k
        return 0;
8971
92.3M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8972
2.48k
        return 0;
8973
92.3M
    if (dev_spec_op == gxdso_overprint_active) {
8974
6.44M
        if (p14dev->pclist_device != NULL) {
8975
6.41M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8976
6.41M
        } else {
8977
29.8k
            return p14dev->overprint || p14dev->stroke_overprint;
8978
29.8k
        }
8979
6.44M
    }
8980
8981
    /* These should be coming only from the abuf device
8982
       during fill-stroke operation. Any other use will
8983
       result in bad things. */
8984
85.8M
    if (dev_spec_op == gxdso_abuf_optrans)
8985
0
    {
8986
0
        int ret = p14dev->op_state;
8987
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
8988
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
8989
0
        const gs_gstate* cpgs = state_data->pgs;
8990
0
        union {
8991
0
            const gs_gstate* cpgs;
8992
0
            gs_gstate* pgs;
8993
0
        } const_breaker;
8994
0
        gs_gstate* pgs;
8995
0
        int code = 0;
8996
0
        int code1 = 0;
8997
8998
        /* A compile time assert to check our storage types are appropriately sized. */
8999
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9000
9001
        /* I don't really like this, but there is no easy way around it. The device
9002
           in the pgs needs to be the pdf14 device to ensure that the compositor
9003
           actions occur with the gs_transparency calls. We have to call at that
9004
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9005
           operations are invoked. We could change the gs_trans calls to take a
9006
           device to avoid this dance but that changes the device procs. */
9007
0
        gx_device *curr_dev;
9008
9009
0
        const_breaker.cpgs = cpgs;
9010
0
        pgs = const_breaker.pgs;
9011
0
        curr_dev = pgs->device;
9012
0
        pgs->device = pdev;
9013
9014
0
        switch (state_data->op_trans) {
9015
9016
0
            case OP_FS_TRANS_PREFILL:
9017
0
                pdf14_abuf->orig_state = p14dev->op_state;
9018
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9019
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9020
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9021
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9022
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9023
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9024
0
                    pdf14_abuf->group_needed = false;
9025
0
                else
9026
0
                    pdf14_abuf->group_needed = true;
9027
9028
0
                if (pdf14_abuf->group_needed) {
9029
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9030
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9031
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9032
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9033
0
                        state_data->alpha_buf_path_scale);
9034
0
                    if (code < 0)
9035
0
                        goto cleanup;
9036
0
                }
9037
0
                code = gs_update_trans_marking_params(pgs);
9038
0
                break;
9039
9040
0
            case OP_FS_TRANS_PRESTROKE:
9041
0
                if (pdf14_abuf->group_needed) {
9042
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9043
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9044
0
                }
9045
0
                code = gs_update_trans_marking_params(pgs);
9046
0
                break;
9047
9048
0
            case OP_FS_TRANS_POSTSTROKE:
9049
0
                if (pdf14_abuf->group_needed) {
9050
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9051
0
                                                        pdf14_abuf->op_ca_eq_CA);
9052
0
                }
9053
0
                if (code >= 0)
9054
0
                    code = gs_update_trans_marking_params(pgs);
9055
9056
                /* fallthrough */
9057
9058
0
            case OP_FS_TRANS_CLEANUP:
9059
0
cleanup:
9060
0
                if (pdf14_abuf->group_needed) {
9061
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9062
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, (PDF14_OP_FS_STATE)pdf14_abuf->orig_state);
9063
0
                    if (code1 < 0)
9064
0
                        code = gs_note_error(gs_error_Fatal);
9065
0
                }
9066
0
                break;
9067
0
        }
9068
0
        pgs->device = curr_dev;
9069
9070
0
        return (code < 0) ? code : ret;
9071
0
    }
9072
9073
85.8M
    if (dev_spec_op == gxdso_in_smask_construction)
9074
6.55M
        return p14dev->in_smask_construction > 0;
9075
79.3M
    if (dev_spec_op == gxdso_in_smask)
9076
50.3M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9077
28.9M
    if (dev_spec_op == gxdso_replacecolor) {
9078
28.2M
        gx_device *tdev = p14dev->target;
9079
28.2M
        cmm_dev_profile_t *tdev_profile;
9080
28.2M
        int code;
9081
9082
         /* If in a softmask or softmask construction do not allow
9083
           replacement. */
9084
28.2M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9085
555k
            return 0;
9086
9087
        /* If the target CS is different than the pdf14 profile add this information
9088
           for the target device that will be handling the replacement. While not
9089
           perfect this at least lets you do the replacehment and have some information
9090
           about what the situation is. */
9091
27.6M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9092
27.6M
        if (code != 0)
9093
0
            return 0;
9094
9095
27.6M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9096
27.6M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9097
18.5M
            color_replace_t* replace_data = (color_replace_t*)data;
9098
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9099
               color remap operation. */
9100
18.5M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9101
18.5M
        }
9102
9103
        /* Pass on to target device */
9104
27.6M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9105
27.6M
    }
9106
691k
    if (dev_spec_op == gxdso_device_insert_child) {
9107
105
        gx_device *tdev = p14dev->target;
9108
105
        p14dev->target = (gx_device *)data;
9109
105
        rc_increment(p14dev->target);
9110
105
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9111
105
        return 0;
9112
105
    }
9113
691k
    if (dev_spec_op == gxdso_interpolate_threshold)
9114
15.9k
        return p14dev->interpolate_threshold;
9115
9116
675k
    if (dev_spec_op == gxdso_overprintsim_state) {
9117
15.8k
        unsigned char *data_uchar = (unsigned char *) data;
9118
15.8k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9119
15.8k
        if (p14dev->ctx != NULL)
9120
11
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9121
15.8k
        else
9122
15.8k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9123
15.8k
        return 1;
9124
15.8k
    }
9125
9126
659k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9127
675k
}
9128
9129
/* Needed to set color monitoring in the target device's profile */
9130
int
9131
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9132
0
{
9133
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9134
0
    gx_device *targ = p14dev->target;
9135
0
    cmm_dev_profile_t *dev_profile;
9136
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9137
9138
0
    if (code == 0)
9139
0
        dev_profile->pageneutralcolor = monitoring;
9140
0
    return code;
9141
0
}
9142
9143
static int
9144
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9145
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9146
1.56M
{
9147
1.56M
    pdf14_device dev_proto;
9148
1.56M
    pdf14_device * p14dev;
9149
1.56M
    int code;
9150
1.56M
    bool has_tags;
9151
1.56M
    cmm_profile_t *icc_profile;
9152
1.56M
    gsicc_rendering_param_t render_cond;
9153
1.56M
    cmm_dev_profile_t *dev_profile;
9154
1.56M
    uchar k;
9155
1.56M
    int max_bitmap;
9156
1.56M
    bool use_pdf14_accum = false;
9157
1.56M
    bool deep;
9158
9159
    /* Guard against later seg faults, this should not be possible */
9160
1.56M
    if (target == NULL)
9161
0
        return gs_throw_code(gs_error_Fatal);
9162
9163
1.56M
    has_tags = device_encodes_tags(target);
9164
1.56M
    deep = device_is_deep(target);
9165
1.56M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9166
1.56M
                                 target->space_params.MaxBitmap;
9167
    /* If the device is not a printer class device, it won't support saved-pages */
9168
    /* and so we may need to make a clist device in order to prevent very large  */
9169
    /* or high resolution pages from having allocation problems.                 */
9170
    /* We use MaxBitmap to decide when a clist is needed.*/
9171
1.56M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9172
1.56M
        gx_device_is_pattern_clist(target) == 0 &&
9173
1.56M
        gx_device_is_pattern_accum(target) == 0 &&
9174
1.56M
        gs_device_is_memory(target) == 0) {
9175
9176
5.89k
        uint32_t pdf14_trans_buffer_size =
9177
5.89k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9178
5.89k
                                         target->color_info.num_components,
9179
5.89k
                                         deep ? 16 : 8) >> 3);
9180
9181
5.89k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9182
5.89k
                pdf14_trans_buffer_size *= target->height;
9183
0
        else
9184
0
                max_bitmap = 0;     /* Force decision to clist */
9185
5.89k
        if (pdf14_trans_buffer_size > max_bitmap)
9186
5.71k
            use_pdf14_accum = true;
9187
5.89k
    }
9188
1.56M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9189
1.56M
    if (code < 0)
9190
0
        return code;
9191
1.56M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9192
1.56M
                          &render_cond);
9193
1.56M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9194
9195
    /* Get the proto from which to copy the device. This will always
9196
     * ignore tags! */
9197
1.56M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9198
1.56M
                                  pdf14pct, use_pdf14_accum);
9199
1.56M
    if (code < 0)
9200
0
        return code;
9201
1.56M
    code = gs_copydevice((gx_device **) &p14dev,
9202
1.56M
                         (const gx_device *) &dev_proto, mem);
9203
1.56M
    if (code < 0)
9204
0
        return code;
9205
9206
    /* Copying the params across will add tags to the colorinfo as required. */
9207
1.56M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9208
1.56M
    if (code < 0)
9209
0
        return code;
9210
9211
1.56M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9212
1.56M
    p14dev->pad = target->pad;
9213
1.56M
    p14dev->log2_align_mod = target->log2_align_mod;
9214
1.56M
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
9215
0
        p14dev->num_planar_planes = p14dev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
9216
1.56M
    else
9217
1.56M
        p14dev->num_planar_planes = target->num_planar_planes;
9218
1.56M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9219
9220
1.56M
    p14dev->alpha = 1.0;
9221
1.56M
    p14dev->shape = 1.0;
9222
1.56M
    p14dev->opacity = 1.0;
9223
1.56M
    p14dev->fillconstantalpha = 1.0;
9224
1.56M
    p14dev->strokeconstantalpha = 1.0;
9225
9226
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9227
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9228
       do the mapping to the NCLR profile when the put_image occurs */
9229
1.56M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9230
1.56M
        icc_profile->data_cs == gsNCHANNEL) {
9231
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9232
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9233
0
            -1, "gs_pdf14_device_push");
9234
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9235
1.56M
    } else {
9236
        /* If the target profile was CIELAB (and we are not using a blend CS),
9237
           then overide with default RGB for proper blending.  During put_image
9238
           we will convert from RGB to CIELAB.  Need to check that we have a
9239
           default profile, which will not be the case if we are coming from the clist reader */
9240
1.56M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9241
1.56M
            && pgs->icc_manager->default_rgb != NULL &&
9242
1.56M
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9243
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9244
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9245
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9246
0
                -1, "gs_pdf14_device_push");
9247
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9248
0
        }
9249
1.56M
    }
9250
9251
1.56M
    if (pdf14pct->params.overprint_sim_push &&
9252
1.56M
        pdf14pct->params.num_spot_colors_int > 0) {
9253
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9254
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9255
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9256
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9257
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9258
0
    }
9259
9260
    /* The number of color planes should not exceed that of the target.
9261
       Unless we are using a blend CS */
9262
1.56M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9263
1.56M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev))
9264
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9265
1.56M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9266
101k
            p14dev->color_info.max_components = target->color_info.max_components;
9267
1.56M
    }
9268
1.56M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9269
    /* If we have a tag device then go ahead and do a special encoder
9270
       decoder for the pdf14 device to make sure we maintain this
9271
       information in the encoded color information.  We could use
9272
       the target device's methods but the PDF14 device has to maintain
9273
       8 bit color always and we could run into other issues if the number
9274
       of colorants became large.  If we need to do compressed color with
9275
       tags that will be a special project at that time */
9276
1.56M
    if (deep) {
9277
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9278
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9279
0
    }
9280
1.56M
    if (has_tags) {
9281
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9282
0
    }
9283
    /* if the device has separations already defined (by SeparationOrderNames) */
9284
    /* we need to copy them (allocating new names) so the colorants are in the */
9285
    /* same order as the target device.                                        */
9286
1.56M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9287
101k
        code = devn_copy_params(target, (gx_device *)p14dev);
9288
101k
        if (code < 0) {
9289
50
            *pdev = NULL;
9290
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9291
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9292
50
            return code;
9293
50
        }
9294
101k
    }
9295
    /* by definition pdf14_encode _is_ standard */
9296
1.56M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9297
1.56M
    gx_device_fill_in_procs((gx_device *)p14dev);
9298
1.56M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9299
1.56M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9300
1.56M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9301
9302
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9303
5.42M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9304
3.85M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9305
3.85M
        p14dev->color_info.comp_shift[k] =
9306
3.85M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9307
3.85M
    }
9308
1.56M
    if (use_pdf14_accum) {
9309
        /* we will disable this device later, but we don't want to allocate large buffers */
9310
5.71k
        p14dev->width = 1;
9311
5.71k
        p14dev->height = 1;
9312
5.71k
    }
9313
9314
1.56M
    p14dev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
9315
1.56M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9316
1.56M
    *pdev = (gx_device *) p14dev;
9317
1.56M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9318
1.56M
    p14dev->color_model_stack = NULL;
9319
9320
    /* In case we have alphabits set */
9321
1.56M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9322
9323
1.56M
    if (pdf14pct->params.is_pattern) {
9324
18.6k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9325
18.6k
        if (code < 0) {
9326
0
            *pdev = NULL;
9327
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9328
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9329
0
            return code;
9330
0
        }
9331
18.6k
    }
9332
9333
    /* We should never go into this when using a blend color space */
9334
1.56M
    if (use_pdf14_accum) {
9335
5.71k
        const gx_device_pdf14_accum *accum_proto = NULL;
9336
5.71k
        gx_device *new_target = NULL;
9337
5.71k
        gx_device_color pdcolor;
9338
5.71k
        frac pconc_white = frac_1;
9339
5.71k
        bool UsePlanarBuffer = false;
9340
9341
5.71k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9342
9343
        /* get the prototype for the accumulator device based on colorspace */
9344
5.71k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9345
1.03k
            case 1:
9346
1.03k
                accum_proto = &pdf14_accum_Gray;
9347
1.03k
                break;
9348
4.67k
            case 3:
9349
4.67k
                accum_proto = &pdf14_accum_RGB;
9350
4.67k
                break;
9351
0
            case 4:
9352
0
                accum_proto = &pdf14_accum_CMYK;
9353
0
                break;
9354
0
            default:
9355
0
                accum_proto = &pdf14_accum_CMYKspot;
9356
0
                UsePlanarBuffer = true;
9357
5.71k
        }
9358
5.71k
        if (accum_proto == NULL ||
9359
5.71k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9360
0
            goto no_clist_accum;
9361
9362
5.71k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9363
        /* Fill in values from the target device before opening */
9364
5.71k
        new_target->color_info = p14dev->color_info;
9365
5.71k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9366
5.71k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9367
5.71k
        set_linear_color_bits_mask_shift(new_target);
9368
5.71k
        gs_pdf14_device_copy_params(new_target, target);
9369
5.71k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9370
5.71k
        gx_device_fill_in_procs(new_target);
9371
9372
5.71k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9373
5.71k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9374
5.71k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9375
9376
5.71k
        new_target->PageHandlerPushed = true;
9377
5.71k
        new_target->ObjectHandlerPushed = true;
9378
5.71k
        new_target->NupHandlerPushed = true;
9379
        /* if the device has separations already defined (by SeparationOrderNames) */
9380
        /* we need to copy them (allocating new names) so the colorants are in the */
9381
        /* same order as the target device.                                        */
9382
5.71k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
9383
0
            code = devn_copy_params(target, (gx_device *)pdev);
9384
0
            if (code < 0)
9385
0
                return code;
9386
0
        }
9387
        /* UsePlanarBuffer is true in case this is CMYKspot */
9388
5.71k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9389
5.71k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9390
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9391
0
            goto no_clist_accum;
9392
0
        }
9393
        /* Do the initial fillpage into the pdf14-accum device we just created */
9394
5.71k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9395
5.71k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9396
5.71k
                                            &pconc_white,
9397
5.71k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9398
5.71k
                                            dev_profile)) < 0)
9399
0
            goto no_clist_accum;
9400
9401
5.71k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9402
5.71k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9403
5.71k
        if (code < 0)
9404
0
            goto no_clist_accum;
9405
9406
5.71k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9407
5.71k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9408
5.71k
    }
9409
1.56M
    return code;
9410
9411
0
no_clist_accum:
9412
        /* FIXME: We allocated a really small p14dev, but that won't work */
9413
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9414
1.56M
}
9415
9416
/*
9417
 * In a modest violation of good coding practice, the gs_composite_common
9418
 * fields are "known" to be simple (contain no pointers to garbage
9419
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9420
 * to be simple, so we just create a trivial structure descriptor for the
9421
 * entire gs_pdf14trans_s structure.
9422
 */
9423
#define private_st_gs_pdf14trans_t()\
9424
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9425
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9426
9427
/* GC descriptor for gs_pdf14trans_t */
9428
private_st_gs_pdf14trans_t();
9429
9430
/*
9431
 * Check for equality of two PDF 1.4 transparency compositor objects.
9432
 *
9433
 * We are currently always indicating that PDF 1.4 transparency compositors are
9434
 * equal.  Two transparency compositors may have teh same data but still
9435
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9436
 * operations in a row mean that we are creating a group inside of a group.
9437
 */
9438
static  bool
9439
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9440
0
{
9441
0
    return false;
9442
0
}
9443
9444
#ifdef DEBUG
9445
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9446
#endif
9447
9448
#define put_value(dp, value)\
9449
10.0M
    BEGIN\
9450
10.0M
        memcpy(dp, &value, sizeof(value));\
9451
10.0M
        dp += sizeof(value);\
9452
10.0M
    END
9453
9454
static inline int
9455
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9456
1.17M
{
9457
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9458
       because clist writer may skip this command for some bands.
9459
       For a better result we need individual CTM for each band.
9460
     */
9461
1.17M
    byte *pbuf = *ppbuf;
9462
1.17M
    int len, code;
9463
9464
1.17M
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9465
1.17M
    pbuf--; /* For cmd_write_ctm. */
9466
1.17M
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9467
1.17M
    if (code < 0)
9468
0
        return code;
9469
1.17M
    pbuf += len + 1;
9470
1.17M
    *ppbuf = pbuf;
9471
1.17M
    return 0;
9472
1.17M
}
9473
9474
/*
9475
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9476
 * list device. This is also where we update the pdf14_needed. When set the clist
9477
 * painting procs will update the trans_bbox state for bands that are affected.
9478
*/
9479
static  int
9480
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9481
                   gx_device_clist_writer *cdev)
9482
2.85M
{
9483
2.85M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9484
2.85M
    int need, avail = *psize;
9485
2.85M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9486
        to fit the data written below. We don't implement a dynamic check for
9487
        the buffer owerflow, assuming that the consistency is verified in the
9488
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9489
2.85M
    byte * pbuf = buf;
9490
2.85M
    int opcode = pparams->pdf14_op;
9491
2.85M
    int mask_size = 0;
9492
2.85M
    uint mask_id = 0;
9493
2.85M
    int code;
9494
2.85M
    bool found_icc;
9495
2.85M
    int64_t hashcode = 0;
9496
2.85M
    cmm_profile_t *icc_profile;
9497
2.85M
    gsicc_rendering_param_t render_cond;
9498
2.85M
    cmm_dev_profile_t *dev_profile;
9499
    /* We maintain and update working copies until we actually write the clist */
9500
2.85M
    int pdf14_needed = cdev->pdf14_needed;
9501
2.85M
    int trans_group_level = cdev->pdf14_trans_group_level;
9502
2.85M
    int smask_level = cdev->pdf14_smask_level;
9503
2.85M
    bool deep = device_is_deep((gx_device *)cdev);
9504
9505
2.85M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9506
2.85M
                                                     &dev_profile);
9507
2.85M
    if (code < 0)
9508
0
        return code;
9509
2.85M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9510
2.85M
                          &render_cond);
9511
2.85M
    *pbuf++ = opcode;     /* 1 byte */
9512
2.85M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9513
1
        return_error(gs_error_unregistered); /* prevent spurious transparency ops (Bug 702327) */
9514
9515
2.85M
    switch (opcode) {
9516
0
        default:      /* Should not occur. */
9517
0
            break;
9518
26.2k
        case PDF14_PUSH_DEVICE:
9519
26.2k
            trans_group_level = 0;
9520
26.2k
            cdev->pdf14_smask_level = 0;
9521
26.2k
            cdev->page_pdf14_needed = false;
9522
26.2k
            put_value(pbuf, pparams->num_spot_colors);
9523
26.2k
            put_value(pbuf, pparams->num_spot_colors_int);
9524
26.2k
            put_value(pbuf, pparams->overprint_sim_push);
9525
26.2k
            put_value(pbuf, pparams->is_pattern);
9526
9527
            /* If we happen to be going to a color space like CIELAB then
9528
               we are going to do our blending in default RGB and convert
9529
               to CIELAB at the end.  To do this, we need to store the
9530
               default RGB profile in the clist so that we can grab it
9531
               later on during the clist read back and put image command */
9532
26.2k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9533
                /* Get the default RGB profile.  Set the device hash code
9534
                   so that we can extract it during the put_image operation. */
9535
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9536
0
                found_icc =
9537
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9538
0
                if (!found_icc) {
9539
                    /* Add it to the table */
9540
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9541
0
                                       pparams->iccprofile);
9542
0
                }
9543
0
            }
9544
26.2k
            break;
9545
25.3k
        case PDF14_POP_DEVICE:
9546
25.3k
            pdf14_needed = false;   /* reset pdf14_needed */
9547
25.3k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9548
25.3k
            smask_level = 0;
9549
25.3k
            put_value(pbuf, pparams->is_pattern);
9550
25.3k
            break;
9551
635k
        case PDF14_END_TRANS_GROUP:
9552
641k
        case PDF14_END_TRANS_TEXT_GROUP:
9553
641k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9554
641k
            if (smask_level == 0 && trans_group_level == 0)
9555
34.4k
                pdf14_needed = cdev->page_pdf14_needed;
9556
641k
            break;      /* No data */
9557
10.0k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9558
641k
        case PDF14_BEGIN_TRANS_GROUP:
9559
641k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9560
641k
            trans_group_level++;
9561
641k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9562
641k
            if (code < 0)
9563
0
                return code;
9564
641k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9565
641k
            *pbuf++ = pparams->blend_mode;
9566
641k
            *pbuf++ = pparams->group_color_type;
9567
641k
            *pbuf++ = pparams->page_group;
9568
641k
            put_value(pbuf, pparams->group_color_numcomps);
9569
641k
            put_value(pbuf, pparams->opacity);
9570
641k
            put_value(pbuf, pparams->shape);
9571
641k
            put_value(pbuf, pparams->bbox);
9572
641k
            put_value(pbuf, pparams->shade_group);
9573
641k
            put_value(pbuf, pparams->text_group);
9574
641k
            mask_id = pparams->mask_id;
9575
641k
            put_value(pbuf, mask_id);
9576
            /* Color space information maybe ICC based
9577
               in this case we need to store the ICC
9578
               profile or the ID if it is cached already */
9579
641k
            if (pparams->group_color_type == ICC) {
9580
                /* Check if it is already in the ICC clist table */
9581
18.5k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9582
18.5k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9583
18.5k
                if (!found_icc) {
9584
                    /* Add it to the table */
9585
5.35k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9586
5.35k
                    put_value(pbuf, hashcode);
9587
13.2k
                } else {
9588
                    /* It will be in the clist. Just write out the hashcode */
9589
13.2k
                    put_value(pbuf, hashcode);
9590
13.2k
                }
9591
622k
            } else {
9592
622k
                put_value(pbuf, hashcode);
9593
622k
            }
9594
641k
            break;
9595
532k
        case PDF14_BEGIN_TRANS_MASK:
9596
532k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9597
456k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9598
456k
                smask_level++;
9599
456k
            }
9600
532k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9601
532k
            if (code < 0)
9602
0
                return code;
9603
532k
            put_value(pbuf, pparams->subtype);
9604
532k
            *pbuf++ = pparams->group_color_type;
9605
532k
            put_value(pbuf, pparams->group_color_numcomps);
9606
532k
            *pbuf++ = pparams->replacing;
9607
532k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9608
532k
            *pbuf++ = pparams->Background_components;
9609
532k
            *pbuf++ = pparams->Matte_components;
9610
532k
            put_value(pbuf, pparams->bbox);
9611
532k
            mask_id = pparams->mask_id;
9612
532k
            put_value(pbuf, mask_id);
9613
532k
            if (pparams->Background_components) {
9614
3.95k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9615
9616
3.95k
                memcpy(pbuf, pparams->Background, l);
9617
3.95k
                pbuf += l;
9618
3.95k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9619
3.95k
                pbuf += sizeof(pparams->GrayBackground);
9620
3.95k
            }
9621
532k
            if (pparams->Matte_components) {
9622
164
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9623
9624
164
                memcpy(pbuf, pparams->Matte, m);
9625
164
                pbuf += m;
9626
164
            }
9627
532k
            if (!pparams->function_is_identity)
9628
1.23k
                mask_size = (256+deep)<<deep;
9629
            /* Color space information may be ICC based
9630
               in this case we need to store the ICC
9631
               profile or the ID if it is cached already */
9632
532k
            if (pparams->group_color_type == ICC) {
9633
                /* Check if it is already in the ICC clist table */
9634
456k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9635
456k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9636
456k
                if (!found_icc) {
9637
                    /* Add it to the table */
9638
3.77k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9639
3.77k
                    put_value(pbuf, hashcode);
9640
452k
                } else {
9641
                    /* It will be in the clist. Just write out the hashcode */
9642
452k
                    put_value(pbuf, hashcode);
9643
452k
                }
9644
456k
            } else {
9645
76.4k
                put_value(pbuf, hashcode);
9646
76.4k
            }
9647
532k
            break;
9648
456k
        case PDF14_END_TRANS_MASK:
9649
456k
            smask_level--;
9650
456k
            if (smask_level == 0 && trans_group_level == 0)
9651
13.3k
                pdf14_needed = cdev->page_pdf14_needed;
9652
456k
            break;
9653
463k
        case PDF14_SET_BLEND_PARAMS:
9654
463k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9655
463k
                pparams->shape != 1.0)
9656
463k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9657
0
            else if (smask_level == 0 && trans_group_level == 0)
9658
0
                pdf14_needed = false;   /* At page level, set back to false */
9659
463k
            if (smask_level == 0 && trans_group_level == 0)
9660
171k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9661
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9662
463k
            put_value(pbuf, pparams->changed);
9663
463k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9664
46.0k
                *pbuf++ = pparams->blend_mode;
9665
463k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9666
24.5k
                *pbuf++ = pparams->text_knockout;
9667
463k
            if (pparams->changed & PDF14_SET_AIS)
9668
463k
                put_value(pbuf, pparams->ais);
9669
463k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9670
463k
                put_value(pbuf, pparams->overprint);
9671
463k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9672
463k
                put_value(pbuf, pparams->stroke_overprint);
9673
463k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9674
463k
                put_value(pbuf, pparams->fillconstantalpha);
9675
463k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9676
463k
                put_value(pbuf, pparams->strokeconstantalpha);
9677
463k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9678
463k
                put_value(pbuf, pparams->op_fs_state);
9679
463k
            break;
9680
0
        case PDF14_PUSH_TRANS_STATE:
9681
0
            break;
9682
66.0k
        case PDF14_POP_TRANS_STATE:
9683
66.0k
            break;
9684
0
        case PDF14_PUSH_SMASK_COLOR:
9685
0
            return 0;   /* We really should never be here */
9686
0
            break;
9687
0
        case PDF14_POP_SMASK_COLOR:
9688
0
            return 0;   /* We really should never be here */
9689
0
            break;
9690
2.85M
    }
9691
9692
    /* check for fit */
9693
2.85M
    need = (pbuf - buf) + mask_size;
9694
2.85M
    *psize = need;
9695
2.85M
    if (need > avail) {
9696
495k
        if (avail)
9697
0
            return_error(gs_error_rangecheck);
9698
495k
        else
9699
495k
            return gs_error_rangecheck;
9700
495k
    }
9701
9702
    /* If we are writing more than the maximum ever expected,
9703
     * return a rangecheck error. Second check is for Coverity
9704
     */
9705
2.35M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9706
2.35M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9707
0
        return_error(gs_error_rangecheck);
9708
9709
    /* Copy our serialized data into the output buffer */
9710
2.35M
    memcpy(data, buf, need - mask_size);
9711
2.35M
    if (mask_size)  /* Include the transfer mask data if present */
9712
925
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9713
2.35M
    if_debug3m('v', cdev->memory,
9714
2.35M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9715
2.35M
               pdf14_opcode_names[opcode], mask_id, need);
9716
2.35M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9717
2.35M
    cdev->pdf14_trans_group_level = trans_group_level;
9718
2.35M
    cdev->pdf14_smask_level = smask_level;
9719
2.35M
    return 0;
9720
2.35M
}
9721
9722
#undef put_value
9723
9724
/* Function prototypes */
9725
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9726
                const gs_pdf14trans_params_t * pparams,
9727
                gs_memory_t * mem );
9728
9729
#define read_value(dp, value)\
9730
235M
    BEGIN\
9731
235M
        memcpy(&value, dp, sizeof(value));\
9732
235M
        dp += sizeof(value);\
9733
235M
    END
9734
9735
/*
9736
 * Convert the string representation of the PDF 1.4 transparency parameter
9737
 * into the full compositor.
9738
 */
9739
static  int
9740
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9741
                                uint size, gs_memory_t * mem )
9742
70.2M
{
9743
70.2M
    gs_pdf14trans_params_t params = {0};
9744
70.2M
    const byte * start = data;
9745
70.2M
    int used, code = 0;
9746
70.2M
    bool deep;
9747
9748
70.2M
    if (size < 1)
9749
0
        return_error(gs_error_rangecheck);
9750
9751
    /* Read PDF 1.4 compositor data from the clist */
9752
70.2M
    params.pdf14_op = *data++;
9753
70.2M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9754
70.2M
               pdf14_opcode_names[params.pdf14_op], size);
9755
70.2M
    memset(&params.ctm, 0, sizeof(params.ctm));
9756
70.2M
    switch (params.pdf14_op) {
9757
0
        default:      /* Should not occur. */
9758
0
            break;
9759
2.26M
        case PDF14_PUSH_DEVICE:
9760
2.26M
            read_value(data, params.num_spot_colors);
9761
2.26M
            read_value(data, params.num_spot_colors_int);
9762
2.26M
            read_value(data, params.overprint_sim_push);
9763
2.26M
            read_value(data, params.is_pattern);
9764
2.26M
            break;
9765
0
        case PDF14_ABORT_DEVICE:
9766
0
            break;
9767
2.26M
        case PDF14_POP_DEVICE:
9768
2.26M
            read_value(data, params.is_pattern);
9769
2.26M
            break;
9770
3.45M
        case PDF14_END_TRANS_GROUP:
9771
3.89M
        case PDF14_END_TRANS_TEXT_GROUP:
9772
#ifdef DEBUG
9773
            code += 0; /* A good place for a breakpoint. */
9774
#endif
9775
3.89M
            break;      /* No data */
9776
0
        case PDF14_PUSH_TRANS_STATE:
9777
0
            break;
9778
5.13M
        case PDF14_POP_TRANS_STATE:
9779
5.13M
            break;
9780
942k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9781
3.89M
        case PDF14_BEGIN_TRANS_GROUP:
9782
            /*
9783
             * We are currently not using the bbox or the colorspace so they were
9784
             * not placed in the clist
9785
             */
9786
3.89M
            data = cmd_read_matrix(&params.ctm, data);
9787
3.89M
            params.Isolated = (*data) & 1;
9788
3.89M
            params.Knockout = (*data++ >> 1) & 1;
9789
3.89M
            params.blend_mode = *data++;
9790
3.89M
            params.group_color_type = *data++;  /* Trans group color */
9791
3.89M
            params.page_group = *data++;
9792
3.89M
            read_value(data,params.group_color_numcomps);  /* color group size */
9793
3.89M
            read_value(data, params.opacity);
9794
3.89M
            read_value(data, params.shape);
9795
3.89M
            read_value(data, params.bbox);
9796
3.89M
            read_value(data, params.shade_group);
9797
3.89M
            read_value(data, params.text_group);
9798
3.89M
            read_value(data, params.mask_id);
9799
3.89M
            read_value(data, params.icc_hash);
9800
3.89M
            break;
9801
7.64M
        case PDF14_BEGIN_TRANS_MASK:
9802
                /* This is the largest transparency parameter at this time (potentially
9803
                 * 1531 bytes in size if Background_components =
9804
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9805
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9806
                 *
9807
                 * NOTE:
9808
                 * The clist reader must be able to handle this sized device.
9809
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9810
                 * may also need to be changed correspondingly (defined in gstparam.h)
9811
                 * Also... if another compositor param should exceed this size, this
9812
                 * same condition applies.
9813
                 */
9814
7.64M
            data = cmd_read_matrix(&params.ctm, data);
9815
7.64M
            read_value(data, params.subtype);
9816
7.64M
            params.group_color_type = *data++;
9817
7.64M
            read_value(data, params.group_color_numcomps);
9818
7.64M
            params.replacing = *data++;
9819
7.64M
            params.function_is_identity = *data & 1;
9820
7.64M
            deep = (*data++)>>1;
9821
7.64M
            params.Background_components = *data++;
9822
7.64M
            params.Matte_components = *data++;
9823
7.64M
            read_value(data, params.bbox);
9824
7.64M
            read_value(data, params.mask_id);
9825
7.64M
            if (params.Background_components) {
9826
266k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9827
9828
266k
                memcpy(params.Background, data, l);
9829
266k
                data += l;
9830
266k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9831
266k
                data += sizeof(params.GrayBackground);
9832
266k
            }
9833
7.64M
            if (params.Matte_components) {
9834
5.59k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9835
9836
5.59k
                memcpy(params.Matte, data, m);
9837
5.59k
                data += m;
9838
5.59k
            }
9839
7.64M
            read_value(data, params.icc_hash);
9840
7.64M
            if (params.function_is_identity) {
9841
7.60M
                int i;
9842
9843
7.60M
                if (deep) {
9844
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9845
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9846
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9847
7.60M
                } else {
9848
1.95G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9849
1.94G
                        params.transfer_fn[i] = (byte)floor(i *
9850
1.94G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9851
1.94G
                    }
9852
7.60M
                }
9853
7.60M
            } else {
9854
35.4k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9855
35.4k
                data += (256+deep)<<deep;
9856
35.4k
            }
9857
7.64M
            break;
9858
800k
        case PDF14_END_TRANS_MASK:
9859
800k
            break;
9860
0
        case PDF14_PUSH_SMASK_COLOR:
9861
0
            return 0;
9862
0
            break;
9863
0
        case PDF14_POP_SMASK_COLOR:
9864
0
            return 0;
9865
0
            break;
9866
44.3M
        case PDF14_SET_BLEND_PARAMS:
9867
44.3M
            read_value(data, params.changed);
9868
44.3M
            if (params.changed & PDF14_SET_BLEND_MODE)
9869
4.59M
                params.blend_mode = *data++;
9870
44.3M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9871
2.20M
                params.text_knockout = *data++;
9872
44.3M
            if (params.changed & PDF14_SET_AIS)
9873
44.3M
                read_value(data, params.ais);
9874
44.3M
            if (params.changed & PDF14_SET_OVERPRINT)
9875
44.3M
                read_value(data, params.overprint);
9876
44.3M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9877
44.3M
                read_value(data, params.stroke_overprint);
9878
44.3M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9879
44.3M
                read_value(data, params.fillconstantalpha);
9880
44.3M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9881
44.3M
                read_value(data, params.strokeconstantalpha);
9882
44.3M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9883
44.3M
                read_value(data, params.op_fs_state);
9884
44.3M
            break;
9885
70.2M
    }
9886
70.2M
    code = gs_create_pdf14trans(ppct, &params, mem);
9887
70.2M
    if (code < 0)
9888
0
        return code;
9889
70.2M
    used = data - start;
9890
70.2M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9891
9892
    /* If we read more than the maximum expected, return a rangecheck error */
9893
70.2M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9894
0
        return_error(gs_error_rangecheck);
9895
70.2M
    else
9896
70.2M
        return used;
9897
70.2M
}
9898
9899
/*
9900
 * Adjust the compositor's CTM.
9901
 */
9902
static int
9903
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9904
36.1M
{
9905
36.1M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9906
36.1M
    gs_matrix mat = pct->params.ctm;
9907
9908
36.1M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9909
36.1M
               mat.xx, mat.xy, mat.yx, mat.yy,
9910
36.1M
               mat.tx, mat.ty);
9911
36.1M
    mat.tx -= x0;
9912
36.1M
    mat.ty -= y0;
9913
36.1M
    gs_gstate_setmatrix(pgs, &mat);
9914
36.1M
    return 0;
9915
36.1M
}
9916
9917
/*
9918
 * Create a PDF 1.4 transparency compositor.
9919
 *
9920
 * Note that this routine will be called only if the device is not already
9921
 * a PDF 1.4 transparency compositor.
9922
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9923
 */
9924
static  int
9925
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9926
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9927
    gs_memory_t * mem)
9928
1.58M
{
9929
1.58M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9930
1.58M
    int code = 0;
9931
9932
    /*
9933
     * We only handle the push operation.  All other operations are ignored.
9934
     * The other operations will be handled by the composite routine
9935
     * for the PDF 1.4 compositing device.
9936
     */
9937
1.58M
    switch (pdf14pct->params.pdf14_op) {
9938
1.56M
        case PDF14_PUSH_DEVICE:
9939
1.56M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9940
            /* Change (non-error) code to 1 to indicate that we created
9941
             * a device. */
9942
1.56M
            if (code >= 0)
9943
1.56M
                code = 1;
9944
1.56M
            break;
9945
25.4k
        default:
9946
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9947
25.4k
            *pp14dev = NULL;
9948
25.4k
            return_error(gs_error_unregistered);
9949
1.58M
    }
9950
1.56M
    return code;
9951
1.58M
}
9952
9953
/*
9954
 * Find an opening compositor op.
9955
 */
9956
static gs_compositor_closing_state
9957
find_opening_op(int opening_op, gs_composite_t **ppcte,
9958
                gs_compositor_closing_state return_code)
9959
3.53M
{
9960
    /* Assuming a right *BEGIN* - *END* operation balance. */
9961
3.53M
    gs_composite_t *pcte = *ppcte;
9962
9963
8.36M
    for (;;) {
9964
8.36M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9965
7.87M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9966
7.87M
            int op = pct->params.pdf14_op;
9967
9968
7.87M
            *ppcte = pcte;
9969
7.87M
            if (op == opening_op)
9970
2.26M
                return return_code;
9971
5.61M
            if (op != PDF14_SET_BLEND_PARAMS) {
9972
3.55M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
9973
913
                    return COMP_ENQUEUE;
9974
3.55M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
9975
375k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
9976
330k
                        return COMP_ENQUEUE;
9977
375k
                }
9978
3.21M
                if (opening_op == PDF14_PUSH_DEVICE) {
9979
3.17M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
9980
3.17M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
9981
3.17M
                        op != PDF14_END_TRANS_TEXT_GROUP)
9982
211k
                        return COMP_ENQUEUE;
9983
3.17M
                }
9984
3.21M
            }
9985
5.61M
        } else
9986
493k
            return COMP_ENQUEUE;
9987
5.07M
        pcte = pcte->prev;
9988
5.07M
        if (pcte == NULL)
9989
237k
            return COMP_EXEC_QUEUE; /* Not in queue. */
9990
5.07M
    }
9991
3.53M
}
9992
9993
/*
9994
 * Find an opening compositor op.
9995
 */
9996
static gs_compositor_closing_state
9997
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
9998
36.6M
{
9999
36.6M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10000
36.6M
    gs_composite_t *pct = *ppcte;
10001
10002
36.6M
    for (;;) {
10003
36.6M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10004
32.1M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10005
10006
32.1M
            *ppcte = pct;
10007
32.1M
            if (pct_pdf14->params.pdf14_op != my_op)
10008
5.83M
                return COMP_ENQUEUE;
10009
26.2M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10010
                /* If the new parameters completely replace the old ones
10011
                   then remove the old one from the queu */
10012
26.2M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10013
26.2M
                    pct_pdf14->params.changed) {
10014
24.6M
                    return COMP_REPLACE_CURR;
10015
24.6M
                } else {
10016
1.68M
                    return COMP_ENQUEUE;
10017
1.68M
                }
10018
26.2M
            }
10019
26.2M
        } else
10020
4.50M
            return COMP_ENQUEUE;
10021
0
        pct = pct->prev;
10022
0
        if (pct == NULL)
10023
0
            return COMP_ENQUEUE; /* Not in queue. */
10024
0
    }
10025
36.6M
}
10026
10027
/*
10028
 * Check for closing compositor.
10029
 */
10030
static gs_compositor_closing_state
10031
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10032
                        gx_device *dev)
10033
60.7M
{
10034
60.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10035
60.7M
    int op0 = pct0->params.pdf14_op;
10036
10037
60.7M
    switch (op0) {
10038
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10039
1.66M
        case PDF14_PUSH_DEVICE:
10040
1.66M
            return COMP_ENQUEUE;
10041
0
        case PDF14_ABORT_DEVICE:
10042
0
            return COMP_ENQUEUE;
10043
1.66M
        case PDF14_POP_DEVICE:
10044
1.66M
            if (*ppcte == NULL)
10045
1.12M
                return COMP_ENQUEUE;
10046
537k
            else {
10047
537k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10048
10049
537k
                if (state == COMP_EXEC_IDLE)
10050
109k
                    return COMP_DROP_QUEUE;
10051
428k
                return state;
10052
537k
            }
10053
722k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10054
3.35M
        case PDF14_BEGIN_TRANS_GROUP:
10055
3.35M
            return COMP_ENQUEUE;
10056
2.94M
        case PDF14_END_TRANS_GROUP:
10057
3.35M
        case PDF14_END_TRANS_TEXT_GROUP:
10058
3.35M
            if (*ppcte == NULL)
10059
630k
                return COMP_EXEC_QUEUE;
10060
2.72M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10061
6.36M
        case PDF14_BEGIN_TRANS_MASK:
10062
6.36M
            return COMP_ENQUEUE;
10063
0
        case PDF14_PUSH_TRANS_STATE:
10064
0
            return COMP_ENQUEUE;
10065
4.25M
        case PDF14_POP_TRANS_STATE:
10066
4.25M
            return COMP_ENQUEUE;
10067
0
        case PDF14_PUSH_SMASK_COLOR:
10068
0
            return COMP_ENQUEUE;
10069
0
            break;
10070
0
        case PDF14_POP_SMASK_COLOR:
10071
0
            return COMP_ENQUEUE;
10072
0
            break;
10073
699k
        case PDF14_END_TRANS_MASK:
10074
699k
            if (*ppcte == NULL)
10075
422k
                return COMP_EXEC_QUEUE;
10076
277k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10077
39.3M
        case PDF14_SET_BLEND_PARAMS:
10078
39.3M
            if (*ppcte == NULL)
10079
2.74M
                return COMP_ENQUEUE;
10080
            /* hack : ignore csel - here it is always zero : */
10081
36.6M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10082
60.7M
    }
10083
60.7M
}
10084
10085
/*
10086
 * Check whether a next operation is friendly to the compositor.
10087
 */
10088
static bool
10089
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10090
6.36M
{
10091
6.36M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10092
6.36M
    int op0 = pct0->params.pdf14_op;
10093
10094
6.36M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10095
6.36M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10096
        /* Halftone commands are always passed to the target printer device,
10097
           because transparency buffers are always contone.
10098
           So we're safe to execute them before queued transparency compositors. */
10099
1.59M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10100
680k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10101
680k
            return true;
10102
909k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10103
892k
            return true;
10104
909k
    }
10105
4.79M
    return false;
10106
6.36M
}
10107
10108
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10109
static composite_equal_proc(c_pdf14trans_equal);
10110
static composite_write_proc(c_pdf14trans_write);
10111
static composite_read_proc(c_pdf14trans_read);
10112
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10113
static composite_is_closing_proc(c_pdf14trans_is_closing);
10114
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10115
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10116
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10117
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10118
10119
/*
10120
 * Methods for the PDF 1.4 transparency compositor
10121
 *
10122
 * Note:  We have two set of methods.  They are the same except for the
10123
 * composite_clist_write_update method.  Once the clist write device is created,
10124
 * we use the second set of procedures.  This prevents the creation of multiple
10125
 * PDF 1.4 clist write compositor devices being chained together.
10126
 */
10127
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10128
    GX_COMPOSITOR_PDF14_TRANS,
10129
    {
10130
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10131
        c_pdf14trans_equal,                      /* procs.equal */
10132
        c_pdf14trans_write,                      /* procs.write */
10133
        c_pdf14trans_read,                       /* procs.read */
10134
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10135
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10136
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10137
                /* Create a PDF 1.4 clist write device */
10138
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10139
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10140
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10141
    }                                            /* procs */
10142
};
10143
10144
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10145
    GX_COMPOSITOR_PDF14_TRANS,
10146
    {
10147
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10148
        c_pdf14trans_equal,                      /* procs.equal */
10149
        c_pdf14trans_write,                      /* procs.write */
10150
        c_pdf14trans_read,                       /* procs.read */
10151
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10152
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10153
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10154
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10155
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10156
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10157
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10158
    }                                            /* procs */
10159
};
10160
10161
/*
10162
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10163
 */
10164
int
10165
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10166
442M
{
10167
442M
    return (pct->type == &gs_composite_pdf14trans_type
10168
442M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10169
442M
}
10170
10171
/*
10172
 * Create a PDF 1.4 transparency compositor data structure.
10173
 */
10174
static int
10175
gs_create_pdf14trans(
10176
    gs_composite_t **               ppct,
10177
    const gs_pdf14trans_params_t *  pparams,
10178
    gs_memory_t *                   mem )
10179
72.8M
{
10180
72.8M
    gs_pdf14trans_t *                pct;
10181
10182
72.8M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10183
72.8M
                             "gs_create_pdf14trans");
10184
72.8M
    if (pct == NULL)
10185
0
        return_error(gs_error_VMerror);
10186
72.8M
    pct->type = &gs_composite_pdf14trans_type;
10187
72.8M
    pct->id = gs_next_ids(mem, 1);
10188
72.8M
    pct->params = *pparams;
10189
72.8M
    pct->idle = false;
10190
72.8M
    *ppct = (gs_composite_t *)pct;
10191
72.8M
    return 0;
10192
72.8M
}
10193
10194
/*
10195
 * Send a PDF 1.4 transparency compositor action to the specified device.
10196
 */
10197
int
10198
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10199
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10200
2.33M
{
10201
2.33M
    gs_composite_t * pct = NULL;
10202
2.33M
    int code;
10203
10204
2.33M
    pparams->ctm = ctm_only(pgs);
10205
2.33M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10206
2.33M
    if (code < 0)
10207
0
        return code;
10208
2.33M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10209
2.33M
    if (code == gs_error_handled)
10210
0
        code = 0;
10211
10212
2.33M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10213
10214
2.33M
    return code;
10215
2.33M
}
10216
10217
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10218
10219
/*
10220
 * The PDF 1.4 transparency compositor device may have a different process
10221
 * color model than the output device.  If we are banding then we need to
10222
 * create two compositor devices.  The output side (clist reader) needs a
10223
 * compositor to actually composite the output.  We also need a compositor
10224
 * device before the clist writer.  This is needed to provide a process color
10225
 * model which matches the PDF 1.4 blending space.
10226
 *
10227
 * This section provides support for this device.
10228
 */
10229
10230
/*
10231
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10232
 * We actually use the same structure for both the clist writer and reader
10233
 * devices.  However we use separate names to identify the routines for each
10234
 * device.
10235
 */
10236
10237
static  dev_proc_composite(pdf14_clist_composite);
10238
static  dev_proc_composite(pdf14_clist_forward_composite);
10239
static  dev_proc_fill_path(pdf14_clist_fill_path);
10240
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10241
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10242
static  dev_proc_text_begin(pdf14_clist_text_begin);
10243
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10244
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10245
10246
static void
10247
pdf14_clist_init_procs(gx_device *dev,
10248
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10249
                       dev_proc_get_color_comp_index(get_color_comp_index))
10250
13.1k
{
10251
13.1k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10252
13.1k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10253
13.1k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10254
13.1k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10255
13.1k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10256
13.1k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10257
13.1k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10258
13.1k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10259
13.1k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10260
13.1k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10261
13.1k
    set_dev_proc(dev, put_params, pdf14_put_params);
10262
13.1k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10263
13.1k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10264
13.1k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10265
13.1k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10266
13.1k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10267
13.1k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10268
13.1k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10269
13.1k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10270
13.1k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10271
13.1k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10272
13.1k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10273
13.1k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10274
13.1k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10275
13.1k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10276
13.1k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10277
13.1k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10278
13.1k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10279
13.1k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10280
13.1k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10281
13.1k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10282
13.1k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10283
13.1k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10284
13.1k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10285
13.1k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10286
13.1k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10287
13.1k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10288
13.1k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10289
13.1k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10290
13.1k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10291
13.1k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10292
13.1k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10293
13.1k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10294
13.1k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10295
13.1k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10296
13.1k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10297
13.1k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10298
13.1k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10299
13.1k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10300
13.1k
}
10301
10302
static void
10303
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10304
3.51k
{
10305
3.51k
    pdf14_clist_init_procs(dev,
10306
3.51k
                           gx_default_DevGray_get_color_mapping_procs,
10307
3.51k
                           gx_default_DevGray_get_color_comp_index);
10308
3.51k
}
10309
10310
static void
10311
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10312
8.34k
{
10313
8.34k
    pdf14_clist_init_procs(dev,
10314
8.34k
                           gx_default_DevRGB_get_color_mapping_procs,
10315
8.34k
                           gx_default_DevRGB_get_color_comp_index);
10316
8.34k
}
10317
10318
static void
10319
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10320
12
{
10321
12
    pdf14_clist_init_procs(dev,
10322
12
                           gx_default_DevCMYK_get_color_mapping_procs,
10323
12
                           gx_default_DevCMYK_get_color_comp_index);
10324
12
}
10325
10326
static void
10327
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10328
1.26k
{
10329
1.26k
    pdf14_clist_init_procs(dev,
10330
1.26k
                           pdf14_cmykspot_get_color_mapping_procs,
10331
1.26k
                           pdf14_cmykspot_get_color_comp_index);
10332
1.26k
}
10333
10334
static void
10335
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10336
0
{
10337
0
    pdf14_clist_init_procs(dev,
10338
0
                           pdf14_rgbspot_get_color_mapping_procs,
10339
0
                           pdf14_rgbspot_get_color_comp_index);
10340
0
}
10341
10342
#if 0 /* NOT USED */
10343
static int
10344
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10345
{
10346
    pdf14_clist_init_procs(dev,
10347
                           pdf14_grayspot_get_color_mapping_procs,
10348
                           pdf14_grayspot_get_color_comp_index);
10349
}
10350
#endif  /* NOT USED */
10351
10352
const pdf14_clist_device pdf14_clist_Gray_device = {
10353
    std_device_color_stype_body(pdf14_clist_device,
10354
                                pdf14_clist_Gray_initialize_device_procs,
10355
                                "pdf14clistgray",
10356
                                &st_pdf14_device,
10357
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10358
    { 0 },      /* Procs */
10359
    NULL,     /* target */
10360
    { 0 },      /* devn_params - not used */
10361
    &gray_pdf14_procs,
10362
    &gray_blending_procs
10363
};
10364
10365
const pdf14_clist_device pdf14_clist_RGB_device = {
10366
    std_device_color_stype_body(pdf14_clist_device,
10367
                                pdf14_clist_RGB_initialize_device_procs,
10368
                                "pdf14clistRGB",
10369
                                &st_pdf14_device,
10370
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10371
    { 0 },      /* Procs */
10372
    NULL,     /* target */
10373
    { 0 },      /* devn_params - not used */
10374
    &rgb_pdf14_procs,
10375
    &rgb_blending_procs
10376
};
10377
10378
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10379
    std_device_part1_(pdf14_device,
10380
                      pdf14_clist_RGBspot_initialize_device_procs,
10381
                      "pdf14clistrgbspot",
10382
                      &st_pdf14_device,
10383
                      open_init_closed),
10384
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10385
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10386
    offset_margin_values(0, 0, 0, 0, 0, 0),
10387
    std_device_part3_(),
10388
    { 0 },      /* Procs */
10389
    NULL,     /* target */
10390
    /* DeviceN parameters */
10391
    { 8,      /* Not used - Bits per color */
10392
      DeviceRGBComponents,  /* Names of color model colorants */
10393
      3,      /* Number colorants for CMYK */
10394
      0,      /* MaxSeparations has not been specified */
10395
      -1,     /* PageSpotColors has not been specified */
10396
      {0},      /* SeparationNames */
10397
      0,      /* SeparationOrder names */
10398
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10399
    },
10400
    &rgbspot_pdf14_procs,
10401
    &rgb_blending_procs
10402
};
10403
10404
const pdf14_clist_device pdf14_clist_CMYK_device = {
10405
    std_device_std_color_full_body_type(pdf14_clist_device,
10406
                                        pdf14_clist_CMYK_initialize_device_procs,
10407
                                        "pdf14clistcmyk",
10408
                                        &st_pdf14_device,
10409
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10410
                                        0, 0, 0, 0, 0, 0),
10411
    { 0 },      /* Procs */
10412
    NULL,     /* target */
10413
    { 0 },      /* devn_params - not used */
10414
    &cmyk_pdf14_procs,
10415
    &cmyk_blending_procs
10416
};
10417
10418
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10419
    std_device_part1_(pdf14_device,
10420
                      pdf14_clist_CMYKspot_initialize_device_procs,
10421
                      "pdf14clistcmykspot",
10422
                      &st_pdf14_device,
10423
                      open_init_closed),
10424
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10425
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10426
    offset_margin_values(0, 0, 0, 0, 0, 0),
10427
    std_device_part3_(),
10428
    { 0 },      /* Procs */
10429
    NULL,     /* target */
10430
    /* DeviceN parameters */
10431
    { 8,      /* Not used - Bits per color */
10432
      DeviceCMYKComponents, /* Names of color model colorants */
10433
      4,      /* Number colorants for CMYK */
10434
      0,      /* MaxSeparations has not been specified */
10435
      -1,     /* PageSpotColors has not been specified */
10436
      {0},      /* SeparationNames */
10437
      0,      /* SeparationOrder names */
10438
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10439
    },
10440
    &cmykspot_pdf14_procs,
10441
    &cmyk_blending_procs
10442
};
10443
10444
const pdf14_clist_device pdf14_clist_custom_device = {
10445
    std_device_part1_(pdf14_device,
10446
                      pdf14_clist_CMYKspot_initialize_device_procs,
10447
                      "pdf14clistcustom",
10448
                      &st_pdf14_device,
10449
                      open_init_closed),
10450
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10451
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10452
    offset_margin_values(0, 0, 0, 0, 0, 0),
10453
    std_device_part3_(),
10454
    { 0 },      /* Procs */
10455
    NULL,     /* target */
10456
    /* DeviceN parameters */
10457
    { 8,      /* Not used - Bits per color */
10458
      DeviceCMYKComponents, /* Names of color model colorants */
10459
      4,      /* Number colorants for CMYK */
10460
      0,      /* MaxSeparations has not been specified */
10461
      -1,     /* PageSpotColors has not been specified */
10462
      {0},      /* SeparationNames */
10463
      0,      /* SeparationOrder names */
10464
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10465
    },
10466
    &custom_pdf14_procs,
10467
    &custom_blending_procs
10468
};
10469
10470
/*
10471
 * the PDF 1.4 transparency spec says that color space for blending
10472
 * operations can be based upon either a color space specified in the
10473
 * group or a default value based upon the output device.  We are
10474
 * currently only using a color space based upon the device.
10475
 */
10476
static  int
10477
get_pdf14_clist_device_proto(gx_device          *dev,
10478
                             pdf14_clist_device *pdevproto,
10479
                             gs_gstate          *pgs,
10480
                       const gs_pdf14trans_t    *pdf14pct,
10481
                             bool                use_pdf14_accum)
10482
13.1k
{
10483
13.1k
    pdf14_blend_cs_t blend_cs_state;
10484
13.1k
    pdf14_default_colorspace_t dev_cs =
10485
13.1k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10486
13.1k
                                                 &blend_cs_state);
10487
13.1k
    bool deep = device_is_deep(dev);
10488
13.1k
    int num_spots = pdf14pct->params.num_spot_colors;
10489
10490
    /* overprint overide */
10491
13.1k
    if (pdf14pct->params.overprint_sim_push &&
10492
13.1k
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10493
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10494
0
            dev_cs = PDF14_DeviceCMYKspot;
10495
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10496
0
        } else
10497
0
            dev_cs = PDF14_DeviceCMYK;
10498
0
    }
10499
10500
13.1k
    switch (dev_cs) {
10501
3.51k
        case PDF14_DeviceGray:
10502
           /* We want gray to be single channel.  Low level
10503
               initialization of gray device prototype is
10504
               peculiar in that in dci_std_color_num_components
10505
               the comment is
10506
              "A device is monochrome only if it is bi-level"
10507
              Here we want monochrome anytime we have a gray device.
10508
              To avoid breaking things elsewhere, we will overide
10509
              the prototype intialization here */
10510
3.51k
            *pdevproto = pdf14_clist_Gray_device;
10511
3.51k
            pdevproto->color_info.max_components = 1;
10512
3.51k
            pdevproto->color_info.num_components =
10513
3.51k
                                    pdevproto->color_info.max_components;
10514
3.51k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10515
3.51k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10516
3.51k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10517
3.51k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10518
3.51k
            pdevproto->color_info.depth = deep ? 16 : 8;
10519
3.51k
            pdevproto->sep_device = false;
10520
3.51k
            break;
10521
8.34k
        case PDF14_DeviceRGB:
10522
8.34k
            *pdevproto = pdf14_clist_RGB_device;
10523
8.34k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10524
8.34k
            pdevproto->sep_device = false;
10525
8.34k
            if (deep) {
10526
0
                pdevproto->color_info.depth = 3*16;
10527
0
                pdevproto->color_info.max_color = 65535;
10528
0
                pdevproto->color_info.max_gray = 65535;
10529
0
                pdevproto->color_info.dither_colors = 65536;
10530
0
                pdevproto->color_info.dither_grays = 65536;
10531
0
            }
10532
8.34k
            break;
10533
12
        case PDF14_DeviceCMYK:
10534
12
            *pdevproto = pdf14_clist_CMYK_device;
10535
12
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10536
12
            pdevproto->sep_device = false;
10537
12
            if (deep) {
10538
0
                pdevproto->color_info.depth = 4*16;
10539
0
                pdevproto->color_info.max_color = 65535;
10540
0
                pdevproto->color_info.max_gray = 65535;
10541
0
                pdevproto->color_info.dither_colors = 65536;
10542
0
                pdevproto->color_info.dither_grays = 65536;
10543
0
            }
10544
12
            break;
10545
1.26k
        case PDF14_DeviceCMYKspot:
10546
1.26k
            *pdevproto = pdf14_clist_CMYKspot_device;
10547
            /*
10548
             * The number of components for the PDF14 device is the sum
10549
             * of the process components and the number of spot colors
10550
             * for the page. If we are using an NCLR ICC profile at
10551
             * the output device, those spot colors are skipped. They
10552
             * do not appear in the transparency buffer, but appear
10553
             * during put image transform of the page group to the target
10554
             * color space.
10555
             */
10556
1.26k
            if (num_spots >= 0) {
10557
1.26k
                pdevproto->devn_params.page_spot_colors = num_spots;
10558
1.26k
                pdevproto->color_info.num_components =
10559
1.26k
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10560
1.26k
                if (pdevproto->color_info.num_components >
10561
1.26k
                              pdevproto->color_info.max_components)
10562
0
                    pdevproto->color_info.num_components =
10563
0
                              pdevproto->color_info.max_components;
10564
1.26k
                pdevproto->color_info.depth =
10565
1.26k
                              pdevproto->color_info.num_components * (8<<deep);
10566
1.26k
            }
10567
1.26k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10568
1.26k
            pdevproto->sep_device = true;
10569
1.26k
            break;
10570
0
        case PDF14_DeviceRGBspot:
10571
0
            *pdevproto = pdf14_clist_RGBspot_device;
10572
            /*
10573
             * The number of components for the PDF14 device is the sum
10574
             * of the process components and the number of spot colors
10575
             * for the page. If we are using an NCLR ICC profile at
10576
             * the output device, those spot colors are skipped. They
10577
             * do not appear in the transparency buffer, but appear
10578
             * during put image transform of the page group to the target
10579
             * color space.
10580
             */
10581
0
            if (num_spots >= 0) {
10582
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10583
0
                pdevproto->color_info.num_components =
10584
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10585
0
                if (pdevproto->color_info.num_components >
10586
0
                    pdevproto->color_info.max_components)
10587
0
                    pdevproto->color_info.num_components =
10588
0
                        pdevproto->color_info.max_components;
10589
0
                pdevproto->color_info.depth =
10590
0
                    pdevproto->color_info.num_components * (8 << deep);
10591
0
            }
10592
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10593
0
            pdevproto->sep_device = true;
10594
0
            break;
10595
0
        case PDF14_DeviceCustom:
10596
            /*
10597
             * We are using the output device's process color model.  The
10598
             * color_info for the PDF 1.4 compositing device needs to match
10599
             * the output device.
10600
             */
10601
0
            *pdevproto = pdf14_clist_custom_device;
10602
0
            pdevproto->color_info = dev->color_info;
10603
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10604
0
            pdevproto->color_info.depth =
10605
0
                pdevproto->color_info.num_components * (8<<deep);
10606
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10607
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10608
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10609
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10610
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10611
0
            break;
10612
0
        default:      /* Should not occur */
10613
0
            return_error(gs_error_rangecheck);
10614
13.1k
    }
10615
13.1k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10616
13.1k
    pdevproto->blend_cs_state = blend_cs_state;
10617
13.1k
    return 0;
10618
13.1k
}
10619
10620
static  int
10621
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10622
                                gx_device ** ppdev, gx_device * target,
10623
                                const gs_pdf14trans_t * pdf14pct)
10624
13.1k
{
10625
13.1k
    pdf14_clist_device dev_proto;
10626
13.1k
    pdf14_clist_device * pdev;
10627
13.1k
    int code;
10628
13.1k
    bool has_tags = device_encodes_tags(target);
10629
13.1k
    cmm_profile_t *target_profile;
10630
13.1k
    gsicc_rendering_param_t render_cond;
10631
13.1k
    cmm_dev_profile_t *dev_profile;
10632
13.1k
    uchar k;
10633
13.1k
    bool deep = device_is_deep(target);
10634
13.1k
    cmm_profile_t *icc_profile;
10635
10636
10637
13.1k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10638
13.1k
    if (code < 0)
10639
0
        return code;
10640
13.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10641
13.1k
                          &render_cond);
10642
13.1k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10643
    /* Prototypes never include tags. We add those in later. */
10644
13.1k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10645
13.1k
                                        pgs, pdf14pct, false);
10646
13.1k
    if (code < 0)
10647
0
        return code;
10648
13.1k
    code = gs_copydevice((gx_device **) &pdev,
10649
13.1k
                         (const gx_device *) &dev_proto, mem);
10650
13.1k
    if (code < 0)
10651
0
        return code;
10652
10653
    /* If we are not using a blending color space, the number of color planes
10654
       should not exceed that of the target */
10655
13.1k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10656
13.1k
        if (pdev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10657
0
            pdev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10658
13.1k
        if (pdev->color_info.max_components > target->color_info.max_components)
10659
1.30k
            pdev->color_info.max_components = target->color_info.max_components;
10660
13.1k
    }
10661
13.1k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10662
13.1k
    pdev->pad = target->pad;
10663
13.1k
    pdev->log2_align_mod = target->log2_align_mod;
10664
10665
13.1k
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10666
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10667
13.1k
    else
10668
13.1k
        pdev->num_planar_planes = target->num_planar_planes;
10669
13.1k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10670
10671
13.1k
    pdev->op_state = pgs->is_fill_color ? PDF14_OP_STATE_FILL : PDF14_OP_STATE_NONE;
10672
10673
13.1k
    if (deep) {
10674
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10675
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10676
0
    }
10677
    /* If we have a tag device then go ahead and do a special encoder decoder
10678
       for the pdf14 device to make sure we maintain this information in the
10679
       encoded color information.  We could use the target device's methods but
10680
       the PDF14 device has to maintain 8 bit color always and we could run
10681
       into other issues if the number of colorants became large.  If we need to
10682
       do compressed color with tags that will be a special project at that time */
10683
13.1k
    if (has_tags) {
10684
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10685
0
    }
10686
13.1k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10687
13.1k
    gx_device_fill_in_procs((gx_device *)pdev);
10688
    /* Copying the params adds the tags to the color_info if required. */
10689
13.1k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10690
13.1k
    gx_device_set_target((gx_device_forward *)pdev, target);
10691
10692
    /* Components shift, etc have to be based upon 8 bit */
10693
46.8k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10694
33.6k
        pdev->color_info.comp_bits[k] = 8<<deep;
10695
33.6k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10696
33.6k
    }
10697
13.1k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10698
13.1k
    if (code < 0)
10699
0
        return code;
10700
13.1k
    pdev->pclist_device = target;
10701
10702
13.1k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10703
13.1k
    if (code < 0)
10704
0
        return code;
10705
13.1k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10706
13.1k
        &render_cond);
10707
13.1k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10708
10709
    /* Simulated overprint case.  We have to use CMYK-based profile
10710
       Also if the target profile is NCLR, we are going to use a pdf14
10711
       device that is CMYK based and do the mapping to the NCLR profile
10712
       when the put_image occurs */
10713
13.1k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10714
13.1k
         icc_profile->data_cs == gsNCHANNEL) {
10715
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10716
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10717
0
            -1, "pdf14_create_clist_device");
10718
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10719
13.1k
    } else {
10720
        /* If the target profile was CIELAB, then overide with default RGB for
10721
           proper blending.  During put_image we will convert from RGB to
10722
           CIELAB */
10723
13.1k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10724
13.1k
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10725
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10726
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10727
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10728
0
        }
10729
13.1k
    }
10730
10731
13.1k
    if (pdf14pct->params.overprint_sim_push &&
10732
13.1k
        pdf14pct->params.num_spot_colors_int > 0) {
10733
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10734
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10735
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10736
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10737
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10738
0
    }
10739
    /* if the device has separations already defined (by SeparationOrderNames) */
10740
    /* we need to copy them (allocating new names) so the colorants are in the */
10741
    /* same order as the target device.                                        */
10742
13.1k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0)) {
10743
1.36k
        code = devn_copy_params(target, (gx_device *)pdev);
10744
1.36k
        if (code < 0)
10745
0
            return code;
10746
1.36k
    }
10747
13.1k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10748
13.1k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10749
13.1k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10750
13.1k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10751
13.1k
    pdev->color_info.separable_and_linear =
10752
13.1k
        target->color_info.separable_and_linear;
10753
13.1k
    *ppdev = (gx_device *) pdev;
10754
13.1k
    return code;
10755
13.1k
}
10756
10757
/*
10758
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10759
 * compositor device is never removed.  (We do not have a remove compositor
10760
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10761
 * routine implements that action.
10762
 */
10763
static  int
10764
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10765
                                gx_device * dev)
10766
12.6k
{
10767
12.6k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10768
12.6k
    gx_device * target = pdev->target;
10769
10770
12.6k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10771
10772
    /*
10773
     * To disable the action of this device, we forward all device
10774
     * procedures to the target except the composite and copy
10775
     * the target's color_info.
10776
     */
10777
12.6k
    dev->color_info = target->color_info;
10778
12.6k
    pdf14_forward_device_procs(dev);
10779
12.6k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10780
12.6k
    return 0;
10781
12.6k
}
10782
10783
/*
10784
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10785
 * compositor device is never removed.  (We do not have a remove compositor
10786
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10787
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10788
 * again.
10789
 */
10790
static  int
10791
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10792
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10793
0
{
10794
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10795
0
    gx_device * target = pdev->target;
10796
0
    pdf14_clist_device dev_proto;
10797
0
    int code;
10798
10799
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10800
    /*
10801
     * We will not use the entire prototype device but we will set the
10802
     * color related info to match the prototype.
10803
     */
10804
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10805
0
                                        pgs, pdf14pct, false);
10806
0
    if (code < 0)
10807
0
        return code;
10808
0
    pdev->color_info = dev_proto.color_info;
10809
0
    pdev->procs = dev_proto.procs;
10810
0
    pdev->pad = target->pad;
10811
0
    pdev->log2_align_mod = target->log2_align_mod;
10812
10813
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10814
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10815
0
    else
10816
0
        pdev->num_planar_planes = target->num_planar_planes;
10817
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10818
10819
0
    copy_tag_setup(dev, target);
10820
10821
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10822
0
    gx_device_fill_in_procs((gx_device *)pdev);
10823
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10824
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10825
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10826
0
    check_device_separable((gx_device *)pdev);
10827
0
    return code;
10828
0
}
10829
10830
/*
10831
 * devicen params
10832
 */
10833
gs_devn_params *
10834
pdf14_ret_devn_params(gx_device *pdev)
10835
1.67M
{
10836
1.67M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10837
10838
1.67M
    return &(p14dev->devn_params);
10839
1.67M
}
10840
10841
/*
10842
 * devicen params
10843
 */
10844
gs_devn_params *
10845
pdf14_accum_ret_devn_params(gx_device *pdev)
10846
0
{
10847
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10848
10849
0
    return &(p14dev->devn_params);
10850
0
}
10851
10852
static int
10853
pdf14_accum_get_color_comp_index(gx_device * dev,
10854
    const char * pname, int name_size, int component_type)
10855
0
{
10856
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10857
0
    gx_device *target = p14dev->target;
10858
0
    int colorant_number = devn_get_color_comp_index(dev,
10859
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10860
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10861
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10862
10863
0
    if (target != NULL)
10864
        /* colorant_number returned here _should_ be the same as from above */
10865
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10866
0
                              (target, (const char *)pname, name_size, component_type);
10867
0
    return colorant_number;
10868
0
}
10869
10870
/*
10871
 * The following procedures are used to map the standard color spaces into
10872
 * the separation color components for the pdf14_accum device.
10873
 */
10874
static void
10875
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10876
0
{
10877
0
    int * map =
10878
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10879
10880
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10881
0
}
10882
10883
static void
10884
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10885
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10886
0
{
10887
0
    int * map =
10888
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10889
10890
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10891
0
}
10892
10893
static void
10894
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10895
    frac c, frac m, frac y, frac k, frac out[])
10896
0
{
10897
0
    const int * map =
10898
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10899
10900
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10901
0
}
10902
10903
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10904
    pdf14_accum_gray_cs_to_cmyk_cm,
10905
    pdf14_accum_rgb_cs_to_cmyk_cm,
10906
    pdf14_accum_cmyk_cs_to_cmyk_cm
10907
};
10908
10909
static const gx_cm_color_map_procs *
10910
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10911
0
{
10912
0
    *map_dev = dev;
10913
0
    return &pdf14_accum_cm_procs;
10914
0
}
10915
10916
/*
10917
 *  Device proc for updating the equivalent CMYK color for spot colors.
10918
 */
10919
static int
10920
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10921
0
{
10922
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10923
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10924
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10925
0
                                              &pdev->equiv_cmyk_colors);
10926
10927
0
    if (code >= 0 && tdev != NULL)
10928
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10929
0
    return code;
10930
0
}
10931
10932
/* Used when doing overprint simulation and have spot colors */
10933
static int
10934
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10935
0
{
10936
0
    pdf14_device *pdev = (pdf14_device *)dev;
10937
0
    int code;
10938
10939
    /* Make sure we are not All or None */
10940
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10941
0
        pcs->params.separation.sep_type != SEP_OTHER)
10942
0
            return 0;
10943
10944
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10945
0
        &pdev->op_pequiv_cmyk_colors);
10946
0
    return code;
10947
0
}
10948
10949
/*
10950
 * Retrieve a list of spot color names for the PDF14 device.
10951
 */
10952
int
10953
put_param_pdf14_spot_names(gx_device * pdev,
10954
                gs_separations * pseparations, gs_param_list * plist)
10955
55.1k
{
10956
55.1k
    int code, num_spot_colors, i;
10957
55.1k
    gs_param_string str;
10958
10959
    /* Check if the given keyname is present. */
10960
55.1k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10961
55.1k
                                                &num_spot_colors);
10962
55.1k
    switch (code) {
10963
0
        default:
10964
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10965
0
            break;
10966
55.1k
        case 1:
10967
55.1k
            return 0;
10968
0
        case 0:
10969
0
            if (num_spot_colors < 1 ||
10970
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
10971
0
                return_error(gs_error_rangecheck);
10972
0
            for (i = 0; i < num_spot_colors; i++) {
10973
0
                char buff[20];
10974
0
                byte * sep_name;
10975
10976
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
10977
0
                code = param_read_string(plist, buff, &str);
10978
0
                switch (code) {
10979
0
                    default:
10980
0
                        param_signal_error(plist, buff, code);
10981
0
                        break;
10982
0
                    case 0:
10983
0
                        sep_name = gs_alloc_bytes(pdev->memory,
10984
0
                                str.size, "put_param_pdf14_spot_names");
10985
0
                        if (sep_name == NULL)
10986
0
                            return_error(gs_error_VMerror);
10987
10988
0
                        memcpy(sep_name, str.data, str.size);
10989
0
                        pseparations->names[i].size = str.size;
10990
0
                        pseparations->names[i].data = sep_name;
10991
0
                }
10992
0
            }
10993
0
            pseparations->num_separations = num_spot_colors;
10994
0
            break;
10995
55.1k
    }
10996
0
    return 0;;
10997
0
}
10998
10999
/*
11000
 * This procedure will have information from the PDF 1.4 clist writing
11001
 * clist compositior device.  This is information output the compressed
11002
 * color list info which is needed for the support of spot colors in
11003
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11004
 * clist reading compositor.  However this device is not created until
11005
 * the clist is read.  To get this info to that device, we have to
11006
 * temporarily store that info in the output device.  This routine saves
11007
 * that info in the output device.
11008
 */
11009
int
11010
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11011
                                        gs_param_list * plist)
11012
55.1k
{
11013
55.1k
    int code;
11014
55.1k
    code = put_param_pdf14_spot_names(pdev,
11015
55.1k
                       &pdevn_params->pdf14_separations, plist);
11016
55.1k
    return code;
11017
55.1k
}
11018
11019
/*
11020
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11021
 * when we are creating the clist.  The second is for imaging the data from
11022
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11023
 * This routine is only called once the PDF 1.4 clist write compositor already
11024
 * exists.
11025
 */
11026
static  int
11027
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11028
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11029
    gx_device *cdev)
11030
2.81M
{
11031
2.81M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11032
2.81M
    int code, is_pdf14_compositor;
11033
2.81M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11034
2.81M
    bool deep = device_is_deep(dev);
11035
11036
    /* We only handle a few PDF 1.4 transparency operations */
11037
2.81M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11038
1.95M
        switch (pdf14pct->params.pdf14_op) {
11039
0
            case PDF14_PUSH_DEVICE:
11040
                /* Re-activate the PDF 1.4 compositor */
11041
0
                pdev->saved_target_color_info = pdev->target->color_info;
11042
0
                pdev->target->color_info = pdev->color_info;
11043
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11044
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11045
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11046
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11047
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11048
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11049
0
                pdev->saved_target_get_color_mapping_procs =
11050
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11051
0
                pdev->saved_target_get_color_comp_index =
11052
0
                                        dev_proc(pdev->target, get_color_comp_index);
11053
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11054
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11055
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11056
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11057
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11058
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11059
0
                gx_set_cmap_procs(pgs, dev);
11060
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11061
0
                pdev->blend_mode = pdev->text_knockout = 0;
11062
0
                pdev->opacity = pdev->shape = 0.0;
11063
0
                if (code < 0)
11064
0
                    return code;
11065
                /*
11066
                 * This routine is part of the PDF 1.4 clist write device.
11067
                 * Change the compositor procs to not create another since we
11068
                 * do not need to create a chain of identical devices.
11069
                 */
11070
0
                {
11071
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11072
11073
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11074
0
                    code = dev_proc(pdev->target, composite)
11075
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11076
                    /* We should never have created a new device here. */
11077
0
                    assert(code != 1);
11078
0
                    return code;
11079
0
                }
11080
12.6k
            case PDF14_POP_DEVICE:
11081
12.6k
            {
11082
12.6k
                gx_device *clistdev = pdev->target;
11083
11084
                /* Find the clist device */
11085
12.6k
                while (1) {
11086
12.6k
                    gxdso_device_child_request req;
11087
                    /* Ignore any errors here, that's expected as non-clist
11088
                     * devices don't implement it. */
11089
12.6k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11090
12.6k
                    if (code == 1)
11091
12.6k
                        break;
11092
0
                    req.n = 0;
11093
0
                    req.target = clistdev;
11094
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11095
0
                    if (code < 0)
11096
0
                        return code;
11097
0
                    clistdev = req.target;
11098
0
                }
11099
11100
                /* If we have overprint simulation spot color information, store
11101
                   it in a pseudo-band of the clist */
11102
12.6k
                if (pdev->overprint_sim &&
11103
12.6k
                    pdev->devn_params.page_spot_colors > 0) {
11104
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11105
0
                        &pdev->op_pequiv_cmyk_colors);
11106
0
                    if (code < 0)
11107
0
                        return code;
11108
0
                }
11109
11110
                /* If we hit an error during an SMask, we need to undo the color
11111
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11112
                 * for itself if it needs to take action.
11113
                 */
11114
12.6k
                pdf14_decrement_smask_color(pgs, dev);
11115
                /* Restore the color_info for the clist device */
11116
12.6k
                clistdev->color_info = pdev->saved_target_color_info;
11117
12.6k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11118
12.6k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11119
12.6k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11120
12.6k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11121
12.6k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11122
12.6k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11123
12.6k
                gx_set_cmap_procs(pgs, clistdev);
11124
12.6k
                gx_device_decache_colors(clistdev);
11125
                /* Disable the PDF 1.4 compositor */
11126
12.6k
                pdf14_disable_clist_device(mem, pgs, dev);
11127
                /*
11128
                 * Make sure that the transfer funtions, etc. are current.
11129
                 */
11130
12.6k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11131
12.6k
                if (code < 0)
11132
0
                    return code;
11133
12.6k
                break;
11134
12.6k
            }
11135
12.6k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11136
59.7k
            case PDF14_BEGIN_TRANS_GROUP:
11137
59.7k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11138
28.2k
                    pdev->depth_within_smask++;
11139
59.7k
                pdev->smask_constructed = 0;
11140
                /*
11141
                 * Keep track of any changes made in the blending parameters.
11142
                   These need to be written out in the same bands as the group
11143
                   information is written.  Hence the passing of the dimensions
11144
                   for the group. */
11145
59.7k
                code = pdf14_clist_update_params(pdev, pgs, true,
11146
59.7k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11147
59.7k
                if (code < 0)
11148
0
                    return code;
11149
59.7k
                if (pdf14pct->params.Background_components != 0 &&
11150
59.7k
                    pdf14pct->params.Background_components !=
11151
0
                    pdev->color_info.num_components)
11152
0
                    return_error(gs_error_rangecheck);
11153
11154
                /* We need to update the clist writer device procs based upon the
11155
                   the group color space. This ensures the proper color data is
11156
                   written out to the device. For simplicity, the list item is
11157
                   created even if the color space did not change */
11158
59.7k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11159
59.7k
                if (code < 0)
11160
0
                    return code;
11161
11162
59.7k
                break;
11163
62.5k
            case PDF14_BEGIN_TRANS_MASK:
11164
                /* We need to update the clist writer device procs based upon the
11165
                   the group color space.  For simplicity, the list item is created
11166
                   even if the color space did not change */
11167
                /* First store the current ones */
11168
62.5k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11169
33.9k
                    break;
11170
11171
                /* Update the color settings of the clist writer.  Store information in stack */
11172
28.5k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11173
28.5k
                if (code < 0)
11174
0
                    return code;
11175
11176
                /* Also, if the BC is a value that may end up as something other
11177
                  than transparent. We must use the parent colors bounding box in
11178
                  determining the range of bands in which this mask can affect.
11179
                  So, if needed change the masks bounding box at this time */
11180
28.5k
                pdev->in_smask_construction++;
11181
28.5k
                break;
11182
808k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11183
808k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11184
0
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11185
0
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11186
0
                } else
11187
808k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11188
808k
                *pcdev = dev;
11189
808k
                return 0; /* Never put into clist. Only used during writing */
11190
836k
            case PDF14_END_TRANS_TEXT_GROUP:
11191
836k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11192
834k
                    *pcdev = dev;
11193
834k
                    return 0; /* Avoids spurious ET calls in interpreter */
11194
834k
                }
11195
2.24k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11196
2.24k
                code = pdf14_clist_pop_color_model(dev, pgs);
11197
2.24k
                if (code < 0)
11198
0
                    return code;
11199
2.24k
                break;
11200
28.5k
            case PDF14_END_TRANS_MASK:
11201
28.5k
                pdev->in_smask_construction--;
11202
28.5k
                if (pdev->in_smask_construction < 0)
11203
0
                    pdev->in_smask_construction = 0;
11204
28.5k
                if (pdev->in_smask_construction == 0)
11205
28.4k
                    pdev->smask_constructed = 1;
11206
                /* fallthrough */
11207
85.9k
            case PDF14_END_TRANS_GROUP:
11208
                /* We need to update the clist writer device procs based upon the
11209
                   the group color space. */
11210
85.9k
                code = pdf14_clist_pop_color_model(dev, pgs);
11211
85.9k
                if (pdev->depth_within_smask)
11212
28.2k
                    pdev->depth_within_smask--;
11213
85.9k
                if (code < 0)
11214
0
                    return code;
11215
85.9k
                break;
11216
85.9k
            case PDF14_PUSH_TRANS_STATE:
11217
0
                break;
11218
27.6k
            case PDF14_POP_TRANS_STATE:
11219
27.6k
                break;
11220
28.5k
            case PDF14_PUSH_SMASK_COLOR:
11221
28.5k
                code = pdf14_increment_smask_color(pgs,dev);
11222
28.5k
                *pcdev = dev;
11223
28.5k
                return code;  /* Note, this are NOT put in the clist */
11224
0
                break;
11225
28.5k
            case PDF14_POP_SMASK_COLOR:
11226
28.5k
                code = pdf14_decrement_smask_color(pgs,dev);
11227
28.5k
                *pcdev = dev;
11228
28.5k
                return code;  /* Note, this are NOT put in the clist */
11229
0
                break;
11230
0
            case PDF14_SET_BLEND_PARAMS:
11231
                /* If there is a change we go ahead and apply it to the target */
11232
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11233
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11234
0
                *pcdev = dev;
11235
0
                return code;
11236
0
                break;
11237
0
            case PDF14_ABORT_DEVICE:
11238
0
                code = gx_abort_trans_device(pgs, dev);
11239
0
                if (pdev->free_devicen) {
11240
0
                    devn_free_params(dev);
11241
0
                }
11242
0
                pdf14_disable_device(dev);
11243
0
                pdf14_close(dev);
11244
0
                *pcdev = dev;
11245
0
                return code;
11246
0
                break;
11247
0
            default:
11248
0
                break;   /* Pass remaining ops to target */
11249
1.95M
        }
11250
1.95M
    }
11251
1.11M
    code = dev_proc(pdev->target, composite)
11252
1.11M
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11253
    /* If we were accumulating into a pdf14-clist-accum device, */
11254
    /* we now have to render the page into it's target device */
11255
1.11M
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11256
1.11M
        pdev->target->stype == &st_gx_devn_accum_device) {
11257
11258
5.71k
        int i, y, rows_used;
11259
5.71k
        byte *linebuf;
11260
5.71k
        byte *actual_data;
11261
5.71k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11262
        /* get the target device we want to send the image to */
11263
5.71k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11264
5.71k
        gs_image1_t image;
11265
5.71k
        gs_color_space *pcs;
11266
5.71k
        gx_image_enum_common_t *info = NULL;
11267
5.71k
        gx_image_plane_t planes;
11268
5.71k
        gsicc_rendering_param_t render_cond;
11269
5.71k
        cmm_dev_profile_t *dev_profile;
11270
5.71k
        bool save_planar = pdev->num_planar_planes;
11271
5.71k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11272
5.71k
        int save_num_separations;
11273
5.71k
        gs_int_rect rect;
11274
11275
5.71k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11276
5.71k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11277
5.71k
        pdev->num_planar_planes = save_planar;
11278
11279
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11280
         * colors do require devn support
11281
         */
11282
5.71k
        if (tdev->color_info.num_components <= 4 ||
11283
5.71k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11284
            /*
11285
             * Set color space in preparation for sending an image.
11286
             */
11287
5.71k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11288
5.71k
            if (code < 0)
11289
0
                goto put_accum_error;
11290
11291
            /* Need to set this to avoid color management during the
11292
               image color render operation.  Exception is for the special case
11293
               when the destination was CIELAB.  Then we need to convert from
11294
               default RGB to CIELAB in the put image operation.  That will happen
11295
               here as we should have set the profile for the pdf14 device to RGB
11296
               and the target will be CIELAB */
11297
5.71k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11298
5.71k
            if (code < 0)
11299
0
                goto put_accum_error;
11300
5.71k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11301
5.71k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11302
            /* pcs takes a reference to the profile data it just retrieved. */
11303
5.71k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11304
5.71k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11305
5.71k
        } else {
11306
             /* DeviceN case -- need to handle spot colors */
11307
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11308
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11309
0
            if (code < 0)
11310
0
                goto put_accum_error;
11311
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11312
0
            pcs->params.device_n.use_alt_cspace = false;
11313
11314
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11315
0
                goto put_accum_error;
11316
0
            }
11317
            /* One last thing -- we need to fudge the pgs->color_component_map */
11318
0
            for (i=0; i < tdev->color_info.num_components; i++)
11319
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11320
            /* copy devn_params that were accumulated into the target device's devn_params */
11321
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11322
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11323
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11324
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11325
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11326
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11327
0
            target_devn_params->separations = tdev->devn_params.separations;
11328
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11329
0
                   sizeof(gs_separation_map));
11330
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11331
0
        }
11332
5.71k
        if (linebuf == NULL) {
11333
0
            code = gs_error_VMerror;
11334
0
            goto put_accum_error;
11335
0
        }
11336
5.71k
        gs_image_t_init_adjust(&image, pcs, false);
11337
5.71k
        image.ImageMatrix.xx = (float)pdev->width;
11338
5.71k
        image.ImageMatrix.yy = (float)pdev->height;
11339
5.71k
        image.Width = pdev->width;
11340
5.71k
        image.Height = pdev->height;
11341
5.71k
        image.BitsPerComponent = 8<<deep;
11342
5.71k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11343
5.71k
        ctm_only_writable(pgs).xy = 0;
11344
5.71k
        ctm_only_writable(pgs).yx = 0;
11345
5.71k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11346
5.71k
        ctm_only_writable(pgs).tx = 0.0;
11347
5.71k
        ctm_only_writable(pgs).ty = 0.0;
11348
5.71k
        code = dev_proc(target, begin_typed_image) (target,
11349
5.71k
                                                    pgs, NULL,
11350
5.71k
                                                    (gs_image_common_t *)&image,
11351
5.71k
                                                    NULL, NULL, NULL,
11352
5.71k
                                                    pgs->memory, &info);
11353
5.71k
        if (code < 0)
11354
0
            goto put_accum_error;
11355
5.71k
        rect.p.x = 0;
11356
5.71k
        rect.q.x = tdev->width;
11357
12.5M
        for (y=0; y < tdev->height; y++) {
11358
12.5M
            gs_get_bits_params_t params;
11359
11360
12.5M
            params.options = (GB_ALIGN_ANY |
11361
12.5M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11362
12.5M
                              GB_OFFSET_0 |
11363
12.5M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11364
12.5M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11365
12.5M
            params.x_offset = 0;
11366
12.5M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11367
12.5M
            params.data[0] = linebuf;
11368
12.5M
            rect.p.y = y;
11369
12.5M
            rect.q.y = y+1;
11370
12.5M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11371
12.5M
                                                      &rect, &params);
11372
12.5M
            if (code < 0)
11373
5
                goto put_accum_error;
11374
12.5M
            actual_data = params.data[0];
11375
12.5M
            planes.data = actual_data;
11376
12.5M
            planes.data_x = 0;
11377
12.5M
            planes.raster = tdev->width * tdev->color_info.num_components;
11378
12.5M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11379
0
                goto put_accum_error;
11380
12.5M
        }
11381
11382
5.71k
put_accum_error:
11383
5.71k
        if (info != NULL) {
11384
5.71k
            if (code < 0)
11385
5
                (void)info->procs->end_image(info, true);
11386
5.70k
            else
11387
5.70k
                code = info->procs->end_image(info, true);
11388
5.71k
        }
11389
11390
5.71k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11391
        /* This will also decrement the device profile */
11392
5.71k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11393
5.71k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11394
        /* Now unhook the clist device and hook to the original so we can clean up */
11395
5.71k
        gx_device_set_target((gx_device_forward *)pdev,
11396
5.71k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11397
5.71k
        pdev->pclist_device = pdev->target;
11398
5.71k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11399
5.71k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11400
5.71k
        if (target_devn_params != NULL) {
11401
            /* prevent devn_free_params from freeing names still in use by target device */
11402
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11403
0
            tdev->devn_params.separations.num_separations = 0;
11404
0
        }
11405
5.71k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11406
5.71k
        if (target_devn_params != NULL) {
11407
0
            target_devn_params->separations.num_separations = save_num_separations;
11408
0
        }
11409
5.71k
        return code;    /* DON'T perform set_target */
11410
5.71k
    }
11411
1.10M
    if (code == 1) {
11412
        /* We just wrapped pdev->target, so we need to update that.*/
11413
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11414
0
        code = 0; /* We did not wrap dev. */
11415
0
    }
11416
1.10M
    *pcdev = dev;
11417
1.10M
    return code;
11418
1.11M
}
11419
11420
/*
11421
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11422
 * compositor' method.  However the compositor is disabled when we are not
11423
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11424
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11425
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11426
 * to the targer.
11427
 */
11428
static  int
11429
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11430
        const gs_composite_t * pct, gs_gstate * pgs,
11431
        gs_memory_t * mem, gx_device *cdev)
11432
0
{
11433
0
    pdf14_device *pdev = (pdf14_device *)dev;
11434
0
    gx_device * tdev = pdev->target;
11435
0
    gx_device * ndev;
11436
0
    int code;
11437
11438
0
    *pcdev = dev;
11439
0
    if (gs_is_pdf14trans_compositor(pct)) {
11440
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11441
11442
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11443
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11444
0
        return 0;
11445
0
    }
11446
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11447
0
    if (code == 1) {
11448
        /* We just wrapped tdev, so update our target. */
11449
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11450
0
        code = 0; /* We did not wrap dev. */
11451
0
    }
11452
0
    return code;
11453
0
}
11454
11455
/*
11456
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11457
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11458
 */
11459
static  int
11460
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11461
                          bool crop_blend_params,
11462
                          gs_pdf14trans_params_t *group_params)
11463
6.72M
{
11464
6.72M
    gs_pdf14trans_params_t params = { 0 };
11465
6.72M
    gx_device * pcdev;
11466
6.72M
    int changed = 0;
11467
6.72M
    int code = 0;
11468
6.72M
    gs_composite_t *pct_new = NULL;
11469
11470
6.72M
    params.crop_blend_params = crop_blend_params;
11471
11472
6.72M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11473
6.72M
    if (pgs->blend_mode != pdev->blend_mode) {
11474
23.0k
        changed |= PDF14_SET_BLEND_MODE;
11475
23.0k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11476
23.0k
    }
11477
6.72M
    if (pgs->text_knockout != pdev->text_knockout) {
11478
12.2k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11479
12.2k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11480
12.2k
    }
11481
6.72M
    if (pgs->alphaisshape != pdev->ais) {
11482
3.89k
        changed |= PDF14_SET_AIS;
11483
3.89k
        params.ais = pdev->ais = pgs->alphaisshape;
11484
3.89k
    }
11485
6.72M
    if (pgs->overprint != pdev->overprint) {
11486
23.3k
        changed |= PDF14_SET_OVERPRINT;
11487
23.3k
        params.overprint = pdev->overprint = pgs->overprint;
11488
23.3k
    }
11489
6.72M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11490
23.3k
        changed |= PDF14_SET_STROKEOVERPRINT;
11491
23.3k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11492
23.3k
    }
11493
6.72M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11494
40.9k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11495
40.9k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11496
40.9k
    }
11497
6.72M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11498
34.7k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11499
34.7k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11500
34.7k
    }
11501
6.72M
    if ((pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_FILL)) {
11502
74.2k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11503
74.2k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_FILL;
11504
74.2k
        if_debug0m('v', pgs->memory,
11505
74.2k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_FILL \n");
11506
74.2k
    }
11507
6.72M
    if ((!pgs->is_fill_color && pdev->op_state != PDF14_OP_STATE_STROKE)) {
11508
75.3k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11509
75.3k
        params.op_fs_state = pdev->op_state = PDF14_OP_STATE_STROKE;
11510
75.3k
        if_debug0m('v', pgs->memory,
11511
75.3k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as PDF14_OP_STATE_STROKE \n");
11512
75.3k
    }
11513
6.72M
    if (crop_blend_params) {
11514
59.7k
        params.ctm = group_params->ctm;
11515
59.7k
        params.bbox = group_params->bbox;
11516
59.7k
    }
11517
6.72M
    params.changed = changed;
11518
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11519
       now to the target.  Otherwise we send the compositor action
11520
       to the pdf14 device at this time.  This is due to the fact that we
11521
       need to often perform this operation when we are already starting to
11522
       do a compositor action */
11523
6.72M
    if (changed != 0) {
11524
231k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11525
231k
        if (code < 0)
11526
0
            return code;
11527
231k
        code = dev_proc(pdev->target, composite)
11528
231k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11529
231k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11530
231k
    }
11531
6.72M
    return code;
11532
6.72M
}
11533
11534
/*
11535
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11536
 * writing the clist.
11537
 */
11538
static  int
11539
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11540
                           gx_path *ppath, const gx_fill_params *params,
11541
                           const gx_drawing_color *pdcolor,
11542
                           const gx_clip_path *pcpath)
11543
1.94M
{
11544
1.94M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11545
1.94M
    gs_gstate new_pgs = *pgs;
11546
1.94M
    int code;
11547
1.94M
    gs_pattern2_instance_t *pinst = NULL;
11548
1.94M
    gx_device_forward * fdev = (gx_device_forward *)dev;
11549
1.94M
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11550
1.94M
    gsicc_rendering_param_t render_cond;
11551
1.94M
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11552
1.94M
    int push_group = 0;
11553
11554
1.94M
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11555
1.94M
    if (code < 0)
11556
0
        return code;
11557
1.94M
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11558
1.94M
    if (code < 0)
11559
0
        return code;
11560
11561
1.94M
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11562
1.07k
        check_device_separable(dev);
11563
11564
1.94M
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11565
1.94M
                          &render_cond);
11566
1.94M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11567
1.94M
                          &render_cond);
11568
11569
    /*
11570
     * Ensure that that the PDF 1.4 reading compositor will have the current
11571
     * blending parameters.  This is needed since the fill_rectangle routines
11572
     * do not have access to the gs_gstate.  Thus we have to pass any
11573
     * changes explictly.
11574
     */
11575
1.94M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11576
1.94M
    if (code < 0)
11577
0
        return code;
11578
    /* If we are doing a shading fill and we are in a transparency group of a
11579
       different color space, then we do not want to do the shading in the
11580
       device color space. It must occur in the source space.  To handle it in
11581
       the device space would require knowing all the nested transparency group
11582
       color space as well as the transparency.  Some of the shading code ignores
11583
       this, so we have to pass on the clist_writer device to enable proper
11584
       mapping to the transparency group color space. */
11585
11586
1.94M
    if (gx_dc_is_pattern2_color(pdcolor)) {
11587
        /* Non-idempotent blends require a transparency
11588
         * group to be pushed because shadings might
11589
         * paint several pixels twice. */
11590
52.8k
        push_group = pgs->fillconstantalpha != 1.0 ||
11591
52.8k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11592
52.8k
        pinst =
11593
52.8k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11594
52.8k
           pinst->saved->has_transparency = true;
11595
           /* The transparency color space operations are driven by the pdf14
11596
              clist writer device.  */
11597
52.8k
           pinst->saved->trans_device = dev;
11598
52.8k
    }
11599
1.94M
    if (push_group) {
11600
2.19k
        gs_fixed_rect box;
11601
2.19k
        gs_fixed_rect dev_bbox;
11602
11603
2.19k
        if (pcpath) {
11604
2.19k
            gx_cpath_outer_box(pcpath, &box);
11605
2.19k
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11606
2.19k
            rect_intersect(box, dev_bbox);
11607
2.19k
        } else
11608
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11609
11610
2.19k
        if (ppath) {
11611
16
            gs_fixed_rect path_box;
11612
11613
16
            gx_path_bbox(ppath, &path_box);
11614
16
            if (box.p.x < path_box.p.x)
11615
16
                box.p.x = path_box.p.x;
11616
16
            if (box.p.y < path_box.p.y)
11617
16
                box.p.y = path_box.p.y;
11618
16
            if (box.q.x > path_box.q.x)
11619
16
                box.q.x = path_box.q.x;
11620
16
            if (box.q.y > path_box.q.y)
11621
16
                box.q.y = path_box.q.y;
11622
16
        }
11623
11624
2.19k
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11625
            /* No need to do anything */
11626
214
            if (pinst != NULL) {
11627
214
                pinst->saved->trans_device = NULL;
11628
214
            }
11629
214
            return 0;
11630
214
        }
11631
11632
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11633
1.98k
        code = push_shfill_group(pdev, &new_pgs, &box);
11634
1.98k
    } else
11635
1.94M
        update_lop_for_pdf14(&new_pgs, pdcolor);
11636
1.94M
    if (code >= 0) {
11637
1.94M
        new_pgs.trans_device = dev;
11638
1.94M
        new_pgs.has_transparency = true;
11639
1.94M
        if (gx_dc_is_pattern2_color(pdcolor))
11640
52.6k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11641
1.89M
        else
11642
1.89M
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11643
1.94M
        new_pgs.trans_device = NULL;
11644
1.94M
        new_pgs.has_transparency = false;
11645
1.94M
    }
11646
1.94M
    if (code >= 0 && push_group) {
11647
1.98k
        code = pop_shfill_group(&new_pgs);
11648
1.98k
        if (code >= 0)
11649
1.98k
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11650
1.98k
    }
11651
1.94M
    if (pinst != NULL){
11652
52.6k
        pinst->saved->trans_device = NULL;
11653
52.6k
    }
11654
1.94M
    return code;
11655
1.94M
}
11656
11657
/*
11658
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11659
 * writing the clist.
11660
 */
11661
static  int
11662
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11663
                             gx_path *ppath, const gx_stroke_params *params,
11664
                             const gx_drawing_color *pdcolor,
11665
                             const gx_clip_path *pcpath)
11666
531k
{
11667
531k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11668
531k
    gs_gstate new_pgs = *pgs;
11669
531k
    int code = 0;
11670
531k
    gs_pattern2_instance_t *pinst = NULL;
11671
531k
    int push_group = 0;
11672
11673
    /*
11674
     * Ensure that that the PDF 1.4 reading compositor will have the current
11675
     * blending parameters.  This is needed since the fill_rectangle routines
11676
     * do not have access to the gs_gstate.  Thus we have to pass any
11677
     * changes explictly.
11678
     */
11679
531k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11680
531k
    if (code < 0)
11681
0
        return code;
11682
    /* If we are doing a shading stroke and we are in a transparency group of a
11683
       different color space, then we need to get the proper device information
11684
       passed along so that we use the correct color procs and colorinfo about
11685
       the transparency device and not the final target device */
11686
531k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11687
        /* Non-idempotent blends require a transparency
11688
         * group to be pushed because shadings might
11689
         * paint several pixels twice. */
11690
192
        push_group = pgs->strokeconstantalpha != 1.0 ||
11691
192
               !blend_is_idempotent(gs_currentblendmode(pgs));
11692
192
        if (pdev->color_model_stack != NULL) {
11693
192
            pinst =
11694
192
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11695
192
            pinst->saved->has_transparency = true;
11696
            /* The transparency color space operations are driven
11697
              by the pdf14 clist writer device.  */
11698
192
            pinst->saved->trans_device = dev;
11699
192
        }
11700
192
    }
11701
531k
    if (push_group) {
11702
0
        gs_fixed_rect box;
11703
0
        if (pcpath)
11704
0
            gx_cpath_outer_box(pcpath, &box);
11705
0
        else
11706
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11707
0
        if (ppath) {
11708
0
            gs_fixed_rect path_box;
11709
0
            gs_fixed_point expansion;
11710
11711
0
            gx_path_bbox(ppath, &path_box);
11712
            /* Expand the path bounding box by the scaled line width. */
11713
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11714
                /* The expansion is so large it caused a limitcheck. */
11715
0
                path_box.p.x = path_box.p.y = min_fixed;
11716
0
                path_box.q.x = path_box.q.y = max_fixed;
11717
0
            } else {
11718
0
                expansion.x += pgs->fill_adjust.x;
11719
0
                expansion.y += pgs->fill_adjust.y;
11720
                /*
11721
                 * It's theoretically possible for the following computations to
11722
                 * overflow, so we need to check for this.
11723
                 */
11724
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11725
0
                                path_box.p.x - expansion.x);
11726
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11727
0
                                path_box.p.y - expansion.y);
11728
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11729
0
                                path_box.q.x + expansion.x);
11730
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11731
0
                                path_box.q.y + expansion.y);
11732
0
            }
11733
0
            if (box.p.x < path_box.p.x)
11734
0
                box.p.x = path_box.p.x;
11735
0
            if (box.p.y < path_box.p.y)
11736
0
                box.p.y = path_box.p.y;
11737
0
            if (box.q.x > path_box.q.x)
11738
0
                box.q.x = path_box.q.x;
11739
0
            if (box.q.y > path_box.q.y)
11740
0
                box.q.y = path_box.q.y;
11741
0
        }
11742
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11743
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11744
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11745
0
    } else
11746
531k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11747
11748
531k
    if (code >= 0) {
11749
531k
        new_pgs.trans_device = dev;
11750
531k
        new_pgs.has_transparency = true;
11751
531k
        if (gx_dc_is_pattern2_color(pdcolor))
11752
192
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11753
531k
        else
11754
531k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11755
531k
        new_pgs.trans_device = NULL;
11756
531k
        new_pgs.has_transparency = false;
11757
531k
    }
11758
531k
    if (code >= 0 && push_group) {
11759
0
        code = pop_shfill_group(&new_pgs);
11760
0
        if (code >= 0)
11761
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11762
0
    }
11763
531k
    if (pinst != NULL)
11764
192
        pinst->saved->trans_device = NULL;
11765
531k
    return code;
11766
531k
}
11767
11768
/* Set up work for doing shading patterns in fill stroke through
11769
   the clist.  We have to do all the dirty work now since we are
11770
   going through the default fill and stroke operations individually */
11771
static int
11772
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11773
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11774
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11775
    const gx_clip_path* pcpath)
11776
0
{
11777
0
    union {
11778
0
        const gs_gstate *cpgs;
11779
0
        gs_gstate *pgs;
11780
0
    } const_breaker;
11781
0
    gs_gstate *pgs;
11782
0
    int code, code2;
11783
0
    gs_transparency_group_params_t params = { 0 };
11784
0
    gs_fixed_rect clip_bbox;
11785
0
    gs_rect bbox, group_stroke_box;
11786
0
    float fill_alpha;
11787
0
    float stroke_alpha;
11788
0
    gs_blend_mode_t blend_mode;
11789
0
    gs_fixed_rect path_bbox;
11790
0
    int expansion_code;
11791
0
    gs_fixed_point expansion;
11792
11793
    /* Break const just once, neatly */
11794
0
    const_breaker.cpgs = cpgs;
11795
0
    pgs = const_breaker.pgs;
11796
11797
0
    fill_alpha = pgs->fillconstantalpha;
11798
0
    stroke_alpha = pgs->strokeconstantalpha;
11799
0
    blend_mode = pgs->blend_mode;
11800
11801
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11802
0
    if (code < 0 && code != gs_error_unknownerror)
11803
0
        return code;
11804
0
    if (code == gs_error_unknownerror) {
11805
        /* didn't get clip box from gx_curr_fixed_bbox */
11806
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11807
0
        clip_bbox.q.x = int2fixed(dev->width);
11808
0
        clip_bbox.q.y = int2fixed(dev->height);
11809
0
    }
11810
0
    if (pcpath)
11811
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11812
11813
    /* expand the ppath using stroke expansion rule, then intersect it */
11814
0
    code = gx_path_bbox(ppath, &path_bbox);
11815
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11816
0
        return 0;   /* ignore empty path */
11817
0
    if (code < 0)
11818
0
        return code;
11819
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11820
0
    if (expansion_code >= 0) {
11821
0
        path_bbox.p.x -= expansion.x;
11822
0
        path_bbox.p.y -= expansion.y;
11823
0
        path_bbox.q.x += expansion.x;
11824
0
        path_bbox.q.y += expansion.y;
11825
0
    }
11826
0
    rect_intersect(path_bbox, clip_bbox);
11827
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11828
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11829
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11830
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11831
11832
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11833
0
    if (code < 0)
11834
0
        return code;
11835
11836
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11837
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11838
0
        pgs->overprint && pgs->stroke_overprint &&
11839
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11840
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11841
11842
0
        params.Isolated = false;
11843
0
        params.group_color_type = UNKNOWN;
11844
0
        params.Knockout = false;
11845
0
        params.page_group = false;
11846
0
        params.group_opacity = fill_alpha;
11847
0
        params.group_shape = 1.0;
11848
11849
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11850
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11851
0
        if (code < 0)
11852
0
            return code;
11853
11854
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11855
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11856
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11857
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11858
11859
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11860
0
        if (code < 0)
11861
0
            goto cleanup;
11862
11863
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11864
0
        if (code < 0)
11865
0
            goto cleanup;
11866
11867
0
    } else {
11868
        /* Push a non-isolated knockout group. Do not change the alpha or
11869
           blend modes */
11870
0
        params.Isolated = false;
11871
0
        params.group_color_type = UNKNOWN;
11872
0
        params.Knockout = true;
11873
0
        params.page_group = false;
11874
0
        params.group_opacity = 1.0;
11875
0
        params.group_shape = 1.0;
11876
11877
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11878
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11879
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11880
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11881
11882
        /* restore blend mode for actual drawing in the group */
11883
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11884
11885
0
        if (fill_alpha > 0.0) {
11886
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11887
11888
            /* If we are in an overprint situation, set the blend mode to compatible
11889
               overprint */
11890
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11891
0
                pgs->overprint &&
11892
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11893
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11894
11895
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11896
0
            if (code < 0)
11897
0
                goto cleanup;
11898
11899
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11900
0
                pgs->overprint &&
11901
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11902
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11903
0
        }
11904
11905
0
        if (stroke_alpha > 0.0) {
11906
            /* Note that the stroke can end up looking like a fill here */
11907
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11908
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11909
11910
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11911
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11912
11913
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11914
0
            if (code < 0)
11915
0
                goto cleanup;
11916
11917
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11918
0
                pgs->overprint &&
11919
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11920
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11921
0
        }
11922
0
    }
11923
11924
0
cleanup:
11925
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11926
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11927
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11928
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11929
11930
    /* Restore where we were. If an error occured while in the group push
11931
       return that error code but try to do the cleanup */
11932
0
    code2 = gs_end_transparency_group(pgs);
11933
0
    if (code2 < 0) {
11934
        /* At this point things have gone very wrong. We should just shut down */
11935
0
        code = gs_abort_pdf14trans_device(pgs);
11936
0
        return code2;
11937
0
    }
11938
11939
    /* Restore if there were any changes */
11940
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11941
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11942
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11943
11944
0
    return code;
11945
0
}
11946
11947
/*
11948
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11949
 * writing the clist.
11950
 */
11951
static  int
11952
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11953
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
11954
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
11955
                             const gx_clip_path *pcpath)
11956
13.1k
{
11957
13.1k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11958
13.1k
    gs_gstate new_pgs = *pgs;
11959
13.1k
    int code;
11960
11961
13.1k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
11962
13.1k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
11963
87
        return 0;
11964
11965
    /*
11966
     * Ensure that that the PDF 1.4 reading compositor will have the current
11967
     * blending parameters.  This is needed since the fill_rectangle routines
11968
     * do not have access to the gs_gstate.  Thus we have to pass any
11969
     * changes explictly.
11970
     */
11971
13.0k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11972
13.0k
    if (code < 0)
11973
0
        return code;
11974
    /* If we are doing a shading fill or stroke, the clist can't
11975
       deal with this and end up in the pdf_fill_stroke operation.
11976
       We will need to break up the fill stroke now and do
11977
       the appropriate group pushes and set up. */
11978
11979
13.0k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
11980
13.0k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
11981
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
11982
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
11983
0
    }
11984
13.0k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
11985
13.0k
    new_pgs.trans_device = dev;
11986
13.0k
    new_pgs.has_transparency = true;
11987
13.0k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
11988
13.0k
                                       params_stroke, pdevc_stroke, pcpath);
11989
13.0k
    new_pgs.trans_device = NULL;
11990
13.0k
    new_pgs.has_transparency = false;
11991
13.0k
    return code;
11992
13.0k
}
11993
11994
/*
11995
 * text_begin routine for the PDF 1.4 transaprency compositor device for
11996
 * writing the clist.
11997
 */
11998
static  int
11999
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12000
                 const gs_text_params_t * text, gs_font * font,
12001
                 const gx_clip_path * pcpath,
12002
                 gs_text_enum_t ** ppenum)
12003
4.10M
{
12004
4.10M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12005
4.10M
    gs_text_enum_t *penum;
12006
4.10M
    int code;
12007
4.10M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12008
4.10M
    float opacity = pgs->fillconstantalpha;
12009
4.10M
    float shape = 1.0;
12010
4.10M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12011
4.10M
    bool draw = !(text->operation & TEXT_DO_NONE);
12012
4.10M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12013
4.10M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12014
4.10M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12015
12016
4.10M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12017
    /*
12018
     * Ensure that that the PDF 1.4 reading compositor will have the current
12019
     * blending parameters.  This is needed since the fill_rectangle routines
12020
     * do not have access to the gs_gstate.  Thus we have to pass any
12021
     * changes explictly.
12022
     */
12023
4.10M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12024
4.10M
    if (code < 0)
12025
0
        return code;
12026
    /* Pass text_begin to the target */
12027
4.10M
    code = gx_forward_text_begin(dev, pgs, text, font,
12028
4.10M
                                 pcpath, &penum);
12029
4.10M
    if (code < 0)
12030
1.28k
        return code;
12031
12032
   /* Catch case where we already pushed a group and are trying to push another one.
12033
   In that case, we will pop the current one first, as we don't want to be left
12034
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12035
   will not be caught until we do the put_image and notice that the stack is not
12036
   empty. */
12037
4.10M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12038
0
        code = gs_end_transparency_group(pgs);
12039
0
        if (code < 0)
12040
0
            return code;
12041
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12042
0
    }
12043
12044
    /* We may need to push a non-isolated transparency group if the following
12045
    is true.
12046
    1) We are not currently in one that we pushed for text.  This is
12047
    is determined by looking at the pdf14 device.
12048
    2) The blend mode is not Normal or the opacity is not 1.0
12049
    3) Text knockout is set to true
12050
    4) And we are actually drawing text
12051
    */
12052
12053
4.10M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12054
4.10M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12055
4.10M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12056
4.10M
        text_mode != 3 && /* don't bother with invisible text */
12057
4.10M
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12058
2.25k
        if (draw) {
12059
2.25k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12060
2.25k
            if (code == 0)
12061
2.25k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12062
2.25k
        }
12063
2.25k
    }
12064
4.10M
    *ppenum = (gs_text_enum_t *)penum;
12065
4.10M
    return code;
12066
4.10M
}
12067
12068
static  int
12069
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12070
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12071
                           const gs_int_rect * prect,
12072
                           const gx_drawing_color * pdcolor,
12073
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12074
                           gx_image_enum_common_t ** pinfo)
12075
61.2k
{
12076
61.2k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12077
61.2k
    int code;
12078
61.2k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12079
61.2k
    const gs_image_t *pim = (const gs_image_t *)pic;
12080
61.2k
    gx_image_enum *penum;
12081
61.2k
    gx_color_tile *ptile;
12082
61.2k
    gs_rect bbox_in, bbox_out;
12083
61.2k
    gs_transparency_group_params_t tgp;
12084
    /*
12085
     * Ensure that that the PDF 1.4 reading compositor will have the current
12086
     * blending parameters.  This is needed since the fill_rectangle routines
12087
     * do not have access to the gs_gstate.  Thus we have to pass any
12088
     * changes explictly.
12089
     */
12090
61.2k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12091
61.2k
    if (code < 0)
12092
0
        return code;
12093
    /* Pass image to the target */
12094
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12095
       case the clist writer cannot handle this image itself.  In such a case,
12096
       we want to make sure we dont use the target device.  I don't necc. like
12097
       doing it this way.  Probably need to go back and do something a bit
12098
       more elegant. */
12099
61.2k
    pgs_noconst->has_transparency = true;
12100
61.2k
    pgs_noconst->trans_device = dev;
12101
12102
    /* If we are filling an image mask with a pattern that has a transparency
12103
       then we need to do some special handling */
12104
61.2k
    if (pim->ImageMask) {
12105
58
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12106
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12107
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12108
0
                    ptile = pdcolor->colors.pattern.p_tile;
12109
                    /* Set up things in the ptile so that we get the proper
12110
                       blending etc */
12111
                    /* Set the blending procs and the is_additive setting based
12112
                       upon the number of channels */
12113
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12114
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12115
0
                        ptile->ttrans->is_additive = true;
12116
0
                    } else {
12117
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12118
0
                        ptile->ttrans->is_additive = false;
12119
0
                    }
12120
                    /* Set the blending mode in the ptile based upon the current
12121
                       setting in the gs_gstate */
12122
0
                    ptile->blending_mode = pgs->blend_mode;
12123
                    /* Set the procs so that we use the proper filling method. */
12124
                    /* Let the imaging stuff get set up */
12125
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12126
0
                                                        prect, pdcolor,
12127
0
                                                        pcpath, mem, pinfo);
12128
0
                    if (code < 0)
12129
0
                        return code;
12130
12131
0
                    penum = (gx_image_enum *) *pinfo;
12132
                    /* Apply inverse of the image matrix to our
12133
                       image size to get our bounding box. */
12134
0
                    bbox_in.p.x = 0;
12135
0
                    bbox_in.p.y = 0;
12136
0
                    bbox_in.q.x = pim->Width;
12137
0
                    bbox_in.q.y = pim->Height;
12138
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12139
0
                                                     &bbox_out);
12140
0
                    if (code < 0)
12141
0
                        return code;
12142
                    /* Set up a compositor action for pushing the group */
12143
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12144
0
                    tgp.Isolated = true;
12145
0
                    tgp.Knockout = false;
12146
0
                    tgp.page_group = false;
12147
0
                    tgp.mask_id = 0;
12148
0
                    tgp.image_with_SMask = false;
12149
0
                    tgp.idle = false;
12150
0
                    tgp.iccprofile = NULL;
12151
0
                    tgp.icc_hashcode = 0;
12152
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12153
0
                    tgp.ColorSpace = NULL;
12154
0
                    tgp.text_group = 0;
12155
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12156
0
                    tgp.group_shape = 1.0;
12157
                    /* This will handle the compositor command */
12158
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12159
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12160
0
                    ptile->ttrans->image_render = penum->render;
12161
0
                    penum->render = &pdf14_pattern_trans_render;
12162
0
                    ptile->trans_group_popped = false;
12163
0
                    pgs_noconst->has_transparency = false;
12164
0
                    pgs_noconst->trans_device = NULL;
12165
0
                    return code;
12166
0
                }
12167
0
            }
12168
21
        }
12169
58
    }
12170
    /* This basically tries high level images for clist. If that fails
12171
       then we do the default */
12172
61.2k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12173
61.2k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12174
61.2k
    if (code < 0){
12175
16.8k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12176
16.8k
                                        pdcolor, pcpath, mem, pinfo);
12177
16.8k
        pgs_noconst->has_transparency = false;
12178
16.8k
        pgs_noconst->trans_device = NULL;
12179
16.8k
        return code;
12180
44.4k
    } else {
12181
44.4k
        pgs_noconst->has_transparency = false;
12182
44.4k
        pgs_noconst->trans_device = NULL;
12183
44.4k
        return code;
12184
44.4k
    }
12185
61.2k
}
12186
12187
static int
12188
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12189
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12190
2.45k
{
12191
2.45k
    int code;
12192
12193
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12194
2.45k
                                  x, y, w, h, plane_height);
12195
2.45k
    return code;
12196
2.45k
}
12197
12198
static int
12199
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12200
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12201
13.1k
{
12202
13.1k
    int code;
12203
13.1k
    pdf14_clist_device *p14dev;
12204
13.1k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12205
12206
13.1k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12207
13.1k
    if (code < 0)
12208
0
        return code;
12209
    /*
12210
     * Set the color_info of the clist device to match the compositing
12211
     * device.  We will restore it when the compositor is popped.
12212
     * See pdf14_clist_composite for the restore.  Do the
12213
     * same with the gs_gstate's get_cmap_procs.  We do not want
12214
     * the gs_gstate to use transfer functions on our color values.
12215
     * The transfer functions will be applied at the end after we
12216
     * have done our PDF 1.4 blend operations.
12217
     */
12218
13.1k
    p14dev = (pdf14_clist_device *)(*pcdev);
12219
13.1k
    p14dev->saved_target_color_info = dev->color_info;
12220
13.1k
    dev->color_info = (*pcdev)->color_info;
12221
    /* Make sure that we keep the anti-alias information though */
12222
13.1k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12223
13.1k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12224
12225
    /* adjust the clist_color_info now */
12226
13.1k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12227
13.1k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12228
13.1k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12229
13.1k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12230
13.1k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12231
12232
13.1k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12233
13.1k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12234
13.1k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12235
13.1k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12236
13.1k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12237
13.1k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12238
13.1k
    p14dev->saved_target_get_color_mapping_procs =
12239
13.1k
                              dev_proc(dev, get_color_mapping_procs);
12240
13.1k
    p14dev->saved_target_get_color_comp_index =
12241
13.1k
                              dev_proc(dev, get_color_comp_index);
12242
13.1k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12243
13.1k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12244
13.1k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12245
13.1k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12246
13.1k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12247
13.1k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12248
13.1k
    gx_set_cmap_procs(pgs, dev);
12249
13.1k
    return code;
12250
13.1k
}
12251
/*
12252
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12253
 * to create a compositing device for clist writing.  The primary purpose of
12254
 * this device is to provide support for the process color model in which
12255
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12256
 * model of the output device.)  The actual work of compositing the image is
12257
 * done on the output (reader) side of the clist.
12258
 */
12259
static  int
12260
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12261
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12262
495k
{
12263
495k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12264
495k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12265
495k
    int code = 0;
12266
12267
    /* We only handle the push/pop operations */
12268
495k
    switch (pdf14pct->params.pdf14_op) {
12269
13.1k
        case PDF14_PUSH_DEVICE:
12270
13.1k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12271
            /* Change (non-error) code to 1 to indicate that we created
12272
             * a device. */
12273
13.1k
            if (code >= 0)
12274
13.1k
                code = 1;
12275
13.1k
            return code;
12276
12277
12.6k
        case PDF14_POP_DEVICE:
12278
12.6k
            code = clist_writer_check_empty_cropping_stack(cdev);
12279
12.6k
            break;
12280
12281
5.00k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12282
59.7k
        case PDF14_BEGIN_TRANS_GROUP:
12283
59.7k
            { /* HACK: store mask_id into our params for subsequent
12284
                   calls of c_pdf14trans_write. To do this we must
12285
                   break const. */
12286
59.7k
                gs_pdf14trans_t * pdf14pct_noconst;
12287
12288
59.7k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12289
                /* What ever the current mask ID is, that is the
12290
                   softmask group through which this transparency
12291
                   group must be rendered. Store it now. */
12292
59.7k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12293
59.7k
                if_debug1m('v', pgs->memory,
12294
59.7k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12295
59.7k
                           cdev->mask_id);
12296
59.7k
            }
12297
59.7k
            break;
12298
57.4k
        case PDF14_END_TRANS_GROUP:
12299
59.7k
        case PDF14_END_TRANS_TEXT_GROUP:
12300
59.7k
            code = 0; /* A place for breakpoint. */
12301
59.7k
            break;
12302
62.5k
        case PDF14_BEGIN_TRANS_MASK:
12303
            /* A new mask has been started */
12304
62.5k
            cdev->mask_id = ++cdev->mask_id_count;
12305
            /* replacing is set everytime that we
12306
               have a zpushtransparencymaskgroup */
12307
62.5k
            { /* HACK: store mask_id into our params for subsequent
12308
                   calls of c_pdf14trans_write. To do this we must
12309
                   break const. */
12310
62.5k
                gs_pdf14trans_t * pdf14pct_noconst;
12311
12312
62.5k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12313
62.5k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12314
62.5k
                if_debug1m('v', pgs->memory,
12315
62.5k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12316
62.5k
                           cdev->mask_id);
12317
62.5k
            }
12318
62.5k
            break;
12319
28.5k
        case PDF14_END_TRANS_MASK:
12320
28.5k
            code = 0; /* A place for breakpoint. */
12321
28.5k
            break;
12322
0
        case PDF14_PUSH_TRANS_STATE:
12323
0
            code = 0; /* A place for breakpoint. */
12324
0
            break;
12325
27.6k
        case PDF14_POP_TRANS_STATE:
12326
27.6k
            code = 0; /* A place for breakpoint. */
12327
27.6k
            break;
12328
0
        case PDF14_ABORT_DEVICE:
12329
0
            code = 0;
12330
0
            break;
12331
0
        case PDF14_PUSH_SMASK_COLOR:
12332
0
            *pcdev = dev;
12333
0
            return 0;
12334
0
            break;
12335
0
        case PDF14_POP_SMASK_COLOR:
12336
0
            *pcdev = dev;
12337
0
            return 0;
12338
0
            break;
12339
231k
        default:
12340
231k
            break;   /* do nothing for remaining ops */
12341
495k
    }
12342
482k
    *pcdev = dev;
12343
482k
    if (code < 0)
12344
0
        return code;
12345
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12346
       apply_composite. */
12347
482k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12348
    /* Wrote an extra ctm. */
12349
482k
    cmd_clear_known(cdev, ctm_known);
12350
12351
482k
    return code;
12352
482k
}
12353
12354
/*
12355
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12356
 * device color_info data match the compositing device.  We need to do this
12357
 * since the PDF 1.4 transparency compositing device may use a different
12358
 * process color model than the output device.  We do not need to modify the
12359
 * color related device procs since the compositing device has its own.  We
12360
 * restore the color_info data when the transparency device is popped.
12361
 */
12362
static  int
12363
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12364
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12365
35.5M
{
12366
35.5M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12367
35.5M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12368
35.5M
    gs_devn_params * pclist_devn_params;
12369
35.5M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12370
35.5M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12371
35.5M
    gsicc_rendering_param_t render_cond;
12372
35.5M
    cmm_dev_profile_t *dev_profile;
12373
12374
35.5M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12375
35.5M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12376
35.5M
                          &render_cond);
12377
12378
    /* If we are using the blending color space, then be sure to use that. */
12379
35.5M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12380
35.5M
        dev_profile->blend_profile != NULL)
12381
0
        cl_icc_profile = dev_profile->blend_profile;
12382
35.5M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12383
35.5M
        dev_profile->oi_profile != NULL)
12384
0
        cl_icc_profile = dev_profile->oi_profile;
12385
12386
35.5M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12387
35.5M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12388
35.5M
                          &render_cond);
12389
    /*
12390
     * We only handle the push/pop operations. Save and restore the color_info
12391
     * field for the clist device.  This is needed since the process color
12392
     * model of the clist device needs to match the PDF 1.4 compositing
12393
     * device.
12394
     */
12395
35.5M
    switch (pdf14pct->params.pdf14_op) {
12396
1.55M
    case PDF14_PUSH_DEVICE:
12397
        /* Overprint simulation sets the profile at prototype creation, as does
12398
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12399
1.55M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12400
1.55M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12401
1.55M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12402
1.55M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12403
1.55M
                -1, "c_pdf14trans_clist_read_update");
12404
1.55M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12405
1.55M
        }
12406
            /*
12407
             * If we are blending using spot colors (i.e. the output device
12408
             * supports spot colors) then we need to transfer
12409
             * color info from the clist PDF 1.4 compositing reader device
12410
             * to the clist writer PDF 1.4 compositing device.
12411
             * This info was transfered from that device to the output
12412
             * device as a set of device parameters.  However the clist
12413
             * reader PDF 1.4 compositing device did not exist when the
12414
             * device parameters were read from the clist.  So that info
12415
             * was buffered into the output device.
12416
             */
12417
1.55M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12418
1.55M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12419
326
                int num_comp = p14dev->color_info.num_components;
12420
326
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12421
                /*
12422
                 * The number of components for the PDF14 device is the sum
12423
                 * of the process components and the number of spot colors
12424
                 * for the page.  If the color capabilities of the parent
12425
                 * device (which coming into this are the same as the p14dev)
12426
                 * are smaller than the number of page spot colors then
12427
                 * use that for the number of components. Otherwise use
12428
                 * the page_spot_colors.  The exception is, if we had used
12429
                 * the sICCOutputColors setting, then just use that, which
12430
                 * should be already baked into num_comp. With clist patterns,
12431
                 * cdev->icc_struct may be null.
12432
                 */
12433
12434
326
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12435
326
                    p14dev->devn_params.page_spot_colors =
12436
326
                        pclist_devn_params->page_spot_colors;
12437
326
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12438
0
                        if (p14dev->num_planar_planes > 0)
12439
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12440
0
                        p14dev->color_info.num_components = num_comp;
12441
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12442
326
                    } else {
12443
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12444
326
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12445
326
                            int n = p14dev->num_std_colorants +
12446
326
                                    p14dev->devn_params.page_spot_colors + has_tags;
12447
326
                            if (p14dev->num_planar_planes > 0)
12448
326
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12449
326
                            p14dev->color_info.num_components = n;
12450
326
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12451
326
                        }
12452
326
                    }
12453
326
                }
12454
                /* limit the num_components to the max. */
12455
326
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12456
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12457
                /* Transfer the data for the spot color names
12458
                   But we have to free what may be there before we do this */
12459
326
                devn_free_params((gx_device*) p14dev);
12460
326
                p14dev->devn_params.separations =
12461
326
                    pclist_devn_params->pdf14_separations;
12462
326
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12463
326
                if (num_comp != p14dev->color_info.num_components) {
12464
                    /* Historically, there has been a comment here:
12465
                       "When the pdf14 device is opened it creates a context and some
12466
                       soft mask related objects.  The push device compositor action
12467
                       will have already created these but they are the wrong size.
12468
                       We must destroy them though before reopening the device."
12469
                       I can't see why this is the case, and testing in the cluster
12470
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12471
                       shows that this freeing/NULLing the ctx here causes problems
12472
                       when the freed ctx is reinserted at the end of clist pattern
12473
                       files. Accordingly, I'm removing the freeing/NULLing for now
12474
                       at least. */
12475
0
                    int code = dev_proc(tdev, open_device) (tdev);
12476
0
                    if (code < 0)
12477
0
                        return code;
12478
0
                }
12479
326
            }
12480
            /* Check if we need to swap out the ICC profile for the pdf14
12481
               device.  This will occur if our source profile for our device
12482
               happens to be something like CIELAB.  Then we will blend in
12483
               RGB (unless a trans group is specified) */
12484
1.55M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12485
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12486
0
                                        -1, "c_pdf14trans_clist_read_update");
12487
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12488
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12489
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12490
                /* Keep a pointer to the clist device */
12491
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12492
0
            }
12493
1.55M
            break;
12494
12495
1.55M
        case PDF14_POP_DEVICE:
12496
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12497
                    the clist playback. This code is not executed while clist
12498
                    writing. */
12499
            cdev->color_info = p14dev->saved_target_color_info;
12500
#     endif
12501
1.55M
           break;
12502
12503
32.4M
        default:
12504
32.4M
            break;   /* do nothing for remaining ops */
12505
35.5M
    }
12506
12507
35.5M
    return 0;
12508
35.5M
}
12509
12510
/*
12511
 * Get cropping for the compositor command.
12512
 */
12513
static  int
12514
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12515
                          int cropping_min, int cropping_max)
12516
495k
{
12517
495k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12518
495k
    switch (pdf14pct->params.pdf14_op) {
12519
13.1k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12520
12.6k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12521
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12522
5.00k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12523
59.7k
        case PDF14_BEGIN_TRANS_GROUP:
12524
59.7k
            { gs_int_rect rect;
12525
12526
                /* Text group always uses parents size*/
12527
59.7k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12528
2.25k
                    *ry = cropping_min;
12529
2.25k
                    *rheight = cropping_max - *ry;
12530
57.4k
                } else {
12531
57.4k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12532
57.4k
                        &pdf14pct->params.bbox, &rect);
12533
                    /* We have to crop this by the parent object.   */
12534
57.4k
                    *ry = max(rect.p.y, cropping_min);
12535
57.4k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12536
57.4k
                }
12537
59.7k
                return PUSHCROP; /* Push cropping. */
12538
5.00k
            }
12539
62.5k
        case PDF14_BEGIN_TRANS_MASK:
12540
62.5k
            { gs_int_rect rect;
12541
12542
62.5k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12543
62.5k
                                                    &pdf14pct->params.bbox, &rect);
12544
                /* We have to crop this by the parent object and worry about the BC outside
12545
                   the range, except for image SMask which don't affect areas outside the image.
12546
                   The presence of a transfer function opens the possibility of issues with this */
12547
62.5k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12548
36.3k
                      pdf14pct->params.function_is_identity)) {
12549
                    /* In this case there will not be a background effect to
12550
                       worry about.  The mask will not have any effect outside
12551
                       the bounding box.  This is NOT the default or common case. */
12552
26.1k
                    *ry = max(rect.p.y, cropping_min);
12553
26.1k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12554
26.1k
                    return PUSHCROP; /* Push cropping. */
12555
36.3k
                }  else {
12556
                    /* We need to make the soft mask range as large as the parent
12557
                       due to the fact that the background color can have an impact
12558
                       OUTSIDE the bounding box of the soft mask */
12559
36.3k
                    *ry = cropping_min;
12560
36.3k
                    *rheight = cropping_max - cropping_min;
12561
36.3k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12562
33.9k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12563
2.33k
                    else
12564
2.33k
                        return PUSHCROP; /* Push cropping. */
12565
36.3k
                }
12566
62.5k
            }
12567
57.4k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12568
2.24k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12569
28.5k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12570
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12571
27.6k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12572
231k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12573
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12574
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12575
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12576
495k
    }
12577
0
    return ALLBANDS;
12578
495k
}
12579
12580
/*
12581
 * This routine will check to see if the color component name matches those
12582
 * that are available amoung the current device's color components.  If the
12583
 * color name is known to the output device then we add it to the list of
12584
 * colorants for the PDF 1.4 transparency compositor.
12585
 *
12586
 * Notes:  There are currently three different versions of The PDF 1.4
12587
 * transparency compositor device.  The choice of which one is being used
12588
 * depends upon the process color model of the output device.  This procedure
12589
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12590
 * plus spot color process color model.
12591
 *
12592
 * Parameters:
12593
 *   dev - pointer to device data structure.
12594
 *   pname - pointer to name (zero termination not required)
12595
 *   nlength - length of the name
12596
 *   number of process colorants (either 1, 3, or 4)
12597
 *
12598
 * This routine returns a positive value (0 to n) which is the device colorant
12599
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12600
 * the colorant is not being used due to a SeparationOrder device parameter.
12601
 * It returns a negative value if not found.
12602
 */
12603
static int
12604
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12605
    int name_size, int component_type, int num_process_colors)
12606
16.5k
{
12607
16.5k
    pdf14_device *pdev = (pdf14_device *)dev;
12608
16.5k
    gx_device *tdev = pdev->target;
12609
16.5k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12610
16.5k
    gs_separations *pseparations;
12611
16.5k
    int comp_index;
12612
16.5k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12613
16.5k
    int offset;
12614
12615
16.5k
    while (tdev->child) {
12616
0
        tdev = tdev->child;
12617
0
    }
12618
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12619
    /* get the devn_params from the target to avoid accessing using the wrong  */
12620
    /* pointer. Bug 696372.                                                    */
12621
16.5k
    if (tdev == (gx_device *)pdev)
12622
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12623
16.5k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12624
16.5k
    pseparations = &pdevn_params->separations;
12625
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12626
     * where we are in a blend color space that is RGB or Gray based and we
12627
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12628
     * Yellow or Black, then we should use the alternate tint transform */
12629
16.5k
    if (num_process_colors < 4) {
12630
468
        int k;
12631
2.34k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12632
1.87k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12633
0
                return -1;
12634
1.87k
        }
12635
468
    }
12636
12637
16.5k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12638
12639
    /* The pdf14_clist_composite may have set the color procs.
12640
       We need the real target procs, but not if we are doing simulated
12641
       overprint */
12642
16.5k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12643
16.5k
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index) &&
12644
16.5k
        !pdev->overprint_sim)
12645
16.5k
        target_get_color_comp_index =
12646
16.5k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12647
    /*
12648
    * If this is not a separation name then simply forward it to the target
12649
    * device or return -1 if we are doing overprint simulation.
12650
    * The halftone setup expects this.
12651
    */
12652
16.5k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12653
16.5k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12654
11.9k
            if (target_get_color_comp_index != NULL)
12655
11.9k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12656
0
            else
12657
0
                return -1;
12658
11.9k
    }
12659
4.63k
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12660
0
        return -1;
12661
0
    }
12662
12663
    /*
12664
    * Check if the component is in either the process color model list
12665
    * or in the SeparationNames list.
12666
    */
12667
4.63k
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12668
4.63k
        name_size, component_type);
12669
12670
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12671
     * This is a decision we take here to avoid problems with PDFI not
12672
     * counting such colorants as spots. */
12673
4.63k
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12674
29
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12675
0
            return -1;
12676
29
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12677
0
            return -1;
12678
29
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12679
0
            return -1;
12680
29
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12681
0
            return -1;
12682
29
    }
12683
12684
    /*
12685
    * Return the colorant number if we know this name.  Note adjustment for
12686
    * compensating of blend color space.
12687
    */
12688
4.63k
    if (comp_index >= 0)
12689
4.60k
        return comp_index - offset;
12690
12691
    /* Only worry about the target if we are not doing an overprint simulation */
12692
29
    if (!pdev->overprint_sim) {
12693
        /*
12694
        * If we do not know this color, check if the output (target) device does.
12695
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12696
        * the colorant so we will only get < 0 returned when we hit the max. for
12697
        * the target device.
12698
        */
12699
29
        if (target_get_color_comp_index != NULL)
12700
29
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12701
0
        else
12702
0
            return -1;
12703
        /*
12704
        * Ignore color if unknown to the output device or if color is not being
12705
        * imaged due to the SeparationOrder device parameter.
12706
        */
12707
29
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12708
0
            return comp_index - offset;
12709
29
    }
12710
12711
    /*
12712
    * This is a new colorant.  Add it to our list of colorants.
12713
    * The limit accounts for the number of process colors (at least 4).
12714
    */
12715
29
    if ((pseparations->num_separations + 1) <
12716
29
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12717
29
        int sep_num = pseparations->num_separations++;
12718
29
        int color_component_number;
12719
29
        byte * sep_name;
12720
12721
29
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12722
29
            name_size, "pdf14_spot_get_color_comp_index");
12723
29
        if (sep_name == NULL) {
12724
0
            pseparations->num_separations--;  /* we didn't add it */
12725
0
            return -1;
12726
0
        }
12727
29
        memcpy(sep_name, pname, name_size);
12728
29
        pseparations->names[sep_num].size = name_size;
12729
29
        pseparations->names[sep_num].data = sep_name;
12730
29
        color_component_number = sep_num + num_process_colors;
12731
29
        if (color_component_number >= dev->color_info.max_components)
12732
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12733
29
        else
12734
29
            pdevn_params->separation_order_map[color_component_number] =
12735
29
            color_component_number;
12736
12737
        /* Indicate that we need to find equivalent CMYK color. */
12738
29
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12739
29
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12740
12741
29
        return color_component_number;
12742
29
    }
12743
12744
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12745
29
}
12746
12747
12748
/* CMYK process + spots */
12749
static int
12750
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12751
    int name_size, int component_type)
12752
16.0k
{
12753
16.0k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4);
12754
16.0k
}
12755
12756
/* RGB process + spots */
12757
static int
12758
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12759
    int name_size, int component_type)
12760
468
{
12761
468
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3);
12762
468
}
12763
12764
/* Gray process + spots */
12765
static int
12766
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12767
    int name_size, int component_type)
12768
0
{
12769
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1);
12770
0
}
12771
12772
/* These functions keep track of when we are dealing with soft masks.
12773
   In such a case, we set the default color profiles to ones that ensure
12774
   proper soft mask rendering. */
12775
static int
12776
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12777
42.5k
{
12778
42.5k
    pdf14_device * pdev = (pdf14_device *) dev;
12779
42.5k
    pdf14_smaskcolor_t *result;
12780
42.5k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12781
42.5k
    int k;
12782
12783
    /* See if we have profiles already in place.   Note we also have to
12784
       worry about a corner case where this device does not have a
12785
       smaskcolor stucture to store the profiles AND the profiles were
12786
       already swapped out in the icc_manager.  This can occur when we
12787
       pushed a transparency mask and then inside the mask we have a pattern
12788
       which also has a transparency mask.   The state of the icc_manager
12789
       is that it already has done the swap and there is no need to fool
12790
       with any of this while dealing with the soft mask within the pattern */
12791
42.5k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12792
42.5k
        pgs->icc_manager->smask_profiles->swapped) {
12793
0
            return 0;
12794
0
    }
12795
42.5k
    if (pdev->smaskcolor != NULL) {
12796
112
        pdev->smaskcolor->ref_count++;
12797
112
        if_debug1m(gs_debug_flag_icc, dev->memory,
12798
112
                   "[icc] Increment smask color now %d\n",
12799
112
                   pdev->smaskcolor->ref_count);
12800
42.4k
    } else {
12801
        /* Allocate and swap out the current profiles.  The softmask
12802
           profiles should already be in place */
12803
42.4k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12804
42.4k
                                &st_pdf14_smaskcolor,
12805
42.4k
                                "pdf14_increment_smask_color");
12806
42.4k
        if (result == NULL)
12807
0
            return gs_error_VMerror;
12808
12809
42.4k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12810
42.4k
        if (result->profiles == NULL)
12811
0
            return gs_error_VMerror;
12812
12813
42.4k
        pdev->smaskcolor = result;
12814
12815
42.4k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12816
42.4k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12817
42.4k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12818
42.4k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12819
42.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12820
42.4k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12821
42.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12822
42.4k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12823
42.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12824
42.4k
        pgs->icc_manager->smask_profiles->swapped = true;
12825
42.4k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12826
42.4k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12827
42.4k
        pdev->smaskcolor->ref_count = 1;
12828
        /* We also need to update the profile that is currently in the
12829
           color spaces of the graphic state.  Otherwise this can be
12830
           referenced, which will result in a mismatch.  What we want to do
12831
           is see if it was the original default and only swap in that case. */
12832
127k
        for (k = 0; k < 2; k++) {
12833
84.9k
            gs_color_space *pcs     = pgs->color[k].color_space;
12834
84.9k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12835
84.9k
            if (profile != NULL) {
12836
82.5k
                switch(profile->data_cs) {
12837
45.2k
                    case gsGRAY:
12838
45.2k
                        if (profile->hashcode ==
12839
45.2k
                            result->profiles->smask_gray->hashcode) {
12840
42.3k
                                profile = pgs->icc_manager->default_gray;
12841
42.3k
                        }
12842
45.2k
                        break;
12843
36.6k
                    case gsRGB:
12844
36.6k
                        if (profile->hashcode ==
12845
36.6k
                            result->profiles->smask_rgb->hashcode) {
12846
15.1k
                                profile = pgs->icc_manager->default_rgb;
12847
15.1k
                        }
12848
36.6k
                        break;
12849
608
                    case gsCMYK:
12850
608
                        if (profile->hashcode ==
12851
608
                            result->profiles->smask_cmyk->hashcode) {
12852
608
                                profile = pgs->icc_manager->default_cmyk;
12853
608
                        }
12854
608
                        break;
12855
0
                    default:
12856
12857
0
                        break;
12858
82.5k
                }
12859
82.5k
                if (pcs->cmm_icc_profile_data != profile) {
12860
58.1k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12861
58.1k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12862
58.1k
                    pcs->cmm_icc_profile_data = profile;
12863
58.1k
                }
12864
82.5k
            }
12865
84.9k
        }
12866
42.4k
    }
12867
42.5k
    return 0;
12868
42.5k
}
12869
12870
static int
12871
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12872
55.2k
{
12873
55.2k
    pdf14_device * pdev = (pdf14_device *) dev;
12874
55.2k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12875
55.2k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12876
55.2k
    int k;
12877
12878
    /* See comment in pdf14_increment_smask_color to understand this one */
12879
55.2k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12880
55.2k
        pgs->icc_manager->smask_profiles->swapped) {
12881
0
            return 0;
12882
0
    }
12883
55.2k
    if (smaskcolor != NULL) {
12884
42.5k
        smaskcolor->ref_count--;
12885
42.5k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12886
42.5k
                   "[icc] Decrement smask color.  Now %d\n",
12887
42.5k
                   smaskcolor->ref_count);
12888
42.5k
        if (smaskcolor->ref_count == 0) {
12889
42.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12890
            /* Lets return the profiles and clean up */
12891
            /* First see if we need to "reset" the profiles that are in
12892
               the graphic state */
12893
42.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12894
127k
            for (k = 0; k < 2; k++) {
12895
84.9k
                gs_color_space *pcs = pgs->color[k].color_space;
12896
84.9k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12897
84.9k
                if (profile != NULL) {
12898
82.5k
                    switch(profile->data_cs) {
12899
45.2k
                        case gsGRAY:
12900
45.2k
                            if (profile->hashcode ==
12901
45.2k
                                pgs->icc_manager->default_gray->hashcode) {
12902
42.3k
                                    profile =
12903
42.3k
                                        smaskcolor->profiles->smask_gray;
12904
42.3k
                            }
12905
45.2k
                            break;
12906
36.6k
                        case gsRGB:
12907
36.6k
                            if (profile->hashcode ==
12908
36.6k
                                pgs->icc_manager->default_rgb->hashcode) {
12909
15.1k
                                    profile =
12910
15.1k
                                        smaskcolor->profiles->smask_rgb;
12911
15.1k
                            }
12912
36.6k
                            break;
12913
608
                        case gsCMYK:
12914
608
                            if (profile->hashcode ==
12915
608
                                pgs->icc_manager->default_cmyk->hashcode) {
12916
608
                                    profile =
12917
608
                                        smaskcolor->profiles->smask_cmyk;
12918
608
                            }
12919
608
                            break;
12920
0
                        default:
12921
12922
0
                            break;
12923
82.5k
                    }
12924
82.5k
                    if (pcs->cmm_icc_profile_data != profile) {
12925
58.1k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12926
58.1k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12927
58.1k
                        pcs->cmm_icc_profile_data = profile;
12928
58.1k
                    }
12929
82.5k
                }
12930
84.9k
            }
12931
12932
42.4k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12933
42.4k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
12934
42.4k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
12935
42.4k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
12936
42.4k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
12937
42.4k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
12938
42.4k
            icc_manager->smask_profiles->swapped = false;
12939
            /* We didn't increment the reference count when we assigned these
12940
             * so NULL them to avoid decrementing when smaskcolor is freed
12941
             */
12942
42.4k
            smaskcolor->profiles->smask_gray =
12943
42.4k
              smaskcolor->profiles->smask_rgb =
12944
42.4k
              smaskcolor->profiles->smask_cmyk = NULL;
12945
12946
42.4k
            pdf14_free_smask_color(pdev);
12947
42.4k
        }
12948
42.5k
    }
12949
55.2k
    return 0;
12950
55.2k
}
12951
12952
static void
12953
pdf14_free_smask_color(pdf14_device * pdev)
12954
42.4k
{
12955
42.4k
    if (pdev->smaskcolor != NULL) {
12956
42.4k
        if ( pdev->smaskcolor->profiles != NULL) {
12957
            /* Do not decrement the profiles - the references were moved
12958
               here and moved back again, so the ref counts don't change
12959
             */
12960
42.4k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
12961
42.4k
                        "pdf14_free_smask_color");
12962
42.4k
        }
12963
42.4k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
12964
42.4k
        pdev->smaskcolor = NULL;
12965
42.4k
    }
12966
42.4k
}
12967
12968
static void
12969
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
12970
1.57M
{
12971
1.57M
    gx_device * const dev = (gx_device *)vptr;
12972
1.57M
    pdf14_device * pdev = (pdf14_device *)dev;
12973
1.57M
    int k;
12974
12975
1.57M
    pdf14_cleanup_group_color_profiles (pdev);
12976
12977
1.57M
    if (pdev->ctx) {
12978
34
        pdf14_ctx_free(pdev->ctx);
12979
34
        pdev->ctx = NULL;
12980
34
    }
12981
12982
1.57M
    while (pdev->color_model_stack) {
12983
17
        pdf14_pop_group_color(dev, NULL);
12984
17
    }
12985
12986
1.57M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
12987
29
        if (pdev->devn_params.separations.names[k].data) {
12988
29
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
12989
29
            pdev->devn_params.separations.names[k].data = NULL;
12990
29
        }
12991
29
    }
12992
12993
1.57M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
12994
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
12995
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
12996
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
12997
0
        }
12998
0
    }
12999
13000
1.57M
    gx_device_finalize(cmem, vptr);
13001
1.57M
}
13002
13003
#if DUMP_MASK_STACK
13004
13005
static void
13006
dump_mask_stack(pdf14_mask_t *mask_stack)
13007
{
13008
    pdf14_mask_t *curr_mask = mask_stack;
13009
    int level = 0;
13010
13011
    while (curr_mask != NULL) {
13012
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13013
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13014
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13015
        level++;
13016
        curr_mask = curr_mask->previous;
13017
    }
13018
}
13019
13020
/* A function to display the current state of the mask stack */
13021
static void
13022
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13023
{
13024
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13025
    if (ctx->mask_stack != NULL) {
13026
        dump_mask_stack(ctx->mask_stack);
13027
    }
13028
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13029
    if (ctx->stack != NULL) {
13030
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13031
        if (ctx->stack->mask_stack != NULL) {
13032
            dump_mask_stack(ctx->stack->mask_stack);
13033
        }
13034
    }
13035
}
13036
13037
#else
13038
13039
#ifdef DEBUG
13040
static void
13041
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13042
{
13043
    return;
13044
}
13045
#endif
13046
13047
#endif /* DUMP_MASK_STACK */