Coverage Report

Created: 2026-09-14 07:34

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/ghostpdl/base/gdevp14.c
Line
Count
Source
1
/* Copyright (C) 2001-2026 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
/* Compositing devices for implementing PDF 1.4 imaging model */
17
18
#include "assert_.h"
19
#include "math_.h"
20
#include "memory_.h"
21
#include "gx.h"
22
#include "gserrors.h"
23
#include "gscdefs.h"
24
#include "gxdevice.h"
25
#include "gsdevice.h"
26
#include "gsstruct.h"
27
#include "gxgstate.h"
28
#include "gxdcolor.h"
29
#include "gxiparam.h"
30
#include "gstparam.h"
31
#include "gxblend.h"
32
#include "gxtext.h"
33
#include "gsimage.h"
34
#include "gsrect.h"
35
#include "gscoord.h"
36
#include "gzstate.h"
37
#include "gdevdevn.h"
38
#include "gdevmem.h"
39
#include "gdevp14.h"
40
#include "gdevprn.h"    /* for prn_device structures */
41
#include "gdevppla.h"   /* for gdev_prn_open_planar */
42
#include "gdevdevnprn.h"
43
#include "gscdevn.h"
44
#include "gsovrc.h"
45
#include "gxcmap.h"
46
#include "gscolor1.h"
47
#include "gstrans.h"
48
#include "gsutil.h"
49
#include "gxcldev.h"
50
#include "gxclpath.h"
51
#include "gxdcconv.h"
52
#include "gsptype2.h"
53
#include "gxpcolor.h"
54
#include "gsptype1.h"
55
#include "gzcpath.h"
56
#include "gxpaint.h"
57
#include "gsicc_manage.h"
58
#include "gsicc_cache.h"
59
#include "gxclist.h"
60
#include "gxiclass.h"
61
#include "gximage.h"
62
#include "gsmatrix.h"
63
#include "gxdevsop.h"
64
#include "gsicc.h"
65
#ifdef WITH_CAL
66
#include "cal.h"
67
#define CAL_SLOP 16
68
#else
69
#define CAL_SLOP 0
70
#endif
71
#include "assert_.h"
72
#include "gxgetbit.h"
73
#include "gdevkrnlsclass.h"
74
75
#if RAW_DUMP
76
unsigned int global_index = 0;
77
unsigned int clist_band_count = 0;
78
#endif
79
80
#define DUMP_MASK_STACK 0
81
82
/* Static prototypes */
83
/* Used for filling rects when we are doing a fill with a pattern that
84
   has transparency */
85
static int pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
86
                                   gx_path * ppath, const gx_fill_params * params,
87
                                   const gx_device_color * pdevc, const gx_clip_path * pcpath);
88
static pdf14_mask_t *pdf14_mask_element_new(gs_memory_t *memory);
89
static void pdf14_free_smask_color(pdf14_device * pdev);
90
static int compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
91
                                         const gs_rect *pbbox, gs_gstate *pgs);
92
static int pdf14_clist_update_params(pdf14_clist_device * pdev,
93
                                     const gs_gstate * pgs,
94
                                     bool crop_blend_params,
95
                                     gs_pdf14trans_params_t *group_params);
96
static int pdf14_mark_fill_rectangle_ko_simple(gx_device *  dev, int x, int y,
97
                                               int w, int h, gx_color_index color,
98
                                               const gx_device_color *pdc,
99
                                               bool devn);
100
static int pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
101
                                  int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
102
                                  gx_color_index color, const gx_device_color *pdc,
103
                                  int depth, bool devn);
104
105
/* Functions for dealing with soft mask color */
106
static int pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev);
107
static int pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev);
108
109
/*
110
 * We chose the blending color space based upon the process color model of the
111
 * output device.  For gray, RGB, CMYK, or CMYK+spot devices, the choice is
112
 * usually simple.  For other devices or if the user is doing custom color
113
 * processing then the user may want to control this choice.
114
 */
115
#define AUTO_USE_CUSTOM_BLENDING 0
116
#define ALWAYS_USE_CUSTOM_BLENDING 1
117
#define DO_NOT_USE_CUSTOM_BLENDING 2
118
119
#define CUSTOM_BLENDING_MODE AUTO_USE_CUSTOM_BLENDING
120
121
# define INCR(v) DO_NOTHING
122
123
/* Forward prototypes */
124
void pdf14_cmyk_cs_to_cmyk_cm(const gx_device *, frac, frac, frac, frac, frac *);
125
static int gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
126
                                gx_device ** pdev, gx_device * target,
127
                                const gs_pdf14trans_t * pdf14pct);
128
static int gs_pdf14_clist_device_push(gs_memory_t * mem, gs_gstate * pgs,
129
                                      gx_device ** pdev, gx_device * target,
130
                                      const gs_pdf14trans_t * pdf14pct);
131
static int pdf14_tile_pattern_fill(gx_device * pdev,
132
                const gs_gstate * pgs, gx_path * ppath,
133
                const gx_fill_params * params,
134
                const gx_device_color * pdevc, const gx_clip_path * pcpath);
135
#ifdef DEBUG
136
static void pdf14_debug_mask_stack_state(pdf14_ctx *ctx);
137
#endif
138
139
/* A structure used by the pdf14 device so that
140
   we can do the proper dance when the alphabuf
141
   device is being used */
142
typedef struct pdf14_abuf_state_s {
143
    bool op_ca_eq_CA;
144
    bool path_empty;
145
    float stroke_alpha;
146
    float fill_alpha;
147
    gs_gstate* pgs;
148
    gs_blend_mode_t blend_mode;
149
    bool group_needed;
150
    GS_OP_FS_STATE orig_state;
151
} pdf14_abuf_state_t;
152
153
/* Buffer stack data structure */
154
gs_private_st_ptrs7(st_pdf14_buf, pdf14_buf, "pdf14_buf",
155
                    pdf14_buf_enum_ptrs, pdf14_buf_reloc_ptrs,
156
                    saved, data, backdrop, transfer_fn, mask_stack,
157
                    matte, group_color_info);
158
159
gs_private_st_ptrs3(st_pdf14_ctx, pdf14_ctx, "pdf14_ctx",
160
                    pdf14_ctx_enum_ptrs, pdf14_ctx_reloc_ptrs,
161
                    stack, mask_stack, base_color);
162
163
gs_private_st_ptrs1(st_pdf14_clr, pdf14_group_color_t, "pdf14_clr",
164
                    pdf14_clr_enum_ptrs, pdf14_clr_reloc_ptrs, previous);
165
166
gs_private_st_ptrs2(st_pdf14_mask, pdf14_mask_t, "pdf_mask",
167
                    pdf14_mask_enum_ptrs, pdf14_mask_reloc_ptrs,
168
                    mask_buf, previous);
169
170
gs_private_st_ptrs1(st_pdf14_smaskcolor, pdf14_smaskcolor_t, "pdf14_smaskcolor",
171
                    pdf14_smaskcolor_enum_ptrs, pdf14_smaskcolor_reloc_ptrs,
172
                    profiles);
173
174
/* ------ The device descriptors ------ */
175
176
/*
177
 * Default X and Y resolution.
178
 */
179
#define X_DPI 72
180
#define Y_DPI 72
181
182
static int pdf14_initialize_device(gx_device *dev);
183
184
static  int pdf14_open(gx_device * pdev);
185
static  dev_proc_close_device(pdf14_close);
186
static  int pdf14_output_page(gx_device * pdev, int num_copies, int flush);
187
static  dev_proc_put_params(pdf14_put_params);
188
static  dev_proc_get_color_comp_index(pdf14_cmykspot_get_color_comp_index);
189
static  dev_proc_get_color_comp_index(pdf14_rgbspot_get_color_comp_index);
190
static  dev_proc_get_color_comp_index(pdf14_grayspot_get_color_comp_index);
191
static  dev_proc_get_color_mapping_procs(pdf14_cmykspot_get_color_mapping_procs);
192
static  dev_proc_get_color_mapping_procs(pdf14_rgbspot_get_color_mapping_procs);
193
static  dev_proc_get_color_mapping_procs(pdf14_grayspot_get_color_mapping_procs);
194
dev_proc_encode_color(pdf14_encode_color);
195
dev_proc_encode_color(pdf14_encode_color_tag);
196
dev_proc_decode_color(pdf14_decode_color);
197
dev_proc_encode_color(pdf14_encode_color16);
198
dev_proc_encode_color(pdf14_encode_color16_tag);
199
dev_proc_decode_color(pdf14_decode_color16);
200
static  dev_proc_fill_rectangle(pdf14_fill_rectangle);
201
static  dev_proc_fill_rectangle_hl_color(pdf14_fill_rectangle_hl_color);
202
static  dev_proc_fill_path(pdf14_fill_path);
203
static  dev_proc_fill_stroke_path(pdf14_fill_stroke_path);
204
static  dev_proc_copy_mono(pdf14_copy_mono);
205
static  dev_proc_fill_mask(pdf14_fill_mask);
206
static  dev_proc_stroke_path(pdf14_stroke_path);
207
static  dev_proc_begin_typed_image(pdf14_begin_typed_image);
208
static  dev_proc_text_begin(pdf14_text_begin);
209
static  dev_proc_composite(pdf14_composite);
210
static  dev_proc_composite(pdf14_forward_composite);
211
static  dev_proc_begin_transparency_group(pdf14_begin_transparency_group);
212
static  dev_proc_end_transparency_group(pdf14_end_transparency_group);
213
static  dev_proc_begin_transparency_mask(pdf14_begin_transparency_mask);
214
static  dev_proc_end_transparency_mask(pdf14_end_transparency_mask);
215
static  dev_proc_dev_spec_op(pdf14_dev_spec_op);
216
static  dev_proc_push_transparency_state(pdf14_push_transparency_state);
217
static  dev_proc_pop_transparency_state(pdf14_pop_transparency_state);
218
static  dev_proc_ret_devn_params(pdf14_ret_devn_params);
219
static  dev_proc_update_spot_equivalent_colors(pdf14_update_spot_equivalent_colors);
220
static  dev_proc_copy_alpha(pdf14_copy_alpha);
221
static  dev_proc_copy_planes(pdf14_copy_planes);
222
static  dev_proc_copy_alpha_hl_color(pdf14_copy_alpha_hl_color);
223
static  dev_proc_discard_transparency_layer(pdf14_discard_trans_layer);
224
static  dev_proc_strip_tile_rect_devn(pdf14_strip_tile_rect_devn);
225
static  const gx_color_map_procs *
226
    pdf14_get_cmap_procs(const gs_gstate *, const gx_device *);
227
228
#define XSIZE (int)(8.5 * X_DPI)  /* 8.5 x 11 inch page, by default */
229
#define YSIZE (int)(11 * Y_DPI)
230
231
/* 24-bit color. */
232
233
static void
234
pdf14_procs_initialize(gx_device *dev,
235
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
236
                       dev_proc_get_color_comp_index(get_color_comp_index),
237
                       dev_proc_encode_color(encode_color),
238
                       dev_proc_decode_color(decode_color))
239
4.76M
{
240
4.76M
    set_dev_proc(dev, initialize_device, pdf14_initialize_device);
241
4.76M
    set_dev_proc(dev, open_device, pdf14_open);
242
4.76M
    set_dev_proc(dev, output_page, pdf14_output_page);
243
4.76M
    set_dev_proc(dev, close_device, pdf14_close);
244
4.76M
    set_dev_proc(dev, map_rgb_color, encode_color);
245
4.76M
    set_dev_proc(dev, map_color_rgb, decode_color);
246
4.76M
    set_dev_proc(dev, fill_rectangle, pdf14_fill_rectangle);
247
4.76M
    set_dev_proc(dev, copy_mono, pdf14_copy_mono);
248
4.76M
    set_dev_proc(dev, get_params, gx_forward_get_params);
249
4.76M
    set_dev_proc(dev, put_params, pdf14_put_params);
250
4.76M
    set_dev_proc(dev, copy_alpha, pdf14_copy_alpha);
251
4.76M
    set_dev_proc(dev, fill_path, pdf14_fill_path);
252
4.76M
    set_dev_proc(dev, stroke_path, pdf14_stroke_path);
253
4.76M
    set_dev_proc(dev, fill_mask, pdf14_fill_mask);
254
4.76M
    set_dev_proc(dev, begin_typed_image, pdf14_begin_typed_image);
255
4.76M
    set_dev_proc(dev, composite, pdf14_composite);
256
4.76M
    set_dev_proc(dev, text_begin, pdf14_text_begin);
257
4.76M
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
258
4.76M
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
259
4.76M
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
260
4.76M
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
261
4.76M
    set_dev_proc(dev, discard_transparency_layer, pdf14_discard_trans_layer);
262
4.76M
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
263
4.76M
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
264
4.76M
    set_dev_proc(dev, encode_color, encode_color);
265
4.76M
    set_dev_proc(dev, decode_color, decode_color);
266
4.76M
    set_dev_proc(dev, fill_rectangle_hl_color, pdf14_fill_rectangle_hl_color);
267
4.76M
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
268
4.76M
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
269
4.76M
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
270
4.76M
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
271
4.76M
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
272
4.76M
    set_dev_proc(dev, copy_planes, pdf14_copy_planes);
273
4.76M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
274
4.76M
    set_dev_proc(dev, strip_tile_rect_devn, pdf14_strip_tile_rect_devn);
275
4.76M
    set_dev_proc(dev, copy_alpha_hl_color, pdf14_copy_alpha_hl_color);
276
4.76M
    set_dev_proc(dev, fill_stroke_path, pdf14_fill_stroke_path);
277
4.76M
}
278
279
static void
280
pdf14_Gray_initialize_device_procs(gx_device *dev)
281
1.33M
{
282
1.33M
    pdf14_procs_initialize(dev,
283
1.33M
                           gx_default_DevGray_get_color_mapping_procs,
284
1.33M
                           gx_default_DevGray_get_color_comp_index,
285
1.33M
                           pdf14_encode_color,
286
1.33M
                           pdf14_decode_color);
287
1.33M
}
288
289
static void
290
pdf14_RGB_initialize_device_procs(gx_device *dev)
291
2.95M
{
292
2.95M
    pdf14_procs_initialize(dev,
293
2.95M
                           gx_default_DevRGB_get_color_mapping_procs,
294
2.95M
                           gx_default_DevRGB_get_color_comp_index,
295
2.95M
                           pdf14_encode_color,
296
2.95M
                           pdf14_decode_color);
297
2.95M
}
298
299
static void
300
pdf14_CMYK_initialize_device_procs(gx_device *dev)
301
252k
{
302
252k
    pdf14_procs_initialize(dev,
303
252k
                           gx_default_DevCMYK_get_color_mapping_procs,
304
252k
                           gx_default_DevCMYK_get_color_comp_index,
305
252k
                           pdf14_encode_color,
306
252k
                           pdf14_decode_color);
307
252k
}
308
309
static void
310
pdf14_CMYKspot_initialize_device_procs(gx_device *dev)
311
159k
{
312
159k
    pdf14_procs_initialize(dev,
313
159k
                           pdf14_cmykspot_get_color_mapping_procs,
314
159k
                           pdf14_cmykspot_get_color_comp_index,
315
159k
                           pdf14_encode_color,
316
159k
                           pdf14_decode_color);
317
159k
}
318
319
static void
320
pdf14_RGBspot_initialize_device_procs(gx_device *dev)
321
58.3k
{
322
58.3k
    pdf14_procs_initialize(dev,
323
58.3k
                           pdf14_rgbspot_get_color_mapping_procs,
324
58.3k
                           pdf14_rgbspot_get_color_comp_index,
325
58.3k
                           pdf14_encode_color,
326
58.3k
                           pdf14_decode_color);
327
58.3k
}
328
329
static void
330
pdf14_Grayspot_initialize_device_procs(gx_device *dev)
331
0
{
332
0
    pdf14_procs_initialize(dev,
333
0
                           pdf14_grayspot_get_color_mapping_procs,
334
0
                           pdf14_grayspot_get_color_comp_index,
335
0
                           pdf14_encode_color,
336
0
                           pdf14_decode_color);
337
0
}
338
339
static void
340
pdf14_custom_initialize_device_procs(gx_device *dev)
341
0
{
342
0
    pdf14_procs_initialize(dev,
343
0
                           gx_forward_get_color_mapping_procs,
344
0
                           gx_forward_get_color_comp_index,
345
0
                           gx_forward_encode_color,
346
0
                           gx_forward_decode_color);
347
0
}
348
349
static struct_proc_finalize(pdf14_device_finalize);
350
351
gs_private_st_composite_use_final(st_pdf14_device, pdf14_device, "pdf14_device",
352
                                  pdf14_device_enum_ptrs, pdf14_device_reloc_ptrs,
353
                          pdf14_device_finalize);
354
355
static int pdf14_put_image(gx_device * dev, gs_gstate * pgs,
356
                                                        gx_device * target);
357
static int pdf14_cmykspot_put_image(gx_device * dev, gs_gstate * pgs,
358
                                                        gx_device * target);
359
static int pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs,
360
                                                        gx_device * target);
361
362
/* Alter pdf14 device color model based upon group or softmask. This occurs
363
   post clist or in immediate rendering case. Data stored with buffer */
364
static pdf14_group_color_t* pdf14_push_color_model(gx_device *dev,
365
                              gs_transparency_color_t group_color, int64_t icc_hashcode,
366
                              cmm_profile_t *iccprofile, bool is_mask);
367
static void pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color);
368
369
/* Alter clist writer device color model based upon group or softmask. Data
370
   stored in the device color model stack */
371
static int pdf14_clist_push_color_model(gx_device* dev, gx_device* cdev, gs_gstate* pgs,
372
    const gs_pdf14trans_t* pdf14pct, gs_memory_t* mem, bool is_mask);
373
static int pdf14_clist_pop_color_model(gx_device* dev, gs_gstate* pgs);
374
375
/* Used for cleaning up the stack if things go wrong */
376
static void pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs);
377
378
static const pdf14_procs_t gray_pdf14_procs = {
379
    pdf14_unpack_additive,
380
    pdf14_put_image,
381
    pdf14_unpack16_additive
382
};
383
384
static const pdf14_procs_t rgb_pdf14_procs = {
385
    pdf14_unpack_additive,
386
    pdf14_put_image,
387
    pdf14_unpack16_additive
388
};
389
390
static const pdf14_procs_t cmyk_pdf14_procs = {
391
    pdf14_unpack_subtractive,
392
    pdf14_put_image,
393
    pdf14_unpack16_subtractive
394
};
395
396
static const pdf14_procs_t cmykspot_pdf14_procs = {
397
    pdf14_unpack_custom,  /* should never be used since we will use devn values */
398
    pdf14_cmykspot_put_image,
399
    pdf14_unpack16_custom /* should never be used since we will use devn values */
400
};
401
402
static const pdf14_procs_t rgbspot_pdf14_procs = {
403
    pdf14_unpack_rgb_mix,
404
    pdf14_cmykspot_put_image,
405
    pdf14_unpack16_rgb_mix
406
};
407
408
static const pdf14_procs_t grayspot_pdf14_procs = {
409
    pdf14_unpack_gray_mix,
410
    pdf14_cmykspot_put_image,
411
    pdf14_unpack16_gray_mix
412
};
413
414
static const pdf14_procs_t custom_pdf14_procs = {
415
    pdf14_unpack_custom,
416
    pdf14_custom_put_image,
417
    pdf14_unpack16_custom
418
};
419
420
static const pdf14_nonseparable_blending_procs_t gray_blending_procs = {
421
    art_blend_luminosity_custom_8,
422
    art_blend_saturation_custom_8,
423
    art_blend_luminosity_custom_16,
424
    art_blend_saturation_custom_16
425
};
426
427
static const pdf14_nonseparable_blending_procs_t rgb_blending_procs = {
428
    art_blend_luminosity_rgb_8,
429
    art_blend_saturation_rgb_8,
430
    art_blend_luminosity_rgb_16,
431
    art_blend_saturation_rgb_16
432
};
433
434
static const pdf14_nonseparable_blending_procs_t cmyk_blending_procs = {
435
    art_blend_luminosity_cmyk_8,
436
    art_blend_saturation_cmyk_8,
437
    art_blend_luminosity_cmyk_16,
438
    art_blend_saturation_cmyk_16
439
};
440
441
static const pdf14_nonseparable_blending_procs_t rgbspot_blending_procs = {
442
    art_blend_luminosity_rgb_8,
443
    art_blend_saturation_rgb_8,
444
    art_blend_luminosity_rgb_16,
445
    art_blend_saturation_rgb_16
446
};
447
448
static const pdf14_nonseparable_blending_procs_t grayspot_blending_procs = {
449
    art_blend_luminosity_custom_8,
450
    art_blend_saturation_custom_8,
451
    art_blend_luminosity_custom_16,
452
    art_blend_saturation_custom_16
453
};
454
455
static const pdf14_nonseparable_blending_procs_t custom_blending_procs = {
456
    art_blend_luminosity_custom_8,
457
    art_blend_saturation_custom_8,
458
    art_blend_luminosity_custom_16,
459
    art_blend_saturation_custom_16
460
};
461
462
const pdf14_device gs_pdf14_Gray_device = {
463
    std_device_std_color_full_body_type(pdf14_device,
464
                                        pdf14_Gray_initialize_device_procs,
465
                                        "pdf14gray",
466
                                        &st_pdf14_device,
467
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 8,
468
                                        0, 0, 0, 0, 0, 0),
469
    { 0 },      /* Procs */
470
    NULL,     /* target */
471
    { 0 },      /* devn_params - not used */
472
    &gray_pdf14_procs,
473
    &gray_blending_procs,
474
    1
475
};
476
477
const pdf14_device gs_pdf14_RGB_device = {
478
    std_device_color_stype_body(pdf14_device,
479
                                pdf14_RGB_initialize_device_procs,
480
                                "pdf14RGB",
481
                                &st_pdf14_device,
482
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
483
    { 0 },      /* Procs */
484
    NULL,     /* target */
485
    { 0 },      /* devn_params - not used */
486
    &rgb_pdf14_procs,
487
    &rgb_blending_procs,
488
    3
489
};
490
491
const pdf14_device gs_pdf14_CMYK_device = {
492
    std_device_std_color_full_body_type(pdf14_device,
493
                                        pdf14_CMYK_initialize_device_procs,
494
                                        "pdf14cmyk",
495
                                        &st_pdf14_device,
496
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
497
                                        0, 0, 0, 0, 0, 0),
498
    { 0 },      /* Procs */
499
    NULL,     /* target */
500
    { 0 },      /* devn_params - not used */
501
    &cmyk_pdf14_procs,
502
    &cmyk_blending_procs,
503
    4
504
};
505
506
const pdf14_device gs_pdf14_CMYKspot_device = {
507
    std_device_part1_(pdf14_device,
508
                      pdf14_CMYKspot_initialize_device_procs,
509
                      "pdf14cmykspot",
510
                      &st_pdf14_device,
511
                      open_init_closed),
512
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
513
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
514
    offset_margin_values(0, 0, 0, 0, 0, 0),
515
    std_device_part3_(),
516
    { 0 },      /* Procs */
517
    NULL,     /* target */
518
    /* DeviceN parameters */
519
    { 8,      /* Not used - Bits per color */
520
      DeviceCMYKComponents, /* Names of color model colorants */
521
      4,      /* Number colorants for CMYK */
522
      0,      /* MaxSeparations has not been specified */
523
      -1,     /* PageSpotColors has not been specified */
524
      {0},      /* SeparationNames */
525
      0,      /* SeparationOrder names */
526
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
527
    },
528
    &cmykspot_pdf14_procs,
529
    &cmyk_blending_procs,
530
    4
531
};
532
533
const pdf14_device gs_pdf14_RGBspot_device = {
534
    std_device_part1_(pdf14_device,
535
                      pdf14_RGBspot_initialize_device_procs,
536
                      "pdf14rgbspot",
537
                      &st_pdf14_device,
538
                      open_init_closed),
539
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
540
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
541
    offset_margin_values(0, 0, 0, 0, 0, 0),
542
    std_device_part3_(),
543
    { 0 },      /* Procs */
544
    NULL,     /* target */
545
                    /* DeviceN parameters */
546
    { 8,      /* Not used - Bits per color */
547
    0,              /* Names of color model colorants */
548
    3,          /* Number colorants for RGB */
549
    0,          /* MaxSeparations has not been specified */
550
    -1,         /* PageSpotColors has not been specified */
551
    { 0 },      /* SeparationNames */
552
    0,          /* SeparationOrder names */
553
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
554
    },
555
    &rgbspot_pdf14_procs,
556
    &rgbspot_blending_procs,
557
    3
558
};
559
560
const pdf14_device gs_pdf14_Grayspot_device = {
561
    std_device_part1_(pdf14_device,
562
                      pdf14_Grayspot_initialize_device_procs,
563
                      "pdf14grayspot",
564
                      &st_pdf14_device,
565
                      open_init_closed),
566
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
567
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
568
    offset_margin_values(0, 0, 0, 0, 0, 0),
569
    std_device_part3_(),
570
    { 0 },      /* Procs */
571
    NULL,     /* target */
572
                    /* DeviceN parameters */
573
    { 8,      /* Not used - Bits per color */
574
    0,              /* Names of color model colorants */
575
    3,          /* Number colorants for RGB */
576
    0,          /* MaxSeparations has not been specified */
577
    -1,         /* PageSpotColors has not been specified */
578
    { 0 },      /* SeparationNames */
579
    0,          /* SeparationOrder names */
580
    { 0, 1, 2, 3, 4, 5, 6, 7 }  /* Initial component SeparationOrder */
581
    },
582
    &grayspot_pdf14_procs,
583
    &grayspot_blending_procs,
584
    1
585
};
586
587
/*
588
 * The 'custom' PDF 1.4 compositor device is for working with those devices
589
 * which support spot colors but do not have a CMYK process color model.
590
 *
591
 * This causes some problems with the Hue, Saturation, Color, and Luminosity
592
 * blending modes.  These blending modes are 'non separable' and depend upon
593
 * knowing the details of the blending color space.  However we use the
594
 * process color model of the output device for our blending color space.
595
 * With an unknown process color model, we have to fall back to some 'guesses'
596
 * about how to treat these blending modes.
597
 */
598
const pdf14_device gs_pdf14_custom_device = {
599
    std_device_part1_(pdf14_device,
600
                      pdf14_custom_initialize_device_procs,
601
                      "pdf14custom",
602
                      &st_pdf14_device,
603
                      open_init_closed),
604
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
605
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
606
    offset_margin_values(0, 0, 0, 0, 0, 0),
607
    std_device_part3_(),
608
    { 0 },      /* Procs */
609
    NULL,     /* target */
610
    /* DeviceN parameters */
611
    { 8,      /* Not used - Bits per color */
612
      DeviceCMYKComponents, /* Names of color model colorants */
613
      4,      /* Number colorants for CMYK */
614
      0,      /* MaxSeparations has not been specified */
615
      -1,     /* PageSpotColors has not been specified */
616
      {0},      /* SeparationNames */
617
      0,      /* SeparationOrder names */
618
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
619
    },
620
    &custom_pdf14_procs,
621
    &custom_blending_procs,
622
    4
623
};
624
625
/* Devices used for pdf14-accum-* device, one for  each image colorspace, */
626
/* Gray, RGB, CMYK, DeviceN. Before calling gdev_prn_open, the following  */
627
/* are set from the target device: width, height, xdpi, ydpi, MaxBitmap.  */
628
629
static dev_proc_print_page(no_print_page);
630
static  dev_proc_ret_devn_params(pdf14_accum_ret_devn_params);
631
static  dev_proc_get_color_comp_index(pdf14_accum_get_color_comp_index);
632
static  dev_proc_get_color_mapping_procs(pdf14_accum_get_color_mapping_procs);
633
static  dev_proc_update_spot_equivalent_colors(pdf14_accum_update_spot_equivalent_colors);
634
635
static int
636
no_print_page(gx_device_printer *pdev, gp_file *prn_stream)
637
0
{
638
0
    return_error(gs_error_unknownerror);
639
0
}
640
641
struct gx_device_pdf14_accum_s {
642
    gx_devn_prn_device_common;
643
    gx_device *save_p14dev;   /* the non-clist pdf14 deivce saved for after accum */
644
};
645
typedef struct gx_device_pdf14_accum_s gx_device_pdf14_accum;
646
647
int
648
pdf14_accum_dev_spec_op(gx_device *pdev, int dev_spec_op, void *data, int size)
649
7.06M
{
650
7.06M
    gx_device_pdf14_accum *adev = (gx_device_pdf14_accum *)pdev;
651
652
7.06M
    if (dev_spec_op == gxdso_device_child) {
653
1.92k
        gxdso_device_child_request *req = (gxdso_device_child_request *)data;
654
1.92k
        if (size < sizeof(*req))
655
0
            return gs_error_unknownerror;
656
1.92k
        req->target = adev->save_p14dev;
657
1.92k
        req->n = 0;
658
1.92k
        return 0;
659
1.92k
    }
660
661
7.06M
    return gdev_prn_dev_spec_op(pdev, dev_spec_op, data, size);
662
7.06M
}
663
664
gs_private_st_suffix_add1_final(st_gx_devn_accum_device, gx_device_pdf14_accum,
665
        "gx_device_pdf14_accum", pdf14_accum_device_enum_ptrs, pdf14_accum_device_reloc_ptrs,
666
                          gx_devn_prn_device_finalize, st_gx_devn_prn_device, save_p14dev);
667
668
static void
669
pdf14_accum_Gray_initialize_device_procs(gx_device *dev)
670
675
{
671
675
    gdev_prn_initialize_device_procs_gray8(dev);
672
673
675
    set_dev_proc(dev, encode_color, gx_default_8bit_map_gray_color);
674
675
    set_dev_proc(dev, decode_color, gx_default_8bit_map_color_gray);
675
675
}
676
677
const gx_device_pdf14_accum pdf14_accum_Gray = {
678
    prn_device_stype_body(gx_device_pdf14_accum,
679
                          pdf14_accum_Gray_initialize_device_procs,
680
                          "pdf14-accum-Gray",
681
                          &st_gx_devn_accum_device,
682
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
683
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
684
                          1/*ncomp*/, 8/*depth*/, 255/*max_gray*/, 0/*max_color*/,
685
                          256/*dither_grays*/, 0/*dither_colors*/,
686
                          no_print_page),
687
    { 0 },      /* devn_params - not used */
688
    { 0 },      /* equivalent_cmyk_color_params - not used */
689
    0/*save_p14dev*/
690
};
691
692
static void
693
pdf14_accum_RGB_initialize_device_procs(gx_device *dev)
694
3.03k
{
695
3.03k
    gdev_prn_initialize_device_procs_rgb(dev);
696
3.03k
}
697
698
const gx_device_pdf14_accum pdf14_accum_RGB = {
699
    prn_device_stype_body(gx_device_pdf14_accum,
700
                          pdf14_accum_RGB_initialize_device_procs,
701
                          "pdf14-accum-RGB",
702
                          &st_gx_devn_accum_device,
703
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
704
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
705
                          3/*ncomp*/, 24/*depth*/, 0/*max_gray*/, 255/*max_color*/,
706
                          1/*dither_grays*/, 256/*dither_colors*/,
707
                          no_print_page),
708
    { 0 },      /* devn_params - not used */
709
    { 0 },      /* equivalent_cmyk_color_params - not used */
710
    0/*save_p14dev*/
711
};
712
713
static void
714
pdf14_accum_CMYK_initialize_device_procs(gx_device *dev)
715
0
{
716
0
    gdev_prn_initialize_device_procs_cmyk8(dev);
717
718
0
    set_dev_proc(dev, encode_color, cmyk_8bit_map_cmyk_color);
719
0
    set_dev_proc(dev, decode_color, cmyk_8bit_map_color_cmyk);
720
0
}
721
722
const gx_device_pdf14_accum pdf14_accum_CMYK = {
723
    prn_device_stype_body(gx_device_pdf14_accum,
724
                          pdf14_accum_CMYK_initialize_device_procs,
725
                          "pdf14-accum-CMYK",
726
                          &st_gx_devn_accum_device,
727
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
728
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
729
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
730
                          256/*dither_grays*/, 256/*dither_colors*/,
731
                          no_print_page),
732
    { 0 },      /* devn_params - not used */
733
    { 0 },      /* equivalent_cmyk_color_params - not used */
734
    0/*save_p14dev*/
735
};
736
737
static void
738
pdf14_accum_initialize_device_procs_cmykspot(gx_device *dev)
739
0
{
740
0
    pdf14_accum_CMYK_initialize_device_procs(dev);
741
742
0
    set_dev_proc(dev, get_color_mapping_procs, pdf14_accum_get_color_mapping_procs);
743
0
    set_dev_proc(dev, get_color_comp_index, pdf14_accum_get_color_comp_index);
744
0
    set_dev_proc(dev, update_spot_equivalent_colors, pdf14_accum_update_spot_equivalent_colors);
745
0
    set_dev_proc(dev, ret_devn_params, pdf14_accum_ret_devn_params);
746
0
}
747
748
const gx_device_pdf14_accum pdf14_accum_CMYKspot = {
749
    prn_device_stype_body(gx_device_pdf14_accum,
750
                          pdf14_accum_initialize_device_procs_cmykspot,
751
                          "pdf14-accum-CMYKspot",
752
                          &st_gx_devn_accum_device,
753
                          0/*width*/, 0/*height*/, 300/*xdpi*/, 300/*ydpi*/,
754
                          0/*lm*/, 0/*bm*/, 0/*rm*/, 0/*tm*/,
755
                          4/*ncomp*/, 32/*depth*/, 255/*max_gray*/, 255/*max_color*/,
756
                          256/*dither_grays*/, 256/*dither_colors*/,
757
                          no_print_page),
758
    /* DeviceN parameters */
759
    { 8,      /* Not used - Bits per color */
760
      DeviceCMYKComponents, /* Names of color model colorants */
761
      4,      /* Number colorants for CMYK */
762
      0,      /* MaxSeparations has not been specified */
763
      -1,     /* PageSpotColors has not been specified */
764
      { 0 },      /* SeparationNames */
765
      0,      /* SeparationOrder names */
766
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
767
    },
768
    { true },     /* equivalent_cmyk_color_params */
769
    0/*save_p14dev*/
770
};
771
772
/* GC procedures */
773
static
774
0
ENUM_PTRS_WITH(pdf14_device_enum_ptrs, pdf14_device *pdev)
775
0
{
776
0
    index -= 5;
777
0
    if (index < pdev->devn_params.separations.num_separations)
778
0
        ENUM_RETURN(pdev->devn_params.separations.names[index].data);
779
0
    index -= pdev->devn_params.separations.num_separations;
780
0
    if (index < pdev->devn_params.pdf14_separations.num_separations)
781
0
        ENUM_RETURN(pdev->devn_params.pdf14_separations.names[index].data);
782
0
    return 0;
783
0
}
784
0
case 0: return ENUM_OBJ(pdev->ctx);
785
0
case 1: return ENUM_OBJ(pdev->color_model_stack);
786
0
case 2: return ENUM_OBJ(pdev->smaskcolor);
787
0
case 3: ENUM_RETURN(gx_device_enum_ptr(pdev->target));
788
0
case 4: ENUM_RETURN(gx_device_enum_ptr(pdev->pclist_device));
789
0
ENUM_PTRS_END
790
791
0
static  RELOC_PTRS_WITH(pdf14_device_reloc_ptrs, pdf14_device *pdev)
792
0
{
793
0
    {
794
0
        int i;
795
796
0
        for (i = 0; i < pdev->devn_params.separations.num_separations; ++i) {
797
0
            RELOC_PTR(pdf14_device, devn_params.separations.names[i].data);
798
0
        }
799
0
    }
800
0
    RELOC_VAR(pdev->ctx);
801
0
    RELOC_VAR(pdev->smaskcolor);
802
0
    RELOC_VAR(pdev->color_model_stack);
803
0
    pdev->target = gx_device_reloc_ptr(pdev->target, gcst);
804
0
    pdev->pclist_device = gx_device_reloc_ptr(pdev->pclist_device, gcst);
805
0
}
806
0
RELOC_PTRS_END
807
808
/* ------ Private definitions ------ */
809
810
static void
811
resolve_matte(pdf14_buf *maskbuf, byte *src_data, intptr_t src_planestride, intptr_t src_rowstride,
812
              int width, int height, cmm_profile_t *src_profile, int deep)
813
1.05k
{
814
1.05k
    if (deep) {
815
0
        int x, y, i;
816
0
        uint16_t *mask_row_ptr  = (uint16_t *)maskbuf->data;
817
0
        uint16_t *src_row_ptr   = (uint16_t *)src_data;
818
0
        uint16_t *mask_tr_fn    = (uint16_t *)maskbuf->transfer_fn;
819
820
0
        src_planestride >>= 1;
821
0
        src_rowstride >>= 1;
822
823
0
        for (y = 0; y < height; y++) {
824
0
            uint16_t *mask_curr_ptr = mask_row_ptr;
825
0
            uint16_t *src_curr_ptr = src_row_ptr;
826
0
            for (x = 0; x < width; x++) {
827
0
                uint16_t idx = *mask_curr_ptr;
828
0
                byte     top = idx>>8;
829
0
                uint16_t a   = mask_tr_fn[top];
830
0
                int      b   = mask_tr_fn[top+1]-a;
831
0
                uint16_t matte_alpha = a + ((0x80 + b*(idx & 0xff))>>8);
832
833
                /* matte's happen rarely enough that we allow ourselves to
834
                 * resort to 64bit here. */
835
0
                if (matte_alpha != 0 && matte_alpha != 0xffff) {
836
0
                    for (i = 0; i < src_profile->num_comps; i++) {
837
0
                        int val = src_curr_ptr[i * src_planestride] - maskbuf->matte[i];
838
0
                        int temp = (((int64_t)val) * 0xffff / matte_alpha) + maskbuf->matte[i];
839
840
                        /* clip */
841
0
                        if (temp > 0xffff)
842
0
                            src_curr_ptr[i * src_planestride] = 0xffff;
843
0
                        else if (temp < 0)
844
0
                            src_curr_ptr[i * src_planestride] = 0;
845
0
                        else
846
0
                            src_curr_ptr[i * src_planestride] = temp;
847
0
                    }
848
0
                }
849
0
                mask_curr_ptr++;
850
0
                src_curr_ptr++;
851
0
            }
852
0
            src_row_ptr += src_rowstride;
853
0
            mask_row_ptr += (maskbuf->rowstride>>1);
854
0
        }
855
1.05k
    } else {
856
1.05k
        int x, y, i;
857
1.05k
        byte *mask_row_ptr  = maskbuf->data;
858
1.05k
        byte *src_row_ptr   = src_data;
859
1.05k
        byte *mask_tr_fn    = maskbuf->transfer_fn;
860
861
13.6k
        for (y = 0; y < height; y++) {
862
12.5k
            byte *mask_curr_ptr = mask_row_ptr;
863
12.5k
            byte *src_curr_ptr = src_row_ptr;
864
15.8M
            for (x = 0; x < width; x++) {
865
15.8M
                byte matte_alpha = mask_tr_fn[*mask_curr_ptr];
866
15.8M
                if (matte_alpha != 0 && matte_alpha != 0xff) {
867
8.23M
                    for (i = 0; i < src_profile->num_comps; i++) {
868
6.17M
                        byte matte = maskbuf->matte[i]>>8;
869
6.17M
                        int val = src_curr_ptr[i * src_planestride] - matte;
870
6.17M
                        int temp = ((((val * 0xff) << 8) / matte_alpha) >> 8) + matte;
871
872
                        /* clip */
873
6.17M
                        if (temp > 0xff)
874
4.29M
                            src_curr_ptr[i * src_planestride] = 0xff;
875
1.87M
                        else if (temp < 0)
876
0
                            src_curr_ptr[i * src_planestride] = 0;
877
1.87M
                        else
878
1.87M
                            src_curr_ptr[i * src_planestride] = temp;
879
6.17M
                    }
880
2.05M
                }
881
15.8M
                mask_curr_ptr++;
882
15.8M
                src_curr_ptr++;
883
15.8M
            }
884
12.5k
            src_row_ptr += src_rowstride;
885
12.5k
            mask_row_ptr += maskbuf->rowstride;
886
12.5k
        }
887
1.05k
    }
888
1.05k
}
889
890
/* Transform of color data and copy noncolor data.  Used in
891
   group pop and during the pdf14 put image calls when the blend color space
892
   is different than the target device color space.  The function will try do
893
   in-place conversion if possible.  If not, it will do an allocation.  The
894
   put_image call needs to know if an allocation was made so that it can adjust
895
   for the fact that we likely don't have a full page any longer and we don't
896
   need to do the offset to our data in the buffer. Bug 700686: If we are in
897
   a softmask that includes a matte entry, then we need to undo the matte
898
   entry here at this time in the image's native color space not the parent
899
   color space.   The endian_swap term here is only set to true if the data
900
   has been baked as BE during the put_image blending operation and we are
901
   on a LE machine.  */
902
static forceinline pdf14_buf*
903
template_transform_color_buffer(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
904
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
905
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
906
    bool has_matte, bool deep, bool endian_swap, int num_channels_to_lose)
907
10.9k
{
908
10.9k
    gsicc_rendering_param_t rendering_params;
909
10.9k
    gsicc_link_t *icc_link;
910
10.9k
    gsicc_bufferdesc_t src_buff_desc;
911
10.9k
    gsicc_bufferdesc_t des_buff_desc;
912
10.9k
    intptr_t src_planestride = src_buf->planestride;
913
10.9k
    intptr_t src_rowstride = src_buf->rowstride;
914
10.9k
    int src_n_planes = src_buf->n_planes;
915
10.9k
    int src_n_chan = src_buf->n_chan;
916
10.9k
    intptr_t des_planestride = src_planestride;
917
10.9k
    intptr_t des_rowstride = src_rowstride;
918
10.9k
    int des_n_planes = src_n_planes;
919
10.9k
    int des_n_chan = src_n_chan;
920
10.9k
    int diff;
921
10.9k
    int k, j;
922
10.9k
    byte *des_data = NULL;
923
10.9k
    pdf14_buf *output = src_buf;
924
10.9k
    pdf14_mask_t *mask_stack;
925
10.9k
    pdf14_buf *maskbuf;
926
10.9k
    int code;
927
928
10.9k
    *did_alloc = false;
929
930
    /* Same profile */
931
10.9k
    if (gsicc_get_hash(src_profile) == gsicc_get_hash(des_profile))
932
0
        return src_buf;
933
934
    /* Define the rendering intent get the link */
935
10.9k
    rendering_params.black_point_comp = gsBLACKPTCOMP_ON;
936
10.9k
    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
937
10.9k
    rendering_params.override_icc = false;
938
10.9k
    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
939
10.9k
    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;  /* Use relative intent */
940
10.9k
    rendering_params.cmm = gsCMM_DEFAULT;
941
10.9k
    icc_link = gsicc_get_link_profile(pgs, dev, src_profile, des_profile,
942
10.9k
        &rendering_params, pgs->memory, false);
943
10.9k
    if (icc_link == NULL)
944
0
        return NULL;
945
946
    /* If different data sizes, we have to do an allocation */
947
10.9k
    diff = des_profile->num_comps - src_profile->num_comps;
948
10.9k
    if (diff != 0) {
949
10.4k
        byte *src_ptr;
950
10.4k
        byte *des_ptr;
951
952
10.4k
        *did_alloc = true;
953
10.4k
        des_rowstride = ((width + 3) & -4)<<deep;
954
10.4k
        des_planestride = height * des_rowstride;
955
10.4k
        des_n_planes = src_n_planes + diff - num_channels_to_lose;
956
10.4k
        des_n_chan = src_n_chan + diff;
957
10.4k
        des_data = gs_alloc_bytes(ctx->memory,
958
10.4k
                                  des_planestride * des_n_planes + CAL_SLOP,
959
10.4k
                                  "pdf14_transform_color_buffer");
960
10.4k
        if (des_data == NULL)
961
0
            return NULL;
962
963
        /* Copy over the noncolor planes. May only be a dirty part, so have
964
           to copy row by row */
965
10.4k
        src_ptr = src_data;
966
10.4k
        des_ptr = des_data;
967
112k
        for (j = 0; j < height; j++) {
968
205k
            for (k = 0; k < (src_n_planes - src_profile->num_comps); k++) {
969
102k
                memcpy(des_ptr + des_planestride * (k + des_profile->num_comps - num_channels_to_lose),
970
102k
                       src_ptr + src_planestride * (k + src_profile->num_comps),
971
102k
                       width<<deep);
972
102k
            }
973
102k
            src_ptr += src_rowstride;
974
102k
            des_ptr += des_rowstride;
975
102k
        }
976
10.4k
    } else
977
479
        des_data = src_data;
978
979
    /* Set up the buffer descriptors. */
980
10.9k
    gsicc_init_buffer(&src_buff_desc, src_profile->num_comps, 1<<deep, false,
981
10.9k
                      false, true, src_planestride, src_rowstride, height, width);
982
10.9k
    gsicc_init_buffer(&des_buff_desc, des_profile->num_comps, 1<<deep, false,
983
10.9k
                      false, true, des_planestride, des_rowstride, height, width);
984
985
10.9k
    src_buff_desc.endian_swap = endian_swap;
986
10.9k
    des_buff_desc.endian_swap = endian_swap;
987
988
    /* If we have a matte entry, undo the pre-blending now.  Also set pdf14
989
       context to ensure that this is not done again during the group
990
       composition */
991
10.9k
    if (has_matte &&
992
        /* Should always happen, but check for safety */
993
1.20k
        ((mask_stack = ctx->mask_stack) != NULL) &&
994
1.20k
        ((maskbuf = mask_stack->mask_buf) != NULL) &&
995
1.20k
         (maskbuf->data != NULL))
996
1.05k
    {
997
1.05k
        resolve_matte(maskbuf, src_data, src_planestride, src_rowstride, width, height, src_profile, deep);
998
1.05k
    }
999
1000
    /* Transform the data. Since the pdf14 device should be using RGB, CMYK or
1001
       Gray buffers, this transform does not need to worry about the cmap procs
1002
       of the target device. */
1003
10.9k
    code = (icc_link->procs.map_buffer)(dev, icc_link, &src_buff_desc, &des_buff_desc,
1004
10.9k
        src_data, des_data);
1005
10.9k
    gsicc_release_link(icc_link);
1006
10.9k
    if (code < 0)
1007
0
        return NULL;
1008
1009
10.9k
    output->planestride = des_planestride;
1010
10.9k
    output->rowstride = des_rowstride;
1011
10.9k
    output->n_planes = des_n_planes;
1012
10.9k
    output->n_chan = des_n_chan;
1013
    /* If not in-place conversion, then release. */
1014
10.9k
    if (des_data != src_data) {
1015
10.4k
        gs_free_object(ctx->memory, output->data,
1016
10.4k
            "pdf14_transform_color_buffer");
1017
10.4k
        output->data = des_data;
1018
        /* Note, this is needed for case where we did a put image, as the
1019
           resulting transformed buffer may not be a full page. */
1020
10.4k
        output->rect.p.x = x0;
1021
10.4k
        output->rect.p.y = y0;
1022
10.4k
        output->rect.q.x = x0 + width;
1023
10.4k
        output->rect.q.y = y0 + height;
1024
10.4k
    }
1025
10.9k
    return output;
1026
10.9k
}
1027
1028
/* This is a routine to do memset's but with 16 bit values.
1029
 * Note, that we still take bytes, NOT "num values to set".
1030
 * We assume dest is 16 bit aligned. We assume that bytes is
1031
 * a multiple of 2. */
1032
static void gs_memset16(byte *dest_, uint16_t value, int bytes)
1033
0
{
1034
0
    uint16_t *dest = (uint16_t *)(void *)dest_;
1035
0
    uint32_t v;
1036
0
    if (bytes < 0)
1037
0
        return;
1038
0
    if (((intptr_t)dest) & 2) {
1039
0
        *dest++ = value;
1040
0
        bytes--;
1041
0
        if (bytes == 0)
1042
0
            return;
1043
0
    }
1044
0
    v = value | (value<<16);
1045
0
    bytes -= 2;
1046
0
    while (bytes > 0) {
1047
0
        *(uint32_t *)dest = v;
1048
0
        dest += 2;
1049
0
        bytes -= 4;
1050
0
    }
1051
0
    bytes += 2;
1052
0
    if (bytes & 2) {
1053
0
        *dest = value;
1054
0
    }
1055
0
}
1056
1057
static pdf14_buf*
1058
pdf14_transform_color_buffer_no_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1059
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1060
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1061
    bool deep, bool endian_swap, int num_channels_to_lose)
1062
9.70k
{
1063
9.70k
    if (deep)
1064
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1065
0
            des_profile, x0, y0, width, height, did_alloc, false, true, endian_swap, num_channels_to_lose);
1066
9.70k
    else
1067
9.70k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1068
9.70k
            des_profile, x0, y0, width, height, did_alloc, false, false, endian_swap, num_channels_to_lose);
1069
9.70k
}
1070
1071
static pdf14_buf*
1072
pdf14_transform_color_buffer_with_matte(gs_gstate *pgs, pdf14_ctx *ctx, gx_device *dev,
1073
    pdf14_buf *src_buf, byte *src_data, cmm_profile_t *src_profile,
1074
    cmm_profile_t *des_profile, int x0, int y0, int width, int height, bool *did_alloc,
1075
    bool deep, bool endian_swap)
1076
1.20k
{
1077
1.20k
    if (deep)
1078
0
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1079
0
            des_profile, x0, y0, width, height, did_alloc, true, true, endian_swap, false);
1080
1.20k
    else
1081
1.20k
        return template_transform_color_buffer(pgs, ctx, dev, src_buf, src_data, src_profile,
1082
1.20k
            des_profile, x0, y0, width, height, did_alloc, true, false, endian_swap, false);
1083
1.20k
}
1084
1085
/**
1086
 * pdf14_buf_new: Allocate a new PDF 1.4 buffer.
1087
 * @n_chan: Number of pixel channels including alpha, but not including
1088
 * shape, group alpha, or tags.
1089
 *
1090
 * Return value: Newly allocated buffer, or NULL on failure.
1091
 **/
1092
static  pdf14_buf *
1093
pdf14_buf_new(gs_int_rect *rect, bool has_tags, bool has_alpha_g,
1094
              bool has_shape, bool idle, int n_chan, int num_spots,
1095
              gs_memory_t *memory, bool deep)
1096
3.19M
{
1097
1098
    /* Note that alpha_g is the alpha for the GROUP */
1099
    /* This is distinct from the alpha that may also exist */
1100
    /* for the objects within the group.  Hence it can introduce */
1101
    /* yet another plane */
1102
1103
3.19M
    pdf14_buf *result;
1104
3.19M
    int64_t rowstride = ((size_t)((rect->q.x - rect->p.x + 3) & -4))<<deep;
1105
3.19M
    int64_t height = (rect->q.y - rect->p.y);
1106
3.19M
    int n_planes = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0) +
1107
3.19M
                   (has_tags ? 1 : 0);
1108
3.19M
    size_t planestride;
1109
#if ARCH_SIZEOF_SIZE_T <= 4
1110
    int64_t dsize = rowstride * height * n_planes;
1111
1112
    if (dsize > max_size_t)
1113
        return NULL;
1114
#endif
1115
1116
3.19M
    result = gs_alloc_struct(memory, pdf14_buf, &st_pdf14_buf,
1117
3.19M
                             "pdf14_buf_new");
1118
3.19M
    if (result == NULL)
1119
0
        return result;
1120
1121
3.19M
    result->memory = memory;
1122
3.19M
    result->backdrop = NULL;
1123
3.19M
    result->saved = NULL;
1124
3.19M
    result->isolated = false;
1125
3.19M
    result->knockout = false;
1126
3.19M
    result->has_alpha_g = has_alpha_g;
1127
3.19M
    result->has_shape = has_shape;
1128
3.19M
    result->has_tags = has_tags;
1129
3.19M
    result->rect = *rect;
1130
3.19M
    result->n_chan = n_chan;
1131
3.19M
    result->n_planes = n_planes;
1132
3.19M
    result->rowstride = rowstride;
1133
3.19M
    result->transfer_fn = NULL;
1134
3.19M
    result->is_ident = true;
1135
3.19M
    result->matte_num_comps = 0;
1136
3.19M
    result->matte = NULL;
1137
3.19M
    result->mask_stack = NULL;
1138
3.19M
    result->idle = idle;
1139
3.19M
    result->mask_id = 0;
1140
3.19M
    result->num_spots = num_spots;
1141
3.19M
    result->deep = deep;
1142
3.19M
    result->page_group = false;
1143
3.19M
    result->group_color_info = NULL;
1144
3.19M
    result->group_popped = false;
1145
1146
3.19M
    if (idle || height <= 0) {
1147
        /* Empty clipping - will skip all drawings. */
1148
1.57M
        result->planestride = 0;
1149
1.57M
        result->data = 0;
1150
1.62M
    } else {
1151
1.62M
        planestride = rowstride * height;
1152
1.62M
        result->planestride = planestride;
1153
1.62M
        result->data = gs_alloc_bytes(memory,
1154
1.62M
                                      planestride * n_planes + CAL_SLOP,
1155
1.62M
                                      "pdf14_buf_new");
1156
1.62M
        if (result->data == NULL) {
1157
0
            gs_free_object(memory, result, "pdf14_buf_new");
1158
0
            return NULL;
1159
0
        }
1160
1.62M
        if (has_alpha_g) {
1161
381k
            int alpha_g_plane = n_chan + (has_shape ? 1 : 0);
1162
            /* Memsetting by 0, so this copes with the deep case too */
1163
381k
            memset(result->data + alpha_g_plane * planestride, 0, planestride);
1164
381k
        }
1165
1.62M
        if (has_tags) {
1166
0
            int tags_plane = n_chan + (has_shape ? 1 : 0) + (has_alpha_g ? 1 : 0);
1167
            /* Memsetting by 0, so this copes with the deep case too */
1168
0
            memset (result->data + tags_plane * planestride,
1169
0
                    GS_UNTOUCHED_TAG, planestride);
1170
0
        }
1171
1.62M
    }
1172
    /* Initialize dirty box with an invalid rectangle (the reversed rectangle).
1173
     * Any future drawing will make it valid again, so we won't blend back
1174
     * more than we need. */
1175
3.19M
    result->dirty.p.x = rect->q.x;
1176
3.19M
    result->dirty.p.y = rect->q.y;
1177
3.19M
    result->dirty.q.x = rect->p.x;
1178
3.19M
    result->dirty.q.y = rect->p.y;
1179
3.19M
    return result;
1180
3.19M
}
1181
1182
static  void
1183
pdf14_buf_free(pdf14_buf *buf)
1184
3.19M
{
1185
3.19M
    pdf14_group_color_t *group_color_info = buf->group_color_info;
1186
3.19M
    gs_memory_t *memory = buf->memory;
1187
1188
3.19M
    if (buf->mask_stack)
1189
3.19M
        rc_decrement(buf->mask_stack, "pdf14_buf_free");
1190
1191
3.19M
    gs_free_object(memory, buf->transfer_fn, "pdf14_buf_free");
1192
3.19M
    gs_free_object(memory, buf->matte, "pdf14_buf_free");
1193
3.19M
    gs_free_object(memory, buf->data, "pdf14_buf_free");
1194
1195
6.38M
    while (group_color_info) {
1196
3.19M
       if (group_color_info->icc_profile != NULL) {
1197
3.19M
           gsicc_adjust_profile_rc(group_color_info->icc_profile, -1, "pdf14_buf_free");
1198
3.19M
       }
1199
3.19M
       buf->group_color_info = group_color_info->previous;
1200
3.19M
       gs_free_object(memory, group_color_info, "pdf14_buf_free");
1201
3.19M
       group_color_info = buf->group_color_info;
1202
3.19M
    }
1203
1204
3.19M
    gs_free_object(memory, buf->backdrop, "pdf14_buf_free");
1205
3.19M
    gs_free_object(memory, buf, "pdf14_buf_free");
1206
3.19M
}
1207
1208
static  pdf14_ctx *
1209
pdf14_ctx_new(gx_device *dev, bool deep)
1210
1.02M
{
1211
1.02M
    pdf14_ctx *result;
1212
1.02M
    gs_memory_t *memory = dev->memory->stable_memory;
1213
1214
1.02M
    result = gs_alloc_struct(memory, pdf14_ctx, &st_pdf14_ctx, "pdf14_ctx_new");
1215
1.02M
    if (result == NULL)
1216
0
        return result;
1217
1.02M
    result->stack = NULL;
1218
1.02M
    result->mask_stack = pdf14_mask_element_new(memory);
1219
1.02M
    if (result->mask_stack == NULL) {
1220
0
        gs_free_object(memory, result, "pdf14_ctx_new");
1221
0
        return NULL;
1222
0
    }
1223
1.02M
    result->memory = memory;
1224
1.02M
    result->smask_depth = 0;
1225
1.02M
    result->smask_blend = false;
1226
1.02M
    result->deep = deep;
1227
1.02M
    result->base_color = NULL;
1228
1.02M
    return result;
1229
1.02M
}
1230
1231
static  void
1232
pdf14_ctx_free(pdf14_ctx *ctx)
1233
1.02M
{
1234
1.02M
    pdf14_buf *buf, *next;
1235
1236
1.02M
    if (ctx->base_color) {
1237
535k
       gsicc_adjust_profile_rc(ctx->base_color->icc_profile, -1, "pdf14_ctx_free");
1238
535k
        gs_free_object(ctx->memory, ctx->base_color, "pdf14_ctx_free");
1239
535k
    }
1240
1.02M
    if (ctx->mask_stack) {
1241
        /* A mask was created but was not used in this band. */
1242
491k
        rc_decrement(ctx->mask_stack, "pdf14_ctx_free");
1243
491k
    }
1244
1.89M
    for (buf = ctx->stack; buf != NULL; buf = next) {
1245
873k
        next = buf->saved;
1246
873k
        pdf14_buf_free(buf);
1247
873k
    }
1248
1.02M
    gs_free_object (ctx->memory, ctx, "pdf14_ctx_free");
1249
1.02M
}
1250
1251
/**
1252
 * pdf14_find_backdrop_buf: Find backdrop buffer.
1253
 *
1254
 * Return value: Backdrop buffer for current group operation, or NULL
1255
 * if backdrop is fully transparent.
1256
 **/
1257
static  pdf14_buf *
1258
pdf14_find_backdrop_buf(pdf14_ctx *ctx, bool *is_backdrop)
1259
895k
{
1260
    /* Our new buffer is buf */
1261
895k
    pdf14_buf *buf = ctx->stack;
1262
1263
895k
    *is_backdrop = false;
1264
1265
895k
    if (buf != NULL) {
1266
        /* If the new buffer is isolated there is no backdrop */
1267
895k
        if (buf->isolated) return NULL;
1268
1269
        /* If the previous buffer is a knockout group
1270
           then we need to use its backdrop as the backdrop. If
1271
           it was isolated then that back drop was NULL */
1272
381k
        if (buf->saved != NULL && buf->saved->knockout) {
1273
            /* Per the spec, if we have a non-isolated group
1274
               in a knockout group the non-isolated group
1275
               uses the backdrop of its parent group (the knockout group)
1276
               as its own backdrop.  The non-isolated group must
1277
               go through the standard re-composition operation
1278
               to avoid the double application of the backdrop */
1279
244
            *is_backdrop = true;
1280
244
            return buf->saved;
1281
244
        }
1282
        /* This should be the non-isolated case where its parent is
1283
           not a knockout */
1284
381k
        if (buf->saved != NULL) {
1285
381k
            return buf->saved;
1286
381k
        }
1287
381k
    }
1288
0
    return NULL;
1289
895k
}
1290
1291
static pdf14_group_color_t*
1292
pdf14_make_base_group_color(gx_device* dev)
1293
535k
{
1294
535k
    pdf14_device* pdev = (pdf14_device*)dev;
1295
535k
    pdf14_group_color_t* group_color;
1296
535k
    bool deep = pdev->ctx->deep;
1297
535k
    bool has_tags = device_encodes_tags(dev);
1298
1299
535k
    if_debug0m('v', dev->memory, "[v]pdf14_make_base_group_color\n");
1300
1301
535k
    group_color = gs_alloc_struct(pdev->ctx->memory,
1302
535k
        pdf14_group_color_t, &st_pdf14_clr,
1303
535k
        "pdf14_make_base_group_color");
1304
1305
535k
    if (group_color == NULL)
1306
0
        return NULL;
1307
535k
    memset(group_color, 0, sizeof(pdf14_group_color_t));
1308
1309
535k
    group_color->num_std_colorants = pdev->num_std_colorants;
1310
535k
    group_color->blend_procs = pdev->blend_procs;
1311
535k
    group_color->polarity = pdev->color_info.polarity;
1312
535k
    group_color->num_components = pdev->color_info.num_components - has_tags;
1313
535k
    group_color->isadditive = pdev->ctx->additive;
1314
535k
    group_color->unpack_procs = pdev->pdf14_procs;
1315
535k
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
1316
535k
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
1317
535k
    group_color->depth = pdev->color_info.depth;
1318
535k
    group_color->decode = dev_proc(pdev, decode_color);
1319
535k
    group_color->encode = dev_proc(pdev, encode_color);
1320
535k
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
1321
535k
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
1322
535k
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
1323
535k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1324
535k
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
1325
535k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1326
535k
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
1327
535k
    group_color->icc_profile =
1328
535k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1329
535k
    gsicc_adjust_profile_rc(group_color->icc_profile, 1, "pdf14_make_base_group_color");
1330
1331
535k
    return group_color;
1332
535k
}
1333
1334
/* This wil create the first buffer when we have
1335
   either the first drawing operation or transparency
1336
   group push.  At that time, the color space in which
1337
   we are going to be doing the alpha blend will be known. */
1338
static int
1339
pdf14_initialize_ctx(gx_device* dev, const gs_gstate* pgs)
1340
378M
{
1341
378M
    pdf14_device *pdev = (pdf14_device *)dev;
1342
378M
    bool has_tags = device_encodes_tags(dev);
1343
378M
    int n_chan = pdev->color_info.num_components - has_tags;
1344
378M
    bool additive = pdev->color_info.polarity != GX_CINFO_POLARITY_SUBTRACTIVE;
1345
378M
    int num_spots = pdev->ctx->num_spots;
1346
378M
    pdf14_buf* buf;
1347
378M
    gs_memory_t* memory = dev->memory->stable_memory;
1348
1349
    /* Check for a blank idle group as a base group */
1350
378M
    if (pdev->ctx->stack != NULL && pdev->ctx->stack->group_popped &&
1351
0
        pdev->ctx->stack->idle) {
1352
0
        pdf14_buf_free(pdev->ctx->stack);
1353
0
        pdev->ctx->stack = NULL;
1354
0
    }
1355
1356
378M
    if (pdev->ctx->stack != NULL)
1357
377M
        return 0;
1358
1359
378M
    if_debug2m('v', dev->memory, "[v]pdf14_initialize_ctx: width = %d, height = %d\n",
1360
478k
        dev->width, dev->height);
1361
1362
478k
    buf = pdf14_buf_new(&(pdev->ctx->rect), has_tags, false, false, false, n_chan + 1,
1363
478k
        num_spots, memory, pdev->ctx->deep);
1364
478k
    if (buf == NULL) {
1365
0
        return gs_error_VMerror;
1366
0
    }
1367
478k
    if_debug5m('v', memory,
1368
478k
        "[v]base buf: %d x %d, %d color channels, %d planes, deep=%d\n",
1369
478k
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes, pdev->ctx->deep);
1370
1371
478k
    memset(buf->data, 0, buf->planestride * (buf->n_planes - !!has_tags));
1372
478k
    buf->saved = NULL;
1373
478k
    pdev->ctx->stack = buf;
1374
478k
    pdev->ctx->additive = additive;
1375
1376
    /* Every buffer needs group color information including the base
1377
       one that is created for when we have no group */
1378
478k
    buf->group_color_info = gs_alloc_struct(pdev->memory->stable_memory,
1379
478k
            pdf14_group_color_t, &st_pdf14_clr, "pdf14_initialize_ctx");
1380
478k
    if (buf->group_color_info == NULL)
1381
0
        return gs_error_VMerror;
1382
1383
478k
    if (pgs != NULL)
1384
246k
        buf->group_color_info->get_cmap_procs = pgs->get_cmap_procs;
1385
232k
    else
1386
232k
        buf->group_color_info->get_cmap_procs = pdf14_get_cmap_procs;
1387
1388
478k
    buf->group_color_info->group_color_mapping_procs =
1389
478k
        dev_proc(pdev, get_color_mapping_procs);
1390
478k
    buf->group_color_info->group_color_comp_index =
1391
478k
        dev_proc(pdev, get_color_comp_index);
1392
478k
    buf->group_color_info->blend_procs = pdev->blend_procs;
1393
478k
    buf->group_color_info->polarity = pdev->color_info.polarity;
1394
478k
    buf->group_color_info->num_components = pdev->color_info.num_components - has_tags;
1395
478k
    buf->group_color_info->isadditive = pdev->ctx->additive;
1396
478k
    buf->group_color_info->unpack_procs = pdev->pdf14_procs;
1397
478k
    buf->group_color_info->depth = pdev->color_info.depth;
1398
478k
    buf->group_color_info->max_color = pdev->color_info.max_color;
1399
478k
    buf->group_color_info->max_gray = pdev->color_info.max_gray;
1400
478k
    buf->group_color_info->encode = dev_proc(pdev, encode_color);
1401
478k
    buf->group_color_info->decode = dev_proc(pdev, decode_color);
1402
478k
    memcpy(&(buf->group_color_info->comp_bits), &(pdev->color_info.comp_bits),
1403
478k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1404
478k
    memcpy(&(buf->group_color_info->comp_shift), &(pdev->color_info.comp_shift),
1405
478k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
1406
478k
    buf->group_color_info->previous = NULL;  /* used during clist writing */
1407
478k
    buf->group_color_info->icc_profile =
1408
478k
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
1409
478k
    if (buf->group_color_info->icc_profile != NULL)
1410
478k
        gsicc_adjust_profile_rc(buf->group_color_info->icc_profile, 1, "pdf14_initialize_ctx");
1411
1412
478k
    return 0;
1413
478k
}
1414
1415
static pdf14_group_color_t*
1416
pdf14_clone_group_color_info(gx_device* pdev, pdf14_group_color_t* src)
1417
18.8k
{
1418
18.8k
    pdf14_group_color_t* des = gs_alloc_struct(pdev->memory->stable_memory,
1419
18.8k
        pdf14_group_color_t, &st_pdf14_clr, "pdf14_clone_group_color_info");
1420
18.8k
    if (des == NULL)
1421
0
        return NULL;
1422
1423
18.8k
    memcpy(des, src, sizeof(pdf14_group_color_t));
1424
18.8k
    if (des->icc_profile != NULL)
1425
18.8k
        gsicc_adjust_profile_rc(des->icc_profile, 1, "pdf14_clone_group_color_info");
1426
18.8k
    des->previous = NULL;  /* used during clist writing for state stack */
1427
1428
18.8k
    return des;
1429
18.8k
}
1430
1431
static  int
1432
pdf14_push_transparency_group(pdf14_ctx *ctx, gs_int_rect *rect, bool isolated,
1433
                              bool knockout, uint16_t alpha, uint16_t shape, uint16_t opacity,
1434
                              gs_blend_mode_t blend_mode, bool idle, uint mask_id,
1435
                              int numcomps, bool cm_back_drop, bool shade_group,
1436
                              cmm_profile_t *group_profile, cmm_profile_t *tos_profile,
1437
                              pdf14_group_color_t* group_color, gs_gstate *pgs,
1438
                              gx_device *dev)
1439
2.29M
{
1440
2.29M
    pdf14_buf *tos = ctx->stack;
1441
2.29M
    pdf14_buf *buf, * pdf14_backdrop;
1442
2.29M
    bool has_shape = false;
1443
2.29M
    bool is_backdrop;
1444
2.29M
    int num_spots;
1445
1446
2.29M
    if_debug1m('v', ctx->memory,
1447
2.29M
               "[v]pdf14_push_transparency_group, idle = %d\n", idle);
1448
1449
2.29M
    if (tos != NULL)
1450
1.89M
        has_shape = tos->has_shape || tos->knockout;
1451
1452
2.29M
    if (ctx->smask_depth > 0)
1453
1.41k
        num_spots = 0;
1454
2.29M
    else
1455
2.29M
        num_spots = ctx->num_spots;
1456
1457
1458
2.29M
    buf = pdf14_buf_new(rect, ctx->has_tags, !isolated, has_shape, idle, numcomps + 1,
1459
2.29M
                        num_spots, ctx->memory, ctx->deep);
1460
2.29M
    if (buf == NULL)
1461
0
        return_error(gs_error_VMerror);
1462
1463
2.29M
    if_debug4m('v', ctx->memory,
1464
2.29M
        "[v]base buf: %d x %d, %d color channels, %d planes\n",
1465
2.29M
        buf->rect.q.x, buf->rect.q.y, buf->n_chan, buf->n_planes);
1466
2.29M
    buf->isolated = isolated;
1467
2.29M
    buf->knockout = knockout;
1468
2.29M
    buf->alpha = alpha;
1469
2.29M
    buf->shape = shape;
1470
2.29M
    buf->opacity = opacity;
1471
2.29M
    buf->blend_mode = blend_mode;
1472
2.29M
    buf->mask_id = mask_id;
1473
2.29M
    buf->mask_stack = ctx->mask_stack; /* Save because the group rendering may
1474
                                          set up another (nested) mask. */
1475
2.29M
    ctx->mask_stack = NULL; /* Clean the mask field for rendering this group.
1476
                            See pdf14_pop_transparency_group how to handle it. */
1477
2.29M
    buf->saved = tos;
1478
2.29M
    buf->group_color_info = group_color;
1479
1480
2.29M
    if (tos == NULL)
1481
395k
        buf->page_group = true;
1482
1483
2.29M
    ctx->stack = buf;
1484
2.29M
    if (buf->data == NULL)
1485
1.39M
        return 0;
1486
895k
    if (idle)
1487
0
        return 0;
1488
895k
    pdf14_backdrop = pdf14_find_backdrop_buf(ctx, &is_backdrop);
1489
1490
    /* Initializes buf->data with the backdrop or as opaque */
1491
895k
    if (pdf14_backdrop == NULL || (is_backdrop && pdf14_backdrop->backdrop == NULL)) {
1492
        /* Note, don't clear out tags set by pdf14_buf_new == GS_UNKNOWN_TAG */
1493
        /* Memsetting by 0, so this copes with the deep case too */
1494
514k
        memset(buf->data, 0, buf->planestride *
1495
514k
                                          (buf->n_chan +
1496
514k
                                           (buf->has_shape ? 1 : 0) +
1497
514k
                                           (buf->has_alpha_g ? 1 : 0)));
1498
514k
    } else {
1499
381k
        if (!cm_back_drop) {
1500
381k
            pdf14_preserve_backdrop(buf, pdf14_backdrop, is_backdrop
1501
#if RAW_DUMP
1502
                                    , ctx->memory
1503
#endif
1504
381k
                                    );
1505
381k
        } else {
1506
            /* We must have an non-isolated group with a mismatch in color spaces.
1507
                In this case, we can't just copy the buffer but must CM it */
1508
0
            pdf14_preserve_backdrop_cm(buf, group_profile, pdf14_backdrop, tos_profile,
1509
0
                                        ctx->memory, pgs, dev, is_backdrop);
1510
0
        }
1511
381k
    }
1512
1513
    /* If our new group is a non-isolated knockout group, we have to maintain
1514
       a copy of the backdrop in case we are drawing nonisolated groups on top of the
1515
       knockout group. They have to always blend with the groups backdrop
1516
       not what is currently drawn in the group. Selection of the backdrop
1517
       depends upon the properties of the parent group. For example, if
1518
       the parent itself is a knockout group we actually
1519
       need to blend with its backdrop. This could be NULL if the parent was
1520
       an isolated knockout group. */
1521
895k
    if (buf->knockout && pdf14_backdrop != NULL) {
1522
34.8k
        buf->backdrop = gs_alloc_bytes(ctx->memory,
1523
34.8k
                                       buf->planestride * buf->n_planes + CAL_SLOP,
1524
34.8k
                                       "pdf14_push_transparency_group");
1525
34.8k
        if (buf->backdrop == NULL) {
1526
0
            return gs_throw(gs_error_VMerror, "Knockout backdrop allocation failed");
1527
0
        }
1528
1529
34.8k
        memcpy(buf->backdrop, buf->data,
1530
34.8k
               buf->planestride * buf->n_planes);
1531
1532
#if RAW_DUMP
1533
        /* Dump the current buffer to see what we have. */
1534
        dump_raw_buffer(ctx->memory,
1535
            ctx->stack->rect.q.y - ctx->stack->rect.p.y,
1536
            ctx->stack->rowstride >> buf->deep, buf->n_planes,
1537
            ctx->stack->planestride, ctx->stack->rowstride,
1538
            "KnockoutBackDrop", buf->backdrop, buf->deep);
1539
        global_index++;
1540
#endif
1541
34.8k
    }
1542
#if RAW_DUMP
1543
    /* Dump the current buffer to see what we have. */
1544
    dump_raw_buffer(ctx->memory,
1545
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1546
                    ctx->stack->rowstride>>buf->deep, ctx->stack->n_planes,
1547
                    ctx->stack->planestride, ctx->stack->rowstride,
1548
                    "TransGroupPush", ctx->stack->data, buf->deep);
1549
    global_index++;
1550
#endif
1551
895k
    return 0;
1552
895k
}
1553
1554
static  int
1555
pdf14_pop_transparency_group(gs_gstate *pgs, pdf14_ctx *ctx,
1556
    const pdf14_nonseparable_blending_procs_t * pblend_procs,
1557
    int tos_num_color_comp, cmm_profile_t *curr_icc_profile, gx_device *dev)
1558
2.29M
{
1559
2.29M
    pdf14_buf *tos = ctx->stack;
1560
2.29M
    pdf14_buf *nos = tos->saved;
1561
2.29M
    pdf14_mask_t *mask_stack = tos->mask_stack;
1562
2.29M
    pdf14_buf *maskbuf;
1563
2.29M
    int x0, x1, y0, y1;
1564
2.29M
    int nos_num_color_comp;
1565
2.29M
    bool no_icc_match;
1566
2.29M
    pdf14_device *pdev = (pdf14_device *)dev;
1567
2.29M
    bool overprint = pdev->overprint;
1568
2.29M
    gx_color_index drawn_comps = pdev->drawn_comps_stroke | pdev->drawn_comps_fill;
1569
2.29M
    bool has_matte = false;
1570
2.29M
    int code = 0;
1571
1572
#ifdef DEBUG
1573
    pdf14_debug_mask_stack_state(ctx);
1574
#endif
1575
2.29M
    maskbuf = (mask_stack == NULL) ? NULL : mask_stack->mask_buf;
1576
2.29M
    if (maskbuf != NULL && maskbuf->matte != NULL)
1577
3.69k
        has_matte = true;
1578
1579
    /* Check if this is our last buffer, if yes, there is nothing to
1580
       compose to.  Keep this buffer until we have the put image.
1581
       If we have another group push, this group must be destroyed.
1582
       This only occurs sometimes when at clist creation time
1583
       push_shfill_group occured and nothing was drawn in this group.
1584
       There is also the complication if we have a softmask.  There
1585
       are two approaches to this problem.  Apply the softmask during
1586
       the put image or handle it now.  I choose the later as the
1587
       put_image code is already way to complicated. */
1588
2.29M
    if (nos == NULL && maskbuf == NULL) {
1589
394k
        tos->group_popped = true;
1590
394k
        return 0;
1591
394k
    }
1592
1593
    /* Here is the case with the soft mask.  Go ahead and create a new
1594
       target buffer (nos) with the same color information etc, but blank
1595
       and go ahead and do the blend with the softmask so that it gets applied. */
1596
1.89M
    if (nos == NULL && maskbuf != NULL) {
1597
0
        nos = pdf14_buf_new(&(tos->rect), ctx->has_tags, !tos->isolated, tos->has_shape,
1598
0
            tos->idle, tos->n_chan, tos->num_spots, ctx->memory, ctx->deep);
1599
0
        if (nos == NULL) {
1600
0
            code = gs_error_VMerror;
1601
0
            goto exit;
1602
0
        }
1603
1604
0
        if_debug4m('v', ctx->memory,
1605
0
            "[v] special buffer for softmask application: %d x %d, %d color channels, %d planes\n",
1606
0
            nos->rect.q.x, nos->rect.q.y, nos->n_chan, nos->n_planes);
1607
1608
0
        nos->dirty = tos->dirty;
1609
0
        nos->isolated = tos->isolated;
1610
0
        nos->knockout = tos->knockout;
1611
0
        nos->alpha = 65535;
1612
0
        nos->shape = 65535;
1613
0
        nos->opacity = 65535;
1614
0
        nos->blend_mode = tos->blend_mode;
1615
0
        nos->mask_id = tos->mask_id;
1616
0
        nos->group_color_info = pdf14_clone_group_color_info(dev, tos->group_color_info);
1617
1618
0
        if (nos->data != NULL)
1619
0
            memset(nos->data, 0,
1620
0
                   nos->planestride * (nos->n_chan +
1621
0
                                       (nos->has_shape ? 1 : 0) +
1622
0
                                       (nos->has_alpha_g ? 1 : 0)));
1623
0
    }
1624
1625
    /* Before we get started, lets see if we have somehow gotten into
1626
       what should be an impossible situation where the group color
1627
       information does not match the buffer color information. This
1628
       can occur is there were memory issues that have perhaps blown
1629
       away information, or in the example of Bug 705197 the PDF interpreter
1630
       reuses a pattern during a circular reference causing an aliasing
1631
       of two nested patterns, one of which has a softmask. The change in
1632
       the buffer size of the inner one blows away the buffer of the
1633
       outer one leading to a mismatch of color spaces. Here
1634
       we can at least catch the case when the color space sizes have
1635
       changed and avoid buffer over-runs that would occur when we try
1636
       to do the group composition */
1637
1.89M
    if (nos->n_chan - 1 != nos->group_color_info->num_components ||
1638
1.89M
        tos->n_chan - 1 != tos_num_color_comp)
1639
0
        return_error(gs_error_Fatal);
1640
1641
1.89M
    nos_num_color_comp = nos->group_color_info->num_components - tos->num_spots;
1642
1.89M
    tos_num_color_comp = tos_num_color_comp - tos->num_spots;
1643
1644
    /* Sanitise the dirty rectangles, in case some of the drawing routines
1645
     * have made them overly large. */
1646
1.89M
    rect_intersect(tos->dirty, tos->rect);
1647
1.89M
    rect_intersect(nos->dirty, nos->rect);
1648
    /* dirty = the marked bbox. rect = the entire bounds of the buffer. */
1649
    /* Everything marked on tos that fits onto nos needs to be merged down. */
1650
1.89M
    y0 = max(tos->dirty.p.y, nos->rect.p.y);
1651
1.89M
    y1 = min(tos->dirty.q.y, nos->rect.q.y);
1652
1.89M
    x0 = max(tos->dirty.p.x, nos->rect.p.x);
1653
1.89M
    x1 = min(tos->dirty.q.x, nos->rect.q.x);
1654
1.89M
    if (ctx->mask_stack) {
1655
        /* This can occur when we have a situation where we are ending out of
1656
           a group that has internal to it a soft mask and another group.
1657
           The soft mask left over from the previous trans group pop is put
1658
           into ctx->masbuf, since it is still active if another trans group
1659
           push occurs to use it.  If one does not occur, but instead we find
1660
           ourselves popping from a parent group, then this softmask is no
1661
           longer needed.  We will rc_decrement and set it to NULL. */
1662
66
        rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_group");
1663
66
        ctx->mask_stack = NULL;
1664
66
    }
1665
1.89M
    ctx->mask_stack = mask_stack;  /* Restore the mask saved by pdf14_push_transparency_group. */
1666
1.89M
    tos->mask_stack = NULL;        /* Clean the pointer sinse the mask ownership is now passed to ctx. */
1667
1.89M
    if (tos->idle)
1668
1.37M
        goto exit;
1669
528k
    if (maskbuf != NULL && maskbuf->data == NULL && maskbuf->alpha == 255)
1670
0
        goto exit;
1671
1672
#if RAW_DUMP
1673
    /* Dump the current buffer to see what we have. */
1674
    dump_raw_buffer(ctx->memory,
1675
                    ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1676
                    ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1677
                    ctx->stack->planestride, ctx->stack->rowstride,
1678
                    "aaTrans_Group_Pop", ctx->stack->data, ctx->stack->deep);
1679
    global_index++;
1680
#endif
1681
/* Note currently if a pattern space has transparency, the ICC profile is not used
1682
   for blending purposes.  Instead we rely upon the gray, rgb, or cmyk parent space.
1683
   This is partially due to the fact that pdf14_pop_transparency_group and
1684
   pdf14_push_transparnecy_group have no real ICC interaction and those are the
1685
   operations called in the tile transparency code.  Instead we may want to
1686
   look at pdf14_begin_transparency_group and pdf14_end_transparency group which
1687
   is where all the ICC information is handled.  We will return to look at that later */
1688
528k
    if (nos->group_color_info->icc_profile != NULL) {
1689
528k
        no_icc_match = !gsicc_profiles_equal(nos->group_color_info->icc_profile, curr_icc_profile);
1690
528k
    } else {
1691
        /* Let the other tests make the decision if we need to transform */
1692
0
        no_icc_match = false;
1693
0
    }
1694
    /* If the color spaces are different and we actually did do a swap of
1695
       the procs for color */
1696
528k
    if ((nos->group_color_info->group_color_mapping_procs != NULL &&
1697
528k
        nos_num_color_comp != tos_num_color_comp) || no_icc_match) {
1698
3.66k
        if (x0 < x1 && y0 < y1) {
1699
3.42k
            pdf14_buf *result;
1700
3.42k
            bool did_alloc; /* We don't care here */
1701
1702
3.42k
            if (has_matte) {
1703
1.20k
                result = pdf14_transform_color_buffer_with_matte(pgs, ctx, dev,
1704
1.20k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1705
1.20k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1706
1.20k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false);
1707
1.20k
                has_matte = false;
1708
2.21k
            } else {
1709
2.21k
                result = pdf14_transform_color_buffer_no_matte(pgs, ctx, dev,
1710
2.21k
                    tos, tos->data, curr_icc_profile, nos->group_color_info->icc_profile,
1711
2.21k
                    tos->rect.p.x, tos->rect.p.y, tos->rect.q.x - tos->rect.p.x,
1712
2.21k
                    tos->rect.q.y - tos->rect.p.y, &did_alloc, tos->deep, false, false);
1713
2.21k
            }
1714
3.42k
            if (result == NULL) {
1715
                /* Clean up and return error code */
1716
0
                code = gs_error_unknownerror;
1717
0
                goto exit;
1718
0
            }
1719
1720
#if RAW_DUMP
1721
            /* Dump the current buffer to see what we have. */
1722
            dump_raw_buffer(ctx->memory,
1723
                            ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1724
                            ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_chan,
1725
                            ctx->stack->planestride, ctx->stack->rowstride,
1726
                            "aCMTrans_Group_ColorConv", ctx->stack->data,
1727
                            ctx->stack->deep);
1728
#endif
1729
             /* compose. never do overprint in this case */
1730
3.42k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1731
3.42k
                 nos->group_color_info->isadditive,
1732
3.42k
                 nos->group_color_info->blend_procs,
1733
3.42k
                 has_matte, false, drawn_comps, ctx->memory, dev);
1734
3.42k
        }
1735
524k
    } else {
1736
        /* Group color spaces are the same.  No color conversions needed */
1737
524k
        if (x0 < x1 && y0 < y1)
1738
314k
            pdf14_compose_group(tos, nos, maskbuf, x0, x1, y0, y1, nos->n_chan,
1739
314k
                                ctx->additive, pblend_procs, has_matte, overprint,
1740
314k
                                drawn_comps, ctx->memory, dev);
1741
524k
    }
1742
1.89M
exit:
1743
1.89M
    ctx->stack = nos;
1744
    /* We want to detect the cases where we have luminosity soft masks embedded
1745
       within one another.  The "alpha" channel really needs to be merged into
1746
       the luminosity channel in this case.  This will occur during the mask pop */
1747
1.89M
    if (ctx->smask_depth > 0 && maskbuf != NULL) {
1748
        /* Set the trigger so that we will blend if not alpha. Since
1749
           we have softmasks embedded in softmasks */
1750
546
        ctx->smask_blend = true;
1751
546
    }
1752
1.89M
    if_debug1m('v', ctx->memory, "[v]pop buf, idle=%d\n", tos->idle);
1753
1.89M
    pdf14_buf_free(tos);
1754
1.89M
    if (code < 0)
1755
0
        return_error(code);
1756
1.89M
    return 0;
1757
1.89M
}
1758
1759
/*
1760
 * Create a transparency mask that will be used as the mask for
1761
 * the next transparency group that is created afterwards.
1762
 * The sequence of calls is:
1763
 * push_mask, draw the mask, pop_mask, push_group, draw the group, pop_group
1764
 */
1765
static  int
1766
pdf14_push_transparency_mask(pdf14_ctx *ctx, gs_int_rect *rect, uint16_t bg_alpha,
1767
                             byte *transfer_fn, bool is_ident, bool idle,
1768
                             bool replacing, uint mask_id,
1769
                             gs_transparency_mask_subtype_t subtype,
1770
                             int numcomps, int Background_components,
1771
                             const float Background[], int Matte_components,
1772
                             const float Matte[], const float GrayBackground,
1773
                             pdf14_group_color_t* group_color)
1774
421k
{
1775
421k
    pdf14_buf *buf;
1776
421k
    int i;
1777
1778
421k
    if_debug2m('v', ctx->memory,
1779
421k
               "[v]pdf14_push_transparency_mask, idle=%d, replacing=%d\n",
1780
421k
               idle, replacing);
1781
421k
    ctx->smask_depth += 1;
1782
1783
421k
    if (ctx->stack == NULL) {
1784
0
        return_error(gs_error_VMerror);
1785
0
    }
1786
1787
    /* An optimization to consider is that if the SubType is Alpha
1788
       then we really should only be allocating the alpha band and
1789
       only draw with that channel.  Current architecture makes that
1790
       a bit tricky.  We need to create this based upon the size of
1791
       the color space + an alpha channel. NOT the device size
1792
       or the previous ctx size */
1793
    /* A mask doesn't worry about tags */
1794
421k
    buf = pdf14_buf_new(rect, false, false, false, idle, numcomps + 1, 0,
1795
421k
                        ctx->memory, ctx->deep);
1796
421k
    if (buf == NULL)
1797
0
        return_error(gs_error_VMerror);
1798
421k
    buf->alpha = bg_alpha;
1799
421k
    buf->is_ident = is_ident;
1800
    /* fill in, but these values aren't really used */
1801
421k
    buf->isolated = true;
1802
421k
    buf->knockout = false;
1803
421k
    buf->shape = 0xffff;
1804
421k
    buf->blend_mode = BLEND_MODE_Normal;
1805
421k
    buf->transfer_fn = transfer_fn;
1806
421k
    buf->matte_num_comps = Matte_components;
1807
421k
    buf->group_color_info = group_color;
1808
1809
421k
    if (Matte_components) {
1810
3.69k
        buf->matte = (uint16_t *)gs_alloc_bytes(ctx->memory, Matte_components * sizeof(uint16_t) + CAL_SLOP,
1811
3.69k
                                                "pdf14_push_transparency_mask");
1812
3.69k
        if (buf->matte == NULL)
1813
0
            return_error(gs_error_VMerror);
1814
14.7k
        for (i = 0; i < Matte_components; i++) {
1815
11.0k
            buf->matte[i] = (uint16_t) floor(Matte[i] * 65535.0 + 0.5);
1816
11.0k
        }
1817
3.69k
    }
1818
421k
    buf->mask_id = mask_id;
1819
    /* If replacing=false, we start the mask for an image with SMask.
1820
       In this case the image's SMask temporary replaces the
1821
       mask of the containing group. Save the containing droup's mask
1822
       in buf->mask_stack */
1823
421k
    buf->mask_stack = ctx->mask_stack;
1824
421k
    if (buf->mask_stack)
1825
421k
        rc_increment(buf->mask_stack);
1826
#if RAW_DUMP
1827
    /* Dump the current buffer to see what we have. */
1828
    if (ctx->stack->planestride > 0 ){
1829
        dump_raw_buffer(ctx->memory,
1830
                        ctx->stack->rect.q.y-ctx->stack->rect.p.y,
1831
                        ctx->stack->rowstride>>ctx->stack->deep, ctx->stack->n_planes,
1832
                        ctx->stack->planestride, ctx->stack->rowstride,
1833
                        "Raw_Buf_PreSmask", ctx->stack->data, ctx->stack->deep);
1834
        global_index++;
1835
    }
1836
#endif
1837
421k
    buf->saved = ctx->stack;
1838
421k
    ctx->stack = buf;
1839
    /* Soft Mask related information so we know how to
1840
       compute luminosity when we pop the soft mask */
1841
421k
    buf->SMask_SubType = subtype;
1842
421k
    if (buf->data != NULL) {
1843
        /* We need to initialize it to the BC if it existed */
1844
        /* According to the spec, the CS has to be the same */
1845
        /* If the back ground component is black, then don't bother
1846
           with this.  Since we are forcing the rendering to gray
1847
           earlier now, go ahead and just use the GrayBackGround color
1848
           directly. */
1849
247k
        if ( Background_components && GrayBackground != 0.0 ) {
1850
156
            if (buf->deep) {
1851
0
                uint16_t gray = (uint16_t) (65535.0 * GrayBackground);
1852
0
                gs_memset16(buf->data, gray, buf->planestride);
1853
                /* If we have a background component that was not black, then we
1854
                   need to set the alpha for this mask as if we had drawn in the
1855
                   entire soft mask buffer */
1856
0
                gs_memset16(buf->data + buf->planestride, 65535,
1857
0
                            buf->planestride *(buf->n_chan - 1));
1858
156
            } else {
1859
156
                unsigned char gray = (unsigned char) (255.0 * GrayBackground);
1860
156
                memset(buf->data, gray, buf->planestride);
1861
                /* If we have a background component that was not black, then we
1862
                   need to set the alpha for this mask as if we had drawn in the
1863
                   entire soft mask buffer */
1864
156
                memset(buf->data + buf->planestride, 255,
1865
156
                       buf->planestride * (buf->n_chan - 1));
1866
156
            }
1867
247k
        } else {
1868
            /* Compose mask with opaque background */
1869
247k
            memset(buf->data, 0, buf->planestride * buf->n_chan);
1870
247k
        }
1871
247k
    }
1872
421k
    return 0;
1873
421k
}
1874
1875
static  int
1876
pdf14_pop_transparency_mask(pdf14_ctx *ctx, gs_gstate *pgs, gx_device *dev)
1877
421k
{
1878
421k
    pdf14_buf* tos = ctx->stack;
1879
421k
    pdf14_buf* nos = tos->saved;
1880
421k
    byte *new_data_buf;
1881
421k
    int icc_match;
1882
421k
    cmm_profile_t *des_profile = nos->group_color_info->icc_profile; /* If set, this should be a gray profile */
1883
421k
    cmm_profile_t *src_profile;
1884
421k
    gsicc_rendering_param_t rendering_params;
1885
421k
    gsicc_link_t *icc_link;
1886
421k
    gsicc_rendering_param_t render_cond;
1887
421k
    cmm_dev_profile_t *dev_profile;
1888
421k
    int code = 0;
1889
1890
421k
    dev_proc(dev, get_profile)(dev,  &dev_profile);
1891
421k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &src_profile,
1892
421k
                          &render_cond);
1893
421k
    ctx->smask_depth -= 1;
1894
    /* icc_match == -1 means old non-icc code.
1895
       icc_match == 0 means use icc code
1896
       icc_match == 1 mean no conversion needed */
1897
421k
    if (des_profile != NULL && src_profile != NULL ) {
1898
421k
        icc_match = gsicc_profiles_equal(des_profile, src_profile);
1899
421k
    } else {
1900
0
        icc_match = -1;
1901
0
    }
1902
421k
    if_debug1m('v', ctx->memory, "[v]pdf14_pop_transparency_mask, idle=%d\n",
1903
421k
               tos->idle);
1904
421k
    ctx->stack = tos->saved;
1905
421k
    tos->saved = NULL;  /* To avoid issues with GC */
1906
421k
    if (tos->mask_stack) {
1907
        /* During the soft mask push, the mask_stack was copied (not moved) from
1908
           the ctx to the tos mask_stack. We are done with this now so it is safe to
1909
           just set to NULL.  However, before we do that we must perform
1910
           rc decrement to match the increment that occured was made.  Also,
1911
           if this is the last ref count of the rc_mask, we should free the
1912
           buffer now since no other groups need it. */
1913
109k
        rc_decrement(tos->mask_stack, "pdf14_pop_transparency_mask");
1914
109k
        tos->mask_stack = NULL;
1915
109k
    }
1916
1917
421k
    if (tos->data == NULL ) {
1918
        /* This can occur in clist rendering if the soft mask does
1919
           not intersect the current band.  It would be nice to
1920
           catch this earlier and just avoid creating the structure
1921
           to begin with.  For now we need to delete the structure
1922
           that was created.  Only delete if the alpha value is 65535 */
1923
174k
        if (ctx->mask_stack != NULL) {
1924
45.0k
            rc_decrement(ctx->mask_stack, "pdf14_free_mask_stack");
1925
45.0k
            ctx->mask_stack = NULL;
1926
45.0k
        }
1927
174k
        if ((tos->alpha == 65535 && tos->is_ident) ||
1928
174k
            (!tos->is_ident && (tos->transfer_fn[tos->alpha>>8] == 255))) {
1929
4.41k
            pdf14_buf_free(tos);
1930
169k
        } else {
1931
            /* Assign as mask buffer */
1932
169k
            ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
1933
169k
            if (ctx->mask_stack == NULL) {
1934
0
                pdf14_buf_free(tos);
1935
0
                return gs_note_error(gs_error_VMerror);
1936
0
            }
1937
169k
            ctx->mask_stack->mask_buf = tos;
1938
169k
        }
1939
174k
        ctx->smask_blend = false;  /* just in case */
1940
247k
    } else {
1941
        /* If we are already in the source space then there is no reason
1942
           to do the transformation */
1943
        /* Lets get this to a monochrome buffer and map it to a luminance only value */
1944
        /* This will reduce our memory.  We won't reuse the existing one, due */
1945
        /* Due to the fact that on certain systems we may have issues recovering */
1946
        /* the data after a resize */
1947
247k
        new_data_buf = gs_alloc_bytes(ctx->memory, tos->planestride + CAL_SLOP,
1948
247k
                                        "pdf14_pop_transparency_mask");
1949
247k
        if (new_data_buf == NULL) {
1950
0
            pdf14_buf_free(tos);
1951
0
            return_error(gs_error_VMerror);
1952
0
        }
1953
        /* Initialize with 0.  Need to do this since in Smask_Luminosity_Mapping
1954
           we won't be filling everything during the remap if it had not been
1955
           written into by the PDF14 fill rect */
1956
247k
        memset(new_data_buf, 0, tos->planestride);
1957
        /* If the subtype was alpha, then just grab the alpha channel now
1958
           and we are all done */
1959
247k
        if (tos->SMask_SubType == TRANSPARENCY_MASK_Alpha) {
1960
37.7k
            ctx->smask_blend = false;  /* not used in this case */
1961
37.7k
            smask_copy(tos->rect.q.y - tos->rect.p.y,
1962
37.7k
                       (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
1963
37.7k
                       tos->rowstride,
1964
37.7k
                       (tos->data)+tos->planestride, new_data_buf);
1965
#if RAW_DUMP
1966
            /* Dump the current buffer to see what we have. */
1967
            dump_raw_buffer(ctx->memory,
1968
                            tos->rect.q.y-tos->rect.p.y,
1969
                            tos->rowstride>>tos->deep, 1,
1970
                            tos->planestride, tos->rowstride,
1971
                            "SMask_Pop_Alpha(Mask_Plane1)",tos->data,
1972
                            tos->deep);
1973
            global_index++;
1974
#endif
1975
210k
        } else {
1976
210k
            if (icc_match == 1 || tos->n_chan == 2) {
1977
#if RAW_DUMP
1978
                /* Dump the current buffer to see what we have. */
1979
                dump_raw_buffer(ctx->memory,
1980
                                tos->rect.q.y-tos->rect.p.y,
1981
                                tos->rowstride>>tos->deep, tos->n_planes,
1982
                                tos->planestride, tos->rowstride,
1983
                                "SMask_Pop_Lum(Mask_Plane0)",tos->data,
1984
                                tos->deep);
1985
                global_index++;
1986
#endif
1987
                /* There is no need to color convert.  Data is already gray scale.
1988
                   We just need to copy the gray plane.  However it is
1989
                   possible that the soft mask could have a soft mask which
1990
                   would end us up with some alpha blending information
1991
                   (Bug691803). In fact, according to the spec, the alpha
1992
                   blending has to occur.  See FTS test fts_26_2601.pdf
1993
                   for an example of this.  Softmask buffer is intialized
1994
                   with BG values.  It would be nice to keep track if buffer
1995
                   ever has a alpha value not 1 so that we could detect and
1996
                   avoid this blend if not needed. */
1997
210k
                smask_blend(tos->data, tos->rect.q.x - tos->rect.p.x,
1998
210k
                            tos->rect.q.y - tos->rect.p.y, tos->rowstride,
1999
210k
                            tos->planestride, tos->deep);
2000
#if RAW_DUMP
2001
                /* Dump the current buffer to see what we have. */
2002
                dump_raw_buffer(ctx->memory,
2003
                                tos->rect.q.y-tos->rect.p.y,
2004
                                tos->rowstride>>tos->deep, 1,
2005
                                tos->planestride, tos->rowstride,
2006
                                "SMask_Pop_Lum_Post_Blend",tos->data,
2007
                                tos->deep);
2008
                global_index++;
2009
#endif
2010
210k
                smask_copy(tos->rect.q.y - tos->rect.p.y,
2011
210k
                           (tos->rect.q.x - tos->rect.p.x)<<tos->deep,
2012
210k
                           tos->rowstride, tos->data, new_data_buf);
2013
210k
            } else {
2014
0
                if ( icc_match == -1 ) {
2015
                    /* The slow old fashioned way */
2016
0
                    smask_luminosity_mapping(tos->rect.q.y - tos->rect.p.y ,
2017
0
                        tos->rect.q.x - tos->rect.p.x,tos->n_chan,
2018
0
                        tos->rowstride, tos->planestride,
2019
0
                        tos->data,  new_data_buf, ctx->additive, tos->SMask_SubType,
2020
0
                        tos->deep
2021
#if RAW_DUMP
2022
                        , ctx->memory
2023
#endif
2024
0
                        );
2025
0
                } else {
2026
                    /* ICC case where we use the CMM */
2027
                    /* Request the ICC link for the transform that we will need to use */
2028
0
                    rendering_params.black_point_comp = gsBLACKPTCOMP_OFF;
2029
0
                    rendering_params.graphics_type_tag = GS_IMAGE_TAG;
2030
0
                    rendering_params.override_icc = false;
2031
0
                    rendering_params.preserve_black = gsBKPRESNOTSPECIFIED;
2032
0
                    rendering_params.rendering_intent = gsRELATIVECOLORIMETRIC;
2033
0
                    rendering_params.cmm = gsCMM_DEFAULT;
2034
0
                    icc_link = gsicc_get_link_profile(pgs, dev, des_profile,
2035
0
                        src_profile, &rendering_params, pgs->memory, false);
2036
0
                    code = smask_icc(dev, tos->rect.q.y - tos->rect.p.y,
2037
0
                              tos->rect.q.x - tos->rect.p.x, tos->n_chan,
2038
0
                              tos->rowstride, tos->planestride,
2039
0
                              tos->data, new_data_buf, icc_link, tos->deep);
2040
                    /* Release the link */
2041
0
                    gsicc_release_link(icc_link);
2042
0
                }
2043
0
            }
2044
210k
        }
2045
        /* Free the old object, NULL test was above */
2046
247k
        gs_free_object(ctx->memory, tos->data, "pdf14_pop_transparency_mask");
2047
247k
        tos->data = new_data_buf;
2048
        /* Data is single channel now */
2049
247k
        tos->n_chan = 1;
2050
247k
        tos->n_planes = 1;
2051
        /* Assign as reference counted mask buffer */
2052
247k
        if (ctx->mask_stack != NULL) {
2053
            /* In this case, the source file is wacky as it already had a
2054
               softmask and now is getting a replacement. We need to clean
2055
               up the softmask stack before doing this free and creating
2056
               a new stack. Bug 693312 */
2057
63.9k
            rc_decrement(ctx->mask_stack, "pdf14_pop_transparency_mask(ctx->mask_stack)");
2058
63.9k
        }
2059
247k
        ctx->mask_stack = pdf14_mask_element_new(ctx->memory);
2060
247k
        if (ctx->mask_stack == NULL) {
2061
0
            pdf14_buf_free(tos);
2062
0
            return gs_note_error(gs_error_VMerror);
2063
0
        }
2064
247k
        ctx->mask_stack->mask_buf = tos;
2065
247k
    }
2066
421k
    return code;
2067
421k
}
2068
2069
static void
2070
rc_pdf14_mask_element_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
2071
1.44M
{
2072
    /* Ending the mask buffer. */
2073
1.44M
    pdf14_mask_t *mask = (pdf14_mask_t *)ptr_in;
2074
    /* free the pdf14 buffer. */
2075
1.44M
    if (mask->mask_buf != NULL) {
2076
119k
        pdf14_buf_free(mask->mask_buf);
2077
119k
    }
2078
1.44M
    gs_free_object(mem, mask, "rc_pdf14_mask_element_free");
2079
1.44M
}
2080
2081
static pdf14_mask_t *
2082
pdf14_mask_element_new(gs_memory_t *memory)
2083
1.44M
{
2084
1.44M
    pdf14_mask_t *result;
2085
2086
1.44M
    result = gs_alloc_struct(memory, pdf14_mask_t, &st_pdf14_mask,
2087
1.44M
                             "pdf14_mask_element_new");
2088
1.44M
    if (result == NULL)
2089
0
        return NULL;
2090
2091
1.44M
    rc_init_free(result, memory, 1, rc_pdf14_mask_element_free);
2092
2093
1.44M
    result->mask_buf = NULL;
2094
1.44M
    result->memory = memory;
2095
1.44M
    result->previous = NULL;
2096
2097
1.44M
    return result;
2098
1.44M
}
2099
2100
static int
2101
pdf14_push_transparency_state(gx_device *dev, gs_gstate *pgs)
2102
0
{
2103
    /* We need to push the current soft mask.  We need to
2104
       be able to recover it if we draw a new one and
2105
       then obtain a Q operation ( a pop ) */
2106
2107
0
    pdf14_device *pdev = (pdf14_device *)dev;
2108
0
    pdf14_ctx *ctx = pdev->ctx;
2109
0
    pdf14_mask_t *new_mask;
2110
2111
0
    if_debug0m('v', ctx->memory, "pdf14_push_transparency_state\n");
2112
    /* We need to push the current mask buffer   */
2113
    /* Allocate a new element for the stack.
2114
       Don't do anything if there is no mask present.*/
2115
0
    if (ctx->mask_stack != NULL) {
2116
0
        new_mask = pdf14_mask_element_new(ctx->memory);
2117
0
        if (new_mask == NULL)
2118
0
            return gs_note_error(gs_error_VMerror);
2119
0
        new_mask->previous = ctx->mask_stack;
2120
0
        ctx->mask_stack = new_mask;
2121
0
    }
2122
#ifdef DEBUG
2123
    pdf14_debug_mask_stack_state(pdev->ctx);
2124
#endif
2125
0
    return 0;
2126
0
}
2127
2128
static int
2129
pdf14_pop_transparency_state(gx_device *dev, gs_gstate *pgs)
2130
2.69M
{
2131
    /* Pop the soft mask.  It is no longer needed. Likely due to
2132
       a Q that has occurred. */
2133
2.69M
    pdf14_device *pdev = (pdf14_device *)dev;
2134
2.69M
    pdf14_ctx *ctx = pdev->ctx;
2135
2.69M
    pdf14_mask_t *old_mask;
2136
2137
2.69M
    if_debug0m('v', ctx->memory, "pdf14_pop_transparency_state\n");
2138
    /* rc decrement the current link after we break it from
2139
       the list, then free the stack element.  Don't do
2140
       anything if there is no mask present. */
2141
2.69M
    if (ctx->mask_stack != NULL) {
2142
447k
        old_mask = ctx->mask_stack;
2143
447k
        ctx->mask_stack = ctx->mask_stack->previous;
2144
447k
        rc_decrement(old_mask, "pdf14_pop_transparency_state");
2145
        /* We need to have some special handling here for when we have nested
2146
           soft masks.  There may be a copy in the stack that we may need to
2147
           adjust. */
2148
447k
        if (ctx->smask_depth > 0) {
2149
            /* RJW: This logic was introduced by mvrhel as:
2150
             *    if (ctx->stack != NULL && ctx->stack->mask_stack != NULL)
2151
             * back in commit f0208a3d621. Unfortunately no record exists of the bug
2152
             * that this was supposed to solve. Bug 709701 shows this up as being wrong
2153
             * in at least some cases. In that bug it overwrites a valid smask entry
2154
             * with a NULL one. So the fix, implemented here is never to overwrite
2155
             * with a NULL entry. This shows no diffs in the cluster. More information
2156
             * on the bug.
2157
             */
2158
286
            if (ctx->stack != NULL && ctx->mask_stack != NULL) {
2159
0
                ctx->stack->mask_stack = ctx->mask_stack;
2160
0
            }
2161
286
        }
2162
447k
    }
2163
#ifdef DEBUG
2164
    pdf14_debug_mask_stack_state(pdev->ctx);
2165
#endif
2166
2.69M
    return 0;
2167
2.69M
}
2168
2169
static  int
2170
pdf14_open(gx_device *dev)
2171
1.02M
{
2172
1.02M
    pdf14_device *pdev = (pdf14_device *)dev;
2173
2174
    /* If we are reenabling the device dont create a new ctx. Bug 697456 */
2175
1.02M
    if (pdev->ctx == NULL) {
2176
1.02M
        bool has_tags = device_encodes_tags(dev);
2177
1.02M
        int bits_per_comp = (dev->color_info.depth / dev->color_info.num_components);
2178
1.02M
        pdev->ctx = pdf14_ctx_new(dev, bits_per_comp > 8);
2179
1.02M
        if (pdev->ctx == NULL)
2180
0
            return_error(gs_error_VMerror);
2181
2182
1.02M
        pdev->ctx->rect.p.x = 0;
2183
1.02M
        pdev->ctx->rect.p.y = 0;
2184
1.02M
        pdev->ctx->rect.q.x = dev->width;
2185
1.02M
        pdev->ctx->rect.q.y = dev->height;
2186
1.02M
        pdev->ctx->has_tags = has_tags;
2187
1.02M
        pdev->ctx->num_spots = pdev->color_info.num_components - has_tags - pdev->num_std_colorants;
2188
        /* This can happen because pdev->num_std_colorants is not updated when pdev->color_info.num_components
2189
         * is. I am not sure how to fix that. */
2190
1.02M
        if (pdev->ctx->num_spots < 0)
2191
0
            pdev->ctx->num_spots = 0;
2192
1.02M
        pdev->ctx->additive = (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE);
2193
1.02M
    }
2194
1.02M
    pdev->free_devicen = true;
2195
1.02M
    pdev->text_group = PDF14_TEXTGROUP_NO_BT;
2196
1.02M
    return 0;
2197
1.02M
}
2198
2199
static const gx_cm_color_map_procs pdf14_DeviceCMYKspot_procs = {
2200
    pdf14_gray_cs_to_cmyk_cm, pdf14_rgb_cs_to_cmyk_cm, pdf14_cmyk_cs_to_cmyk_cm
2201
};
2202
2203
static const gx_cm_color_map_procs pdf14_DeviceRGBspot_procs = {
2204
    pdf14_gray_cs_to_rgbspot_cm, pdf14_rgb_cs_to_rgbspot_cm, pdf14_cmyk_cs_to_rgbspot_cm
2205
};
2206
2207
static const gx_cm_color_map_procs pdf14_DeviceGrayspot_procs = {
2208
    pdf14_gray_cs_to_grayspot_cm, pdf14_rgb_cs_to_grayspot_cm, pdf14_cmyk_cs_to_grayspot_cm
2209
};
2210
2211
static const gx_cm_color_map_procs *
2212
pdf14_cmykspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2213
8.33M
{
2214
8.33M
    *tdev = dev;
2215
8.33M
    return &pdf14_DeviceCMYKspot_procs;
2216
8.33M
}
2217
2218
static const gx_cm_color_map_procs *
2219
pdf14_rgbspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2220
2.90M
{
2221
2.90M
    *tdev = dev;
2222
2.90M
    return &pdf14_DeviceRGBspot_procs;
2223
2.90M
}
2224
2225
static const gx_cm_color_map_procs *
2226
pdf14_grayspot_get_color_mapping_procs(const gx_device * dev, const gx_device **tdev)
2227
0
{
2228
0
    *tdev = dev;
2229
0
    return &pdf14_DeviceGrayspot_procs;
2230
0
}
2231
2232
static void
2233
be_rev_cpy(uint16_t *dst,const uint16_t *src,int n)
2234
0
{
2235
0
    for (; n != 0; n--) {
2236
0
        uint16_t in = *src++;
2237
0
        ((byte *)dst)[0] = in>>8;
2238
0
        ((byte *)dst)[1] = in;
2239
0
        dst++;
2240
0
    }
2241
0
}
2242
2243
/* Used to pass along information about the buffer created by the
2244
   pdf14 device.  This is used by the pattern accumulator when the
2245
   pattern contains transparency.  Note that if free_device is true then
2246
   we need to go ahead and get the buffer data copied and free up the
2247
   device.  This only occurs at the end of a pattern accumulation operation */
2248
int
2249
pdf14_get_buffer_information(const gx_device * dev,
2250
                             gx_pattern_trans_t *transbuff, gs_memory_t *mem,
2251
                             bool free_device)
2252
24.0k
{
2253
24.0k
    const pdf14_device * pdev = (pdf14_device *)dev;
2254
24.0k
    pdf14_buf *buf;
2255
24.0k
    gs_int_rect rect;
2256
24.0k
    int x1,y1,width,height;
2257
2258
24.0k
    if ( pdev->ctx == NULL){
2259
0
        return 0;  /* this can occur if the pattern is a clist */
2260
0
    }
2261
#ifdef DEBUG
2262
    pdf14_debug_mask_stack_state(pdev->ctx);
2263
#endif
2264
24.0k
    buf = pdev->ctx->stack;
2265
24.0k
    rect = buf->rect;
2266
24.0k
    transbuff->buf = (free_device ? NULL : buf);
2267
24.0k
    x1 = min(pdev->width, rect.q.x);
2268
24.0k
    y1 = min(pdev->height, rect.q.y);
2269
24.0k
    width = x1 - rect.p.x;
2270
24.0k
    height = y1 - rect.p.y;
2271
2272
24.0k
    transbuff->n_chan    = buf->n_chan;
2273
24.0k
    transbuff->has_tags  = buf->has_tags;
2274
24.0k
    transbuff->has_shape = buf->has_shape;
2275
24.0k
    transbuff->width     = buf->rect.q.x - buf->rect.p.x;
2276
24.0k
    transbuff->height    = buf->rect.q.y - buf->rect.p.y;
2277
24.0k
    transbuff->deep      = buf->deep;
2278
2279
24.0k
    if (width <= 0 || height <= 0 || buf->data == NULL) {
2280
7.83k
        transbuff->planestride = 0;
2281
7.83k
        transbuff->rowstride = 0;
2282
7.83k
        return 0;
2283
7.83k
    }
2284
2285
16.2k
    if (free_device) {
2286
5.19k
        transbuff->pdev14 = NULL;
2287
5.19k
        transbuff->rect = rect;
2288
5.19k
        if ((width < transbuff->width) || (height < transbuff->height)) {
2289
            /* If the bbox is smaller than the whole buffer than go ahead and
2290
               create a new one to use.  This can occur if we drew in a smaller
2291
               area than was specified by the transparency group rect. */
2292
0
            intptr_t rowstride = ((width + 3) & -4)<<buf->deep;
2293
0
            intptr_t planestride = rowstride * height;
2294
0
            int k, j;
2295
0
            byte *buff_ptr_src, *buff_ptr_des;
2296
2297
0
            transbuff->planestride = planestride;
2298
0
            transbuff->rowstride = rowstride;
2299
0
            transbuff->transbytes =
2300
0
                         gs_alloc_bytes(mem,
2301
0
                                        planestride *
2302
0
                                                (buf->n_chan +
2303
0
                                                 (buf->has_tags ? 1 : 0)) + CAL_SLOP,
2304
0
                                        "pdf14_get_buffer_information");
2305
0
            if (transbuff->transbytes == NULL)
2306
0
                return gs_error_VMerror;
2307
2308
0
            transbuff->mem = mem;
2309
0
            if (transbuff->deep) {
2310
0
                for (j = 0; j < transbuff->n_chan; j++) {
2311
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2312
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2313
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2314
0
                    for (k = 0; k < height; k++) {
2315
0
                        be_rev_cpy((uint16_t *)buff_ptr_des, (const uint16_t *)buff_ptr_src, rowstride>>1);
2316
0
                        buff_ptr_des += rowstride;
2317
0
                        buff_ptr_src += buf->rowstride;
2318
0
                    }
2319
0
                }
2320
0
            } else {
2321
0
                for (j = 0; j < transbuff->n_chan; j++) {
2322
0
                    buff_ptr_src = buf->data + j * buf->planestride +
2323
0
                               buf->rowstride * rect.p.y + (rect.p.x<<buf->deep);
2324
0
                    buff_ptr_des = transbuff->transbytes + j * planestride;
2325
0
                    for (k = 0; k < height; k++) {
2326
0
                        memcpy(buff_ptr_des, buff_ptr_src, rowstride);
2327
0
                        buff_ptr_des += rowstride;
2328
0
                        buff_ptr_src += buf->rowstride;
2329
0
                    }
2330
0
                }
2331
0
            }
2332
2333
5.19k
        } else {
2334
            /* The entire buffer is used.  Go ahead and grab the pointer and
2335
               clear the pointer in the pdf14 device data buffer so it is not
2336
               freed when we close the device */
2337
5.19k
            transbuff->planestride = buf->planestride;
2338
5.19k
            transbuff->rowstride = buf->rowstride;
2339
5.19k
            transbuff->transbytes = buf->data;
2340
5.19k
            transbuff->mem = buf->memory;
2341
5.19k
            buf->data = NULL;  /* So that the buffer is not freed */
2342
5.19k
            if (transbuff->deep) {
2343
                /* We have the data in native endian. We need it in big endian. Do an in-place conversion. */
2344
                /* FIXME: This is a nop on big endian machines. Is the compiler smart enough to spot that? */
2345
0
                uint16_t *buff_ptr;
2346
0
                int j, k, z;
2347
0
                intptr_t rowstride = transbuff->rowstride>>1;
2348
0
                intptr_t planestride = transbuff->planestride;
2349
0
                for (j = 0; j < transbuff->n_chan; j++) {
2350
0
                    buff_ptr = (uint16_t *)(transbuff->transbytes + j * planestride);
2351
0
                    for (k = 0; k < height; k++) {
2352
0
                        for (z = 0; z < width; z++) {
2353
0
                            uint16_t in = buff_ptr[z];
2354
0
                            ((byte *)(&buff_ptr[z]))[0] = in>>8;
2355
0
                            ((byte *)(&buff_ptr[z]))[1] = in;
2356
0
                        }
2357
0
                        buff_ptr += rowstride;
2358
0
                    }
2359
0
                }
2360
0
            }
2361
5.19k
        }
2362
#if RAW_DUMP
2363
        /* Dump the buffer that should be going into the pattern */;
2364
        dump_raw_buffer_be(buf->memory,
2365
                           height, width, transbuff->n_chan,
2366
                           transbuff->planestride, transbuff->rowstride,
2367
                           "pdf14_pattern_buff", transbuff->transbytes,
2368
                           transbuff->deep);
2369
        global_index++;
2370
#endif
2371
        /* Go ahead and free up the pdf14 device */
2372
5.19k
        dev_proc(dev, close_device)((gx_device *)dev);
2373
11.0k
    } else {
2374
        /* Here we are coming from one of the fill image / pattern / mask
2375
           operations */
2376
11.0k
        transbuff->pdev14 = dev;
2377
11.0k
        transbuff->planestride = buf->planestride;
2378
11.0k
        transbuff->rowstride = buf->rowstride;
2379
11.0k
        transbuff->transbytes = buf->data;
2380
11.0k
        transbuff->mem = buf->memory;
2381
11.0k
        transbuff->rect = rect;
2382
#if RAW_DUMP
2383
    /* Dump the buffer that should be going into the pattern */;
2384
        dump_raw_buffer(buf->memory,
2385
                        height, width, buf->n_chan,
2386
                        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2387
                        "pdf14_pattern_buff",
2388
                        buf->data,
2389
                        transbuff->deep);
2390
        global_index++;
2391
#endif
2392
11.0k
    }
2393
16.2k
    return 0;
2394
16.2k
}
2395
2396
typedef void (blend_image_row_proc_t) (const byte *gs_restrict buf_ptr,
2397
    intptr_t planestride, int width, int num_comp, uint16_t bg, byte *gs_restrict linebuf);
2398
2399
2400
static int
2401
pdf14_put_image_color_convert(const pdf14_device* dev, gs_gstate* pgs, cmm_profile_t* src_profile,
2402
                        cmm_dev_profile_t* dev_target_profile, pdf14_buf** buf,
2403
                        byte** buf_ptr, bool was_blended, int x, int y, int width, int height, int num_channels_to_lose)
2404
7.48k
{
2405
7.48k
    pdf14_buf* cm_result = NULL;
2406
7.48k
    cmm_profile_t* des_profile;
2407
7.48k
    gsicc_rendering_param_t render_cond;
2408
7.48k
    bool did_alloc;
2409
7.48k
    bool endian_swap;
2410
2411
7.48k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_target_profile, &des_profile,
2412
7.48k
        &render_cond);
2413
2414
#if RAW_DUMP
2415
#if !ARCH_IS_BIG_ENDIAN
2416
    if (was_blended && (*buf)->deep)
2417
      dump_raw_buffer_be(dev->ctx->memory,
2418
          height, width, (*buf)->n_planes, (*buf)->planestride,
2419
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2420
    else
2421
#endif
2422
      dump_raw_buffer(dev->ctx->memory,
2423
          height, width, (*buf)->n_planes, (*buf)->planestride,
2424
          (*buf)->rowstride, "pdf14_put_image_color_convert_pre", *buf_ptr, (*buf)->deep);
2425
    global_index++;
2426
#endif
2427
2428
    /* If we are doing a 16 bit buffer it will be big endian if we have already done the
2429
       blend, otherwise it will be native endian. GS expects its 16bit buffers to be BE
2430
       but for sanity pdf14 device maintains 16bit buffers in native format.  The CMM
2431
       will need to know if it is dealing with native or BE data. */
2432
7.48k
    if (was_blended && (*buf)->deep) {
2433
        /* Data is in BE.  If we are in a LE machine, CMM will need to swap for
2434
           color conversion */
2435
#if ARCH_IS_BIG_ENDIAN
2436
        endian_swap = false;
2437
#else
2438
0
        endian_swap = true;
2439
0
#endif
2440
7.48k
    } else {
2441
        /* Data is in native format. No swap needed for CMM */
2442
7.48k
        endian_swap = false;
2443
7.48k
    }
2444
2445
7.48k
    cm_result = pdf14_transform_color_buffer_no_matte(pgs, dev->ctx, (gx_device*) dev, *buf,
2446
7.48k
        *buf_ptr, src_profile, des_profile, x, y, width,
2447
7.48k
        height, &did_alloc, (*buf)->deep, endian_swap, num_channels_to_lose);
2448
2449
7.48k
    if (cm_result == NULL)
2450
0
        return_error(gs_error_VMerror);
2451
2452
    /* Update */
2453
7.48k
    *buf = cm_result;
2454
2455
    /* Make sure our buf_ptr is pointing to the proper location */
2456
7.48k
    if (did_alloc)
2457
7.48k
        *buf_ptr = cm_result->data;  /* Note the lack of offset */
2458
2459
#if RAW_DUMP
2460
    dump_raw_buffer(dev->ctx->memory,
2461
        height, width, (*buf)->n_planes, (*buf)->planestride,
2462
        (*buf)->rowstride, "pdf14_put_image_color_convert_post", *buf_ptr, (*buf)->deep);
2463
    global_index++;
2464
#endif
2465
7.48k
    return 0;
2466
7.48k
}
2467
2468
/**
2469
 * pdf14_put_image: Put rendered image to target device.
2470
 * @pdev: The PDF 1.4 rendering device.
2471
 * @pgs: State for image draw operation.
2472
 * @target: The target device.
2473
 *
2474
 * Puts the rendered image in @pdev's buffer to @target. This is called
2475
 * as part of the sequence of popping the PDF 1.4 device filter.
2476
 *
2477
 * Return code: negative on error.
2478
 **/
2479
static  int
2480
pdf14_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
2481
947k
{
2482
947k
    const pdf14_device * pdev = (pdf14_device *)dev;
2483
947k
    int code;
2484
947k
    gs_image1_t image;
2485
947k
    gx_image_enum_common_t *info;
2486
947k
    pdf14_buf *buf = pdev->ctx->stack;
2487
947k
    gs_int_rect rect;
2488
947k
    int y;
2489
947k
    int num_comp;
2490
947k
    byte *linebuf, *linebuf_unaligned;
2491
947k
    gs_color_space *pcs;
2492
947k
    int x1, y1, width, height;
2493
947k
    byte *buf_ptr;
2494
947k
    int num_rows_left;
2495
947k
    cmm_profile_t* src_profile = NULL;
2496
947k
    cmm_profile_t* des_profile = NULL;
2497
947k
    cmm_dev_profile_t *pdf14dev_profile;
2498
947k
    cmm_dev_profile_t *dev_target_profile;
2499
947k
    uint16_t bg;
2500
947k
    bool has_tags = device_encodes_tags(dev);
2501
947k
    bool deep = pdev->ctx->deep;
2502
947k
    intptr_t planestride;
2503
947k
    intptr_t rowstride;
2504
947k
    blend_image_row_proc_t *blend_row;
2505
947k
    bool color_mismatch = false;
2506
947k
    bool supports_alpha = false;
2507
947k
    int i;
2508
947k
    int alpha_offset, tag_offset;
2509
947k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
2510
947k
    int rendering_intent_saved;
2511
947k
    int additive;
2512
2513
    /* Nothing was ever drawn. */
2514
947k
    if (buf == NULL)
2515
122k
        return 0;
2516
2517
825k
    additive = buf->group_color_info->isadditive;
2518
2519
825k
    src_profile = buf->group_color_info->icc_profile;
2520
2521
825k
    num_comp = buf->n_chan - 1;
2522
825k
    rect = buf->rect;
2523
825k
    planestride = buf->planestride;
2524
825k
    rowstride = buf->rowstride;
2525
2526
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
2527
       potential problem. Bug 694190 */
2528
825k
    if (buf->saved != NULL) {
2529
14
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
2530
14
    }
2531
825k
    if_debug0m('v', dev->memory, "[v]pdf14_put_image\n");
2532
825k
    rect_intersect(rect, buf->dirty);
2533
825k
    x1 = min(pdev->width, rect.q.x);
2534
825k
    y1 = min(pdev->height, rect.q.y);
2535
825k
    width = x1 - rect.p.x;
2536
825k
    height = y1 - rect.p.y;
2537
#ifdef DUMP_TO_PNG
2538
    dump_planar_rgba(pdev->memory, buf);
2539
#endif
2540
825k
    if (width <= 0 || height <= 0 || buf->data == NULL)
2541
206k
        return 0;
2542
618k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
2543
2544
    /* Check that target is OK.  From fuzzing results the target could have been
2545
       destroyed, for e.g if it were a pattern accumulator that was closed
2546
       prematurely (Bug 694154).  We should always be able to to get an ICC
2547
       profile from the target. */
2548
618k
    code = dev_proc(target, get_profile)(target,  &dev_target_profile);
2549
618k
    if (code < 0)
2550
0
        return code;
2551
618k
    if (dev_target_profile == NULL)
2552
0
        return gs_throw_code(gs_error_Fatal);
2553
2554
618k
    if (src_profile == NULL) {
2555
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
2556
0
        if (code < 0) {
2557
0
            return code;
2558
0
        }
2559
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2560
0
    }
2561
2562
    /* Check if we have a color conversion issue */
2563
618k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
2564
618k
    if (!gsicc_profiles_equal(des_profile, src_profile))
2565
106k
        color_mismatch = true;
2566
2567
    /* Check if target supports alpha */
2568
618k
    supports_alpha = dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0);
2569
618k
    code = 0;
2570
2571
#if RAW_DUMP
2572
    dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2573
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2574
        "pre_final_blend", buf_ptr, deep);
2575
#endif
2576
2577
    /* Note. The logic below will need a little rework if we ever
2578
       have a device that has tags and alpha support */
2579
618k
    if (supports_alpha) {
2580
0
        if (!color_mismatch) {
2581
0
            alpha_offset = num_comp;
2582
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2583
2584
0
            for (i = 0; i < buf->n_planes; i++)
2585
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2586
0
            for (; i < target->color_info.num_components; i++)
2587
0
                buf_ptrs[i] = 0;
2588
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2589
0
                rect.p.x, rect.p.y, width, height,
2590
0
                rowstride, alpha_offset,
2591
0
                tag_offset);
2592
            /* Right now code has number of rows written */
2593
0
        } else {
2594
            /* In this case, just color convert and maintain alpha.  This is a case
2595
               where we either either blend in the right color space and have no
2596
               alpha for the output device or hand back the wrong color space with
2597
               alpha data.  We choose the later. */
2598
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
2599
0
                dev_target_profile, &buf, &buf_ptr, false, rect.p.x, rect.p.y,
2600
0
                width, height, false);
2601
0
            if (code < 0)
2602
0
                return code;
2603
2604
            /* reset */
2605
0
            rowstride = buf->rowstride;
2606
0
            planestride = buf->planestride;
2607
0
            num_comp = buf->n_chan - 1;
2608
0
            alpha_offset = num_comp;
2609
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
2610
2611
            /* And then out */
2612
0
            for (i = 0; i < buf->n_planes; i++)
2613
0
                buf_ptrs[i] = buf_ptr + i * planestride;
2614
0
            for (; i < target->color_info.num_components; i++)
2615
0
                buf_ptrs[i] = 0;
2616
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2617
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2618
0
                tag_offset);
2619
            /* Right now code has number of rows written */
2620
0
        }
2621
618k
    } else if (has_tags) {
2622
        /* We are going out to a device that supports tags */
2623
0
        if (deep) {
2624
0
            gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
2625
0
                buf->planestride, num_comp, additive, false);
2626
0
        } else {
2627
0
            gx_blend_image_buffer(buf_ptr, width, height, rowstride,
2628
0
                buf->planestride, num_comp, additive);
2629
0
        }
2630
2631
#if RAW_DUMP
2632
        dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2633
            pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2634
            "post_final_blend", buf_ptr, deep);
2635
#endif
2636
2637
        /* Take care of color issues */
2638
0
        if (color_mismatch) {
2639
            /* In this case, just color convert and maintain alpha.  This is a case
2640
               where we either either blend in the right color space and have no
2641
               alpha for the output device or hand back the wrong color space with
2642
               alpha data.  We choose the later. */
2643
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
2644
0
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, false);
2645
0
            if (code < 0)
2646
0
                return code;
2647
2648
#if RAW_DUMP
2649
            dump_raw_buffer(pdev->ctx->memory, height, width, buf->n_planes,
2650
                pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2651
                "final_color_manage", buf_ptr, deep);
2652
            global_index++;
2653
#endif
2654
0
        }
2655
2656
        /* reset */
2657
0
        rowstride = buf->rowstride;
2658
0
        planestride = buf->planestride;
2659
0
        num_comp = buf->n_chan - 1;
2660
0
        alpha_offset = 0;  /* It is there but this indicates we have done the blend */
2661
0
        tag_offset = buf->has_tags ? buf->n_chan : 0;
2662
2663
        /* And then out */
2664
0
        for (i = 0; i < buf->n_planes; i++)
2665
0
            buf_ptrs[i] = buf_ptr + i * planestride;
2666
0
        for (; i < target->color_info.num_components; i++)
2667
0
            buf_ptrs[i] = 0;
2668
0
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2669
0
            rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
2670
0
            tag_offset);
2671
        /* Right now code has number of rows written */
2672
2673
0
    }
2674
2675
    /* If code > 0 then put image worked.  Let it finish and then exit */
2676
618k
    if (code > 0) {
2677
        /* We processed some or all of the rows.  Continue until we are done */
2678
0
        num_rows_left = height - code;
2679
0
        while (num_rows_left > 0) {
2680
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
2681
0
                                                rect.p.x, rect.p.y + code, width,
2682
0
                                                num_rows_left, rowstride,
2683
0
                                                alpha_offset, tag_offset);
2684
0
            num_rows_left = num_rows_left - code;
2685
0
        }
2686
0
        return 0;
2687
0
    }
2688
2689
    /* Target device did not support alpha or tags.
2690
     * Set color space in preparation for sending an image.
2691
     * color conversion will occur after blending with through
2692
     * the begin typed image work flow.
2693
     */
2694
2695
618k
    planestride = buf->planestride;
2696
618k
    rowstride = buf->rowstride;
2697
618k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
2698
618k
    if (code < 0)
2699
0
        return code;
2700
    /* Need to set this to avoid color management during the image color render
2701
       operation.  Exception is for the special case when the destination was
2702
       CIELAB.  Then we need to convert from default RGB to CIELAB in the put
2703
       image operation.  That will happen here as we should have set the profile
2704
       for the pdf14 device to RGB and the target will be CIELAB.  In addition,
2705
       the case when we have a blend color space that is different than the
2706
       target device color space */
2707
618k
    pcs->cmm_icc_profile_data = src_profile;
2708
2709
    /* pcs takes a reference to the profile data it just retrieved. */
2710
618k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_image");
2711
618k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
2712
0
        return_error(gs_error_rangecheck);
2713
2714
618k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
2715
618k
    gs_image_t_init_adjust(&image, pcs, false);
2716
618k
    image.ImageMatrix.xx = (float)width;
2717
618k
    image.ImageMatrix.yy = (float)height;
2718
618k
    image.Width = width;
2719
618k
    image.Height = height;
2720
618k
    image.BitsPerComponent = deep ? 16 : 8;
2721
618k
    image.ColorSpace = pcs;
2722
618k
    ctm_only_writable(pgs).xx = (float)width;
2723
618k
    ctm_only_writable(pgs).xy = 0;
2724
618k
    ctm_only_writable(pgs).yx = 0;
2725
618k
    ctm_only_writable(pgs).yy = (float)height;
2726
618k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
2727
618k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
2728
    /* Make sure that the relative colorimetric rendering intent is
2729
       used for this image. */
2730
618k
    rendering_intent_saved = pgs->renderingintent;
2731
618k
    pgs->renderingintent = gsRELATIVECOLORIMETRIC;
2732
618k
    code = dev_proc(target, begin_typed_image) (target,
2733
618k
                                                pgs, NULL,
2734
618k
                                                (gs_image_common_t *)&image,
2735
618k
                                                NULL, NULL, NULL,
2736
618k
                                                pgs->memory, &info);
2737
618k
    pgs->renderingintent = rendering_intent_saved;
2738
618k
    if (code < 0) {
2739
0
        rc_decrement_only_cs(pcs, "pdf14_put_image");
2740
0
        return code;
2741
0
    }
2742
#if RAW_DUMP
2743
    /* Dump the current buffer to see what we have. */
2744
    dump_raw_buffer(pdev->ctx->memory,
2745
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
2746
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
2747
                    pdev->ctx->stack->n_planes,
2748
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2749
                    "pdF14_putimage", pdev->ctx->stack->data, deep);
2750
    dump_raw_buffer(pdev->ctx->memory,
2751
                    height, width, buf->n_planes,
2752
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
2753
                    "PDF14_PUTIMAGE_SMALL", buf_ptr, deep);
2754
    global_index++;
2755
    clist_band_count++;
2756
#endif
2757
    /* Allocate on 32-byte border for AVX CMYK case. Four byte overflow for RGB case */
2758
    /* 28 byte overflow for AVX CMYK case. */
2759
618k
#define SSE_ALIGN 32
2760
618k
#define SSE_OVERFLOW 28
2761
618k
    linebuf_unaligned = gs_alloc_bytes(pdev->memory, width * (num_comp<<deep) + SSE_ALIGN + SSE_OVERFLOW, "pdf14_put_image");
2762
618k
    if (linebuf_unaligned == NULL)
2763
0
        return gs_error_VMerror;
2764
618k
    linebuf = linebuf_unaligned + ((-(intptr_t)linebuf_unaligned) & (SSE_ALIGN-1));
2765
2766
618k
    blend_row = deep ? gx_build_blended_image_row16 :
2767
618k
                       gx_build_blended_image_row;
2768
#ifdef WITH_CAL
2769
    blend_row = cal_get_blend_row(pdev->memory->gs_lib_ctx->core->cal_ctx,
2770
                                  blend_row, num_comp, deep);
2771
#endif
2772
2773
618k
    bg = additive ? (deep ? 65535 : 255) : 0;
2774
6.83M
    for (y = 0; y < height; y++) {
2775
6.21M
        gx_image_plane_t planes;
2776
6.21M
        int rows_used;
2777
2778
6.21M
        blend_row(buf_ptr, buf->planestride, width, num_comp, bg, linebuf);
2779
6.21M
        planes.data = linebuf;
2780
6.21M
        planes.data_x = 0;
2781
6.21M
        planes.raster = width * num_comp;
2782
6.21M
        info->procs->plane_data(info, &planes, 1, &rows_used);
2783
        /* todo: check return value */
2784
6.21M
        buf_ptr += buf->rowstride;
2785
6.21M
    }
2786
618k
    gs_free_object(pdev->memory, linebuf_unaligned, "pdf14_put_image");
2787
618k
    info->procs->end_image(info, true);
2788
    /* This will also decrement the device profile */
2789
618k
    rc_decrement_only_cs(pcs, "pdf14_put_image");
2790
618k
    return code;
2791
618k
}
2792
2793
/* Overprint simulation with spots.  Collapse to CMYK */
2794
static void
2795
template_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2796
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2797
    cmyk_composite_map *map, bool keep_alpha)
2798
0
{
2799
0
    int comp_num;
2800
0
    uint cyan, magenta, yellow, black;
2801
0
    cmyk_composite_map *cmyk_map_entry;
2802
0
    int x, y;
2803
0
    intptr_t position;
2804
0
    byte comp, a;
2805
2806
0
    for (y = 0; y < height; y++) {
2807
0
        position = y * rowstride;
2808
0
        for (x = 0; x < width; x++) {
2809
0
            a = buf_ptr[position + planestride * num_comp];
2810
0
            if (a != 0) {
2811
0
                cyan = buf_ptr[position] * frac_1;
2812
0
                magenta = buf_ptr[position + planestride] * frac_1;
2813
0
                yellow = buf_ptr[position + planestride * 2] * frac_1;
2814
0
                black = buf_ptr[position + planestride * 3] * frac_1;
2815
0
                cmyk_map_entry = &(map[4]);
2816
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2817
0
                    comp = buf_ptr[position + planestride * comp_num];
2818
0
                    cyan += cmyk_map_entry->c * comp;
2819
0
                    magenta += cmyk_map_entry->m * comp;
2820
0
                    yellow += cmyk_map_entry->y * comp;
2821
0
                    black += cmyk_map_entry->k * comp;
2822
0
                    cmyk_map_entry++;
2823
0
                }
2824
0
                cyan /= frac_1;
2825
0
                magenta /= frac_1;
2826
0
                yellow /= frac_1;
2827
0
                black /= frac_1;
2828
2829
0
                if (cyan > 255)
2830
0
                    cyan = 255;
2831
0
                if (magenta > 255)
2832
0
                    magenta = 255;
2833
0
                if (yellow > 255)
2834
0
                    yellow = 255;
2835
0
                if (black > 255)
2836
0
                    black = 255;
2837
2838
0
                buf_ptr[position] = cyan;
2839
0
                buf_ptr[position + planestride] = magenta;
2840
0
                buf_ptr[position + planestride * 2] = yellow;
2841
0
                buf_ptr[position + planestride * 3] = black;
2842
0
            }
2843
0
            if (keep_alpha) {
2844
                /* Move the alpha and tag data */
2845
0
                buf_ptr[position + planestride * 4] = a;
2846
0
                if (tag_offset > 0) {
2847
0
                    buf_ptr[position + planestride * 5] =
2848
0
                        buf_ptr[position + planestride * tag_offset];
2849
0
                }
2850
0
            } else {
2851
                /* Remove alpha but keep tags */
2852
0
                if (tag_offset > 0) {
2853
0
                    buf_ptr[position + planestride * 4] =
2854
0
                        buf_ptr[position + planestride * tag_offset];
2855
0
                }
2856
2857
0
            }
2858
0
            position += 1;
2859
0
        }
2860
0
    }
2861
0
}
2862
2863
static void
2864
template_spots_to_cmyk_16(byte *buf_ptr_, int width, int height, intptr_t rowstride,
2865
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2866
    cmyk_composite_map *map, bool keep_alpha)
2867
0
{
2868
0
    int comp_num;
2869
0
    ulong cyan, magenta, yellow, black;
2870
0
    cmyk_composite_map *cmyk_map_entry;
2871
0
    int x, y;
2872
0
    intptr_t position;
2873
0
    ulong comp, a;
2874
0
    uint16_t *buf_ptr = (uint16_t *)(void *)buf_ptr_;
2875
2876
    /* planestride and rowstride are in bytes, and we want them in shorts */
2877
0
    planestride >>= 1;
2878
0
    rowstride >>= 1;
2879
2880
0
    for (y = 0; y < height; y++) {
2881
0
        position = y * rowstride;
2882
0
        for (x = 0; x < width; x++) {
2883
0
            a = buf_ptr[position + planestride * num_comp];
2884
0
            if (a != 0) {
2885
0
                cyan = (ulong)buf_ptr[position] * frac_1_long;
2886
0
                magenta = (ulong)buf_ptr[position + planestride] * frac_1_long;
2887
0
                yellow = (ulong)buf_ptr[position + planestride * 2] * frac_1_long;
2888
0
                black = (ulong)buf_ptr[position + planestride * 3] * frac_1_long;
2889
0
                cmyk_map_entry = &(map[4]);
2890
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
2891
0
                    comp = buf_ptr[position + planestride * comp_num];
2892
0
                    cyan += (ulong)cmyk_map_entry->c * comp;
2893
0
                    magenta += (ulong)cmyk_map_entry->m * comp;
2894
0
                    yellow += (ulong)cmyk_map_entry->y * comp;
2895
0
                    black += (ulong)cmyk_map_entry->k * comp;
2896
0
                    cmyk_map_entry++;
2897
0
                }
2898
0
                cyan /= frac_1_long;
2899
0
                magenta /= frac_1_long;
2900
0
                yellow /= frac_1_long;
2901
0
                black /= frac_1_long;
2902
2903
0
                if (cyan > 65535)
2904
0
                    cyan = 65535;
2905
0
                if (magenta > 65535)
2906
0
                    magenta = 65535;
2907
0
                if (yellow > 65535)
2908
0
                    yellow = 65535;
2909
0
                if (black > 65535)
2910
0
                    black = 65535;
2911
2912
#if ARCH_IS_BIG_ENDIAN
2913
                buf_ptr[position] = cyan;
2914
                buf_ptr[position + planestride] = magenta;
2915
                buf_ptr[position + planestride * 2] = yellow;
2916
                buf_ptr[position + planestride * 3] = black;
2917
#else
2918
0
                ((byte *)&buf_ptr[position])[0] = cyan >> 8;
2919
0
                ((byte *)&buf_ptr[position])[1] = cyan;
2920
0
                ((byte *)&buf_ptr[position + planestride])[0] = magenta >> 8;
2921
0
                ((byte *)&buf_ptr[position + planestride])[1] = magenta;
2922
0
                ((byte *)&buf_ptr[position + planestride * 2])[0] = yellow >> 8;
2923
0
                ((byte *)&buf_ptr[position + planestride * 2])[1] = yellow;
2924
0
                ((byte *)&buf_ptr[position + planestride * 3])[0] = black >> 8;
2925
0
                ((byte *)&buf_ptr[position + planestride * 3])[1] = black;
2926
0
#endif
2927
0
            }
2928
            /* Move the alpha and tag data */
2929
#if ARCH_IS_BIG_ENDIAN
2930
            if (keep_alpha) {
2931
                buf_ptr[position + planestride * 4] = a;
2932
                if (tag_offset > 0) {
2933
                    buf_ptr[position + planestride * 5] =
2934
                        buf_ptr[position + planestride * tag_offset];
2935
                }
2936
            } else {
2937
                if (tag_offset > 0) {
2938
                    buf_ptr[position + planestride * 4] =
2939
                        buf_ptr[position + planestride * tag_offset];
2940
                }
2941
            }
2942
#else
2943
0
            if (keep_alpha) {
2944
0
                ((byte *)&buf_ptr[position + planestride * 4])[0] = a >> 8;
2945
0
                ((byte *)&buf_ptr[position + planestride * 4])[1] = a;
2946
0
                if (tag_offset > 0) {
2947
0
                    ((byte *)&buf_ptr[position + planestride * 5])[0] =
2948
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2949
0
                    ((byte *)&buf_ptr[position + planestride * 5])[1] =
2950
0
                        buf_ptr[position + planestride * tag_offset];
2951
0
                }
2952
0
            } else {
2953
0
                if (tag_offset > 0) {
2954
0
                    ((byte *)&buf_ptr[position + planestride * 4])[0] =
2955
0
                        buf_ptr[position + planestride * tag_offset] >> 8;
2956
0
                    ((byte *)&buf_ptr[position + planestride * 4])[1] =
2957
0
                        buf_ptr[position + planestride * tag_offset];
2958
0
                }
2959
0
            }
2960
0
#endif
2961
0
            position += 1;
2962
0
        }
2963
0
    }
2964
0
}
2965
2966
static void
2967
pdf14_spots_to_cmyk(byte *buf_ptr, int width, int height, intptr_t rowstride,
2968
    intptr_t planestride, int num_comp, int spot_start, int tag_offset,
2969
    cmyk_composite_map *map, bool keep_alpha, bool deep)
2970
0
{
2971
0
    if (deep) {
2972
0
        if (keep_alpha) {
2973
0
            if (tag_offset > 0) {
2974
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2975
0
                    planestride, num_comp, spot_start, tag_offset,
2976
0
                    map, true);
2977
0
            } else {
2978
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2979
0
                    planestride, num_comp, spot_start, 0,
2980
0
                    map, true);
2981
0
            }
2982
0
        } else {
2983
0
            if (tag_offset > 0) {
2984
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2985
0
                    planestride, num_comp, spot_start, tag_offset,
2986
0
                    map, false);
2987
0
            } else {
2988
0
                template_spots_to_cmyk_16(buf_ptr, width, height, rowstride,
2989
0
                    planestride, num_comp, spot_start, 0,
2990
0
                    map, false);
2991
0
            }
2992
0
        }
2993
0
    } else {
2994
0
        if (keep_alpha) {
2995
0
            if (tag_offset > 0) {
2996
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
2997
0
                    planestride, num_comp, spot_start, tag_offset,
2998
0
                    map, true);
2999
0
            } else {
3000
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3001
0
                    planestride, num_comp, spot_start, 0,
3002
0
                    map, true);
3003
0
            }
3004
0
        } else {
3005
0
            if (tag_offset > 0) {
3006
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3007
0
                    planestride, num_comp, spot_start, tag_offset,
3008
0
                    map, false);
3009
0
            } else {
3010
0
                template_spots_to_cmyk(buf_ptr, width, height, rowstride,
3011
0
                    planestride, num_comp, spot_start, 0,
3012
0
                    map, false);
3013
0
            }
3014
0
        }
3015
0
    }
3016
0
}
3017
3018
/* This is for the case where we have mixture of spots and additive color.
3019
   For example, RGB + spots or Gray + spots */
3020
static void
3021
pdf14_blend_image_mixed_buffer(byte* buf_ptr, int width, int height, intptr_t rowstride,
3022
    intptr_t planestride, int num_comp, int spot_start)
3023
7.48k
{
3024
7.48k
    int x, y;
3025
7.48k
    intptr_t position;
3026
7.48k
    byte comp, a;
3027
7.48k
    int tmp, comp_num;
3028
3029
77.4k
    for (y = 0; y < height; y++) {
3030
69.9k
        position = y * rowstride;
3031
61.5M
        for (x = 0; x < width; x++) {
3032
61.5M
            a = buf_ptr[position + planestride * num_comp];
3033
61.5M
            if ((a + 1) & 0xfe) {
3034
737k
                a ^= 0xff;
3035
2.94M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3036
2.21M
                    comp = buf_ptr[position + planestride * comp_num];
3037
2.21M
                    tmp = ((0xff - comp) * a) + 0x80;
3038
2.21M
                    comp += (tmp + (tmp >> 8)) >> 8;
3039
2.21M
                    buf_ptr[position + planestride * comp_num] = comp;
3040
2.21M
                }
3041
737k
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3042
0
                    comp = buf_ptr[position + planestride * comp_num];
3043
0
                    tmp = ((-comp) * a) + 0x80;
3044
0
                    comp += (tmp + (tmp >> 8)) >> 8;
3045
0
                    buf_ptr[position + planestride * comp_num] = comp;
3046
0
                }
3047
60.7M
            } else if (a == 0) {
3048
57.1M
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3049
42.8M
                    buf_ptr[position + planestride * comp_num] = 0xff;
3050
42.8M
                }
3051
14.3M
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3052
32.2k
                    buf_ptr[position + planestride * comp_num] = 0;
3053
32.2k
                }
3054
14.2M
            }
3055
61.5M
            position += 1;
3056
61.5M
        }
3057
69.9k
    }
3058
7.48k
}
3059
3060
static void
3061
pdf14_blend_image_mixed_buffer16(byte* buf_ptr_, int width, int height, intptr_t rowstride,
3062
    intptr_t planestride, int num_comp, int spot_start)
3063
0
{
3064
0
    uint16_t* buf_ptr = (uint16_t*)(void*)buf_ptr_;
3065
0
    int x, y;
3066
0
    intptr_t position;
3067
0
    int comp, a;
3068
0
    int tmp, comp_num;
3069
3070
    /* planestride and rowstride are in bytes, and we want them in shorts */
3071
0
    planestride >>= 1;
3072
0
    rowstride >>= 1;
3073
3074
    /* Note that the input here is native endian, and the output must be in big endian! */
3075
0
    for (y = 0; y < height; y++) {
3076
0
        position = y * rowstride;
3077
0
        for (x = 0; x < width; x++) {
3078
            /* composite RGBA (or CMYKA, etc.) pixel with over solid background */
3079
0
            a = buf_ptr[position + planestride * num_comp];
3080
0
            if (a == 0) {
3081
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3082
0
                    buf_ptr[position + planestride * comp_num] = 0xffff;
3083
0
                }
3084
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3085
0
                    buf_ptr[position + planestride * comp_num] = 0;
3086
0
                }
3087
0
            } else if (a == 0xffff) {
3088
#if ARCH_IS_BIG_ENDIAN
3089
#else
3090
                /* Convert from native -> big endian */
3091
0
                for (comp_num = 0; comp_num < num_comp; comp_num++) {
3092
0
                    comp = buf_ptr[position + planestride * comp_num];
3093
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3094
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3095
0
                }
3096
0
#endif
3097
0
            } else {
3098
0
                a ^= 0xffff;
3099
0
                a += a >> 15; /* a is now 0 to 0x10000 */
3100
0
                a >>= 1; /* We can only use 15 bits as bg-comp has a sign bit we can't lose */
3101
0
                for (comp_num = 0; comp_num < spot_start; comp_num++) {
3102
0
                    comp = buf_ptr[position + planestride * comp_num];
3103
0
                    tmp = ((0xffff - comp) * a) + 0x4000;
3104
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3105
                    /* Store as big endian */
3106
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3107
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3108
0
                }
3109
0
                for (comp_num = spot_start; comp_num < num_comp; comp_num++) {
3110
0
                    comp = buf_ptr[position + planestride * comp_num];
3111
0
                    tmp = ((0 - comp) * a) + 0x4000;
3112
0
                    comp += (tmp >> 15); /* Errors in bit 16 upwards will be ignored */
3113
                    /* Store as big endian */
3114
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[0] = comp >> 8;
3115
0
                    ((byte*)&buf_ptr[position + planestride * comp_num])[1] = comp;
3116
0
                }
3117
0
            }
3118
0
            position += 1;
3119
0
        }
3120
0
    }
3121
0
}
3122
3123
static int
3124
pdf14_put_blended_image_cmykspot(gx_device* dev, gx_device* target,
3125
    gs_gstate* pgs, pdf14_buf* buf, intptr_t planestride_in,
3126
    intptr_t rowstride_in, int x0, int y0, int width, int height,
3127
    int num_comp, int additive, bool has_tags, gs_int_rect rect_in,
3128
    gs_separations* pseparations, bool deep)
3129
23.7k
{
3130
23.7k
    pdf14_device* pdev = (pdf14_device*)dev;
3131
23.7k
    int code = 0;
3132
23.7k
    int y;
3133
23.7k
    int num_rows_left;
3134
23.7k
    int i;
3135
23.7k
    gs_int_rect rect = rect_in;
3136
23.7k
    intptr_t planestride = planestride_in;
3137
23.7k
    intptr_t rowstride = rowstride_in;
3138
23.7k
    byte* buf_ptr = NULL;
3139
23.7k
    cmm_profile_t* src_profile = buf->group_color_info->icc_profile;
3140
23.7k
    cmm_profile_t* des_profile = NULL;
3141
23.7k
    cmm_dev_profile_t* dev_target_profile;
3142
23.7k
    cmm_dev_profile_t* pdf14dev_profile;
3143
23.7k
    bool color_mismatch = false;
3144
23.7k
    bool supports_alpha = false;
3145
23.7k
    const byte* buf_ptrs[GS_CLIENT_COLOR_MAX_COMPONENTS];
3146
23.7k
    int alpha_offset = num_comp;
3147
23.7k
    int tag_offset = has_tags ? num_comp + 1 : 0;
3148
23.7k
    gs_color_space *pcs;
3149
23.7k
    gs_image1_t image;
3150
23.7k
    gx_image_enum_common_t *info;
3151
23.7k
    gx_image_plane_t planes[GS_IMAGE_MAX_COMPONENTS];
3152
23.7k
    pdf14_buf *cm_result = NULL;
3153
23.7k
    bool did_alloc;
3154
23.7k
    bool target_sep_device = (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0);
3155
23.7k
    bool has_spots = pdev->ctx->num_spots > 0;
3156
23.7k
    bool blend_spots = !target_sep_device && has_spots;
3157
23.7k
    bool lose_channels = false;
3158
3159
    /* Check if group color space is CMYK based */
3160
23.7k
    code = dev_proc(target, get_profile)(target, &dev_target_profile);
3161
23.7k
    if (code < 0)
3162
0
        return code;
3163
23.7k
    if (dev_target_profile == NULL)
3164
0
        return gs_throw_code(gs_error_Fatal);
3165
3166
23.7k
    if (src_profile == NULL) {
3167
0
        code = dev_proc(dev, get_profile)(dev, &pdf14dev_profile);
3168
0
        if (code < 0) {
3169
0
            return code;
3170
0
        }
3171
0
        src_profile = pdf14dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3172
0
    }
3173
3174
    /* If the target device does not support spot colors and we have spot colors
3175
       here due to overprint simulation (blend_spots == true), then we will need to convert the base
3176
       colors to CMYK if it is RGB or Gray so tha we can blend in the spot colors */
3177
23.7k
    if (blend_spots && src_profile->data_cs != gsCMYK) {
3178
3179
0
        cm_result = pdf14_transform_color_buffer_no_matte(pgs, pdev->ctx, (gx_device *)dev, buf,
3180
0
            buf->data, src_profile, pgs->icc_manager->default_cmyk, 0, 0, buf->rect.q.x,
3181
0
            buf->rect.q.y, &did_alloc, buf->deep, false, false);
3182
0
        if (cm_result == NULL)
3183
0
            return_error(gs_error_VMerror);
3184
3185
        /* Update */
3186
0
        buf = cm_result;
3187
0
        src_profile = pgs->icc_manager->default_cmyk;
3188
0
        num_comp = buf->n_chan - 1;
3189
0
        additive = 0;
3190
0
        tag_offset = has_tags ? num_comp + 1 : 0;
3191
0
        alpha_offset = num_comp;
3192
3193
#if RAW_DUMP
3194
        buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3195
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3196
            "convertbase_to_cmyk_for_spot_blend", buf_ptr, deep);
3197
        global_index++;
3198
#endif
3199
0
    }
3200
3201
    /* Fix order map if needed */
3202
111k
    for (i = 0; i < num_comp; i++) {
3203
87.4k
        pdev->devn_params.separation_order_map[i] = i;
3204
87.4k
    }
3205
3206
    /* Check if we have a color conversion issue */
3207
23.7k
    des_profile = dev_target_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE];
3208
23.7k
    if (!gsicc_profiles_equal(des_profile, src_profile))
3209
7.48k
        color_mismatch = true;
3210
23.7k
    if (des_profile->data_cs == gsNCHANNEL)
3211
0
        lose_channels = true;
3212
3213
    /* Check if target supports alpha */
3214
23.7k
    supports_alpha = (dev_proc(target, dev_spec_op)(target, gxdso_supports_alpha, NULL, 0) > 0);
3215
23.7k
    code = 0;
3216
3217
23.7k
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x) << deep);
3218
3219
    /* Note. The logic below will need a little rework if we ever
3220
       have a device that has tags and alpha support */
3221
23.7k
    if (supports_alpha) {
3222
3223
        /* If doing simulated overprint, Bring the spot color channels into
3224
           CMYK. Data is planar and 16 bit data in native format. */
3225
0
        if (pdev->overprint_sim && pdev->devn_params.page_spot_colors > 0) {
3226
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3227
3228
            /* In the clist case, we need to get equiv spots out of the pseudo-band. */
3229
0
            if (pdev->pclist_device != NULL) {
3230
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3231
3232
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3233
0
                if (code < 0)
3234
0
                    return code;
3235
0
            }
3236
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3237
3238
            /* Now we go to big endian */
3239
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3240
0
                planestride, num_comp, src_profile->num_comps,
3241
0
                tag_offset, cmyk_map, true, deep);
3242
3243
            /* Reset buffer information. We have CMYK+alpha and maybe tags */
3244
0
            buf->n_chan = buf->n_chan - buf->num_spots;
3245
0
            buf->n_planes = buf->n_planes - buf->num_spots;
3246
0
            buf->num_spots = 0;
3247
0
            num_comp = buf->n_chan - 1;
3248
0
            tag_offset = has_tags ? buf->n_planes - 1 : 0; /* Tags at end */
3249
0
        }
3250
3251
0
        if (!color_mismatch) {
3252
0
            for (i = 0; i < buf->n_planes; i++)
3253
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3254
0
            for (; i < target->color_info.num_components; i++)
3255
0
                buf_ptrs[i] = 0;
3256
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3257
0
                rect.p.x, rect.p.y, width, height,
3258
0
                rowstride, alpha_offset, tag_offset);
3259
            /* Right now code has number of rows written */
3260
0
        } else {
3261
            /* In this case, just color convert and maintain alpha.
3262
               This is a case where we either either blend in the
3263
               right color space and have no alpha for the output
3264
               device or hand back the wrong color space with
3265
               alpha data.  We choose the later. */
3266
0
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile,
3267
0
                        dev_target_profile, &buf, &buf_ptr, false, rect.p.x,
3268
0
                        rect.p.y, width, height, false);
3269
0
            if (code < 0)
3270
0
                return code;
3271
3272
            /* reset */
3273
0
            rowstride = buf->rowstride;
3274
0
            planestride = buf->planestride;
3275
0
            num_comp = buf->n_chan - 1;
3276
0
            alpha_offset = num_comp;
3277
0
            tag_offset = buf->has_tags ? buf->n_chan : 0;
3278
3279
            /* And then out */
3280
0
            for (i = 0; i < buf->n_planes; i++)
3281
0
                buf_ptrs[i] = buf_ptr + i * planestride;
3282
0
            for (; i < target->color_info.num_components; i++)
3283
0
                buf_ptrs[i] = 0;
3284
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3285
0
                rect.p.x, rect.p.y, width, height, rowstride, alpha_offset,
3286
0
                tag_offset);
3287
            /* Right now code has number of rows written.  Writing continues below */
3288
0
        }
3289
23.7k
    } else {
3290
        /* Device could not handle the alpha data (we actually don't have
3291
           a device that does spot colorants and has an alpha channel so
3292
           the above code is untested.  Go ahead and preblend now and then
3293
           color convert if needed */
3294
#if RAW_DUMP
3295
           /* Dump before and after the blend to make sure we are doing that ok */
3296
        dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3297
            "pre_put_image_blend_image", buf_ptr, deep);
3298
        global_index++;
3299
#endif
3300
3301
23.7k
        if (color_mismatch && (src_profile->data_cs == gsRGB || src_profile->data_cs == gsGRAY)) {
3302
7.48k
            if (deep) {
3303
            /* In this case, we are NOT going to bring the spots into the CMYK
3304
               equivalent colors, since otherwise src_profile would be CMYK based.  So
3305
               16 bit data will be converted now from native endian to big endian during
3306
               the blending process */
3307
0
                pdf14_blend_image_mixed_buffer16(buf_ptr, width, height, rowstride,
3308
0
                    planestride, num_comp, src_profile->num_comps);
3309
7.48k
            } else {
3310
7.48k
                pdf14_blend_image_mixed_buffer(buf_ptr, width, height, rowstride,
3311
7.48k
                    planestride, num_comp, src_profile->num_comps);
3312
7.48k
            }
3313
16.2k
        } else {
3314
16.2k
            if (deep) {
3315
            /* In this case, if blend_spots == true, we will shortly be bringing
3316
               the spot colors to CMYK equivalent colors. It is at that time that
3317
               we will convert from native endian to big endian. In all other
3318
               cases this blending will due to conversion from native to BE */
3319
0
                bool keep_native = (blend_spots == true);
3320
3321
0
                gx_blend_image_buffer16(buf_ptr, width, height, rowstride,
3322
0
                    planestride, num_comp, additive, keep_native);
3323
16.2k
            } else {
3324
16.2k
                gx_blend_image_buffer(buf_ptr, width, height, rowstride,
3325
16.2k
                    planestride, num_comp, additive);
3326
16.2k
            }
3327
16.2k
        }
3328
3329
23.7k
        if (deep && has_tags)
3330
0
        {
3331
            /* We still need to convert the tags from Native to BE */
3332
#if ARCH_IS_BIG_ENDIAN
3333
#else
3334
0
            uint16_t *tags = (uint16_t *)&buf_ptr[tag_offset * planestride];
3335
0
            int i, j;
3336
0
            for (j = 0; j < height; j++)
3337
0
            {
3338
0
                for (i = 0; i < width; i++)
3339
0
                {
3340
0
                    uint16_t tag = *tags++;
3341
0
                    ((byte *)tags)[-2] = tag >> 8;
3342
0
                    ((byte *)tags)[-1] = tag;
3343
0
                }
3344
0
                tags += (buf->rowstride>>1) - width;
3345
0
            }
3346
0
#endif
3347
0
        }
3348
3349
#if RAW_DUMP
3350
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3351
            "post_put_image_blend_image", buf_ptr, deep);
3352
        global_index++;
3353
#endif
3354
3355
        /* If doing simulated overprint and we are not going to a sep device and
3356
           we have spot colors, then bring the spot color channels into CMYK
3357
           (We should have already converted our base color space to CMYK if it was RGB or gray).
3358
           At this point, data is planar and 16 bit data is still in native format. It is
3359
           here that 16 bit data will be converted to BE. Otherwise it will have been converted
3360
           above during the alpha blend operation. */
3361
23.7k
        if (blend_spots) {
3362
0
            cmyk_composite_map cmyk_map[GX_DEVICE_MAX_SEPARATIONS];  /* Fracs */
3363
3364
            /* In the clist case, we need to get equiv spots out of the
3365
               pseudo-band. */
3366
0
            if (pdev->pclist_device != NULL) {
3367
0
                gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
3368
0
                code = clist_read_op_equiv_cmyk_colors(pcrdev, &(pdev->op_pequiv_cmyk_colors));
3369
0
                if (code < 0)
3370
0
                    return code;
3371
0
            }
3372
3373
0
            build_cmyk_map(dev, num_comp, &(pdev->op_pequiv_cmyk_colors), cmyk_map);
3374
0
            pdf14_spots_to_cmyk(buf_ptr, width, height, rowstride,
3375
0
                planestride, num_comp, src_profile->num_comps,
3376
0
                tag_offset, cmyk_map, false, deep);
3377
3378
            /* Reset buffer information. We have CMYK and maybe tags */
3379
0
            num_comp = 4;
3380
0
            alpha_offset = 0;
3381
0
            buf->n_chan = buf->n_chan - buf->num_spots - 1;     /* No spots or alpha */
3382
0
            buf->n_planes = buf->n_planes - buf->num_spots - 1; /* No spots or alpha */
3383
0
            tag_offset = has_tags ? buf->n_chan : 0;      /* Tags at end */
3384
0
            buf->num_spots = 0;
3385
3386
#if RAW_DUMP
3387
            dump_raw_buffer(target->memory, height, width, buf->n_planes, planestride, rowstride,
3388
                "post_put_image_spot_to_cmyk", buf_ptr, deep);
3389
            global_index++;
3390
#endif
3391
0
        }
3392
3393
        /* Map to the destination color space */
3394
23.7k
        if (color_mismatch) {
3395
            /* We started out with the original process colorants, and spots. If we have an
3396
             * nchannel output profile, this can mean that the first few spots might come from
3397
             * that and the rest from the document itself. e.g:
3398
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3399
             * Then we might have a blend space that changes the process colorants:
3400
             *        R, G, B, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3401
             * Now we're about to convert 'RGB' back to 'CMYKII'.
3402
             * If we're not careful, we'll end up with:
3403
             *        C, M, Y, K, ICC_COLOR_0, ICC_COLOR_1, ICC_COLOR_0, ICC_COLOR_1, Spot 1, Spot 2
3404
             * so we might need to lose some channels.      ^^^^^^^^^^^^^^^^^^^^^^^^
3405
             */
3406
7.48k
            int num_original_process_colorants = target->color_info.num_components - has_tags - buf->num_spots;
3407
7.48k
            int num_channels_to_lose = lose_channels ? des_profile->num_comps - num_original_process_colorants : 0;
3408
7.48k
            code = pdf14_put_image_color_convert(pdev, pgs, src_profile, dev_target_profile,
3409
7.48k
                &buf, &buf_ptr, true, rect.p.x, rect.p.y, width, height, num_channels_to_lose);
3410
7.48k
            if (code < 0)
3411
0
                return code;
3412
3413
            /* reset */
3414
7.48k
            rowstride = buf->rowstride;
3415
7.48k
            planestride = buf->planestride;
3416
7.48k
            num_comp = buf->n_chan;
3417
7.48k
            tag_offset = buf->has_tags ? (buf->n_chan - num_channels_to_lose) : 0;
3418
7.48k
        }
3419
3420
#if RAW_DUMP
3421
        /* Dump after the CS transform */
3422
        dump_raw_buffer_be(target->memory, height, width, buf->n_planes, planestride, rowstride,
3423
            "post_put_image_color_convert", buf_ptr, deep);
3424
        global_index++;
3425
        /* clist_band_count++; */
3426
#endif
3427
3428
        /* Try put_image again. This can occur if the
3429
           target, like psdcmyk and tiffsep, support put_image */
3430
23.7k
        alpha_offset = 0;
3431
142k
        for (i = 0; i < buf->n_planes; i++)
3432
118k
            buf_ptrs[i] = buf_ptr + i * planestride;
3433
23.7k
        for (; i < target->color_info.num_components; i++)
3434
0
            buf_ptrs[i] = 0;
3435
23.7k
        code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3436
23.7k
            rect.p.x, rect.p.y, width, height,
3437
23.7k
            rowstride, alpha_offset, tag_offset);
3438
23.7k
    }
3439
3440
    /* Put image was succesful.  We processed some or all of the rows.
3441
       Continue until we are done */
3442
23.7k
    if (code > 0) {
3443
55
        num_rows_left = height - code;
3444
55
        while (num_rows_left > 0) {
3445
0
            code = dev_proc(target, put_image) (target, target, buf_ptrs, num_comp,
3446
0
                rect.p.x, rect.p.y + code, width, num_rows_left, rowstride,
3447
0
                alpha_offset, tag_offset);
3448
0
            if (code < 0) {
3449
0
                return code;
3450
0
            }
3451
0
            num_rows_left = num_rows_left - code;
3452
0
        }
3453
55
        return 0;
3454
55
    }
3455
3456
    /* Sep devices all support put_image (tiffsep and psdcmyk)
3457
       as well as those devices that support alpha (pngalpha,
3458
       png16malpha). If we are here, then we are doing an
3459
       overprint simulation on some other device. Image data
3460
       is aleady blended and in device color space. */
3461
23.6k
    code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
3462
23.6k
    if (code < 0)
3463
0
        return code;
3464
3465
    /* Already in destination CS */
3466
23.6k
    pcs->cmm_icc_profile_data = des_profile;
3467
3468
    /* pcs takes a reference to the profile data it just retrieved. */
3469
23.6k
    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_put_blended_image_cmykspot");
3470
23.6k
    if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS)
3471
0
        return_error(gs_error_rangecheck);
3472
23.6k
    gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
3473
3474
    /* If we have more components to write out than are in the des_profile,
3475
     * then just using a PCS based on des_profile, will result in us dropping
3476
     * the spot colors.
3477
     * So, if our target supports devn colors, we instead construct a
3478
     * DevN device space with colors names taken from the devn_params, and
3479
     * use that instead. */
3480
23.6k
    if (des_profile->num_comps != target->color_info.num_components &&
3481
24
        dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0)
3482
24
    {
3483
24
        int num_std;
3484
24
        gs_devn_params *devn_params =  dev_proc(target, ret_devn_params)(target);
3485
24
        gs_color_space *pcs2 = pcs;
3486
24
        code = gs_cspace_new_DeviceN(&pcs, target->color_info.num_components,
3487
24
                                     pcs2, pgs->memory->non_gc_memory);
3488
24
        if (code < 0)
3489
0
            return code;
3490
        /* set up a usable DeviceN space with info from the tdev->devn_params */
3491
24
        pcs->params.device_n.use_alt_cspace = false;
3492
24
        num_std = devn_params->num_std_colorant_names;
3493
120
        for (i = 0; i < num_std; i++) {
3494
96
            const char *name = devn_params->std_colorant_names[i];
3495
96
            size_t len = strlen(name);
3496
96
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, len + 1, "mem_planar_put_image_very_slow");
3497
96
            if (pcs->params.device_n.names[i] == NULL) {
3498
0
                int j = 0;
3499
0
                for (j = 0;j < i; j++) {
3500
0
                    if (pcs->params.device_n.names[j] != NULL)
3501
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3502
0
                    pcs->params.device_n.names[j] = NULL;
3503
0
                }
3504
0
                return_error(gs_error_VMerror);
3505
0
            }
3506
96
            strcpy(pcs->params.device_n.names[i], name);
3507
96
        }
3508
24
        for (; i < devn_params->separations.num_separations; i++) {
3509
0
            devn_separation_name *name = &devn_params->separations.names[i - num_std];
3510
0
            pcs->params.device_n.names[i] = (char *)gs_alloc_bytes(pgs->memory->non_gc_memory, name->size + 1, "mem_planar_put_image_very_slow");
3511
0
            if (pcs->params.device_n.names[i] == NULL) {
3512
0
                int j = 0;
3513
0
                for (j = 0;j < i; j++) {
3514
0
                    if (pcs->params.device_n.names[j] != NULL)
3515
0
                        gs_free_object(pgs->memory->non_gc_memory, pcs->params.device_n.names[j], "mem_planar_put_image_very_slow");
3516
0
                    pcs->params.device_n.names[j] = NULL;
3517
0
                }
3518
0
                return_error(gs_error_VMerror);
3519
0
            }
3520
0
            memcpy(pcs->params.device_n.names[i], devn_params->separations.names[i - num_std].data, name->size);
3521
0
            pcs->params.device_n.names[i][name->size] = 0;
3522
0
        }
3523
24
        if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
3524
0
            return code;
3525
0
        }
3526
        /* One last thing -- we need to fudge the pgs->color_component_map */
3527
144
        for (i=0; i < dev->color_info.num_components; i++)
3528
120
            pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
3529
24
    }
3530
3531
23.6k
    gs_image_t_init_adjust(&image, pcs, false);
3532
23.6k
    image.ImageMatrix.xx = (float)width;
3533
23.6k
    image.ImageMatrix.yy = (float)height;
3534
23.6k
    image.Width = width;
3535
23.6k
    image.Height = height;
3536
23.6k
    image.BitsPerComponent = deep ? 16 : 8;
3537
23.6k
    image.ColorSpace = pcs;
3538
23.6k
    image.format = gs_image_format_component_planar;
3539
3540
23.6k
    ctm_only_writable(pgs).xx = (float)width;
3541
23.6k
    ctm_only_writable(pgs).xy = 0;
3542
23.6k
    ctm_only_writable(pgs).yx = 0;
3543
23.6k
    ctm_only_writable(pgs).yy = (float)height;
3544
23.6k
    ctm_only_writable(pgs).tx = (float)rect.p.x;
3545
23.6k
    ctm_only_writable(pgs).ty = (float)rect.p.y;
3546
23.6k
    code = dev_proc(target, begin_typed_image) (target,
3547
23.6k
        pgs, NULL, (gs_image_common_t *)&image,
3548
23.6k
        NULL, NULL, NULL, pgs->memory, &info);
3549
23.6k
    if (code < 0) {
3550
0
        rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3551
0
        return code;
3552
0
    }
3553
#if RAW_DUMP
3554
    /* Dump the current buffer to see what we have. */
3555
    dump_raw_buffer(pdev->ctx->memory,
3556
        pdev->ctx->stack->rect.q.y - pdev->ctx->stack->rect.p.y,
3557
        pdev->ctx->stack->rect.q.x - pdev->ctx->stack->rect.p.x,
3558
        pdev->ctx->stack->n_planes,
3559
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3560
        "put_image_final_big", pdev->ctx->stack->data, deep);
3561
    dump_raw_buffer(pdev->ctx->memory,
3562
        height, width, buf->n_planes,
3563
        pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3564
        "put_image_final_small", buf_ptr, deep);
3565
    global_index++;
3566
    clist_band_count++;
3567
#endif
3568
3569
125k
    for (i = 0; i < num_comp; i++) {
3570
102k
        planes[i].data = buf_ptr + i * planestride;
3571
102k
        planes[i].data_x = 0;
3572
102k
        planes[i].raster = buf->rowstride;
3573
102k
    }
3574
3575
258k
    for (y = 0; y < height; y++) {
3576
234k
        int rows_used;
3577
3578
234k
        info->procs->plane_data(info, (const gx_image_plane_t*) &planes, 1, &rows_used);
3579
3580
1.24M
        for (i = 0; i < num_comp; i++) {
3581
1.00M
            planes[i].data += buf->rowstride;
3582
1.00M
        }
3583
234k
    }
3584
23.6k
    info->procs->end_image(info, true);
3585
3586
    /* This will also decrement the profile */
3587
23.6k
    rc_decrement_only_cs(pcs, "pdf14_put_blended_image_cmykspot");
3588
23.6k
    return code;
3589
23.6k
}
3590
3591
/**
3592
 * pdf14_cmykspot_put_image: Put rendered image to target device.
3593
 * @pdev: The PDF 1.4 rendering device.
3594
 * @pgs: State for image draw operation.
3595
 * @target: The target device.
3596
 *
3597
 * Puts the rendered image in @pdev's buffer to @target. This is called
3598
 * as part of the sequence of popping the PDF 1.4 device filter.
3599
 *
3600
 * Return code: negative on error.
3601
 **/
3602
static  int
3603
pdf14_cmykspot_put_image(gx_device *dev, gs_gstate *pgs, gx_device *target)
3604
66.7k
{
3605
66.7k
    pdf14_device *pdev = (pdf14_device *)dev;
3606
66.7k
    pdf14_buf *buf = pdev->ctx->stack;
3607
66.7k
    gs_int_rect rect;
3608
66.7k
    int x1, y1, width, height;
3609
66.7k
    gs_devn_params *pdevn_params = &pdev->devn_params;
3610
66.7k
    gs_separations *pseparations = &pdevn_params->separations;
3611
66.7k
    intptr_t planestride;
3612
66.7k
    intptr_t rowstride;
3613
66.7k
    bool deep = pdev->ctx->deep;
3614
66.7k
    int num_comp;
3615
3616
    /* Nothing was ever drawn. */
3617
66.7k
    if (buf == NULL)
3618
25.7k
        return 0;
3619
3620
40.9k
    num_comp = buf->n_chan - 1;
3621
40.9k
    rect = buf->rect;
3622
40.9k
    planestride = buf->planestride;
3623
40.9k
    rowstride = buf->rowstride;
3624
3625
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3626
       potential problem. Bug 694190 */
3627
40.9k
    if (buf->saved != NULL) {
3628
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3629
0
    }
3630
40.9k
    if_debug0m('v', dev->memory, "[v]pdf14_cmykspot_put_image\n");
3631
40.9k
    rect_intersect(rect, buf->dirty);
3632
40.9k
    x1 = min(pdev->width, rect.q.x);
3633
40.9k
    y1 = min(pdev->height, rect.q.y);
3634
40.9k
    width = x1 - rect.p.x;
3635
40.9k
    height = y1 - rect.p.y;
3636
40.9k
    if (width <= 0 || height <= 0 || buf->data == NULL)
3637
17.2k
        return 0;
3638
3639
#if RAW_DUMP
3640
    /* Dump the current buffer to see what we have. */
3641
    dump_raw_buffer(pdev->ctx->memory,
3642
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
3643
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
3644
                    pdev->ctx->stack->n_planes,
3645
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
3646
                    "CMYK_SPOT_PUTIMAGE", pdev->ctx->stack->data,
3647
                    pdev->ctx->stack->deep);
3648
3649
    global_index++;
3650
    clist_band_count++;
3651
#endif
3652
3653
23.7k
    return pdf14_put_blended_image_cmykspot(dev, target, pgs,
3654
23.7k
                      buf, planestride, rowstride,
3655
23.7k
                      rect.p.x, rect.p.y, width, height, num_comp, buf->group_color_info->isadditive,
3656
23.7k
                      buf->has_tags, rect, pseparations, deep);
3657
40.9k
}
3658
3659
/**
3660
 * pdf14_custom_put_image: Put rendered image to target device.
3661
 * @pdev: The PDF 1.4 rendering device.
3662
 * @pgs: State for image draw operation.
3663
 * @target: The target device.
3664
 *
3665
 * Puts the rendered image in @pdev's buffer to @target. This is called
3666
 * as part of the sequence of popping the PDF 1.4 device filter.
3667
 *
3668
 * Return code: negative on error.
3669
 **/
3670
static  int
3671
pdf14_custom_put_image(gx_device * dev, gs_gstate * pgs, gx_device * target)
3672
0
{
3673
0
    pdf14_device * pdev = (pdf14_device *)dev;
3674
0
    pdf14_buf *buf = pdev->ctx->stack;
3675
0
    bool deep = pdev->ctx->deep;
3676
0
    gs_int_rect rect;
3677
0
    int x0, y0;
3678
0
    intptr_t planestride;
3679
0
    intptr_t rowstride;
3680
0
    int num_comp;
3681
0
    uint16_t bg;
3682
0
    int x1, y1, width, height;
3683
0
    byte *buf_ptr;
3684
3685
    /* Nothing was ever drawn. */
3686
0
    if (buf == NULL)
3687
0
        return 0;
3688
3689
0
    bg = pdev->ctx->additive ? 0xffff : 0;
3690
0
    num_comp = buf->n_chan - 1;
3691
0
    rect = buf->rect;
3692
0
    x0 = rect.p.x;
3693
0
    y0 = rect.p.y;
3694
0
    planestride = buf->planestride;
3695
0
    rowstride = buf->rowstride;
3696
3697
    /* Make sure that this is the only item on the stack. Fuzzing revealed a
3698
       potential problem. Bug 694190 */
3699
0
    if (buf->saved != NULL) {
3700
0
        return gs_throw(gs_error_unknownerror, "PDF14 device push/pop out of sync");
3701
0
    }
3702
0
    if_debug0m('v', dev->memory, "[v]pdf14_custom_put_image\n");
3703
0
    rect_intersect(rect, buf->dirty);
3704
0
    x1 = min(pdev->width, rect.q.x);
3705
0
    y1 = min(pdev->height, rect.q.y);
3706
0
    width = x1 - rect.p.x;
3707
0
    height = y1 - rect.p.y;
3708
0
    if (width <= 0 || height <= 0 || buf->data == NULL)
3709
0
        return 0;
3710
0
    buf_ptr = buf->data + (rect.p.y - buf->rect.p.y) * buf->rowstride + ((rect.p.x - buf->rect.p.x)<<deep);
3711
3712
0
    return gx_put_blended_image_custom(target, buf_ptr,
3713
0
                      planestride, rowstride,
3714
0
                      x0, y0, width, height, num_comp, bg, deep);
3715
0
}
3716
3717
/* This is rather nasty: in the event we are interrupted (by an error) between a push and pop
3718
 * of one or more groups, we have to cycle through any ICC profile changes since the push
3719
 * putting everything back how it was, and cleaning up the reference counts.
3720
 */
3721
static void pdf14_cleanup_group_color_profiles (pdf14_device *pdev)
3722
2.06M
{
3723
2.06M
    if (pdev->ctx && pdev->ctx->stack) {
3724
873k
        pdf14_buf *buf, *next;
3725
3726
873k
        for (buf = pdev->ctx->stack->saved; buf != NULL; buf = next) {
3727
16
            pdf14_group_color_t *group_color_info = buf->group_color_info;
3728
16
            next = buf->saved;
3729
32
            while (group_color_info) {
3730
16
               if (group_color_info->icc_profile != NULL) {
3731
16
                   cmm_profile_t *group_profile;
3732
16
                   gsicc_rendering_param_t render_cond;
3733
16
                   cmm_dev_profile_t *dev_profile;
3734
16
                   int code = dev_proc((gx_device *)pdev, get_profile)((gx_device *)pdev,  &dev_profile);
3735
3736
16
                   if (code >= 0) {
3737
16
                       gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
3738
16
                                             &render_cond);
3739
3740
16
                       gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
3741
16
                                               -1, "pdf14_end_transparency_group");
3742
16
                       pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
3743
16
                           group_color_info->icc_profile;
3744
16
                       group_color_info->icc_profile = NULL;
3745
16
                   }
3746
16
               }
3747
3748
16
               group_color_info = group_color_info->previous;
3749
16
            }
3750
16
        }
3751
873k
    }
3752
2.06M
}
3753
3754
static  int
3755
pdf14_close(gx_device *dev)
3756
1.03M
{
3757
1.03M
    pdf14_device *pdev = (pdf14_device *)dev;
3758
3759
1.03M
    pdf14_cleanup_group_color_profiles(pdev);
3760
3761
1.03M
    if (pdev->ctx) {
3762
1.02M
        pdf14_ctx_free(pdev->ctx);
3763
1.02M
        pdev->ctx = NULL;
3764
1.02M
    }
3765
1.03M
    return 0;
3766
1.03M
}
3767
3768
/* This is called when something has gone wrong and the interpreter received a
3769
   stop while in the middle of doing something with the PDF14 device.  We need
3770
   to clean up and end this in a graceful manner */
3771
static int
3772
pdf14_discard_trans_layer(gx_device *dev, gs_gstate * pgs)
3773
0
{
3774
0
    pdf14_device *pdev = (pdf14_device *)dev;
3775
    /* The things that need to be cleaned up */
3776
0
    pdf14_ctx *ctx = pdev->ctx;
3777
0
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
3778
3779
    /* Free up the smask color */
3780
0
    if (smaskcolor != NULL) {
3781
0
        smaskcolor->ref_count = 1;
3782
0
        pdf14_decrement_smask_color(pgs, dev);
3783
0
        pdev->smaskcolor = NULL;
3784
0
    }
3785
3786
    /* Free up the nested color procs and decrement the profiles */
3787
0
    while (pdev->color_model_stack)
3788
0
        pdf14_pop_group_color(dev, NULL);
3789
3790
    /* Start the context clean up */
3791
0
    if (ctx != NULL) {
3792
0
        pdf14_buf *buf, *next;
3793
0
        pdf14_group_color_t *procs, *prev_procs;
3794
3795
0
        if (ctx->mask_stack != NULL) {
3796
0
            rc_decrement(ctx->mask_stack, "pdf14_discard_trans_layer");
3797
0
        }
3798
3799
        /* Now the stack of buffers */
3800
0
        for (buf = ctx->stack; buf != NULL; buf = next) {
3801
0
            next = buf->saved;
3802
3803
0
            gs_free_object(ctx->memory, buf->transfer_fn, "pdf14_discard_trans_layer");
3804
0
            gs_free_object(ctx->memory, buf->matte, "pdf14_discard_trans_layer");
3805
0
            gs_free_object(ctx->memory, buf->data, "pdf14_discard_trans_layer");
3806
0
            gs_free_object(ctx->memory, buf->backdrop, "pdf14_discard_trans_layer");
3807
            /* During the soft mask push, the mask_stack was copied (not moved) from
3808
               the ctx to the tos mask_stack. We are done with this now so it is safe
3809
               to free this one object */
3810
0
            gs_free_object(ctx->memory, buf->mask_stack, "pdf14_discard_trans_layer");
3811
0
            for (procs = buf->group_color_info; procs != NULL; procs = prev_procs) {
3812
0
                prev_procs = procs->previous;
3813
0
                gs_free_object(ctx->memory, procs, "pdf14_discard_trans_layer");
3814
0
            }
3815
0
            gs_free_object(ctx->memory, buf, "pdf14_discard_trans_layer");
3816
0
        }
3817
        /* Finally the context itself */
3818
0
        gs_free_object(ctx->memory, ctx, "pdf14_discard_trans_layer");
3819
0
        pdev->ctx = NULL;
3820
0
    }
3821
0
    return 0;
3822
0
}
3823
3824
static  int
3825
pdf14_output_page(gx_device * dev, int num_copies, int flush)
3826
0
{
3827
0
    pdf14_device * pdev = (pdf14_device *)dev;
3828
3829
0
    if (pdev->target != NULL)
3830
0
        return (*dev_proc(pdev->target, output_page)) (pdev->target, num_copies, flush);
3831
0
    return 0;
3832
0
}
3833
3834
8.30M
#define COPY_PARAM(p) dev->p = target->p
3835
5.19M
#define COPY_ARRAY_PARAM(p) memcpy(dev->p, target->p, sizeof(dev->p))
3836
3837
static void
3838
copy_tag_setup(gx_device *dev, const gx_device *target)
3839
1.03M
{
3840
1.03M
    bool deep = device_is_deep(target);
3841
1.03M
    int had_tags = (dev->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3842
1.03M
    int has_tags = (target->graphics_type_tag & GS_DEVICE_ENCODES_TAGS) != 0;
3843
1.03M
    COPY_PARAM(graphics_type_tag);
3844
1.03M
    if (had_tags && !has_tags)
3845
0
    {
3846
        /* We have just removed a tags plane. Adjust num_components and depth accordingly. */
3847
0
        dev->color_info.num_components--;
3848
0
        dev->color_info.depth -= deep ? 16 : 8;
3849
0
    }
3850
1.03M
    else if (!had_tags && has_tags)
3851
0
    {
3852
        /* We have just added a tags plane. Adjust num_components and depth accordingly. */
3853
0
        dev->color_info.num_components++;
3854
0
        dev->color_info.depth += deep ? 16 : 8;
3855
0
    }
3856
1.03M
}
3857
3858
/*
3859
 * Copy device parameters back from a target.  This copies all standard
3860
 * parameters related to page size and resolution, but not any of the
3861
 * color-related parameters, as the pdf14 device retains its own color
3862
 * handling. This routine is parallel to gx_device_copy_params().
3863
 * Note that it DOES copy the devn_params since these are required to
3864
 * keep agreement with colorant name->number mapping, and don't change
3865
 * with the pdf14 color handling.
3866
 */
3867
static  int
3868
gs_pdf14_device_copy_params(gx_device *dev, const gx_device *target)
3869
1.03M
{
3870
1.03M
    cmm_dev_profile_t *profile_targ;
3871
1.03M
    cmm_dev_profile_t *profile_dev14;
3872
1.03M
    pdf14_device *pdev = (pdf14_device*) dev;
3873
1.03M
    cmm_profile_t *blend_profile = NULL;
3874
1.03M
    int k;
3875
3876
1.03M
    COPY_PARAM(width);
3877
1.03M
    COPY_PARAM(height);
3878
1.03M
    COPY_ARRAY_PARAM(MediaSize);
3879
1.03M
    COPY_ARRAY_PARAM(ImagingBBox);
3880
1.03M
    COPY_PARAM(ImagingBBox_set);
3881
1.03M
    COPY_ARRAY_PARAM(HWResolution);
3882
1.03M
    COPY_ARRAY_PARAM(Margins);
3883
1.03M
    COPY_ARRAY_PARAM(HWMargins);
3884
1.03M
    COPY_PARAM(PageCount);
3885
1.03M
    COPY_PARAM(MaxPatternBitmap);
3886
3887
3888
    /* Supposedly this function isn't supposed to change the color setup of dev.
3889
     * BUT... if we change the tags value, we have to change the color setup to
3890
     * keep it valid. This is because num_components and depth include tags. */
3891
1.03M
    copy_tag_setup(dev, target);
3892
1.03M
    COPY_PARAM(interpolate_control);
3893
1.03M
    COPY_PARAM(non_strict_bounds);
3894
1.03M
    memcpy(&(dev->space_params), &(target->space_params), sizeof(gdev_space_params));
3895
3896
1.03M
    if (dev->icc_struct == NULL) {
3897
1.03M
        dev->icc_struct = gsicc_new_device_profile_array(dev);
3898
1.03M
        if (dev->icc_struct == NULL)
3899
0
            return_error(gs_error_VMerror);
3900
1.03M
        profile_dev14 = dev->icc_struct;
3901
1.03M
        dev_proc((gx_device *) target, get_profile)((gx_device *) target,
3902
1.03M
                                          &(profile_targ));
3903
3904
5.19M
        for (k = 0; k < NUM_DEVICE_PROFILES; k++) {
3905
4.15M
            if (profile_targ->device_profile[k] != NULL) {
3906
1.03M
                gsicc_adjust_profile_rc(profile_targ->device_profile[k], 1, "gs_pdf14_device_copy_params");
3907
1.03M
            }
3908
4.15M
            if (profile_dev14->device_profile[k] != NULL) {
3909
0
                gsicc_adjust_profile_rc(profile_dev14->device_profile[k], -1, "gs_pdf14_device_copy_params");
3910
0
            }
3911
4.15M
            profile_dev14->device_profile[k] = profile_targ->device_profile[k];
3912
4.15M
            profile_dev14->rendercond[k] = profile_targ->rendercond[k];
3913
4.15M
        }
3914
3915
1.03M
        dev->icc_struct->devicegraytok = profile_targ->devicegraytok;
3916
1.03M
        dev->icc_struct->graydetection = profile_targ->graydetection;
3917
1.03M
        dev->icc_struct->pageneutralcolor = profile_targ->pageneutralcolor;
3918
1.03M
        dev->icc_struct->supports_devn = profile_targ->supports_devn;
3919
1.03M
        dev->icc_struct->usefastcolor = profile_targ->usefastcolor;
3920
1.03M
        dev->icc_struct->blacktext = profile_targ->blacktext;
3921
1.03M
        dev->icc_struct->blackvector = profile_targ->blackvector;
3922
1.03M
        dev->icc_struct->blackthresholdL = profile_targ->blackthresholdL;
3923
1.03M
        dev->icc_struct->blackthresholdC = profile_targ->blackthresholdC;
3924
3925
1.03M
        switch (pdev->blend_cs_state) {
3926
1.03M
            case PDF14_BLEND_CS_UNSPECIFIED:
3927
1.03M
            case PDF14_BLEND_CS_TARGET_CIELAB:
3928
                /* PDF14_BLEND_CS_TARGET_CIELAB handled
3929
                   during the device push, when we have
3930
                   access to the pgs */
3931
1.03M
                break;
3932
0
            case PDF14_BLEND_CS_OUTPUTINTENT:
3933
0
                blend_profile = profile_targ->oi_profile;
3934
0
                break;
3935
0
            case PDF14_BLEND_CS_SPECIFIED:
3936
0
                blend_profile = profile_targ->blend_profile;
3937
0
                break;
3938
0
            default:
3939
0
                break;
3940
1.03M
        }
3941
3942
1.03M
        if (blend_profile != NULL) {
3943
            /* Set the device profile to the blend profile. Note only default profile is set */
3944
0
            gsicc_adjust_profile_rc(blend_profile, 1, "gs_pdf14_device_copy_params");
3945
0
            gsicc_adjust_profile_rc(profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "gs_pdf14_device_copy_params");
3946
0
            profile_dev14->device_profile[GS_DEFAULT_DEVICE_PROFILE] = blend_profile;
3947
0
        }
3948
3949
1.03M
        profile_dev14->overprint_control = profile_targ->overprint_control;
3950
1.03M
    }
3951
1.03M
#undef COPY_ARRAY_PARAM
3952
1.03M
#undef COPY_PARAM
3953
1.03M
    return 0;
3954
1.03M
}
3955
3956
/*
3957
 * This is a forwarding version of the put_params device proc.  It is only
3958
 * used when the PDF 1.4 compositor devices are closed.  The routine will
3959
 * check if the target device has closed and, if so, close itself.  The routine
3960
 * also sync the device parameters.
3961
 */
3962
static  int
3963
pdf14_forward_put_params(gx_device * dev, gs_param_list * plist)
3964
0
{
3965
0
    pdf14_device * pdev = (pdf14_device *)dev;
3966
0
    gx_device * tdev = pdev->target;
3967
0
    bool was_open = tdev->is_open;
3968
0
    int code = 0;
3969
3970
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
3971
0
        gx_device_decache_colors(dev);
3972
0
        if (!tdev->is_open) {
3973
0
            code = gs_closedevice(dev);
3974
0
            if (code == 0)
3975
0
                code = was_open ? 1 : 0;   /* target device closed */
3976
0
        }
3977
0
        gx_device_copy_params(dev, tdev);
3978
0
    }
3979
0
    return code;
3980
0
}
3981
3982
/* Function prototypes */
3983
int put_param_pdf14_spot_names(gx_device * pdev,
3984
                gs_separations * pseparations, gs_param_list * plist);
3985
80.0k
#define PDF14NumSpotColorsParamName "PDF14NumSpotColors"
3986
3987
/*
3988
 * The put_params method for the PDF 1.4 device will check if the
3989
 * target device has closed and, if so, close itself.  Note:  This routine is
3990
 * currently being used by both the pdf14_clist_device and the pdf_device.
3991
 * Please make sure that any changes are either applicable to both devices
3992
 * or clone the routine for each device.
3993
 */
3994
static  int
3995
pdf14_put_params(gx_device * dev, gs_param_list * plist)
3996
0
{
3997
0
    pdf14_device * pdev = (pdf14_device *)dev;
3998
0
    gx_device * tdev = pdev->target;
3999
0
    bool was_open = tdev->is_open;
4000
0
    int code = 0, code2 = 0;
4001
4002
0
    if (tdev != 0 && (code = dev_proc(tdev, put_params)(tdev, plist)) >= 0) {
4003
0
        gx_device_decache_colors(dev);
4004
0
        if (!tdev->is_open) {
4005
0
            code = gs_closedevice(dev);
4006
0
            if (code == 0)
4007
0
                code = was_open ? 1 : 0;   /* target device closed */
4008
0
        }
4009
0
        code2 = gs_pdf14_device_copy_params(dev, tdev);
4010
0
        if (code2 < 0)
4011
0
            code = code2;
4012
0
    }
4013
0
    return code;
4014
0
}
4015
4016
/*
4017
 * Copy marking related parameters into the PDF 1.4 device structure for use
4018
 * by pdf14_fill_rectangle.
4019
 */
4020
static  void
4021
pdf14_set_marking_params(gx_device *dev, const gs_gstate *pgs)
4022
31.6M
{
4023
31.6M
    pdf14_device * pdev = (pdf14_device *)dev;
4024
4025
31.6M
    if (pgs->alphaisshape) {
4026
405k
        pdev->opacity = 1.0;
4027
405k
        if (pgs->is_fill_color) {
4028
394k
            pdev->shape = pgs->fillconstantalpha;
4029
394k
        } else {
4030
10.9k
            pdev->shape = pgs->strokeconstantalpha;
4031
10.9k
        }
4032
31.2M
    } else {
4033
31.2M
        pdev->shape = 1.0;
4034
31.2M
        if (pgs->is_fill_color) {
4035
11.0M
            pdev->opacity = pgs->fillconstantalpha;
4036
20.1M
        } else {
4037
20.1M
            pdev->opacity = pgs->strokeconstantalpha;
4038
20.1M
        }
4039
31.2M
    }
4040
31.6M
    pdev->alpha = pdev->opacity * pdev->shape;
4041
31.6M
    pdev->blend_mode = pgs->blend_mode;
4042
31.6M
    if (pdev->icc_struct->overprint_control != gs_overprint_control_disable) {
4043
31.6M
        pdev->overprint = pgs->overprint;
4044
31.6M
        pdev->stroke_overprint = pgs->stroke_overprint;
4045
31.6M
    } else {
4046
0
        pdev->overprint = false;
4047
0
        pdev->stroke_overprint = false;
4048
0
    }
4049
4050
31.6M
    pdev->fillconstantalpha = pgs->fillconstantalpha;
4051
31.6M
    pdev->strokeconstantalpha = pgs->strokeconstantalpha;
4052
4053
31.6M
    if (pgs->is_fill_color)
4054
11.4M
        pdev->op_state = GS_OP_STATE_FILL;
4055
20.1M
    else
4056
20.1M
        pdev->op_state = GS_OP_STATE_STROKE;
4057
4058
31.6M
    if_debug6m('v', dev->memory,
4059
31.6M
               "[v]set_marking_params, opacity = %g, shape = %g, bm = %d, op = %d, eop = %d seop = %d\n",
4060
31.6M
               pdev->opacity, pdev->shape, pgs->blend_mode, pgs->overprint, pdev->effective_overprint_mode,
4061
31.6M
               pdev->stroke_effective_op_mode);
4062
31.6M
}
4063
4064
static  void
4065
update_lop_for_pdf14(gs_gstate *pgs, const gx_drawing_color *pdcolor)
4066
23.1M
{
4067
23.1M
    bool hastrans = false;
4068
4069
    /* We'd really rather not have to set the pdf14 bit in the lop, as this
4070
     * makes other operations much slower. We have no option however, if the
4071
     * current colour involves transparency, or if it's anything other than
4072
     * a completely solid (or transparent) operation in the normal blend mode.
4073
     */
4074
23.1M
    if (pdcolor != NULL)
4075
23.1M
    {
4076
23.1M
        if (gx_dc_is_pattern1_color(pdcolor) &&
4077
436k
            gx_pattern1_get_transptr(pdcolor) != NULL) {
4078
5.22k
            hastrans = true;
4079
23.1M
        } else if (gx_dc_is_pattern2_color(pdcolor)) {
4080
            /* FIXME: Here we assume that ALL type 2 patterns are
4081
             * transparent - this test could be better. */
4082
11.3k
            hastrans = true;
4083
11.3k
        }
4084
23.1M
    }
4085
    /* The only idempotent blend modes are Normal, Darken and Lighten.
4086
       This appears to be the only place where this test is done so
4087
       not adding a is_idempotent method */
4088
23.1M
    if ((pgs->blend_mode != BLEND_MODE_Normal &&
4089
119k
        pgs->blend_mode != BLEND_MODE_Darken &&
4090
114k
        pgs->blend_mode != BLEND_MODE_Lighten) ||
4091
23.0M
        (pgs->fillconstantalpha != 1.0) ||
4092
22.8M
        (pgs->strokeconstantalpha != 1.0) ||
4093
22.7M
        (hastrans))
4094
347k
    {
4095
        /*
4096
         * The blend operations are not idempotent.  Force non-idempotent
4097
         * filling and stroking operations.
4098
         */
4099
347k
        pgs->log_op |= lop_pdf14;
4100
347k
    }
4101
23.1M
}
4102
4103
static int
4104
push_shfill_group(pdf14_clist_device *pdev,
4105
                  gs_gstate *pgs,
4106
                  gs_fixed_rect *box)
4107
340
{
4108
340
    gs_transparency_group_params_t params = { 0 };
4109
340
    int code;
4110
340
    gs_rect cb;
4111
340
    gs_gstate fudged_pgs = *pgs;
4112
4113
340
    params.shade_group = true;
4114
4115
    /* gs_begin_transparency_group takes a bbox that it then
4116
     * transforms by ctm. Our bbox has already been transformed,
4117
     * so clear out the ctm. */
4118
340
    fudged_pgs.ctm.xx = 1.0;
4119
340
    fudged_pgs.ctm.xy = 0;
4120
340
    fudged_pgs.ctm.yx = 0;
4121
340
    fudged_pgs.ctm.yy = 1.0;
4122
340
    fudged_pgs.ctm.tx = 0;
4123
340
    fudged_pgs.ctm.ty = 0;
4124
340
    cb.p.x = fixed2int_pixround(box->p.x);
4125
340
    cb.p.y = fixed2int_pixround(box->p.y);
4126
340
    cb.q.x = fixed2int_pixround(box->q.x);
4127
340
    cb.q.y = fixed2int_pixround(box->q.y);
4128
4129
340
    params.Isolated = false;
4130
340
    params.Knockout = true;
4131
340
    params.page_group = false;
4132
340
    params.group_opacity = fudged_pgs.fillconstantalpha;
4133
340
    params.group_shape = 1.0;
4134
340
    code = gs_begin_transparency_group(&fudged_pgs, &params, &cb, PDF14_BEGIN_TRANS_GROUP);
4135
4136
    /* We have the group handle the blendmode and the opacity,
4137
     * and continue with the existing graphics state reset
4138
     * to normal, opaque operation. We could do it the other
4139
     * way around, but this way means that if we push a knockout
4140
     * group for a stroke, and then the code calls back into
4141
     * the fill operation as part of doing the stroking, we don't
4142
     * push another one. */
4143
340
    gs_setblendmode(pgs, BLEND_MODE_Normal);
4144
340
    gs_setfillconstantalpha(pgs, 1.0);
4145
340
    gs_setstrokeconstantalpha(pgs, 1.0);
4146
340
    if (pdev) {
4147
340
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
4148
340
        if (code < 0)
4149
0
            return code;
4150
340
    }
4151
4152
340
    return code;
4153
340
}
4154
4155
static int
4156
pop_shfill_group(gs_gstate *pgs)
4157
338
{
4158
338
     return gs_end_transparency_group(pgs);
4159
338
}
4160
4161
static int
4162
pdf14_fill_path(gx_device *dev, const gs_gstate *pgs,
4163
                           gx_path *ppath, const gx_fill_params *params,
4164
                           const gx_drawing_color *pdcolor,
4165
                           const gx_clip_path *pcpath)
4166
17.6M
{
4167
17.6M
    gs_gstate new_pgs = *pgs;
4168
17.6M
    int code = 0;
4169
17.6M
    gs_pattern2_instance_t *pinst = NULL;
4170
17.6M
    int push_group = 0;
4171
4172
17.6M
    code = pdf14_initialize_ctx(dev, pgs);
4173
17.6M
    if (code < 0)
4174
0
        return code;
4175
4176
17.6M
    if (pdcolor == NULL)
4177
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4178
17.6M
    ((pdf14_device *)dev)->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_STROKE;
4179
17.6M
    if (gx_dc_is_pattern1_color(pdcolor)){
4180
483k
        if( gx_pattern1_get_transptr(pdcolor) != NULL ||
4181
464k
            gx_pattern1_clist_has_trans(pdcolor) ){
4182
            /* In this case, we need to push a transparency group
4183
               and tile the pattern color, which is stored in
4184
               a pdf14 device buffer in the ctile object memember
4185
               variable ttrans */
4186
#if RAW_DUMP
4187
            /* Since we do not get a put_image to view what
4188
               we have do it now */
4189
            if (gx_pattern1_get_transptr(pdcolor) != NULL) {
4190
                const pdf14_device * ppatdev14 = (const pdf14_device *)
4191
                                pdcolor->colors.pattern.p_tile->ttrans->pdev14;
4192
                if (ppatdev14 != NULL) {  /* can occur during clist reading */
4193
                    byte *buf_ptr = ppatdev14->ctx->stack->data  +
4194
                        ppatdev14->ctx->stack->rect.p.y *
4195
                        ppatdev14->ctx->stack->rowstride +
4196
                        ppatdev14->ctx->stack->rect.p.x;
4197
                    dump_raw_buffer(ppatdev14->ctx->memory,
4198
                                    (ppatdev14->ctx->stack->rect.q.y -
4199
                                     ppatdev14->ctx->stack->rect.p.y),
4200
                                    (ppatdev14->ctx->stack->rect.q.x -
4201
                                     ppatdev14->ctx->stack->rect.p.x),
4202
                                    ppatdev14->ctx->stack->n_planes,
4203
                                    ppatdev14->ctx->stack->planestride,
4204
                                    ppatdev14->ctx->stack->rowstride,
4205
                                    "Pattern_Fill", buf_ptr,
4206
                                    ppatdev14->ctx->stack->deep);
4207
                    global_index++;
4208
                } else {
4209
                     gx_pattern_trans_t *patt_trans =
4210
                                        pdcolor->colors.pattern.p_tile->ttrans;
4211
                     dump_raw_buffer(patt_trans->mem,
4212
                                     patt_trans->rect.q.y-patt_trans->rect.p.y,
4213
                                     patt_trans->rect.q.x-patt_trans->rect.p.x,
4214
                                     patt_trans->n_chan,
4215
                                     patt_trans->planestride, patt_trans->rowstride,
4216
                                     "Pattern_Fill_clist",
4217
                                     patt_trans->transbytes +
4218
                                         patt_trans->rect.p.y * patt_trans->rowstride +
4219
                                         (patt_trans->rect.p.x<<patt_trans->deep),
4220
                                     patt_trans->deep);
4221
                    global_index++;
4222
                }
4223
            }
4224
#endif
4225
55.3k
            pdf14_set_marking_params(dev, &new_pgs);
4226
55.3k
            code = pdf14_tile_pattern_fill(dev, &new_pgs, ppath,
4227
55.3k
                params, pdcolor, pcpath);
4228
55.3k
            new_pgs.trans_device = NULL;
4229
55.3k
            new_pgs.has_transparency = false;
4230
55.3k
            return code;
4231
55.3k
        }
4232
483k
    }
4233
17.5M
    if (gx_dc_is_pattern2_color(pdcolor) ||
4234
17.5M
        pdcolor->type == &gx_dc_devn_masked) {
4235
        /* Non-idempotent blends require a transparency
4236
         * group to be pushed because shadings might
4237
         * paint several pixels twice. */
4238
16
        push_group = pgs->fillconstantalpha != 1.0 ||
4239
16
               !blend_is_idempotent(gs_currentblendmode(pgs));
4240
16
        pinst =
4241
16
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
4242
16
        pinst->saved->has_transparency = true;
4243
        /* The transparency color space operations are driven
4244
           by the pdf14 clist writer device.  */
4245
16
        pinst->saved->trans_device = dev;
4246
16
    }
4247
17.5M
    if (push_group) {
4248
0
        gs_fixed_rect box;
4249
0
        if (pcpath)
4250
0
            gx_cpath_outer_box(pcpath, &box);
4251
0
        else
4252
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4253
0
        if (ppath) {
4254
0
            gs_fixed_rect path_box;
4255
4256
0
            gx_path_bbox(ppath, &path_box);
4257
0
            if (box.p.x < path_box.p.x)
4258
0
                box.p.x = path_box.p.x;
4259
0
            if (box.p.y < path_box.p.y)
4260
0
                box.p.y = path_box.p.y;
4261
0
            if (box.q.x > path_box.q.x)
4262
0
                box.q.x = path_box.q.x;
4263
0
            if (box.q.y > path_box.q.y)
4264
0
                box.q.y = path_box.q.y;
4265
0
        }
4266
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4267
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4268
0
    } else
4269
17.5M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4270
17.5M
    pdf14_set_marking_params(dev, &new_pgs);
4271
17.5M
    if (code >= 0) {
4272
17.5M
        new_pgs.trans_device = dev;
4273
17.5M
        new_pgs.has_transparency = true;
4274
        /* ppath can permissibly be NULL here, if we want to have a
4275
         * shading or a pattern fill the clipping path. This upsets
4276
         * coverity, which is not smart enough to realise that the
4277
         * validity of a NULL ppath depends on the type of pdcolor.
4278
         * We'll mark it as a false positive. */
4279
17.5M
        code = gx_default_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4280
17.5M
        new_pgs.trans_device = NULL;
4281
17.5M
        new_pgs.has_transparency = false;
4282
17.5M
    }
4283
17.5M
    if (code >= 0 && push_group) {
4284
0
        code = pop_shfill_group(&new_pgs);
4285
0
        pdf14_set_marking_params(dev, pgs);
4286
0
    }
4287
17.5M
    if (pinst != NULL){
4288
16
        pinst->saved->trans_device = NULL;
4289
16
    }
4290
17.5M
    return code;
4291
17.6M
}
4292
4293
static  int
4294
pdf14_stroke_path(gx_device *dev, const gs_gstate *pgs,
4295
                             gx_path *ppath, const gx_stroke_params *params,
4296
                             const gx_drawing_color *pdcolor,
4297
                             const gx_clip_path *pcpath)
4298
4.28M
{
4299
4.28M
    gs_gstate new_pgs = *pgs;
4300
4.28M
    int push_group = 0;
4301
4.28M
    int code = 0;
4302
4303
4.28M
    if (pdcolor == NULL)
4304
0
       return_error(gs_error_unknownerror);  /* color must be defined */
4305
4306
4.28M
    code = pdf14_initialize_ctx(dev, pgs);
4307
4.28M
    if (code < 0)
4308
0
        return code;
4309
4310
4.28M
    if (gx_dc_is_pattern2_color(pdcolor)) {
4311
        /* Non-idempotent blends require a transparency
4312
         * group to be pushed because shadings might
4313
         * paint several pixels twice. */
4314
0
        push_group = pgs->strokeconstantalpha != 1.0 ||
4315
0
               !blend_is_idempotent(gs_currentblendmode(pgs));
4316
0
    }
4317
4.28M
    if (push_group) {
4318
0
        gs_fixed_rect box;
4319
0
        if (pcpath)
4320
0
            gx_cpath_outer_box(pcpath, &box);
4321
0
        else
4322
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
4323
4324
        /* For fill_path, we accept ppath == NULL to mean
4325
         * fill the entire clipping region. That makes no
4326
         * sense for stroke_path, hence ppath is always non
4327
         * NULL here. */
4328
0
        {
4329
0
            gs_fixed_rect path_box;
4330
0
            gs_fixed_point expansion;
4331
4332
0
            gx_path_bbox(ppath, &path_box);
4333
            /* Expand the path bounding box by the scaled line width. */
4334
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
4335
                /* The expansion is so large it caused a limitcheck. */
4336
0
                path_box.p.x = path_box.p.y = min_fixed;
4337
0
                path_box.q.x = path_box.q.y = max_fixed;
4338
0
            } else {
4339
0
                expansion.x += pgs->fill_adjust.x;
4340
0
                expansion.y += pgs->fill_adjust.y;
4341
                /*
4342
                 * It's theoretically possible for the following computations to
4343
                 * overflow, so we need to check for this.
4344
                 */
4345
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
4346
0
                                path_box.p.x - expansion.x);
4347
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
4348
0
                                path_box.p.y - expansion.y);
4349
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
4350
0
                                path_box.q.x + expansion.x);
4351
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
4352
0
                                path_box.q.y + expansion.y);
4353
0
            }
4354
0
            if (box.p.x < path_box.p.x)
4355
0
                box.p.x = path_box.p.x;
4356
0
            if (box.p.y < path_box.p.y)
4357
0
                box.p.y = path_box.p.y;
4358
0
            if (box.q.x > path_box.q.x)
4359
0
                box.q.x = path_box.q.x;
4360
0
            if (box.q.y > path_box.q.y)
4361
0
                box.q.y = path_box.q.y;
4362
0
        }
4363
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
4364
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
4365
0
        code = push_shfill_group(NULL, &new_pgs, &box);
4366
0
    } else
4367
4.28M
        update_lop_for_pdf14(&new_pgs, pdcolor);
4368
4.28M
    pdf14_set_marking_params(dev, &new_pgs);
4369
4.28M
    if (code >= 0) {
4370
4.28M
        GS_OP_FS_STATE save_op_state = ((pdf14_device *)dev)->op_state;
4371
4372
4.28M
        ((pdf14_device*)dev)->op_state = GS_OP_STATE_STROKE;
4373
4.28M
        code = gx_default_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
4374
4.28M
        ((pdf14_device*)dev)->op_state = save_op_state;
4375
4.28M
    }
4376
4.28M
    if (code >= 0 && push_group) {
4377
0
        code = pop_shfill_group(&new_pgs);
4378
0
        pdf14_set_marking_params(dev, pgs);
4379
0
    }
4380
4381
4.28M
    return code;
4382
4.28M
}
4383
4384
/* Pull out steps of transparency updates for fill/stroke
4385
   so that they can be invoked elsewhere (e.g.
4386
   when the abuf device is handling the stroke/fill */
4387
4388
/* Set-up prior to fill operation in fill-stroke */
4389
static int
4390
pdf14_fill_stroke_prefill(gx_device* dev, gs_gstate* pgs, gx_path* ppath,
4391
    const gx_clip_path* pcpath, float fill_alpha, float stroke_alpha,
4392
    gs_blend_mode_t blend_mode, bool* op_ca_eq_CA, bool* path_empty, gs_log2_scale_point path_log2scale)
4393
22.0k
{
4394
22.0k
    int code = 0;
4395
22.0k
    gs_transparency_group_params_t params = { 0 };
4396
22.0k
    gs_fixed_rect clip_bbox;
4397
22.0k
    gs_rect bbox, group_stroke_box;
4398
22.0k
    gs_fixed_rect path_bbox;
4399
22.0k
    int expansion_code;
4400
22.0k
    gs_fixed_point expansion;
4401
22.0k
    pdf14_device* p14dev = (pdf14_device*)dev;
4402
4403
22.0k
    *path_empty = false;
4404
4405
22.0k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
4406
22.0k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
4407
54
    {
4408
54
        *op_ca_eq_CA = true;
4409
54
        *path_empty = true;
4410
54
        return 0;
4411
54
    }
4412
4413
    /* The clip box returned here is scaled up by path_log2scale, so we need
4414
     * to scale down by this later. */
4415
22.0k
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
4416
22.0k
    if (code < 0 && code != gs_error_unknownerror)
4417
0
        return code;
4418
4419
22.0k
    if (code == gs_error_unknownerror) {
4420
        /* didn't get clip box from gx_curr_fixed_bbox */
4421
        /* This is NOT scaled by path_log2scale, so allow for the fact we'll be
4422
         * scaling down by this in a moment. */
4423
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
4424
0
        clip_bbox.q.x = int2fixed(dev->width) << path_log2scale.x;
4425
0
        clip_bbox.q.y = int2fixed(dev->height) << path_log2scale.y;
4426
0
    }
4427
    /* pcpath->outer_box is scaled by path_log2scale too. */
4428
22.0k
    if (pcpath)
4429
22.0k
        rect_intersect(clip_bbox, pcpath->outer_box);
4430
4431
    /* expand the ppath using stroke expansion rule, then intersect it */
4432
22.0k
    code = gx_path_bbox(ppath, &path_bbox);
4433
4434
    /* If we are coming from the abuf device, the path has been scaled
4435
       by a factor (see alpha_buffer_init).  Undo the scaling here so
4436
       on the path_bbox so that we get the proper bounding box for our group. */
4437
22.0k
    if (path_log2scale.x != 0 || path_log2scale.y != 0) {
4438
0
        path_bbox.p.x = path_bbox.p.x >> path_log2scale.x;
4439
0
        path_bbox.q.x = path_bbox.q.x >> path_log2scale.x;
4440
0
        path_bbox.p.y = path_bbox.p.y >> path_log2scale.y;
4441
0
        path_bbox.q.y = path_bbox.q.y >> path_log2scale.y;
4442
0
        clip_bbox.p.x = clip_bbox.p.x >> path_log2scale.x;
4443
0
        clip_bbox.q.x = clip_bbox.q.x >> path_log2scale.x;
4444
0
        clip_bbox.p.y = clip_bbox.p.y >> path_log2scale.y;
4445
0
        clip_bbox.q.y = clip_bbox.q.y >> path_log2scale.y;
4446
0
    }
4447
4448
22.0k
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0) {
4449
1.92k
        *path_empty = true;
4450
1.92k
        return 0; /* ignore empty path -- could try to send back a positive code for this but
4451
                     there are simply too many return cases that I can't account for. */
4452
1.92k
    }
4453
20.1k
    if (code < 0)
4454
0
        return code;
4455
4456
20.1k
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
4457
20.1k
    if (expansion_code >= 0) {
4458
20.0k
        path_bbox.p.x -= expansion.x;
4459
20.0k
        path_bbox.p.y -= expansion.y;
4460
20.0k
        path_bbox.q.x += expansion.x;
4461
20.0k
        path_bbox.q.y += expansion.y;
4462
20.0k
    }
4463
20.1k
    rect_intersect(path_bbox, clip_bbox);
4464
20.1k
    bbox.p.x = fixed2float(path_bbox.p.x);
4465
20.1k
    bbox.p.y = fixed2float(path_bbox.p.y);
4466
20.1k
    bbox.q.x = fixed2float(path_bbox.q.x);
4467
20.1k
    bbox.q.y = fixed2float(path_bbox.q.y);
4468
4469
20.1k
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
4470
20.1k
    if (code < 0)
4471
2
        return code;
4472
4473
20.1k
    if (p14dev->overprint != pgs->overprint || p14dev->stroke_overprint != pgs->stroke_overprint) {
4474
0
        p14dev->overprint = pgs->overprint;
4475
0
        p14dev->stroke_overprint = pgs->stroke_overprint;
4476
0
    }
4477
4478
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
4479
20.1k
    if (fill_alpha == stroke_alpha &&
4480
4.83k
        p14dev->overprint && p14dev->stroke_overprint &&
4481
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
4482
4483
        /* Push a non-isolated non-knockout group with alpha = 1.0 and
4484
           compatible overprint mode.  Group will be composited with
4485
           original alpha and blend mode */
4486
0
        *op_ca_eq_CA = true;
4487
0
        params.Isolated = false;
4488
0
        params.group_color_type = UNKNOWN;
4489
0
        params.Knockout = false;
4490
0
        params.page_group = false;
4491
0
        params.group_opacity = 1.0;
4492
0
        params.group_shape = fill_alpha;
4493
4494
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
4495
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4496
0
        if (code < 0)
4497
0
            return code;
4498
4499
        /* Change fill alpha to 1.0 and blend mode to compatible overprint for actual drawing */
4500
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
4501
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4502
4503
20.1k
    } else {
4504
        /* Push a non-isolated knockout group. Do not change the alpha or
4505
            blend modes. Note: we need to draw those that have alpha = 0 */
4506
20.1k
        *op_ca_eq_CA = false;
4507
20.1k
        params.Isolated = false;
4508
20.1k
        params.group_color_type = UNKNOWN;
4509
20.1k
        params.Knockout = true;
4510
20.1k
        params.page_group = false;
4511
20.1k
        params.group_shape = 1.0;
4512
20.1k
        params.group_opacity = 1.0;
4513
4514
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
4515
20.1k
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
4516
20.1k
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
4517
20.1k
        if (code < 0)
4518
0
            return code;
4519
4520
        /* restore blend mode for actual drawing in the group */
4521
20.1k
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4522
4523
        /* If we are in an overprint situation, set the blend mode to compatible
4524
            overprint */
4525
20.1k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4526
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4527
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4528
20.1k
    }
4529
20.1k
    p14dev->op_state = GS_OP_STATE_FILL;
4530
20.1k
    return code;
4531
20.1k
}
4532
4533
/* Set-up prior to stroke operation in fill-stroke */
4534
static void
4535
pdf14_fill_stroke_prestroke(gx_device* dev, gs_gstate* pgs, float stroke_alpha,
4536
    gs_blend_mode_t blend_mode, bool op_ca_eq_CA)
4537
20.1k
{
4538
20.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4539
4540
20.1k
    if (op_ca_eq_CA) {
4541
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
4542
20.1k
    } else {
4543
20.1k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->overprint &&
4544
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4545
0
            (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4546
4547
        /* Note that the stroke can end up doing fill methods */
4548
20.1k
        (void)gs_setfillconstantalpha(pgs, stroke_alpha);
4549
4550
20.1k
        if ((p14dev->icc_struct->overprint_control != gs_overprint_control_disable) && pgs->stroke_overprint &&
4551
0
            dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
4552
0
            (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
4553
20.1k
    }
4554
20.1k
    p14dev->op_state = GS_OP_STATE_STROKE;
4555
20.1k
}
4556
4557
/* Cleanup after the stroke in fill-stroke  */
4558
static int
4559
pdf14_fill_stroke_poststroke(gx_device* dev, gs_gstate* pgs, float fill_alpha, bool op_ca_eq_CA)
4560
20.1k
{
4561
20.1k
    int code;
4562
4563
20.1k
    if (!op_ca_eq_CA) {
4564
        /* Bug 703324 we need to reset the fill constant alpha in the graphics
4565
          * state to the correct saved value. We also need to reset the 'opacity' member of the
4566
          * device, because some device methods (eg fill_masked_image) don't take a graphics
4567
          * state pointer as a parameter and so are unable to set the opacity value themselves.
4568
          * We therefore need to make sure it is set according to the current fill state.
4569
          */
4570
20.1k
        (void)gs_setfillconstantalpha(pgs, fill_alpha);
4571
20.1k
        code = gs_update_trans_marking_params(pgs);
4572
20.1k
        if (code < 0)
4573
0
            return code;
4574
20.1k
        pdf14_set_marking_params(dev, pgs);
4575
20.1k
    }
4576
4577
20.1k
    return 0;
4578
20.1k
}
4579
4580
/* cleanup in fill-stroke  */
4581
static int
4582
pdf14_fill_stroke_cleanup(gx_device* dev, gs_gstate* pgs, float fill_alpha, float stroke_alpha,
4583
    gs_blend_mode_t blend_mode, GS_OP_FS_STATE save_op_state)
4584
20.1k
{
4585
20.1k
    pdf14_device* p14dev = (pdf14_device*)dev;
4586
20.1k
    int code2;
4587
20.1k
    int code = 0;
4588
4589
    /* Restore the state */
4590
20.1k
    p14dev->op_state = save_op_state;
4591
20.1k
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
4592
20.1k
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
4593
20.1k
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
4594
4595
20.1k
    code2 = gs_end_transparency_group(pgs);
4596
20.1k
    if (code2 < 0) {
4597
        /* At this point things have gone very wrong. We should just shut down */
4598
0
        code = gs_abort_pdf14trans_device(pgs);
4599
0
        return code2;
4600
0
    }
4601
20.1k
    return code;
4602
20.1k
}
4603
4604
static int
4605
pdf14_fill_stroke_path(gx_device *dev, const gs_gstate *cpgs, gx_path *ppath,
4606
    const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill,
4607
    const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke,
4608
    const gx_clip_path *pcpath)
4609
85.6k
{
4610
85.6k
    bool op_ca_eq_CA;
4611
85.6k
    bool path_empty;
4612
85.6k
    int code;
4613
85.6k
    float stroke_alpha = cpgs->strokeconstantalpha;
4614
85.6k
    float fill_alpha = cpgs->fillconstantalpha;
4615
85.6k
    gs_blend_mode_t blend_mode = cpgs->blend_mode;
4616
85.6k
    pdf14_device* p14dev = (pdf14_device*)dev;
4617
85.6k
    GS_OP_FS_STATE save_op_state = p14dev->op_state;
4618
85.6k
    gs_log2_scale_point path_log2scale;
4619
85.6k
    bool group_needed = true;
4620
85.6k
    gx_device* curr_pgs_dev = cpgs->device;
4621
4622
85.6k
    union {
4623
85.6k
        const gs_gstate* cpgs;
4624
85.6k
        gs_gstate* pgs;
4625
85.6k
    } const_breaker;
4626
85.6k
    gs_gstate* pgs;
4627
4628
    /* Break const just once, neatly */
4629
85.6k
    const_breaker.cpgs = cpgs;
4630
85.6k
    pgs = const_breaker.pgs;
4631
85.6k
    path_log2scale.x = 0;
4632
85.6k
    path_log2scale.y = 0;
4633
4634
85.6k
    code = pdf14_initialize_ctx(dev, pgs);
4635
85.6k
    if (code < 0)
4636
0
        return code;
4637
4638
    /* From looking at what AR is doing, it appears that if alpha is 1 and
4639
     * blend is normal we don't do a group push. Just do the stroke
4640
     * and the fill, even with overprint */
4641
85.6k
    if (stroke_alpha == 1 && fill_alpha == 1 && blend_mode == BLEND_MODE_Normal)
4642
63.5k
        group_needed = false;
4643
4644
85.6k
    if (group_needed) {
4645
22.0k
        pgs->device = dev; /* This is needed due to the gs_trans calls.  This method
4646
                              can be called on the clist writer side when dealing
4647
                              with the abuf/pdf14 interaction. Those calls have to
4648
                              go through the gs_trans API not the gx_trans or pdf14
4649
                              methods.  Perhaps these methods should have a different
4650
                              suffix, but they are static methods here in the pdf14
4651
                              file. */
4652
22.0k
        code = pdf14_fill_stroke_prefill(dev, pgs, ppath, pcpath, fill_alpha, stroke_alpha,
4653
22.0k
            blend_mode, &op_ca_eq_CA, &path_empty, path_log2scale);
4654
22.0k
        pgs->device = curr_pgs_dev;
4655
22.0k
        if (code < 0)
4656
2
            goto cleanup;
4657
22.0k
        if (path_empty)
4658
1.98k
            return 0;
4659
22.0k
    }
4660
4661
83.7k
    code = pdf14_fill_path(dev, pgs, ppath, fill_params, pdcolor_fill, pcpath);
4662
83.7k
    if (code < 0)
4663
0
        goto cleanup;
4664
4665
83.7k
    if (group_needed)
4666
20.1k
        pdf14_fill_stroke_prestroke(dev, pgs, stroke_alpha, blend_mode, op_ca_eq_CA);
4667
83.7k
    gs_swapcolors_quick(pgs);
4668
4669
4670
#if RAW_DUMP
4671
    /* Dump the current buffer to see what we have. */
4672
    dump_raw_buffer(p14dev->ctx->memory,
4673
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4674
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4675
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4676
        "BeforeStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4677
    global_index++;
4678
#endif
4679
4680
83.7k
    code = pdf14_stroke_path(dev, pgs, ppath, stroke_params, pdcolor_stroke, pcpath);
4681
83.7k
    gs_swapcolors_quick(pgs);
4682
83.7k
    if (code < 0) {
4683
0
        goto cleanup;
4684
0
    }
4685
4686
#if RAW_DUMP
4687
    /* Dump the current buffer to see what we have. */
4688
    dump_raw_buffer(p14dev->ctx->memory,
4689
        p14dev->ctx->stack->rect.q.y - p14dev->ctx->stack->rect.p.y,
4690
        p14dev->ctx->stack->rowstride >> p14dev->ctx->stack->deep, p14dev->ctx->stack->n_planes,
4691
        p14dev->ctx->stack->planestride, p14dev->ctx->stack->rowstride,
4692
        "AfterStrokeOnFillStroke", p14dev->ctx->stack->data, p14dev->ctx->stack->deep);
4693
    global_index++;
4694
#endif
4695
83.7k
    if (group_needed)
4696
20.1k
        code = pdf14_fill_stroke_poststroke(dev, pgs, fill_alpha, op_ca_eq_CA);
4697
4698
83.7k
cleanup:
4699
83.7k
    if (group_needed) {
4700
20.1k
        int code1;
4701
20.1k
        pgs->device = dev; /* This is needed due to the gs_trans calls */
4702
20.1k
        code1 = pdf14_fill_stroke_cleanup(dev, pgs, fill_alpha, stroke_alpha, blend_mode,
4703
20.1k
            save_op_state);
4704
20.1k
        if (code1 < 0)
4705
0
            code = code1;
4706
20.1k
        pgs->device = curr_pgs_dev;
4707
20.1k
    }
4708
83.7k
    return code;
4709
83.7k
}
4710
4711
static int
4712
pdf14_copy_alpha(gx_device * dev, const byte * data, int data_x,
4713
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4714
                      gx_color_index color, int depth)
4715
0
{
4716
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4717
0
                                  color, NULL, depth, false);
4718
0
}
4719
4720
static int
4721
pdf14_copy_alpha_hl_color(gx_device * dev, const byte * data, int data_x,
4722
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
4723
                      const gx_drawing_color *pdcolor, int depth)
4724
0
{
4725
0
    return pdf14_copy_alpha_color(dev, data, data_x, aa_raster, id, x, y, w, h,
4726
0
                                  0, pdcolor, depth, true);
4727
0
}
4728
4729
static int
4730
do_pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
4731
                          int aa_raster, gx_bitmap_id id, int x, int y,
4732
                          int w, int h, gx_color_index color,
4733
                          const gx_device_color *pdc, int depth, bool devn)
4734
0
{
4735
0
    const byte *aa_row;
4736
0
    pdf14_device *pdev = (pdf14_device *)dev;
4737
0
    pdf14_buf *buf = pdev->ctx->stack;
4738
0
    int i, j, k;
4739
0
    byte *bline, *line, *dst_ptr, *back_ptr;
4740
0
    byte src[PDF14_MAX_PLANES];
4741
0
    byte dst[PDF14_MAX_PLANES] = { 0 };
4742
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4743
0
    bool additive = pdev->ctx->additive;
4744
0
    intptr_t rowstride = buf->rowstride;
4745
0
    intptr_t planestride = buf->planestride;
4746
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4747
0
    bool has_alpha_g = buf->has_alpha_g;
4748
0
    bool has_shape = buf->has_shape;
4749
0
    bool has_tags = buf->has_tags;
4750
0
    bool knockout = buf->knockout;
4751
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4752
0
        blend_mode == BLEND_MODE_Compatible ||
4753
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4754
0
    int num_chan = buf->n_chan;
4755
0
    int num_comp = num_chan - 1;
4756
0
    intptr_t shape_off = num_chan * planestride;
4757
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4758
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4759
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4760
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4761
0
                                 pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4762
0
    gx_color_index comps;
4763
0
    byte shape = 0; /* Quiet compiler. */
4764
0
    byte src_alpha;
4765
0
    int alpha2_aa, alpha_aa, sx;
4766
0
    int alpha_aa_act;
4767
0
    int xoff;
4768
0
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
4769
0
    int shift = 8;
4770
0
    bool has_backdrop = buf->backdrop != NULL;
4771
4772
0
    if (buf->data == NULL)
4773
0
        return 0;
4774
0
    aa_row = data;
4775
0
    if (has_tags) {
4776
0
        if (devn)
4777
0
            curr_tag = pdc->tag;
4778
0
        else
4779
0
            curr_tag = (color >> (num_comp*8)) & 0xff;
4780
0
    }
4781
4782
0
    if (devn) {
4783
0
        if (additive) {
4784
0
            for (j = 0; j < num_comp; j++) {
4785
0
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
4786
0
            }
4787
0
        } else {
4788
0
            for (j = 0; j < num_comp; j++) {
4789
0
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
4790
0
            }
4791
0
        }
4792
0
    } else
4793
0
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
4794
0
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
4795
0
    if (has_shape)
4796
0
        shape = (byte)floor (255 * pdev->shape + 0.5);
4797
    /* Limit the area we write to the bounding rectangle for this buffer */
4798
0
    if (x < buf->rect.p.x) {
4799
0
        xoff = data_x + buf->rect.p.x - x;
4800
0
        w += x - buf->rect.p.x;
4801
0
        x = buf->rect.p.x;
4802
0
    } else {
4803
0
        xoff = data_x;
4804
0
    }
4805
0
    if (y < buf->rect.p.y) {
4806
0
      h += y - buf->rect.p.y;
4807
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
4808
0
      y = buf->rect.p.y;
4809
0
    }
4810
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
4811
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
4812
    /* Update the dirty rectangle. */
4813
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
4814
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
4815
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
4816
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
4817
4818
    /* composite with backdrop only. */
4819
0
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4820
0
    if (knockout && has_backdrop)
4821
0
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
4822
0
    else
4823
0
        bline = line;
4824
4825
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
4826
0
        back_ptr = bline;
4827
0
        dst_ptr = line;
4828
0
        sx = xoff;
4829
0
        for (i = 0; i < w; ++i, ++sx) {
4830
            /* Complement the components for subtractive color spaces */
4831
0
            if (additive) {
4832
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
4833
0
                    dst[k] = back_ptr[k * planestride];
4834
0
            } else { /* Complement the components for subtractive color spaces */
4835
0
                for (k = 0; k < num_comp; ++k)
4836
0
                    dst[k] = 255 - back_ptr[k * planestride];
4837
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
4838
0
            }
4839
            /* Get the aa alpha from the buffer */
4840
0
            switch(depth)
4841
0
            {
4842
0
            case 2:  /* map 0 - 3 to 0 - 255 */
4843
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
4844
0
                break;
4845
0
            case 4:
4846
0
                alpha2_aa = aa_row[sx >> 1];
4847
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
4848
0
                break;
4849
0
            case 8:
4850
0
                alpha_aa = aa_row[sx];
4851
0
                break;
4852
0
            default:
4853
0
                return_error(gs_error_rangecheck);
4854
0
            }
4855
0
            if (alpha_aa != 0) {  /* This does happen */
4856
0
                if (alpha_aa != 255) {
4857
                    /* We have an alpha value from aa */
4858
0
                    alpha_aa_act = alpha_aa;
4859
0
                    if (src_alpha != 255) {
4860
                        /* Need to combine it with the existing alpha */
4861
0
                        int tmp = src_alpha * alpha_aa_act + 0x80;
4862
0
                        alpha_aa_act = (tmp + (tmp >> 8)) >> 8;
4863
0
                    }
4864
                    /* Set our source alpha value appropriately */
4865
0
                    src[num_comp] = alpha_aa_act;
4866
0
                } else {
4867
                    /* We may have to reset this is it was changed as we
4868
                       moved across the row */
4869
0
                    src[num_comp] = src_alpha;
4870
0
                }
4871
0
                if (knockout) {
4872
0
                    if (buf->isolated) {
4873
0
                        art_pdf_knockoutisolated_group_8(dst, src, num_comp);
4874
0
                    } else {
4875
0
                        art_pdf_composite_knockout_8(dst, src, num_comp,
4876
0
                            blend_mode, pdev->blend_procs, pdev);
4877
0
                    }
4878
0
                } else {
4879
0
                    art_pdf_composite_pixel_alpha_8(dst, src, num_comp, blend_mode, num_comp,
4880
0
                                                    pdev->blend_procs, pdev);
4881
0
                }
4882
                /* Complement the results for subtractive color spaces */
4883
0
                if (additive) {
4884
0
                    for (k = 0; k < num_chan; ++k)
4885
0
                        dst_ptr[k * planestride] = dst[k];
4886
0
                } else {
4887
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
4888
0
                        for (k = 0, comps = drawn_comps; comps != 0;
4889
0
                                ++k, comps >>= 1) {
4890
0
                            if ((comps & 0x1) != 0) {
4891
0
                                dst_ptr[k * planestride] = 255 - dst[k];
4892
0
                            }
4893
0
                        }
4894
                        /* The alpha channel */
4895
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4896
0
                    } else {
4897
0
                        for (k = 0; k < num_comp; ++k)
4898
0
                            dst_ptr[k * planestride] = 255 - dst[k];
4899
                        /* The alpha channel */
4900
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
4901
0
                    }
4902
0
                }
4903
0
                if (has_alpha_g) {
4904
0
                    int tmp = (255 - back_ptr[alpha_g_off]) * (255 - src[num_comp]) + 0x80;
4905
0
                    dst_ptr[alpha_g_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4906
0
                }
4907
0
                if (has_shape) {
4908
0
                    int tmp = (255 - back_ptr[shape_off]) * (255 - shape) + 0x80;
4909
0
                    dst_ptr[shape_off] = 255 - ((tmp + (tmp >> 8)) >> 8);
4910
0
                }
4911
0
                if (has_tags) {
4912
                    /* If alpha is 100% then set to curr_tag, else or */
4913
                    /* other than Normal BM, we always OR */
4914
0
                    if (src[num_comp] == 255 && tag_blend) {
4915
0
                        dst_ptr[tag_off] = curr_tag;
4916
0
                    } else {
4917
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
4918
0
                    }
4919
0
                }
4920
0
            }
4921
0
            ++dst_ptr;
4922
0
            ++back_ptr;
4923
0
        }
4924
0
        line += rowstride;
4925
0
        bline += rowstride;
4926
0
    }
4927
0
    return 0;
4928
0
}
4929
4930
static int
4931
do_pdf14_copy_alpha_color_16(gx_device * dev, const byte * data, int data_x,
4932
                             int aa_raster, gx_bitmap_id id, int x, int y,
4933
                             int w, int h, gx_color_index color,
4934
                             const gx_device_color *pdc, int depth, bool devn)
4935
0
{
4936
0
    const byte *aa_row;
4937
0
    pdf14_device *pdev = (pdf14_device *)dev;
4938
0
    pdf14_buf *buf = pdev->ctx->stack;
4939
0
    int i, j, k;
4940
0
    byte *bline, *line;
4941
0
    uint16_t *dst_ptr, *back_ptr;
4942
0
    uint16_t src[PDF14_MAX_PLANES];
4943
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
4944
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
4945
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
4946
0
        blend_mode == BLEND_MODE_Compatible ||
4947
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
4948
0
    bool additive = pdev->ctx->additive;
4949
0
    intptr_t rowstride = buf->rowstride;
4950
0
    int planestride = buf->planestride;
4951
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
4952
0
    bool has_alpha_g = buf->has_alpha_g;
4953
0
    bool has_shape = buf->has_shape;
4954
0
    bool has_tags = buf->has_tags;
4955
0
    bool knockout = buf->knockout;
4956
0
    int num_chan = buf->n_chan;
4957
0
    int num_comp = num_chan - 1;
4958
0
    intptr_t shape_off = num_chan * planestride;
4959
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
4960
0
    intptr_t tag_off = alpha_g_off + (has_alpha_g ? planestride : 0);
4961
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
4962
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
4963
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
4964
0
    gx_color_index comps;
4965
0
    uint16_t shape = 0; /* Quiet compiler. */
4966
0
    uint16_t src_alpha;
4967
0
    int alpha2_aa, alpha_aa, sx;
4968
0
    int alpha_aa_act;
4969
0
    int xoff;
4970
0
    bool has_backdrop = buf->backdrop != NULL;
4971
4972
0
    if (buf->data == NULL)
4973
0
        return 0;
4974
0
    aa_row = data;
4975
0
    if (has_tags) {
4976
0
        if (devn)
4977
0
            curr_tag = pdc->tag;
4978
0
        else
4979
0
            curr_tag = (color >> (num_comp*16)) & 0xff;
4980
0
    }
4981
4982
0
    if (devn) {
4983
0
        if (additive) {
4984
0
            for (j = 0; j < num_comp; j++) {
4985
0
                src[j] = pdc->colors.devn.values[j];
4986
0
            }
4987
0
        } else {
4988
0
            for (j = 0; j < num_comp; j++) {
4989
0
                src[j] = 65535 - pdc->colors.devn.values[j];
4990
0
            }
4991
0
        }
4992
0
    } else
4993
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
4994
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
4995
0
    if (has_shape)
4996
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
4997
    /* Limit the area we write to the bounding rectangle for this buffer */
4998
0
    if (x < buf->rect.p.x) {
4999
0
        xoff = data_x + buf->rect.p.x - x;
5000
0
        w += x - buf->rect.p.x;
5001
0
        x = buf->rect.p.x;
5002
0
    } else {
5003
0
        xoff = data_x;
5004
0
    }
5005
0
    if (y < buf->rect.p.y) {
5006
0
      h += y - buf->rect.p.y;
5007
0
      aa_row -= (y - buf->rect.p.y) * aa_raster;
5008
0
      y = buf->rect.p.y;
5009
0
    }
5010
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
5011
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
5012
    /* Update the dirty rectangle. */
5013
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
5014
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
5015
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
5016
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
5017
5018
    /* composite with backdrop only. */
5019
0
    line = buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5020
0
    if (knockout && has_backdrop)
5021
0
        bline = buf->backdrop + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride;
5022
0
    else
5023
0
        bline = line;
5024
5025
0
    planestride >>= 1;
5026
0
    rowstride   >>= 1;
5027
0
    alpha_g_off >>= 1;
5028
0
    shape_off   >>= 1;
5029
0
    tag_off     >>= 1;
5030
0
    for (j = 0; j < h; ++j, aa_row += aa_raster) {
5031
0
        back_ptr = (uint16_t *)(void *)bline;
5032
0
        dst_ptr = (uint16_t *)(void *)line;
5033
0
        sx = xoff;
5034
0
        for (i = 0; i < w; ++i, ++sx) {
5035
            /* Complement the components for subtractive color spaces */
5036
0
            if (additive) {
5037
0
                for (k = 0; k < num_chan; ++k)   /* num_chan includes alpha */
5038
0
                    dst[k] = back_ptr[k * planestride];
5039
0
            } else { /* Complement the components for subtractive color spaces */
5040
0
                for (k = 0; k < num_comp; ++k)
5041
0
                    dst[k] = 65535 - back_ptr[k * planestride];
5042
0
                dst[num_comp] = back_ptr[num_comp * planestride]; /* alpha */
5043
0
            }
5044
            /* Get the aa alpha from the buffer */
5045
0
            switch(depth)
5046
0
            {
5047
0
            case 2:  /* map 0 - 3 to 0 - 255 */
5048
0
                alpha_aa = ((aa_row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 85;
5049
0
                break;
5050
0
            case 4:
5051
0
                alpha2_aa = aa_row[sx >> 1];
5052
0
                alpha_aa = (sx & 1 ? alpha2_aa & 0xf : alpha2_aa >> 4) * 17;
5053
0
                break;
5054
0
            case 8:
5055
0
                alpha_aa = aa_row[sx];
5056
0
                break;
5057
0
            default:
5058
0
                return_error(gs_error_rangecheck);
5059
0
            }
5060
0
            if (alpha_aa != 0) {  /* This does happen */
5061
0
                if (alpha_aa != 255) {
5062
                    /* We have an alpha value from aa */
5063
0
                    alpha_aa_act = alpha_aa * 0x101;
5064
0
                    if (src_alpha != 65535) {
5065
                        /* Need to combine it with the existing alpha */
5066
0
                        int tmp = src_alpha * alpha_aa_act + 0x8000;
5067
0
                        alpha_aa_act = (tmp + (tmp >> 16)) >> 16;
5068
0
                    }
5069
                    /* Set our source alpha value appropriately */
5070
0
                    src[num_comp] = alpha_aa_act;
5071
0
                } else {
5072
                    /* We may have to reset this is it was changed as we
5073
                       moved across the row */
5074
0
                    src[num_comp] = src_alpha;
5075
0
                }
5076
0
                if (knockout) {
5077
0
                    if (buf->isolated) {
5078
0
                        art_pdf_knockoutisolated_group_16(dst, src, num_comp);
5079
0
                    } else {
5080
0
                        art_pdf_composite_knockout_16(dst, src, num_comp,
5081
0
                            blend_mode, pdev->blend_procs, pdev);
5082
0
                    }
5083
0
                } else {
5084
0
                    art_pdf_composite_pixel_alpha_16(dst, src, num_comp, blend_mode, num_comp,
5085
0
                                                     pdev->blend_procs, pdev);
5086
0
                }
5087
                /* Complement the results for subtractive color spaces */
5088
0
                if (additive) {
5089
0
                    for (k = 0; k < num_chan; ++k)
5090
0
                        dst_ptr[k * planestride] = dst[k];
5091
0
                } else {
5092
0
                    if (overprint && dst_ptr[num_comp * planestride] != 0) {
5093
0
                        for (k = 0, comps = drawn_comps; comps != 0;
5094
0
                                ++k, comps >>= 1) {
5095
0
                            if ((comps & 0x1) != 0) {
5096
0
                                dst_ptr[k * planestride] = 65535 - dst[k];
5097
0
                            }
5098
0
                        }
5099
                        /* The alpha channel */
5100
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5101
0
                    } else {
5102
0
                        for (k = 0; k < num_comp; ++k)
5103
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
5104
                        /* The alpha channel */
5105
0
                        dst_ptr[num_comp * planestride] = dst[num_comp];
5106
0
                    }
5107
0
                }
5108
0
                if (has_alpha_g) {
5109
0
                    int tmp = (65535 - back_ptr[alpha_g_off]) * (65535 - src[num_comp]) + 0x8000;
5110
0
                    dst_ptr[alpha_g_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5111
0
                }
5112
0
                if (has_shape) {
5113
0
                    int tmp = (65535 - back_ptr[shape_off]) * (65535 - shape) + 0x8000;
5114
0
                    dst_ptr[shape_off] = 65535 - ((tmp + (tmp >> 16)) >> 16);
5115
0
                }
5116
0
                if (has_tags) {
5117
                    /* If alpha is 100% then set to curr_tag, else or */
5118
                    /* other than Normal BM, we always OR */
5119
0
                    if (src[num_comp] == 65535 && tag_blend) {
5120
0
                        dst_ptr[tag_off] = curr_tag;
5121
0
                    } else {
5122
0
                        dst_ptr[tag_off] = back_ptr[tag_off] | curr_tag;
5123
0
                    }
5124
0
                }
5125
0
            }
5126
0
            ++dst_ptr;
5127
0
            ++back_ptr;
5128
0
        }
5129
0
        line += rowstride;
5130
0
        bline += rowstride;
5131
0
    }
5132
0
    return 0;
5133
0
}
5134
5135
static int
5136
pdf14_copy_alpha_color(gx_device * dev, const byte * data, int data_x,
5137
           int aa_raster, gx_bitmap_id id, int x, int y, int w, int h,
5138
                      gx_color_index color, const gx_device_color *pdc,
5139
                      int depth, bool devn)
5140
0
{
5141
0
    bool deep = device_is_deep(dev);
5142
0
    int code;
5143
5144
0
    code = pdf14_initialize_ctx(dev, NULL);
5145
0
    if (code < 0)
5146
0
        return code;
5147
5148
0
    if (deep)
5149
0
        return do_pdf14_copy_alpha_color_16(dev, data, data_x, aa_raster,
5150
0
                                            id, x, y, w, h,
5151
0
                                            color, pdc, depth, devn);
5152
0
    else
5153
0
        return do_pdf14_copy_alpha_color(dev, data, data_x, aa_raster,
5154
0
                                         id, x, y, w, h,
5155
0
                                         color, pdc, depth, devn);
5156
0
}
5157
5158
static  int
5159
pdf14_fill_mask(gx_device * orig_dev,
5160
                     const byte * data, int dx, int raster, gx_bitmap_id id,
5161
                     int x, int y, int w, int h,
5162
                     const gx_drawing_color * pdcolor, int depth,
5163
                     gs_logical_operation_t lop, const gx_clip_path * pcpath)
5164
12.8M
{
5165
12.8M
    gx_device *dev;
5166
12.8M
    pdf14_device *p14dev = (pdf14_device *)orig_dev;
5167
12.8M
    gx_device_clip cdev;
5168
12.8M
    gx_color_tile *ptile = NULL;
5169
12.8M
    int code = 0;
5170
12.8M
    gs_int_rect group_rect;
5171
12.8M
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5172
12.8M
    bool has_pattern_trans = false;
5173
12.8M
    cmm_dev_profile_t *dev_profile;
5174
5175
12.8M
    if (pdcolor == NULL)
5176
0
        return_error(gs_error_unknownerror);  /* color must be defined */
5177
5178
12.8M
    code = pdf14_initialize_ctx(orig_dev, NULL);
5179
12.8M
    if (code < 0)
5180
0
        return code;
5181
5182
    /* If we are doing a fill with a pattern that has a transparency then
5183
       go ahead and do a push and a pop of the transparency group */
5184
12.8M
    if (gx_dc_is_pattern1_color(pdcolor)) {
5185
0
        if( gx_pattern1_get_transptr(pdcolor) != NULL) {
5186
0
            ptile = pdcolor->colors.pattern.p_tile;
5187
            /* Set up things in the ptile so that we get the proper
5188
               blending etc */
5189
            /* Set the blending procs and the is_additive setting based
5190
               upon the number of channels */
5191
0
            if (ptile->ttrans->n_chan-1 < 4) {
5192
0
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5193
0
                ptile->ttrans->is_additive = true;
5194
0
            } else {
5195
0
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5196
0
                ptile->ttrans->is_additive = false;
5197
0
            }
5198
            /* Set the procs so that we use the proper filling method. */
5199
0
            gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5200
            /* Based upon if the tiles overlap pick the type of rect
5201
               fill that we will want to use */
5202
0
            if (ptile->has_overlap) {
5203
                /* This one does blending since there is tile overlap */
5204
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5205
0
            } else {
5206
                /* This one does no blending since there is no tile overlap */
5207
0
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5208
0
            }
5209
            /* Push the group */
5210
0
            group_rect.p.x = x;
5211
0
            group_rect.p.y = max(0,y);
5212
0
            group_rect.q.x = x + w;
5213
0
            group_rect.q.y = y + h;
5214
0
            if (!(w <= 0 || h <= 0)) {
5215
5216
0
                pdf14_group_color_t *group_color_info = pdf14_clone_group_color_info((gx_device *) p14dev, p14dev->ctx->stack->group_color_info);
5217
0
                if (group_color_info == NULL)
5218
0
                    return_error(gs_error_VMerror);
5219
5220
0
                code = pdf14_push_transparency_group(p14dev->ctx, &group_rect,
5221
0
                     1, 0, 65535, 65535, 65535, BLEND_MODE_Normal, 0, 0,
5222
0
                     ptile->ttrans->n_chan-1, false, false, NULL, NULL,
5223
0
                     group_color_info, NULL, NULL);
5224
0
                if (code < 0)
5225
0
                    return code;
5226
                /* Set up the output buffer information now that we have
5227
                   pushed the group */
5228
0
                fill_trans_buffer = new_pattern_trans_buff(p14dev->memory);
5229
0
                if (fill_trans_buffer == NULL)
5230
0
                    return_error(gs_error_VMerror);
5231
5232
0
                pdf14_get_buffer_information((gx_device *) p14dev,
5233
0
                                              fill_trans_buffer, NULL, false);
5234
                /* Store this in the appropriate place in pdcolor.  This
5235
                   is released later after the mask fill */
5236
0
                ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5237
0
                has_pattern_trans = true;
5238
0
            }
5239
0
        }
5240
0
    }
5241
12.8M
    if (pcpath != 0) {
5242
1.63M
        gx_make_clip_device_on_stack(&cdev, pcpath, orig_dev);
5243
1.63M
        dev = (gx_device *) & cdev;
5244
1.63M
    } else
5245
11.1M
        dev = orig_dev;
5246
12.8M
    if (depth > 1) {
5247
        /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/
5248
0
        code = (*dev_proc(dev, copy_alpha))
5249
0
            (dev, data, dx, raster, id, x, y, w, h,
5250
0
             gx_dc_pure_color(pdcolor), depth);
5251
12.8M
    } else {
5252
12.8M
        code = pdcolor->type->fill_masked(pdcolor, data, dx, raster, id,
5253
12.8M
                                          x, y, w, h, dev, lop, false);
5254
12.8M
    }
5255
12.8M
    if (has_pattern_trans) {
5256
0
        bool has_tags = device_encodes_tags(dev);
5257
0
        if (code >= 0)
5258
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5259
0
        if (code >= 0)
5260
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx,
5261
0
                                                p14dev->blend_procs,
5262
0
                                                p14dev->color_info.num_components - has_tags,
5263
0
                                                dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5264
0
                                                orig_dev);
5265
0
        gs_free_object(p14dev->memory, ptile->ttrans->fill_trans_buffer,
5266
0
                       "pdf14_fill_mask");
5267
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5268
0
    }
5269
12.8M
    if (pcpath != 0)
5270
1.63M
        gx_destroy_clip_device_on_stack(&cdev);
5271
12.8M
    return code;
5272
12.8M
}
5273
5274
5275
5276
/* Used for filling rects when we are doing a fill with a pattern that
5277
   has transparency */
5278
static  int
5279
pdf14_tile_pattern_fill(gx_device * pdev, const gs_gstate * pgs,
5280
                        gx_path * ppath, const gx_fill_params * params,
5281
                        const gx_device_color * pdevc,
5282
                        const gx_clip_path * pcpath)
5283
55.3k
{
5284
55.3k
    int code;
5285
55.3k
    gs_gstate *pgs_noconst = (gs_gstate *)pgs; /* Break const. */
5286
55.3k
    gs_fixed_rect clip_box;
5287
55.3k
    gs_fixed_rect outer_box;
5288
55.3k
    pdf14_device * p14dev = (pdf14_device *)pdev;
5289
55.3k
    gs_int_rect rect;
5290
55.3k
    gx_clip_rect *curr_clip_rect;
5291
55.3k
    gx_color_tile *ptile = NULL;
5292
55.3k
    int k;
5293
55.3k
    gx_pattern_trans_t *fill_trans_buffer = NULL;
5294
55.3k
    gs_int_point phase;  /* Needed during clist rendering for band offset */
5295
55.3k
    int n_chan_tile;
5296
55.3k
    gx_clip_path cpath_intersection;
5297
55.3k
    gx_path path_ttrans;
5298
55.3k
    pdf14_group_color_t *group_color_info;
5299
55.3k
    bool has_tags = device_encodes_tags(pdev);
5300
5301
55.3k
    if (ppath == NULL)
5302
0
        return_error(gs_error_unknownerror);  /* should not happen */
5303
55.3k
    if (pcpath != NULL) {
5304
52.1k
        code = gx_cpath_init_local_shared_nested(&cpath_intersection, pcpath, ppath->memory, 1);
5305
52.1k
    } else {
5306
3.25k
        (*dev_proc(pdev, get_clipping_box)) (pdev, &clip_box);
5307
3.25k
        gx_cpath_init_local(&cpath_intersection, ppath->memory);
5308
3.25k
        code = gx_cpath_from_rectangle(&cpath_intersection, &clip_box);
5309
3.25k
    }
5310
55.3k
    if (code < 0)
5311
0
        return code;
5312
55.3k
    code = gx_cpath_intersect_with_params(&cpath_intersection, ppath,
5313
55.3k
                                          params->rule, pgs_noconst, params);
5314
55.3k
    if (code < 0)
5315
0
        return code;
5316
    /* One (common) case worth optimising for is where we have a pattern that
5317
     * is positioned such that only one repeat of the tile is actually
5318
     * visible. In this case, we can restrict the size of the blending group
5319
     * we need to produce to be that of the actual area of the tile that is
5320
     * used. */
5321
55.3k
    ptile = pdevc->colors.pattern.p_tile;
5322
55.3k
    if (ptile->ttrans != NULL)
5323
18.8k
    {
5324
18.8k
        if ((cpath_intersection.outer_box.p.x < 0) ||
5325
18.8k
            (cpath_intersection.outer_box.p.y < 0) ||
5326
18.8k
            (cpath_intersection.outer_box.q.x > int2fixed(ptile->ttrans->width)) ||
5327
10.7k
            (cpath_intersection.outer_box.q.y > int2fixed(ptile->ttrans->height)))
5328
8.64k
        {
5329
            /* More than one repeat of the tile would be visible, so we can't
5330
             * use the optimisation here. (Actually, this test isn't quite
5331
             * right - it actually tests whether more than the '0th' repeat
5332
             * of the tile is visible. A better test would test if just one
5333
             * repeat of the tile was visible, irrespective of which one.
5334
             * This is (hopefully) relatively rare, and would make the code
5335
             * below more complex too, so we're ignoring that for now. If it
5336
             * becomes evident that it's a case that matters we can revisit
5337
             * it.) */
5338
10.2k
        } else {
5339
            /* Only the 0th repeat is visible. Restrict the size further to
5340
             * just the used area of that patch. */
5341
10.2k
            gx_path_init_local(&path_ttrans, ppath->memory);
5342
10.2k
            code = gx_path_add_rectangle(&path_ttrans,
5343
10.2k
                                         int2fixed(ptile->ttrans->rect.p.x),
5344
10.2k
                                         int2fixed(ptile->ttrans->rect.p.y),
5345
10.2k
                                         int2fixed(ptile->ttrans->rect.q.x),
5346
10.2k
                                         int2fixed(ptile->ttrans->rect.q.y));
5347
10.2k
            if (code < 0)
5348
0
                return code;
5349
10.2k
            code = gx_cpath_intersect(&cpath_intersection, &path_ttrans,
5350
10.2k
                                      params->rule, pgs_noconst);
5351
10.2k
            gx_path_free(&path_ttrans, "pdf14_tile_pattern_fill(path_ttrans)");
5352
10.2k
            if (code < 0)
5353
0
                return code;
5354
10.2k
        }
5355
18.8k
    }
5356
    /* Now let us push a transparency group into which we are
5357
     * going to tile the pattern.  */
5358
55.3k
    if (ppath != NULL) {
5359
55.3k
        pdf14_device save_pdf14_dev;    /* save area for p14dev */
5360
5361
55.3k
        gx_cpath_outer_box(&cpath_intersection, &outer_box);
5362
55.3k
        rect.p.x = fixed2int(outer_box.p.x);
5363
55.3k
        rect.p.y = fixed2int(outer_box.p.y);
5364
55.3k
        rect.q.x = fixed2int_ceiling(outer_box.q.x);
5365
55.3k
        rect.q.y = fixed2int_ceiling(outer_box.q.y);
5366
5367
        /* The color space of this group must be the same as that of the
5368
           tile.  Then when we pop the group, if there is a mismatch between
5369
           the tile color space and the current context we will do the proper
5370
           conversion.  In this way, we ensure that if the tile has any overlapping
5371
           occuring it will be blended in the proper manner i.e in the tile
5372
           underlying color space. */
5373
55.3k
        if (ptile->cdev == NULL) {
5374
18.8k
            if (ptile->ttrans == NULL)
5375
0
                return_error(gs_error_unknownerror);  /* should not happen */
5376
18.8k
            n_chan_tile = ptile->ttrans->n_chan;
5377
36.5k
        } else {
5378
36.5k
            n_chan_tile = ptile->cdev->common.color_info.num_components+1;
5379
36.5k
        }
5380
55.3k
        memcpy(&save_pdf14_dev, p14dev, sizeof(pdf14_device));
5381
5382
        /* Transparency handling with patterns confuses me, so some notes...
5383
         *
5384
         * For simple, non-transparent patterns, like you'd get in PS, we've
5385
         * used bitmap tiles. Draw into those tiles, and tile those out multiple
5386
         * times. To cope with unmarked pixels, we have a "transparency" plane
5387
         * (simple on/off) that says whether a pixel is marked or not.
5388
         *
5389
         * For patterns with transparency (but not blending), we can create an
5390
         * isolated transparency group, tile all the bitmap tiles into that, and
5391
         * then blend that back with the required alpha at the end. This works
5392
         * because the alpha values of the individual objects within the tile are
5393
         * recorded in that group.
5394
         *
5395
         * We can't do that for groups that use blending though, as each object
5396
         * in the pattern might use a different blend, and we don't (can't) record
5397
         * the blending mode. An isolated group doesn't even allow us to actually
5398
         * do the blending at all. So, for such patterns (any patterns that sets (or
5399
         * just has a resource that mentions) a non-normal blend mode), we use
5400
         * a pattern clist.
5401
         */
5402
55.3k
        if (ptile->cdev == NULL) {
5403
18.8k
            group_color_info = pdf14_clone_group_color_info(pdev, p14dev->ctx->stack->group_color_info);
5404
18.8k
            if (group_color_info == NULL)
5405
0
                return gs_error_VMerror;
5406
5407
18.8k
            code = pdf14_push_transparency_group(p14dev->ctx, &rect, 1, 0, (uint16_t)floor(65535 * p14dev->alpha + 0.5),
5408
18.8k
                                                 (uint16_t)floor(65535 * p14dev->shape + 0.5), (uint16_t)floor(65535 * p14dev->opacity + 0.5),
5409
18.8k
                                                 BLEND_MODE_Normal, 0, 0, n_chan_tile - 1, false, false,
5410
18.8k
                                                 NULL, NULL, group_color_info, pgs_noconst, pdev);
5411
18.8k
            if (code < 0)
5412
0
                return code;
5413
18.8k
        }
5414
5415
        /* Set the blending procs and the is_additive setting based
5416
           upon the number of channels */
5417
55.3k
        if (ptile->cdev == NULL) {
5418
18.8k
            if (n_chan_tile-1 < 4) {
5419
17.9k
                ptile->ttrans->blending_procs = &rgb_blending_procs;
5420
17.9k
                ptile->ttrans->is_additive = true;
5421
17.9k
            } else {
5422
904
                ptile->ttrans->blending_procs = &cmyk_blending_procs;
5423
904
                ptile->ttrans->is_additive = false;
5424
904
            }
5425
18.8k
        }
5426
        /* Now lets go through the rect list and fill with the pattern */
5427
        /* First get the buffer that we will be filling */
5428
55.3k
        if (ptile->cdev == NULL) {
5429
18.8k
            fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5430
18.8k
            if (fill_trans_buffer == NULL) {
5431
0
                p14dev->pclist_device = NULL;
5432
0
                return_error(gs_error_VMerror);
5433
0
            }
5434
18.8k
            pdf14_get_buffer_information(pdev, fill_trans_buffer, NULL, false);
5435
            /* Based upon if the tiles overlap pick the type of rect fill that we will
5436
               want to use */
5437
18.8k
            if (ptile->has_overlap) {
5438
                /* This one does blending since there is tile overlap */
5439
1.34k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5440
17.5k
            } else {
5441
                /* This one does no blending since there is no tile overlap */
5442
17.5k
                ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5443
17.5k
            }
5444
            /* fill the rectangles */
5445
18.8k
            phase.x = pdevc->phase.x;
5446
18.8k
            phase.y = pdevc->phase.y;
5447
18.8k
            if (cpath_intersection.rect_list->list.head != NULL){
5448
642
                curr_clip_rect = cpath_intersection.rect_list->list.head->next;
5449
10.6k
                for( k = 0; k < cpath_intersection.rect_list->list.count && code >= 0; k++){
5450
9.98k
                    if_debug5m('v', pgs->memory,
5451
9.98k
                               "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5452
9.98k
                               curr_clip_rect->xmin, curr_clip_rect->ymin,
5453
9.98k
                               curr_clip_rect->xmax-curr_clip_rect->xmin,
5454
9.98k
                               curr_clip_rect->ymax-curr_clip_rect->ymin, (int)ptile->id);
5455
9.98k
                    code = gx_trans_pattern_fill_rect(curr_clip_rect->xmin, curr_clip_rect->ymin,
5456
9.98k
                                                      curr_clip_rect->xmax, curr_clip_rect->ymax, ptile,
5457
9.98k
                                                      fill_trans_buffer, phase, pdev, pdevc, 1);
5458
9.98k
                    curr_clip_rect = curr_clip_rect->next;
5459
9.98k
                }
5460
18.2k
            } else if (cpath_intersection.rect_list->list.count == 1) {
5461
                /* The case when there is just a single rect */
5462
17.9k
                if_debug5m('v', pgs->memory,
5463
17.9k
                           "[v]pdf14_tile_pattern_fill, (%d, %d), %d x %d pat_id %u \n",
5464
17.9k
                           cpath_intersection.rect_list->list.single.xmin,
5465
17.9k
                           cpath_intersection.rect_list->list.single.ymin,
5466
17.9k
                           cpath_intersection.rect_list->list.single.xmax-
5467
17.9k
                              cpath_intersection.rect_list->list.single.xmin,
5468
17.9k
                           cpath_intersection.rect_list->list.single.ymax-
5469
17.9k
                              cpath_intersection.rect_list->list.single.ymin,
5470
17.9k
                           (int)ptile->id);
5471
17.9k
                code = gx_trans_pattern_fill_rect(cpath_intersection.rect_list->list.single.xmin,
5472
17.9k
                                                  cpath_intersection.rect_list->list.single.ymin,
5473
17.9k
                                                  cpath_intersection.rect_list->list.single.xmax,
5474
17.9k
                                                  cpath_intersection.rect_list->list.single.ymax,
5475
17.9k
                                                  ptile, fill_trans_buffer, phase, pdev, pdevc, 1);
5476
17.9k
            }
5477
36.5k
        } else {
5478
            /* Clist pattern with transparency.  Create a clip device from our
5479
               cpath_intersection.  The above non-clist case could probably be
5480
               done this way too, which will reduce the amount of code here.
5481
               That is for another day though due to time constraints*/
5482
36.5k
            gx_device *dev;
5483
36.5k
            gx_device_clip clipdev;
5484
5485
36.5k
            gx_make_clip_device_on_stack(&clipdev, &cpath_intersection, pdev);
5486
36.5k
            dev = (gx_device *)&clipdev;
5487
36.5k
            phase.x = pdevc->phase.x;
5488
36.5k
            phase.y = pdevc->phase.y;
5489
36.5k
            code = gx_trans_pattern_fill_rect(rect.p.x, rect.p.y, rect.q.x, rect.q.y,
5490
36.5k
                                              ptile, fill_trans_buffer, phase,
5491
36.5k
                                              dev, pdevc, 1);
5492
36.5k
            gx_destroy_clip_device_on_stack(&clipdev);
5493
36.5k
        }
5494
        /* We're done drawing with the pattern, remove the reference to the
5495
         * pattern device
5496
         */
5497
55.3k
        p14dev->pclist_device = NULL;
5498
55.3k
        if (code < 0)
5499
0
            return code;
5500
5501
        /* free our buffer object */
5502
55.3k
        if (fill_trans_buffer != NULL) {
5503
18.8k
            gs_free_object(pgs->memory, fill_trans_buffer, "pdf14_tile_pattern_fill");
5504
18.8k
            ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5505
18.8k
        }
5506
55.3k
        if (ptile->cdev == NULL) {
5507
            /* pop our transparency group which will force the blending.
5508
               This was all needed for Bug 693498 */
5509
18.8k
            code = pdf14_pop_transparency_group(pgs_noconst, p14dev->ctx,
5510
18.8k
                                                p14dev->blend_procs,
5511
18.8k
                                                p14dev->color_info.num_components - has_tags,
5512
18.8k
                                                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5513
18.8k
                                                pdev);
5514
18.8k
        }
5515
55.3k
        memcpy(p14dev, &save_pdf14_dev, sizeof(pdf14_device));
5516
55.3k
        p14dev->pclist_device = NULL;
5517
55.3k
    }
5518
55.3k
    gx_cpath_free(&cpath_intersection, "pdf14_tile_pattern_fill");
5519
55.3k
    return code;
5520
55.3k
}
5521
5522
/* Useful function that should probably go elsewhere.
5523
 * Call this function to find the topmost pdf14 device in the device chain,
5524
 * or NULL if there is not one.
5525
 */
5526
static pdf14_device *find_pdf14_device(gx_device *dev)
5527
0
{
5528
0
    pdf14_device *pdev;
5529
5530
0
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_is_pdf14_device, &pdev, sizeof(pdev)) <= 0)
5531
0
        return NULL;
5532
0
    return pdev;
5533
0
}
5534
5535
/* Imager render for pattern transparency filling.  This is just here to catch
5536
   the final flush, at which time we will pop the group and reset a few items */
5537
static  int
5538
pdf14_pattern_trans_render(gx_image_enum * penum, const byte * buffer, int data_x,
5539
                    uint w, int h, gx_device * dev)
5540
0
{
5541
0
    int code;
5542
0
    pdf14_device * p14dev;
5543
0
    const gs_gstate * pgs = penum->pgs;
5544
0
    gx_device_color * pdcolor = (penum->icolor1);
5545
0
    gx_color_tile *ptile = pdcolor->colors.pattern.p_tile;
5546
0
    bool has_tags = device_encodes_tags(dev);
5547
5548
    /* Pass along to the original renderer */
5549
0
    code = (ptile->ttrans->image_render)(penum, buffer, data_x, w, h, dev);
5550
0
    if (code < 0)
5551
0
        return code;
5552
    /* On our final time through here, go ahead and pop the transparency
5553
       group and reset the procs in the device color. And free the fill
5554
       trans buffer object */
5555
0
    if (h == 0 && ptile->trans_group_popped == false) {
5556
0
        p14dev = find_pdf14_device(dev);
5557
5558
0
        if (p14dev->pclist_device == NULL) {
5559
            /* Used if we are on clist writing phase.  Would only
5560
               occur if we somehow failed in high level clist
5561
               image writing */
5562
0
            code = gs_end_transparency_group((gs_gstate *) pgs);
5563
0
        } else {
5564
            /* Used if we are on clist reading phase.  If we had high level
5565
               image in clist */
5566
0
            cmm_dev_profile_t *dev_profile;
5567
0
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
5568
0
            if (code < 0)
5569
0
                return code;
5570
5571
0
            if_debug2m('v', p14dev->ctx->memory,
5572
0
                      "[v*] Popping trans group pattern fill, uid = %ld id = %ld \n",
5573
0
                       ptile->uid.id, ptile->id);
5574
0
            code = pdf14_pop_transparency_group(NULL, p14dev->ctx, p14dev->blend_procs,
5575
0
                    p14dev->color_info.num_components - has_tags,
5576
0
                    dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE],
5577
0
                    (gx_device *) p14dev);
5578
0
        }
5579
0
        pdcolor->colors.pattern.p_tile->trans_group_popped = true;
5580
0
        gs_free_object(pgs->memory, ptile->ttrans->fill_trans_buffer,
5581
0
                       "pdf14_pattern_trans_render");
5582
0
        ptile->ttrans->fill_trans_buffer = NULL;  /* Avoid GC issues */
5583
0
    }
5584
0
    return code;
5585
0
}
5586
5587
/* This function is used to get things in place for filling a mask image
5588
   with a pattern that has transparency.  It is used by pdf14_begin_type_image
5589
   and pdf14_clist_begin_type_image */
5590
static int
5591
pdf14_patt_trans_image_fill(gx_device * dev, const gs_gstate * pgs,
5592
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5593
                           const gs_int_rect * prect,
5594
                           const gx_drawing_color * pdcolor,
5595
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5596
                           gx_image_enum_common_t ** pinfo)
5597
0
{
5598
0
    const gs_image_t *pim = (const gs_image_t *)pic;
5599
0
    pdf14_device * p14dev = (pdf14_device *)dev;
5600
0
    gx_color_tile *ptile;
5601
0
    int code;
5602
0
    gs_int_rect group_rect;
5603
0
    gx_image_enum *penum;
5604
0
    gs_rect bbox_in, bbox_out;
5605
0
    gx_pattern_trans_t *fill_trans_buffer;
5606
5607
0
    ptile = pdcolor->colors.pattern.p_tile;
5608
    /* Set up things in the ptile so that we get the proper
5609
       blending etc */
5610
    /* Set the blending procs and the is_additive setting based
5611
       upon the number of channels */
5612
0
    if (ptile->ttrans->n_chan-1 < 4) {
5613
0
        ptile->ttrans->blending_procs = &rgb_blending_procs;
5614
0
        ptile->ttrans->is_additive = true;
5615
0
    } else {
5616
0
        ptile->ttrans->blending_procs = &cmyk_blending_procs;
5617
0
        ptile->ttrans->is_additive = false;
5618
0
    }
5619
    /* Set the blending mode in the ptile based upon the current
5620
       setting in the gs_gstate */
5621
0
    ptile->blending_mode = pgs->blend_mode;
5622
    /* Based upon if the tiles overlap pick the type of rect
5623
       fill that we will want to use */
5624
0
    if (ptile->has_overlap) {
5625
        /* This one does blending since there is tile overlap */
5626
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_blend;
5627
0
    } else {
5628
        /* This one does no blending since there is no tile overlap */
5629
0
        ptile->ttrans->pat_trans_fill = &tile_rect_trans_simple;
5630
0
    }
5631
    /* Set the procs so that we use the proper filling method. */
5632
0
    gx_set_pattern_procs_trans((gx_device_color*) pdcolor);
5633
    /* Let the imaging stuff get set up */
5634
0
    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
5635
0
                            prect, pdcolor,pcpath, mem, pinfo);
5636
0
    if (code < 0)
5637
0
        return code;
5638
    /* Now Push the group */
5639
    /* First apply the inverse of the image matrix to our
5640
       image size to get our bounding box. */
5641
0
    bbox_in.p.x = 0;
5642
0
    bbox_in.p.y = 0;
5643
0
    bbox_in.q.x = pim->Width;
5644
0
    bbox_in.q.y = pim->Height;
5645
0
    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
5646
0
                                &bbox_out);
5647
0
    if (code < 0)
5648
0
        return code;
5649
    /* That in turn will get hit by the matrix in the gs_gstate */
5650
0
    code = compute_group_device_int_rect(p14dev, &group_rect,
5651
0
                                            &bbox_out, (gs_gstate *)pgs);
5652
0
    if (code < 0)
5653
0
        return code;
5654
0
    if (!(pim->Width == 0 || pim->Height == 0)) {
5655
0
        if_debug2m('v', p14dev->ctx->memory,
5656
0
                   "[v*] Pushing trans group patt_trans_image_fill, uid = %ld id = %ld \n",
5657
0
                   ptile->uid.id, ptile->id);
5658
5659
0
        code = pdf14_push_transparency_group(p14dev->ctx, &group_rect, 1, 0, 65535, 65535,
5660
0
                                             65535, pgs->blend_mode, 0, 0,
5661
0
                                             ptile->ttrans->n_chan-1, false, false,
5662
0
                                             NULL, NULL, NULL, (gs_gstate *)pgs, dev);
5663
5664
        /* Set up the output buffer information now that we have
5665
           pushed the group */
5666
0
        fill_trans_buffer = new_pattern_trans_buff(pgs->memory);
5667
0
        if (fill_trans_buffer == NULL)
5668
0
            return_error(gs_error_VMerror);
5669
5670
0
        pdf14_get_buffer_information(dev, fill_trans_buffer, NULL, false);
5671
5672
        /* Store this in the appropriate place in pdcolor.  This
5673
           is released later in pdf14_pattern_trans_render when
5674
           we are all done with the mask fill */
5675
0
        ptile->ttrans->fill_trans_buffer = fill_trans_buffer;
5676
5677
        /* Change the renderer to handle this case so we can catch the
5678
           end.  We will then pop the group and reset the pdcolor proc.
5679
           Keep the base renderer also. */
5680
0
        penum = (gx_image_enum *) *pinfo;
5681
0
        ptile->ttrans->image_render = penum->render;
5682
0
        penum->render = &pdf14_pattern_trans_render;
5683
0
        ptile->trans_group_popped = false;
5684
0
    }
5685
0
    return code;
5686
0
}
5687
5688
static  int
5689
pdf14_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
5690
                           const gs_matrix *pmat, const gs_image_common_t *pic,
5691
                           const gs_int_rect * prect,
5692
                           const gx_drawing_color * pdcolor,
5693
                           const gx_clip_path * pcpath, gs_memory_t * mem,
5694
                           gx_image_enum_common_t ** pinfo)
5695
328k
{
5696
328k
    const gs_image_t *pim = (const gs_image_t *)pic;
5697
328k
    int code;
5698
5699
328k
    code = pdf14_initialize_ctx(dev, pgs);
5700
328k
    if (code < 0)
5701
0
        return code;
5702
5703
    /* If we are filling an image mask with a pattern that has a transparency
5704
       then we need to do some special handling */
5705
328k
    if (pim->ImageMask) {
5706
93
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
5707
0
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
5708
                /* If we are in a final run through here for this case then
5709
                   go ahead and push the transparency group.   Also, update
5710
                   the proc for the pattern color so that we used the
5711
                   appropriate fill operation.  Note that the group
5712
                   is popped and the proc will be reset when we flush the
5713
                   image data.  This is handled in a special pdf14 image
5714
                   renderer which will end up installed for this case.
5715
                   Detect setting of begin_image to gx_no_begin_image.
5716
                   (final recursive call) */
5717
0
                if (dev_proc(dev, begin_typed_image) != gx_default_begin_typed_image) {
5718
0
                    code = pdf14_patt_trans_image_fill(dev, pgs, pmat, pic,
5719
0
                                                prect, pdcolor, pcpath, mem,
5720
0
                                                pinfo);
5721
0
                    return code;
5722
0
                }
5723
0
            }
5724
0
        }
5725
93
    }
5726
328k
    pdf14_set_marking_params(dev, pgs);
5727
328k
    return gx_default_begin_typed_image(dev, pgs, pmat, pic, prect, pdcolor,
5728
328k
                                        pcpath, mem, pinfo);
5729
328k
}
5730
5731
static  void
5732
pdf14_set_params(gs_gstate * pgs,
5733
                 gx_device * dev,
5734
                 const gs_pdf14trans_params_t * pparams)
5735
8.32M
{
5736
8.32M
    if_debug0m('v', dev->memory, "[v]pdf14_set_params\n");
5737
8.32M
    if (pparams->changed & PDF14_SET_BLEND_MODE)
5738
2.02M
        pgs->blend_mode = pparams->blend_mode;
5739
8.32M
    if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
5740
1.02M
        pgs->text_knockout = pparams->text_knockout;
5741
8.32M
    if (pparams->changed & PDF14_SET_AIS)
5742
322k
        pgs->alphaisshape = pparams->ais;
5743
8.32M
    if (pparams->changed & PDF14_SET_OVERPRINT)
5744
2.49M
        pgs->overprint = pparams->overprint;
5745
8.32M
    if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
5746
2.48M
        pgs->stroke_overprint = pparams->stroke_overprint;
5747
8.32M
    if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
5748
2.61M
        pgs->fillconstantalpha = pparams->fillconstantalpha;
5749
8.32M
    if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
5750
1.89M
        pgs->strokeconstantalpha = pparams->strokeconstantalpha;
5751
8.32M
    if (pparams->changed & PDF14_SET_FILLSTROKE_STATE) {
5752
1.92M
        gs_swapcolors_quick(pgs);
5753
1.92M
        if (pparams->op_fs_state == GS_OP_STATE_STROKE)
5754
672k
            pgs->is_fill_color = false;
5755
1.24M
        else
5756
1.24M
            pgs->is_fill_color = true;
5757
1.92M
    }
5758
8.32M
    pdf14_set_marking_params(dev, pgs);
5759
8.32M
}
5760
5761
/*
5762
 * This open_device method for the PDF 1.4 compositor devices is only used
5763
 * when these devices are disabled.  This routine is about as close to
5764
 * a pure "forwarding" open_device operation as is possible. Its only
5765
 * significant function is to ensure that the is_open field of the
5766
 * PDF 1.4 compositor devices matches that of the target device.
5767
 *
5768
 * We assume this procedure is called only if the device is not already
5769
 * open, and that gs_opendevice will take care of the is_open flag.
5770
 */
5771
static  int
5772
pdf14_forward_open_device(gx_device * dev)
5773
0
{
5774
0
    gx_device_forward * pdev = (gx_device_forward *)dev;
5775
0
    gx_device * tdev = pdev->target;
5776
0
    int code;
5777
5778
    /* The PDF 1.4 compositing devices must have a target */
5779
0
    if (tdev == 0)
5780
0
        return_error(gs_error_unknownerror);
5781
0
    if ((code = gs_opendevice(tdev)) >= 0)
5782
0
        gx_device_copy_params(dev, tdev);
5783
0
    return code;
5784
0
}
5785
5786
/*
5787
 * Convert all device procs to be 'forwarding'.  The caller is responsible
5788
 * for setting any device procs that should not be forwarded.
5789
 */
5790
static  void
5791
pdf14_forward_device_procs(gx_device * dev)
5792
1.02M
{
5793
1.02M
    gx_device_forward *pdev = (gx_device_forward *)dev;
5794
1.02M
    pdf14_device *p14dev = (pdf14_device*)dev;
5795
5796
    /* If doing simulated overprint with spot colors
5797
       then makes sure to reset devn setting */
5798
1.02M
    if (p14dev->overprint_sim &&
5799
0
        p14dev->color_info.num_components > 4)
5800
0
        p14dev->icc_struct->supports_devn =
5801
0
            p14dev->target_support_devn;
5802
5803
    /*
5804
     * We are using gx_device_forward_fill_in_procs to set the various procs.
5805
     * This will ensure that any new device procs are also set.  However that
5806
     * routine only changes procs which are NULL.  Thus we start by setting all
5807
     * procs to NULL.
5808
     */
5809
1.02M
    memset(&(pdev->procs), 0, size_of(pdev->procs));
5810
1.02M
    gx_device_forward_fill_in_procs(pdev);
5811
    /*
5812
     * gx_device_forward_fill_in_procs does not forward all procs.
5813
     * Set the remainding procs to also forward.
5814
     */
5815
1.02M
    set_dev_proc(dev, close_device, gx_forward_close_device);
5816
1.02M
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
5817
1.02M
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
5818
1.02M
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
5819
1.02M
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
5820
1.02M
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
5821
1.02M
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
5822
1.02M
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
5823
1.02M
    set_dev_proc(dev, get_profile, gx_forward_get_profile);
5824
1.02M
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
5825
    /* These are forwarding devices with minor tweaks. */
5826
1.02M
    set_dev_proc(dev, open_device, pdf14_forward_open_device);
5827
1.02M
    set_dev_proc(dev, put_params, pdf14_forward_put_params);
5828
1.02M
}
5829
5830
/*
5831
 * Disable the PDF 1.4 compositor device.  Once created, the PDF 1.4
5832
 * compositor device is never removed.  (We do not have a remove compositor
5833
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
5834
 * routine implements that action.
5835
 */
5836
int
5837
pdf14_disable_device(gx_device * dev)
5838
1.01M
{
5839
1.01M
    gx_device_forward * pdev = (gx_device_forward *)dev;
5840
5841
1.01M
    if_debug0m('v', dev->memory, "[v]pdf14_disable_device\n");
5842
1.01M
    dev->color_info = pdev->target->color_info;
5843
1.01M
    pdf14_forward_device_procs(dev);
5844
1.01M
    set_dev_proc(dev, composite, pdf14_forward_composite);
5845
1.01M
    return 0;
5846
1.01M
}
5847
5848
/*
5849
 * The default color space for PDF 1.4 blend modes is based upon the process
5850
 * color model of the output device.
5851
 */
5852
static  pdf14_default_colorspace_t
5853
pdf14_determine_default_blend_cs(gx_device * pdev, bool use_pdf14_accum,
5854
                                 pdf14_blend_cs_t *blend_cs_state)
5855
3.02M
{
5856
    /* If a blend color space was specified, then go ahead and use that to
5857
       define the default color space for the blend modes.  Only Gray, RGB
5858
       or CMYK blend color spaces are allowed.  Note we do not allow this
5859
       setting if we are dealing with a separation device. */
5860
3.02M
    cmm_dev_profile_t *dev_profile;
5861
3.02M
    cmm_profile_t *blend_profile = NULL;
5862
3.02M
    pdf14_blend_cs_t temp_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5863
3.02M
    int code = dev_proc(pdev, get_profile)(pdev, &dev_profile);
5864
3.02M
    bool valid_blend_cs = false;
5865
3.02M
    int has_tags = device_encodes_tags(pdev);
5866
5867
3.02M
    *blend_cs_state = PDF14_BLEND_CS_UNSPECIFIED;
5868
5869
    /* Are we using a blend color space or the output intent color space? Also
5870
       is there a conflict in the settings. i.e. has someone set a blend color
5871
       space and tried to use the output intent with simulate overprint setting.
5872
    */
5873
3.02M
    if (dev_profile->overprint_control == gs_overprint_control_simulate &&
5874
0
        dev_profile->oi_profile != NULL &&
5875
0
        !gsicc_profiles_equal(dev_profile->oi_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5876
        /* If blend profile is also set, throw a warning about output intent not being used. We have
5877
           possible conflicting command line settings and we will err on using the blend profile
5878
           if one was specified. */
5879
0
        if (dev_profile->blend_profile != NULL &&
5880
0
            !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->oi_profile)) {
5881
0
            blend_profile = dev_profile->blend_profile;
5882
0
            temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5883
0
            emprintf(pdev->memory, "Warning: OI profile not used for blending CS\n");
5884
0
        } else {
5885
            /* All good, use the output intent profile as we have one
5886
               and are doing simulate overprint with a different device
5887
               profile set. */
5888
0
            blend_profile = dev_profile->oi_profile;
5889
0
            temp_cs_state = PDF14_BLEND_CS_OUTPUTINTENT;
5890
0
        }
5891
3.02M
    } else if (dev_profile->blend_profile != NULL &&
5892
0
               !gsicc_profiles_equal(dev_profile->blend_profile, dev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE])) {
5893
        /* Blend profile is different than device profile */
5894
0
        blend_profile = dev_profile->blend_profile;
5895
0
        temp_cs_state = PDF14_BLEND_CS_SPECIFIED;
5896
0
    }
5897
5898
    /* Make sure any blend color space is valid along with other cond */
5899
3.02M
    if (code == 0 && blend_profile != NULL && !use_pdf14_accum) {
5900
0
        if (!blend_profile->isdevlink &&
5901
0
            !blend_profile->islab &&
5902
0
            (blend_profile->data_cs == gsGRAY ||
5903
0
             blend_profile->data_cs == gsRGB ||
5904
0
             blend_profile->data_cs == gsCMYK)) {
5905
            /* Also, do not allow the use of the blend space when we are pushing
5906
               a pattern pdf14 device.  Those should inherit from the parent */
5907
0
            if (!(gx_device_is_pattern_clist(pdev) ||
5908
0
                  gx_device_is_pattern_accum(pdev))) {
5909
0
                valid_blend_cs = true;
5910
0
            }
5911
0
        }
5912
0
    }
5913
5914
    /* If num components is one, just go ahead and use gray.  This avoids
5915
       issues with additive/subtractive mono color devices  */
5916
3.02M
    if (pdev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE ||
5917
2.80M
        pdev->color_info.num_components == 1) {
5918
        /*
5919
        * Note:  We do not allow the SeparationOrder device parameter for
5920
        * additive devices.  Thus we always have 1 colorant for DeviceGray
5921
        * and 3 colorants for DeviceRGB.
5922
        */
5923
2.80M
        if (valid_blend_cs) {
5924
0
            *blend_cs_state = temp_cs_state;
5925
0
            switch (blend_profile->num_comps) {
5926
0
            case 1:
5927
0
                return PDF14_DeviceGray;
5928
0
            case 3:
5929
0
                return PDF14_DeviceRGB;
5930
0
            case 4:
5931
0
                return PDF14_DeviceCMYK;
5932
0
            }
5933
0
        }
5934
2.80M
        if (pdev->color_info.num_components - has_tags == 1)
5935
949k
            return PDF14_DeviceGray;
5936
1.85M
        else if (pdev->color_info.num_components - has_tags == 3)
5937
1.85M
            return PDF14_DeviceRGB;
5938
0
        else
5939
0
            return PDF14_DeviceRGBspot;
5940
2.80M
    } else {
5941
        /*
5942
         * Check if the device is CMYK only or CMYK plus spot colors. Note
5943
         * the CMYK plus spot colors will not support the blend color space
5944
         */
5945
219k
        int i, output_comp_num, num_cmyk_used = 0, num_cmyk = 0;
5946
#if CUSTOM_BLENDING_MODE == ALWAYS_USE_CUSTOM_BLENDING
5947
        return PDF14_DeviceCustom;
5948
#endif
5949
        /*
5950
         * Count the number of CMYK process components supported by the output
5951
         * device.
5952
         */
5953
1.09M
        for (i = 0; i < 4; i++) {
5954
876k
            const char * pcomp_name = (const char *)DeviceCMYKComponents[i];
5955
5956
876k
            output_comp_num = dev_proc(pdev, get_color_comp_index)
5957
876k
                (pdev, pcomp_name, strlen(pcomp_name), NO_COMP_NAME_TYPE_OP);
5958
876k
            if (output_comp_num >= 0) {
5959
876k
                num_cmyk++;
5960
876k
                if (output_comp_num != GX_DEVICE_COLOR_MAX_COMPONENTS)
5961
876k
                    num_cmyk_used++;
5962
876k
            }
5963
876k
        }
5964
        /*
5965
         * Check if the device supports only CMYK.  Otherewise we assume that
5966
         * the output device supports spot colors.  Note:  This algorithm can
5967
         * be fooled if the SeparationOrder device parameter is being used by
5968
         * the output device device to only select CMYK.
5969
         */
5970
219k
        if (num_cmyk_used == 4 && pdev->color_info.num_components == 4
5971
209k
            && pdev->color_info.max_components == 4) {
5972
40.5k
            if (valid_blend_cs) {
5973
0
                *blend_cs_state = temp_cs_state;
5974
0
                switch (blend_profile->num_comps) {
5975
0
                case 1:
5976
0
                    return PDF14_DeviceGray;
5977
0
                case 3:
5978
0
                    return PDF14_DeviceRGB;
5979
0
                case 4:
5980
0
                    return PDF14_DeviceCMYK;
5981
0
                }
5982
0
            }
5983
40.5k
            return PDF14_DeviceCMYK;
5984
40.5k
        }
5985
        /*
5986
         * Check if we should use the 'custom' PDF 1.4 compositor device.
5987
         * This device is only needed for those devices which do not support
5988
         * a basic CMYK process color model.
5989
         */
5990
178k
#if CUSTOM_BLENDING_MODE == AUTO_USE_CUSTOM_BLENDING
5991
178k
        if (num_cmyk != 4)
5992
0
            return PDF14_DeviceCustom;
5993
178k
#endif
5994
        /*
5995
         * Otherewise we use a CMYK plus spot colors for blending.
5996
         */
5997
178k
        if (valid_blend_cs)
5998
0
            *blend_cs_state = temp_cs_state;
5999
178k
        return PDF14_DeviceCMYKspot;
6000
178k
    }
6001
3.02M
}
6002
6003
/*
6004
 * the PDF 1.4 transparency spec says that color space for blending
6005
 * operations can be based upon either a color space specified in the
6006
 * group or a default value based upon the output device.  We are
6007
 * currently only using a color space based upon the device.
6008
 */
6009
static  int
6010
get_pdf14_device_proto(gx_device       *dev,
6011
                       pdf14_device    *pdevproto,
6012
                       gs_gstate       *pgs,
6013
                 const gs_pdf14trans_t *pdf14pct,
6014
                       bool             use_pdf14_accum)
6015
1.02M
{
6016
1.02M
    pdf14_blend_cs_t blend_cs_state;
6017
1.02M
    pdf14_default_colorspace_t dev_cs =
6018
1.02M
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
6019
1.02M
                                                 &blend_cs_state);
6020
1.02M
    bool deep = device_is_deep(dev);
6021
1.02M
    int num_spots = pdf14pct->params.num_spot_colors;
6022
1.02M
    bool has_tags = device_encodes_tags(dev);
6023
6024
    /* overprint overide */
6025
1.02M
    if (pdf14pct->params.overprint_sim_push &&
6026
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
6027
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
6028
0
            dev_cs = PDF14_DeviceCMYKspot;
6029
0
            num_spots = pdf14pct->params.num_spot_colors_int;
6030
0
        } else
6031
0
            dev_cs = PDF14_DeviceCMYK;
6032
0
    }
6033
6034
1.02M
    switch (dev_cs) {
6035
357k
        case PDF14_DeviceGray:
6036
357k
            *pdevproto = gs_pdf14_Gray_device;
6037
357k
            pdevproto->color_info.max_components = 1 + has_tags;
6038
357k
            pdevproto->color_info.num_components =
6039
357k
                                    pdevproto->color_info.max_components + has_tags;
6040
357k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6041
357k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6042
357k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
6043
357k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6044
357k
            pdevproto->sep_device = false;
6045
357k
            break;
6046
597k
        case PDF14_DeviceRGB:
6047
597k
            *pdevproto = gs_pdf14_RGB_device;
6048
597k
            pdevproto->color_info.max_components += has_tags;
6049
597k
            pdevproto->color_info.num_components += has_tags;
6050
597k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6051
597k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6052
597k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6053
597k
            pdevproto->sep_device = false;
6054
597k
            break;
6055
2.59k
        case PDF14_DeviceCMYK:
6056
2.59k
            *pdevproto = gs_pdf14_CMYK_device;
6057
2.59k
            pdevproto->color_info.max_components += has_tags;
6058
2.59k
            pdevproto->color_info.num_components += has_tags;
6059
2.59k
            pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6060
2.59k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6061
2.59k
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6062
2.59k
            pdevproto->sep_device = false;
6063
2.59k
            break;
6064
68.0k
        case PDF14_DeviceCMYKspot:
6065
68.0k
            *pdevproto = gs_pdf14_CMYKspot_device;
6066
            /* Need to figure out how we want to handle the device profile
6067
               for this case */
6068
            /*
6069
             * The number of components for the PDF14 device is the sum
6070
             * of the process components and the number of spot colors
6071
             * for the page.
6072
             */
6073
68.0k
            if (num_spots >= 0) {
6074
68.0k
                pdevproto->color_info.num_components =
6075
68.0k
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6076
68.0k
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6077
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6078
68.0k
                pdevproto->color_info.depth =
6079
68.0k
                                    pdevproto->color_info.num_components * (8<<deep);
6080
68.0k
                pdevproto->sep_device = true;
6081
68.0k
            }
6082
0
            else
6083
0
            {
6084
0
                pdevproto->color_info.max_components += has_tags;
6085
0
                pdevproto->color_info.num_components += has_tags;
6086
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6087
0
            }
6088
68.0k
            break;
6089
0
        case PDF14_DeviceRGBspot:
6090
0
            *pdevproto = gs_pdf14_RGBspot_device;
6091
            /* Need to figure out how we want to handle the device profile
6092
               for this case */
6093
            /*
6094
             * The number of components for the PDF14 device is the sum
6095
             * of the process components and the number of spot colors
6096
             * for the page.
6097
             */
6098
0
            if (num_spots >= 0) {
6099
0
                pdevproto->color_info.num_components =
6100
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots + has_tags;
6101
0
                if (pdevproto->color_info.num_components > GS_CLIENT_COLOR_MAX_COMPONENTS)
6102
0
                    pdevproto->color_info.num_components = GS_CLIENT_COLOR_MAX_COMPONENTS;
6103
0
                pdevproto->color_info.depth =
6104
0
                    pdevproto->color_info.num_components * (8 << deep);
6105
0
                pdevproto->sep_device = true;
6106
0
            }
6107
0
            else
6108
0
            {
6109
0
                pdevproto->color_info.max_components += has_tags;
6110
0
                pdevproto->color_info.num_components += has_tags;
6111
0
                pdevproto->color_info.depth = pdevproto->color_info.num_components * (8<<deep);
6112
0
            }
6113
0
            break;
6114
0
        case PDF14_DeviceCustom:
6115
            /*
6116
             * We are using the output device's process color model.  The
6117
             * color_info for the PDF 1.4 compositing device needs to match
6118
             * the output device.
6119
             */
6120
0
            *pdevproto = gs_pdf14_custom_device;
6121
0
            pdevproto->color_info = dev->color_info;
6122
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
6123
0
            pdevproto->color_info.depth =
6124
0
                       pdevproto->color_info.num_components * (8<<deep);
6125
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
6126
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
6127
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
6128
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
6129
0
            break;
6130
0
        default:      /* Should not occur */
6131
0
            return_error(gs_error_rangecheck);
6132
1.02M
    }
6133
1.02M
    pdevproto->initialize_device_procs((gx_device *)pdevproto);
6134
1.02M
    pdevproto->blend_cs_state = blend_cs_state;
6135
1.02M
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
6136
1.02M
    return 0;
6137
1.02M
}
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
1.98M
{
6145
1.98M
    pdf14_blend_cs_t blend_cs_state;
6146
1.98M
    pdf14_default_colorspace_t pdf14_cs =
6147
1.98M
        pdf14_determine_default_blend_cs(dev, false, &blend_cs_state);
6148
1.98M
    gsicc_colorbuffer_t dev_icc_cs;
6149
1.98M
    bool ok = false;
6150
1.98M
    int tag_depth = device_encodes_tags(dev) ? 8 : 0;
6151
1.98M
    cmm_dev_profile_t *dev_profile;
6152
1.98M
    int code = dev_proc(dev, get_profile)(dev,  &dev_profile);
6153
1.98M
    bool deep = device_is_deep(dev);
6154
6155
1.98M
    if (code < 0)
6156
0
        return false;
6157
6158
1.98M
    check_device_compatible_encoding(dev);
6159
6160
1.98M
    if (dev->color_info.separable_and_linear != GX_CINFO_SEP_LIN_STANDARD)
6161
843k
        return false;
6162
6163
1.14M
    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.14M
    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.14M
    switch (pdf14_cs) {
6170
275k
        case PDF14_DeviceGray:
6171
275k
            ok = dev->color_info.max_gray == (deep ? 65535 : 255) && dev->color_info.depth == (8<<deep) + tag_depth;
6172
275k
            break;
6173
761k
        case PDF14_DeviceRGB:
6174
761k
            ok = dev->color_info.max_color == (deep ? 65535: 255) && dev->color_info.depth == (24<<deep) + tag_depth;
6175
761k
            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
109k
        case PDF14_DeviceCMYKspot:
6180
109k
            ok = false;     /* punt for this case */
6181
109k
            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.14M
    }
6196
1.14M
    return ok;
6197
1.14M
}
6198
6199
/*
6200
 * Recreate the PDF 1.4 compositor device.  Once created, the PDF 1.4
6201
 * compositor device is never removed.  (We do not have a remove compositor
6202
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
6203
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
6204
 * again.
6205
 */
6206
static  int
6207
pdf14_recreate_device(gs_memory_t *mem, gs_gstate * pgs,
6208
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
6209
0
{
6210
0
    pdf14_device * pdev = (pdf14_device *)dev;
6211
0
    gx_device * target = pdev->target;
6212
0
    pdf14_device dev_proto;
6213
0
    bool has_tags = device_encodes_tags(dev);
6214
0
    int code;
6215
0
    bool deep = device_is_deep(dev);
6216
6217
0
    if_debug0m('v', dev->memory, "[v]pdf14_recreate_device\n");
6218
6219
    /*
6220
     * We will not use the entire prototype device but we will set the
6221
     * color related info and the device procs to match the prototype.
6222
     */
6223
0
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
6224
0
                                  pdf14pct, false);
6225
0
    if (code < 0)
6226
0
        return code;
6227
0
    pdev->color_info = dev_proto.color_info;
6228
0
    pdev->pad = target->pad;
6229
0
    pdev->log2_align_mod = target->log2_align_mod;
6230
6231
0
    if (target->num_planar_planes == 0)
6232
0
        pdev->num_planar_planes = 0;
6233
0
    else
6234
0
        pdev->num_planar_planes = dev->color_info.num_components;
6235
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
6236
6237
0
    if (dev_proto.initialize_device_procs != NULL)
6238
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
6239
0
    pdev->procs = dev_proto.procs;
6240
0
    if (deep) {
6241
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
6242
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
6243
0
    }
6244
0
    if (has_tags) {
6245
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
6246
0
    }
6247
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
6248
0
    gx_device_fill_in_procs((gx_device *)pdev);
6249
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
6250
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
6251
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
6252
0
    check_device_separable(dev);
6253
0
    return dev_proc(pdev, open_device)(dev);
6254
0
}
6255
6256
/*
6257
 * Implement the various operations that can be specified via the PDF 1.4
6258
 * create compositor request.
6259
 */
6260
static  int
6261
gx_update_pdf14_compositor(gx_device * pdev, gs_gstate * pgs,
6262
    const gs_pdf14trans_t * pdf14pct, gs_memory_t * mem )
6263
20.9M
{
6264
20.9M
    pdf14_device *p14dev = (pdf14_device *)pdev;
6265
20.9M
    gs_pdf14trans_params_t params = pdf14pct->params;
6266
20.9M
    int code = 0;
6267
6268
20.9M
    params.idle = pdf14pct->idle;
6269
20.9M
    switch (params.pdf14_op) {
6270
0
        default:      /* Should not occur. */
6271
0
            break;
6272
9.29k
        case PDF14_PUSH_DEVICE:
6273
9.29k
            if (!(params.is_pattern)) {
6274
0
                p14dev->blend_mode = 0;
6275
0
                p14dev->opacity = p14dev->shape = 0.0;
6276
0
                pdf14_recreate_device(mem, pgs, pdev, pdf14pct);
6277
0
            }
6278
9.29k
            break;
6279
0
        case PDF14_ABORT_DEVICE:
6280
            /* Something has gone very wrong.  Let transparency device clean up
6281
               what ever it has allocated and then we are shutting it down */
6282
0
            code = gx_abort_trans_device(pgs, pdev);
6283
0
            if (p14dev->free_devicen) {
6284
0
                devn_free_params(pdev);
6285
0
            }
6286
0
            pdf14_disable_device(pdev);
6287
0
            pdf14_close(pdev);
6288
0
            break;
6289
1.02M
        case PDF14_POP_DEVICE:
6290
1.02M
            if (!(params.is_pattern)) {
6291
1.01M
                if_debug0m('v', pdev->memory,
6292
1.01M
                           "[v]gx_update_pdf14_compositor(PDF14_POP_DEVICE)\n");
6293
1.01M
                pgs->get_cmap_procs = p14dev->save_get_cmap_procs;
6294
1.01M
                gx_set_cmap_procs(pgs, p14dev->target);
6295
                /* Send image out raster data to output device */
6296
1.01M
                {
6297
                    /* Make a copy so we can change the ROP */
6298
1.01M
                    gs_gstate new_pgs = *pgs;
6299
6300
                    /* We don't use the gs_gstate log_op since this is for the */
6301
                    /* clist playback. Putting the image (band in the case of the */
6302
                    /* clist) only needs to use the default ROP to copy the data  */
6303
1.01M
                    new_pgs.log_op = rop3_default;
6304
1.01M
                    code = p14dev->pdf14_procs->put_image(pdev, &new_pgs, p14dev->target);
6305
1.01M
                }
6306
                /* Before we disable the device release any deviceN structures.
6307
                    free_devicen is set if the pdf14 device had inherited its
6308
                    deviceN parameters from the target clist device.  In this
6309
                    case they should not be freed */
6310
1.01M
                if (p14dev->free_devicen) {
6311
1.01M
                    gs_devn_params *devn_params = dev_proc(pdev, ret_devn_params)(pdev);
6312
1.01M
                    if (devn_params) {
6313
1.01M
                        gxdso_spot_info si;
6314
1.01M
                        si.params = devn_params;
6315
1.01M
                        si.equiv = &p14dev->op_pequiv_cmyk_colors;
6316
1.01M
                        (void)dev_proc(p14dev->target, dev_spec_op)(p14dev->target, gxdso_update_spots, &si, sizeof(si));
6317
1.01M
                    }
6318
1.01M
                    devn_free_params(pdev);
6319
1.01M
                }
6320
1.01M
                pdf14_disable_device(pdev);
6321
1.01M
                pdf14_close(pdev);
6322
1.01M
            }
6323
1.02M
            break;
6324
395k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
6325
2.27M
        case PDF14_BEGIN_TRANS_GROUP:
6326
2.27M
            if (p14dev->smask_constructed || p14dev->depth_within_smask)
6327
310k
                p14dev->depth_within_smask++;
6328
2.27M
            p14dev->smask_constructed = 0;
6329
2.27M
            code = gx_begin_transparency_group(pgs, pdev, &params);
6330
2.27M
            break;
6331
1.87M
        case PDF14_END_TRANS_GROUP:
6332
1.87M
            code = gx_end_transparency_group(pgs, pdev);
6333
1.87M
            if (p14dev->depth_within_smask)
6334
310k
                p14dev->depth_within_smask--;
6335
1.87M
            break;
6336
256
        case PDF14_BEGIN_TRANS_TEXT_GROUP:
6337
256
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
6338
0
                p14dev->text_group = PDF14_TEXTGROUP_MISSING_ET;
6339
0
                emprintf(p14dev->memory, "Warning: Text group pushed but no ET found\n");
6340
0
            } else
6341
256
                p14dev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6342
256
            break;
6343
395k
        case PDF14_END_TRANS_TEXT_GROUP:
6344
395k
            if (p14dev->text_group == PDF14_TEXTGROUP_BT_PUSHED)
6345
395k
                code = gx_end_transparency_group(pgs, pdev);
6346
395k
            p14dev->text_group = PDF14_TEXTGROUP_NO_BT; /* Hit ET */
6347
395k
            break;
6348
3.94M
        case PDF14_BEGIN_TRANS_MASK:
6349
3.94M
            code = gx_begin_transparency_mask(pgs, pdev, &params);
6350
3.94M
            if (code >= 0 && params.subtype != TRANSPARENCY_MASK_None)
6351
421k
                p14dev->in_smask_construction++;
6352
3.94M
            break;
6353
421k
        case PDF14_END_TRANS_MASK:
6354
421k
            code = gx_end_transparency_mask(pgs, pdev, &params);
6355
421k
            if (code >= 0) {
6356
421k
                p14dev->in_smask_construction--;
6357
421k
                if (p14dev->in_smask_construction < 0)
6358
0
                    p14dev->in_smask_construction = 0;
6359
421k
                if (p14dev->in_smask_construction == 0)
6360
421k
                    p14dev->smask_constructed = 1;
6361
421k
            }
6362
421k
            break;
6363
8.32M
        case PDF14_SET_BLEND_PARAMS:
6364
8.32M
            pdf14_set_params(pgs, pdev, &pdf14pct->params);
6365
8.32M
            break;
6366
0
        case PDF14_PUSH_TRANS_STATE:
6367
0
            code = gx_push_transparency_state(pgs, pdev);
6368
0
            break;
6369
2.69M
        case PDF14_POP_TRANS_STATE:
6370
2.69M
            code = gx_pop_transparency_state(pgs, pdev);
6371
2.69M
            break;
6372
4.78k
        case PDF14_PUSH_SMASK_COLOR:
6373
4.78k
            code = pdf14_increment_smask_color(pgs, pdev);
6374
4.78k
            break;
6375
4.78k
        case PDF14_POP_SMASK_COLOR:
6376
4.78k
            code = pdf14_decrement_smask_color(pgs, pdev);
6377
4.78k
            break;
6378
20.9M
    }
6379
20.9M
    return code;
6380
20.9M
}
6381
6382
/*
6383
 * The PDF 1.4 compositor is never removed.  (We do not have a 'remove
6384
 * compositor' method.  However the compositor is disabled when we are not
6385
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
6386
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
6387
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
6388
 * to the target.
6389
 */
6390
static  int
6391
pdf14_forward_composite(gx_device * dev, gx_device * * pcdev,
6392
        const gs_composite_t * pct, gs_gstate * pgs,
6393
        gs_memory_t * mem, gx_device *cdev)
6394
1.34k
{
6395
1.34k
    pdf14_device *pdev = (pdf14_device *)dev;
6396
1.34k
    gx_device * tdev = pdev->target;
6397
1.34k
    int code;
6398
6399
1.34k
    *pcdev = dev;
6400
1.34k
    if (gs_is_pdf14trans_compositor(pct)) {
6401
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6402
6403
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
6404
0
            return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6405
0
        return 0;
6406
0
    }
6407
1.34k
    code = dev_proc(tdev, composite)(tdev, pcdev, pct, pgs, mem, cdev);
6408
1.34k
    if (code == 1) {
6409
        /* We have created a new compositor that wrapped tdev. This means
6410
         * that our target should be updated to point to that. */
6411
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
6412
0
        code = 0; /* We have not created a new compositor that wrapped dev. */
6413
0
    }
6414
1.34k
    return code;
6415
1.34k
}
6416
6417
/*
6418
 * The PDF 1.4 compositor can be handled directly, so just set *pcdev = dev
6419
 * and return. Since the gs_pdf14_device only supports the high-level routines
6420
 * of the interface, don't bother trying to handle any other compositor.
6421
 */
6422
static int
6423
pdf14_composite(gx_device * dev, gx_device * * pcdev,
6424
        const gs_composite_t * pct, gs_gstate * pgs,
6425
        gs_memory_t * mem, gx_device *cdev)
6426
113M
{
6427
113M
    pdf14_device *p14dev = (pdf14_device *)dev;
6428
113M
    if (gs_is_pdf14trans_compositor(pct)) {
6429
20.9M
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
6430
20.9M
        *pcdev = dev;
6431
        /* cdev, may be the clist reader device which may contain information that
6432
           we will need related to the ICC color spaces that define transparency
6433
           groups.  We want this propogated through all the pdf14 functions.  Store
6434
           a pointer to it in the pdf14 device */
6435
20.9M
        p14dev->pclist_device = cdev;
6436
20.9M
        return gx_update_pdf14_compositor(dev, pgs, pdf14pct, mem);
6437
92.3M
    } else if (gs_is_overprint_compositor(pct)) {
6438
                /* If we had an overprint compositer action, then the
6439
                   color components that were drawn should be updated.
6440
                   The overprint compositor logic and its interactions
6441
                   with the clist is a little odd as it passes uninitialized
6442
                   values around a fair amount.  Hence the forced assignement here.
6443
                   See gx_spot_colors_set_overprint in gscspace for issues... */
6444
92.3M
                const gs_overprint_t * op_pct = (const gs_overprint_t *) pct;
6445
92.3M
                gx_color_index drawn_comps;
6446
92.3M
                GS_OP_FS_STATE curr_state = p14dev->op_state;
6447
6448
92.3M
                p14dev->op_state = op_pct->params.op_state;
6449
92.3M
                if (p14dev->op_state == GS_OP_STATE_NONE) {
6450
46.1M
                    if (op_pct->params.retain_any_comps) {
6451
20.9k
                        drawn_comps = op_pct->params.drawn_comps;
6452
46.1M
                    } else {
6453
                        /* Draw everything. If this parameter was not set, clist does
6454
                           not fill it in.  */
6455
46.1M
                        drawn_comps = ((gx_color_index)1 << (p14dev->color_info.num_components)) - (gx_color_index)1;
6456
46.1M
                    }
6457
6458
46.1M
                    if (op_pct->params.is_fill_color) {
6459
25.1M
                        p14dev->effective_overprint_mode = op_pct->params.effective_opm;
6460
25.1M
                        p14dev->drawn_comps_fill = drawn_comps;
6461
25.1M
                    } else {
6462
21.0M
                        p14dev->stroke_effective_op_mode = op_pct->params.effective_opm;
6463
21.0M
                        p14dev->drawn_comps_stroke = drawn_comps;
6464
21.0M
                    }
6465
                    /* We restore the NONE states as that is used just to force
6466
                       overprint settings in the overprint compositor communication */
6467
46.1M
                    p14dev->op_state = curr_state;
6468
46.1M
                }
6469
92.3M
                *pcdev = dev;
6470
92.3M
                return 0;
6471
92.3M
    } else
6472
0
        return gx_no_composite(dev, pcdev, pct, pgs, mem, cdev);
6473
113M
}
6474
6475
static int
6476
pdf14_push_text_group(gx_device *dev, gs_gstate *pgs,
6477
                      gs_blend_mode_t blend_mode, float opacity,
6478
                      float shape, bool is_clist)
6479
2.21k
{
6480
2.21k
    int code;
6481
2.21k
    gs_transparency_group_params_t params = { 0 };
6482
2.21k
    gs_rect bbox = { 0 }; /* Bounding box is set by parent */
6483
2.21k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
6484
2.21k
    float alpha = pgs->fillconstantalpha;
6485
6486
    /* Push a non-isolated knock-out group making sure the opacity and blend
6487
       mode are correct */
6488
2.21k
    params.Isolated = false;
6489
2.21k
    params.Knockout = true;
6490
2.21k
    params.page_group = false;
6491
2.21k
    params.text_group = PDF14_TEXTGROUP_BT_PUSHED;
6492
2.21k
    params.group_opacity = 1.0;
6493
2.21k
    params.group_shape = 1.0;
6494
6495
2.21k
    gs_setfillconstantalpha(pgs, 1.0);
6496
2.21k
    gs_setblendmode(pgs, BLEND_MODE_Normal);
6497
6498
2.21k
    if (is_clist) {
6499
2.21k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6500
2.21k
        if (code < 0)
6501
0
            return code;
6502
2.21k
    }
6503
6504
2.21k
    code = gs_begin_transparency_group(pgs, &params, &bbox, PDF14_BEGIN_TRANS_GROUP);
6505
2.21k
    gs_setfillconstantalpha(pgs, alpha);
6506
2.21k
    gs_setblendmode(pgs, blend_mode);
6507
2.21k
    if (code < 0)
6508
0
        return code;
6509
6510
2.21k
    if (is_clist) {
6511
2.21k
        code = pdf14_clist_update_params(pdev, pgs, false, NULL);
6512
2.21k
    }
6513
2.21k
    return code;
6514
2.21k
}
6515
6516
static  int
6517
pdf14_text_begin(gx_device * dev, gs_gstate * pgs,
6518
                 const gs_text_params_t * text, gs_font * font,
6519
                 const gx_clip_path * pcpath,
6520
                 gs_text_enum_t ** ppenum)
6521
488
{
6522
488
    int code;
6523
488
    gs_text_enum_t *penum;
6524
488
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
6525
488
    float opacity = pgs->fillconstantalpha;
6526
488
    float shape = 1.0;
6527
488
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
6528
488
    pdf14_device *pdev = (pdf14_device*)dev;
6529
488
    bool draw = !(text->operation & TEXT_DO_NONE);
6530
488
    uint text_mode = gs_currenttextrenderingmode(pgs);
6531
488
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
6532
488
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
6533
6534
488
    code = pdf14_initialize_ctx(dev, pgs);
6535
488
    if (code < 0)
6536
0
        return code;
6537
6538
488
    if_debug0m('v', pgs->memory, "[v]pdf14_text_begin\n");
6539
488
    pdf14_set_marking_params(dev, pgs);
6540
488
    code = gx_default_text_begin(dev, pgs, text, font, pcpath, &penum);
6541
488
    if (code < 0)
6542
0
        return code;
6543
6544
    /* We may need to push a non-isolated transparency group if the following
6545
       is true.
6546
       1) We are not currently in one that we pushed for text and we are in
6547
          a BT/ET pair.  This is determined by looking at the pdf14 text_group.
6548
       2) The blend mode is not Normal or the opacity is not 1.0
6549
       3) Text knockout is set to true
6550
       4) We are actually doing a text drawing
6551
6552
       Special note:  If text-knockout is set to false while we are within a
6553
       BT ET pair, we should pop the group.  I need to create a test file for
6554
       this case.  */
6555
6556
       /* Catch case where we already pushed a group and are trying to push another one.
6557
       In that case, we will pop the current one first, as we don't want to be left
6558
       with it. Note that if we have a BT and no other BTs or ETs then this issue
6559
       will not be caught until we do the put_image and notice that the stack is not
6560
       empty. */
6561
488
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
6562
0
        code = gs_end_transparency_group(pgs);
6563
0
        if (code < 0)
6564
0
            return code;
6565
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
6566
0
    }
6567
6568
488
    if (gs_currenttextknockout(pgs) && (blend_issue ||
6569
487
         (pgs->fillconstantalpha != 1.0 && text_fill) ||
6570
487
         (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
6571
1
         text_mode != 3 && /* don't bother with invisible text */
6572
1
         pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED)
6573
1
        if (draw) {
6574
1
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape,
6575
1
                false);
6576
1
        }
6577
488
    *ppenum = (gs_text_enum_t *)penum;
6578
488
    return code;
6579
488
}
6580
6581
static  int
6582
pdf14_initialize_device(gx_device *new_dev)
6583
1.02M
{
6584
1.02M
    pdf14_device *pdev = (pdf14_device*)new_dev;
6585
6586
1.02M
    pdev->ctx = NULL;
6587
1.02M
    pdev->color_model_stack = NULL;
6588
1.02M
    pdev->smaskcolor = NULL;
6589
6590
1.02M
    return 0;
6591
1.02M
}
6592
6593
/*
6594
 * Implement copy_mono by filling lots of small rectangles.
6595
 */
6596
static int
6597
pdf14_copy_mono(gx_device * dev,
6598
               const byte * base, int sourcex, int sraster, gx_bitmap_id id,
6599
        int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
6600
12.9M
{
6601
12.9M
    const byte *sptr;
6602
12.9M
    const byte *line;
6603
12.9M
    int sbit, first_bit;
6604
12.9M
    int code, sbyte, bit, count;
6605
12.9M
    int run_length, startx, current_bit, bit_value;
6606
12.9M
    gx_color_index current_color;
6607
6608
12.9M
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
6609
12.9M
    line = base + (sourcex >> 3);
6610
12.9M
    sbit = sourcex & 7;
6611
12.9M
    first_bit = 7 - sbit;
6612
6613
    /* Loop through the height of the specified area. */
6614
97.7M
    while (h-- > 0) {
6615
        /* Set up for the start of each line of the area. */
6616
84.8M
        sptr = line;
6617
84.8M
        sbyte = *sptr++;
6618
        /* The +1 here is 'sacrificial', we are going to decrement it by 1 immediately in
6619
         * the loop below so adding 1 means that we don't fall into the bit == 0
6620
         * case and incorrectly read a new byte from the source. This weirdness is because
6621
         * the original code wouold read off the end of the buffer if the number of bits in
6622
         * the raster was an exact multiple of 8. If it was also a multiple of the word
6623
         * size we might read unallocated memory. Moving the 'sbyte = *sptr++' from the end
6624
         * of the loop to the beginning meant we would not read past the end of the buffer
6625
         * because we would drop out of the 'do ... while (count-- > 0)' loop before
6626
         * reading another byte.
6627
         */
6628
84.8M
        bit = first_bit + 1;
6629
84.8M
        count = w;
6630
84.8M
        run_length = 0;
6631
84.8M
        startx = x;
6632
84.8M
        current_bit = 0;
6633
84.8M
        current_color = zero;
6634
6635
        /* Loop across each pixel of a line. */
6636
1.20G
        do {
6637
            /* Move to the next input bit. */
6638
1.20G
            if (bit == 0) {
6639
104M
                bit = 7;
6640
104M
                sbyte = *sptr++;
6641
104M
            }
6642
1.09G
            else
6643
1.09G
                bit--;
6644
1.20G
            bit_value = (sbyte >> bit) & 1;
6645
1.20G
            if (bit_value == current_bit) {
6646
                /* The value did not change, simply increment our run length */
6647
991M
                run_length++;
6648
991M
            } else {
6649
                /* The value changed, fill the current rectangle. */
6650
212M
                if (run_length != 0) {
6651
202M
                    if (current_color != gx_no_color_index) {
6652
87.3M
                        code = (*dev_proc(dev, fill_rectangle))
6653
87.3M
                                (dev, startx, y, run_length, 1, current_color);
6654
87.3M
                        if (code < 0)
6655
0
                            return code;
6656
87.3M
                    }
6657
202M
                    startx += run_length;
6658
202M
                }
6659
212M
                run_length = 1;
6660
212M
                current_color = bit_value ? one : zero;
6661
212M
                current_bit = bit_value;
6662
212M
            }
6663
1.20G
        } while (--count > 0);
6664
        /* Fill the last rectangle in the line. */
6665
84.8M
        if (run_length != 0 && current_color != gx_no_color_index) {
6666
37.5M
            code = (*dev_proc(dev, fill_rectangle))
6667
37.5M
                        (dev, startx, y, run_length, 1, current_color);
6668
37.5M
            if (code < 0)
6669
0
                return code;
6670
37.5M
        }
6671
        /* Move to the next line */
6672
84.8M
        line += sraster;
6673
84.8M
        y++;
6674
84.8M
    }
6675
12.9M
    return 0;
6676
12.9M
}
6677
6678
/* Added to avoid having to go back and forth between fixed and int
6679
   in some of the internal methods used for dealing with tiling
6680
   and devn colors */
6681
static int
6682
pdf14_fill_rectangle_devn(gx_device *dev, int x, int y, int w, int h,
6683
    const gx_drawing_color *pdcolor)
6684
962
{
6685
962
    pdf14_device *pdev = (pdf14_device *)dev;
6686
962
    pdf14_buf *buf;
6687
962
    int code;
6688
6689
962
    fit_fill_xywh(dev, x, y, w, h);
6690
962
    if (w <= 0 || h <= 0)
6691
0
        return 0;
6692
6693
962
    code = pdf14_initialize_ctx(dev, NULL);
6694
962
    if (code < 0)
6695
0
        return code;
6696
962
    buf = pdev->ctx->stack;
6697
6698
962
    if (buf->knockout)
6699
0
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
6700
0
            true);
6701
962
    else
6702
962
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
6703
962
}
6704
6705
/* Step through and do rect fills with the devn colors as
6706
   we hit each transition in the bitmap. It is possible
6707
   that one of the colors is not devn, but is pure and
6708
   is set to gx_no_color_index. This type of mix happens
6709
   for example from tile_clip_fill_rectangle_hl_color */
6710
static int
6711
pdf14_copy_mono_devn(gx_device *dev,
6712
    const byte *base, int sourcex, int sraster,
6713
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6714
    const gx_drawing_color *pdcolor1)
6715
248
{
6716
248
    const byte *sptr;
6717
248
    const byte *line;
6718
248
    int sbit, first_bit;
6719
248
    int code, sbyte, bit, count;
6720
248
    int run_length, startx, current_bit, bit_value;
6721
248
    const gx_drawing_color *current_color;
6722
6723
248
    if ((x | y) < 0) {
6724
0
        if (x < 0) {
6725
0
            w += x;
6726
0
            sourcex -= x;
6727
0
            x = 0;
6728
0
        }
6729
0
        if (y < 0) {
6730
0
            h += y;
6731
0
            base -= (int)(y * sraster);
6732
0
            y = 0;
6733
0
        }
6734
0
    }
6735
248
    if (w > (dev)->width - x)
6736
0
        w = (dev)->width - x;
6737
248
    if (h > (dev)->height - y)
6738
0
        h = (dev)->height - y;
6739
248
    if (w <= 0 || h <= 0)
6740
0
        return 0;
6741
6742
248
    line = base + (sourcex >> 3);
6743
248
    sbit = sourcex & 7;
6744
248
    first_bit = 7 - sbit;
6745
6746
    /* Loop through the height of the specified area. */
6747
815
    while (h-- > 0) {
6748
        /* Set up for the start of each line of the area. */
6749
567
        sptr = line;
6750
567
        sbyte = *sptr++;
6751
567
        bit = first_bit;
6752
567
        count = w;
6753
567
        run_length = 0;
6754
567
        startx = x;
6755
567
        current_bit = 0;
6756
567
        current_color = pdcolor0;
6757
6758
        /* Loop across each pixel of a line. */
6759
6.15k
        do {
6760
6.15k
            bit_value = (sbyte >> bit) & 1;
6761
6.15k
            if (bit_value == current_bit) {
6762
                /* The value did not change, simply increment our run length */
6763
4.47k
                run_length++;
6764
4.47k
            } else {
6765
                /* The value changed, fill the current rectangle. */
6766
1.67k
                if (run_length != 0) {
6767
1.51k
                    if (current_color->type != gx_dc_type_pure &&
6768
717
                        current_color->colors.pure != gx_no_color_index) {
6769
717
                        code = pdf14_fill_rectangle_devn(dev, startx, y,
6770
717
                            run_length, 1, current_color);
6771
717
                        if (code < 0)
6772
0
                            return code;
6773
717
                    }
6774
1.51k
                    startx += run_length;
6775
1.51k
                }
6776
1.67k
                run_length = 1;
6777
1.67k
                current_color = bit_value ? pdcolor1 : pdcolor0;
6778
1.67k
                current_bit = bit_value;
6779
1.67k
            }
6780
6781
            /* Move to the next input bit. */
6782
6.15k
            if (bit == 0) {
6783
553
                bit = 7;
6784
553
                sbyte = *sptr++;
6785
553
            } else
6786
5.60k
                bit--;
6787
6.15k
        } while (--count > 0);
6788
6789
        /* Fill the last rectangle in the line. */
6790
567
        if (run_length != 0 && current_color->type != gx_dc_type_pure &&
6791
245
            current_color->colors.pure != gx_no_color_index) {
6792
245
            code = pdf14_fill_rectangle_devn(dev, startx, y,
6793
245
                run_length, 1, current_color);
6794
245
            if (code < 0)
6795
0
                return code;
6796
245
        }
6797
        /* Move to the next line */
6798
567
        line += sraster;
6799
567
        y++;
6800
567
    }
6801
248
    return 0;
6802
248
}
6803
6804
/* Step through the tiles doing essentially copy_mono but with devn colors */
6805
static int
6806
pdf14_impl_strip_tile_rectangle_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6807
    int x, int y, int w, int h, const gx_drawing_color *pdcolor0,
6808
    const gx_drawing_color *pdcolor1, int px, int py)
6809
248
{   /* Fill the rectangle in chunks. */
6810
248
    int width = tiles->size.x;
6811
248
    int height = tiles->size.y;
6812
248
    int raster = tiles->raster;
6813
248
    int rwidth = tiles->rep_width;
6814
248
    int rheight = tiles->rep_height;
6815
248
    int shift = tiles->shift;
6816
6817
248
    if (rwidth == 0 || rheight == 0)
6818
0
        return_error(gs_error_unregistered);
6819
248
    fit_fill_xy(dev, x, y, w, h);
6820
6821
248
     {
6822
248
        int xoff = (shift == 0 ? px :
6823
248
                px + (y + py) / rheight * tiles->rep_shift);
6824
248
        int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */
6825
0
            (x + xoff) & (rwidth - 1) :
6826
248
            (x + xoff) % rwidth);
6827
248
        int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */
6828
0
            (y + py) & (rheight - 1) :
6829
248
            (y + py) % rheight);
6830
248
        int icw = width - irx;
6831
248
        int ch = height - ry;
6832
248
        byte *row = tiles->data + ry * raster;
6833
248
        int code = 0;
6834
6835
248
        if (ch >= h) {      /* Shallow operation */
6836
248
            if (icw >= w) { /* Just one (partial) tile to transfer. */
6837
248
                code = pdf14_copy_mono_devn(dev, row, irx, raster, x, y,
6838
248
                    w, h, pdcolor0, pdcolor1);
6839
248
                if (code < 0)
6840
0
                    return_error(code);
6841
248
            } else {
6842
0
                int ex = x + w;
6843
0
                int fex = ex - width;
6844
0
                int cx = x + icw;
6845
6846
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6847
0
                    x, y, icw, h, pdcolor0, pdcolor1);
6848
0
                if (code < 0)
6849
0
                    return_error(code);
6850
6851
0
                while (cx <= fex) {
6852
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6853
0
                        width, h, pdcolor0, pdcolor1);
6854
0
                    if (code < 0)
6855
0
                        return_error(code);
6856
0
                    cx += width;
6857
0
                }
6858
0
                if (cx < ex) {
6859
0
                    code = pdf14_copy_mono_devn(dev, row, 0, raster, cx, y,
6860
0
                        ex - cx, h, pdcolor0, pdcolor1);
6861
0
                    if (code < 0)
6862
0
                        return_error(code);
6863
0
                }
6864
0
            }
6865
248
        } else if (icw >= w && shift == 0) {
6866
            /* Narrow operation, no shift */
6867
0
            int ey = y + h;
6868
0
            int fey = ey - height;
6869
0
            int cy = y + ch;
6870
6871
0
            code = pdf14_copy_mono_devn(dev, row, irx, raster,
6872
0
                x, y, w, ch, pdcolor0, pdcolor1);
6873
0
            if (code < 0)
6874
0
                return_error(code);
6875
0
            row = tiles->data;
6876
0
            do {
6877
0
                ch = (cy > fey ? ey - cy : height);
6878
0
                code = pdf14_copy_mono_devn(dev, row, irx, raster,
6879
0
                    x, cy, w, ch, pdcolor0, pdcolor1);
6880
0
                if (code < 0)
6881
0
                    return_error(code);
6882
0
            } while ((cy += ch) < ey);
6883
0
        } else {
6884
            /* Full operation.  If shift != 0, some scan lines */
6885
            /* may be narrow.  We could test shift == 0 in advance */
6886
            /* and use a slightly faster loop, but right now */
6887
            /* we don't bother. */
6888
0
            int ex = x + w, ey = y + h;
6889
0
            int fex = ex - width, fey = ey - height;
6890
0
            int cx, cy;
6891
6892
0
            for (cy = y;;) {
6893
0
                if (icw >= w) {
6894
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6895
0
                        x, cy, w, ch, pdcolor0, pdcolor1);
6896
0
                    if (code < 0)
6897
0
                        return_error(code);
6898
0
                } else {
6899
0
                    code = pdf14_copy_mono_devn(dev, row, irx, raster,
6900
0
                        x, cy, icw, ch, pdcolor0, pdcolor1);
6901
0
                    if (code < 0)
6902
0
                        return_error(code);
6903
0
                    cx = x + icw;
6904
0
                    while (cx <= fex) {
6905
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6906
0
                            cx, cy, width, ch, pdcolor0, pdcolor1);
6907
0
                        if (code < 0)
6908
0
                            return_error(code);
6909
0
                        cx += width;
6910
0
                    }
6911
0
                    if (cx < ex) {
6912
0
                        code = pdf14_copy_mono_devn(dev, row, 0, raster,
6913
0
                            cx, cy, ex - cx, ch, pdcolor0, pdcolor1);
6914
0
                        if (code < 0)
6915
0
                            return_error(code);
6916
0
                    }
6917
0
                }
6918
0
                if ((cy += ch) >= ey)
6919
0
                    break;
6920
0
                ch = (cy > fey ? ey - cy : height);
6921
0
                if ((irx += shift) >= rwidth)
6922
0
                    irx -= rwidth;
6923
0
                icw = width - irx;
6924
0
                row = tiles->data;
6925
0
            }
6926
0
        }
6927
248
    }
6928
248
    return 0;
6929
248
}
6930
6931
/* pdf14 device supports devn */
6932
static int
6933
pdf14_strip_tile_rect_devn(gx_device *dev, const gx_strip_bitmap *tiles,
6934
    int x, int y, int w, int h,
6935
    const gx_drawing_color *pdcolor0,
6936
    const gx_drawing_color *pdcolor1, int px, int py)
6937
248
{
6938
248
    pdf14_device *pdev = (pdf14_device *)dev;
6939
248
    pdf14_buf *buf;
6940
248
    int num_comp;
6941
248
    int k;
6942
248
    bool same = false;
6943
248
    int code;
6944
6945
248
    code = pdf14_initialize_ctx(dev, NULL);
6946
248
    if (code < 0)
6947
0
        return code;
6948
248
    buf = pdev->ctx->stack;
6949
248
    num_comp = buf->n_chan - 1;
6950
6951
    /* if color0 is identical to color1, do rect fill */
6952
248
    if (pdcolor0->type == gx_dc_type_devn && pdcolor1->type == gx_dc_type_devn) {
6953
0
        same = true;
6954
0
        for (k = 0; k < num_comp; k++) {
6955
0
            if (pdcolor0->colors.devn.values[k] != pdcolor1->colors.devn.values[k]) {
6956
0
                same = false;
6957
0
                break;
6958
0
            }
6959
0
        }
6960
0
    }
6961
6962
248
    if (same) {
6963
0
        code = pdf14_fill_rectangle_devn(dev, x, y, w, h, pdcolor0);
6964
248
    } else {
6965
        /* Go through the tile stepping using code stolen from
6966
           gx_default_strip_tile_rectangle and call the rect fills
6967
           using code stolen from pdf14_copy_mono but using devn
6968
           colors */
6969
248
        code = pdf14_impl_strip_tile_rectangle_devn(dev, tiles,
6970
248
            x, y, w, h, pdcolor0, pdcolor1, px, py);
6971
248
    }
6972
248
    return code;
6973
248
}
6974
6975
/* Used in a few odd cases where the target device is planar and we have
6976
   a planar tile (pattern) and we are copying it into place here */
6977
static int
6978
pdf14_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
6979
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
6980
2.45k
{
6981
2.45k
    pdf14_device *pdev = (pdf14_device *)dev;
6982
2.45k
    pdf14_ctx *ctx;
6983
2.45k
    pdf14_buf *buf;
6984
2.45k
    int xo = x;
6985
2.45k
    int yo = y;
6986
2.45k
    pdf14_buf fake_tos;
6987
2.45k
    int deep;
6988
6989
2.45k
    int code = pdf14_initialize_ctx(dev, NULL);
6990
2.45k
    if (code < 0)
6991
0
        return code;
6992
6993
2.45k
    fit_fill_xywh(dev, x, y, w, h);
6994
2.45k
    if (w <= 0 || h <= 0)
6995
0
        return 0;
6996
6997
2.45k
    ctx = pdev->ctx;
6998
2.45k
    buf = ctx->stack;
6999
2.45k
    deep = ctx->deep;
7000
7001
2.45k
    fake_tos.deep = deep;
7002
2.45k
    fake_tos.alpha = (uint16_t)(0xffff * pdev->alpha + 0.5);
7003
2.45k
    fake_tos.backdrop = NULL;
7004
2.45k
    fake_tos.blend_mode = pdev->blend_mode;
7005
2.45k
    fake_tos.color_space = buf->color_space;
7006
2.45k
    fake_tos.data = (byte *)data + ((data_x - (x - xo))<<deep) - (y - yo) * raster; /* Nasty, cast away of const */
7007
2.45k
    fake_tos.dirty.p.x = x;
7008
2.45k
    fake_tos.dirty.p.y = y;
7009
2.45k
    fake_tos.dirty.q.x = x + w;
7010
2.45k
    fake_tos.dirty.q.y = y + h;
7011
2.45k
    fake_tos.has_alpha_g = 0;
7012
2.45k
    fake_tos.has_shape = 0;
7013
2.45k
    fake_tos.has_tags = device_encodes_tags(dev);
7014
2.45k
    fake_tos.idle = false;
7015
2.45k
    fake_tos.isolated = false;
7016
2.45k
    fake_tos.knockout = false;
7017
2.45k
    fake_tos.mask_id = 0;
7018
2.45k
    fake_tos.mask_stack = NULL;
7019
2.45k
    fake_tos.matte = NULL;
7020
2.45k
    fake_tos.matte_num_comps = 0;
7021
2.45k
    fake_tos.memory = dev->memory;
7022
2.45k
    fake_tos.n_chan = dev->color_info.num_components;
7023
2.45k
    fake_tos.n_planes = dev->color_info.num_components;
7024
2.45k
    fake_tos.num_spots = 0;
7025
2.45k
    fake_tos.group_color_info = NULL;
7026
2.45k
    fake_tos.planestride = raster * (size_t)plane_height;
7027
2.45k
    fake_tos.rect.p.x = x;
7028
2.45k
    fake_tos.rect.p.y = y;
7029
2.45k
    fake_tos.rect.q.x = x + w;
7030
2.45k
    fake_tos.rect.q.y = y + h;
7031
2.45k
    fake_tos.rowstride = raster;
7032
2.45k
    fake_tos.saved = NULL;
7033
2.45k
    fake_tos.shape = 0xffff;
7034
2.45k
    fake_tos.SMask_SubType = TRANSPARENCY_MASK_Alpha;
7035
2.45k
    fake_tos.transfer_fn = NULL;
7036
2.45k
    pdf14_compose_alphaless_group(&fake_tos, buf, x, x+w, y, y+h,
7037
2.45k
                                  pdev->ctx->memory, dev);
7038
2.45k
    return 0;
7039
2.45k
}
7040
7041
static int
7042
pdf14_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect,
7043
    const gs_gstate *pgs, const gx_drawing_color *pdcolor,
7044
    const gx_clip_path *pcpath)
7045
16.1M
{
7046
16.1M
    pdf14_device *pdev = (pdf14_device *)dev;
7047
16.1M
    pdf14_buf* buf;
7048
16.1M
    int code;
7049
16.1M
    int x = fixed2int(rect->p.x);
7050
16.1M
    int y = fixed2int(rect->p.y);
7051
16.1M
    int w = fixed2int(rect->q.x) - x;
7052
16.1M
    int h = fixed2int(rect->q.y) - y;
7053
7054
16.1M
    fit_fill_xywh(dev, x, y, w, h);
7055
16.1M
    if (w <= 0 || h <= 0)
7056
206k
        return 0;
7057
7058
15.9M
    code = pdf14_initialize_ctx(dev, pgs);
7059
15.9M
    if (code < 0)
7060
0
        return code;
7061
15.9M
    buf = pdev->ctx->stack;
7062
7063
15.9M
    if (buf->knockout)
7064
142k
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, 0, pdcolor,
7065
142k
                                                   true);
7066
15.8M
    else
7067
15.8M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, 0, pdcolor, true);
7068
15.9M
}
7069
7070
static  int
7071
pdf14_fill_rectangle(gx_device * dev,
7072
                    int x, int y, int w, int h, gx_color_index color)
7073
332M
{
7074
332M
    pdf14_device *pdev = (pdf14_device *)dev;
7075
332M
    pdf14_buf *buf;
7076
332M
    int code;
7077
7078
332M
    fit_fill_xywh(dev, x, y, w, h);
7079
332M
    if (w <= 0 || h <= 0)
7080
9.60M
        return 0;
7081
7082
323M
    code = pdf14_initialize_ctx(dev, NULL);
7083
323M
    if (code < 0)
7084
0
        return code;
7085
7086
323M
    buf = pdev->ctx->stack;
7087
7088
323M
    if (buf->knockout)
7089
2.27M
        return pdf14_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, NULL,
7090
2.27M
                                                   false);
7091
320M
    else
7092
320M
        return pdf14_mark_fill_rectangle(dev, x, y, w, h, color, NULL, false);
7093
323M
}
7094
7095
static int
7096
pdf14_compute_group_device_int_rect(const gs_matrix *ctm,
7097
                                    const gs_rect *pbbox, gs_int_rect *rect)
7098
2.37M
{
7099
2.37M
    gs_rect dev_bbox;
7100
2.37M
    int code;
7101
7102
2.37M
    code = gs_bbox_transform(pbbox, ctm, &dev_bbox);
7103
2.37M
    if (code < 0)
7104
0
        return code;
7105
2.37M
    rect->p.x = (int)floor(dev_bbox.p.x);
7106
2.37M
    rect->p.y = (int)floor(dev_bbox.p.y);
7107
2.37M
    rect->q.x = (int)ceil(dev_bbox.q.x);
7108
2.37M
    rect->q.y = (int)ceil(dev_bbox.q.y);
7109
    /* Sanity check rect for insane ctms */
7110
2.37M
    if (rect->p.x < 0)
7111
252k
        rect->p.x = 0;
7112
2.37M
    if (rect->q.x < rect->p.x)
7113
13.6k
        rect->q.x = rect->p.x;
7114
2.37M
    if (rect->p.y < 0)
7115
2.17M
        rect->p.y = 0;
7116
2.37M
    if (rect->q.y < rect->p.y)
7117
48.3k
        rect->q.y = rect->p.y;
7118
2.37M
    return 0;
7119
2.37M
}
7120
7121
static  int
7122
compute_group_device_int_rect(pdf14_device *pdev, gs_int_rect *rect,
7123
                              const gs_rect *pbbox, gs_gstate *pgs)
7124
2.30M
{
7125
2.30M
    int code = pdf14_compute_group_device_int_rect(&ctm_only(pgs), pbbox, rect);
7126
7127
2.30M
    if (code < 0)
7128
0
        return code;
7129
2.30M
    rect_intersect(*rect, pdev->ctx->rect);
7130
    /* Make sure the rectangle is not anomalous (q < p) -- see gsrect.h */
7131
2.30M
    if (rect->q.x < rect->p.x)
7132
10.9k
        rect->q.x = rect->p.x;
7133
2.30M
    if (rect->q.y < rect->p.y)
7134
53.7k
        rect->q.y = rect->p.y;
7135
2.30M
    return 0;
7136
2.30M
}
7137
7138
static  int
7139
pdf14_begin_transparency_group(gx_device* dev,
7140
    const gs_transparency_group_params_t* ptgp,
7141
    const gs_rect* pbbox,
7142
    gs_gstate* pgs, gs_memory_t* mem)
7143
2.27M
{
7144
2.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7145
2.27M
    float alpha = ptgp->group_opacity * ptgp->group_shape;
7146
2.27M
    gs_int_rect rect;
7147
2.27M
    int code;
7148
2.27M
    bool isolated = ptgp->Isolated;
7149
2.27M
    gs_transparency_color_t group_color_type;
7150
2.27M
    cmm_profile_t* group_profile;
7151
2.27M
    cmm_profile_t* tos_profile;
7152
2.27M
    gsicc_rendering_param_t render_cond;
7153
2.27M
    cmm_dev_profile_t* dev_profile;
7154
2.27M
    bool cm_back_drop = false;
7155
2.27M
    bool new_icc = false;
7156
2.27M
    pdf14_group_color_t* group_color_info;
7157
2.27M
    bool has_tags = device_encodes_tags(dev);
7158
7159
2.27M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7160
2.27M
    if (code < 0)
7161
0
        return code;
7162
2.27M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &tos_profile, &render_cond);
7163
7164
2.27M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
7165
395k
        pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* For immediate mode and clist reading */
7166
395k
    }
7167
7168
2.27M
    if (ptgp->text_group == PDF14_TEXTGROUP_BT_PUSHED)
7169
395k
        rect = pdev->ctx->rect; /* Use parent group for text_group. */
7170
1.87M
    else
7171
1.87M
        code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7172
7173
2.27M
    if (code < 0)
7174
0
        return code;
7175
2.27M
    if_debug5m('v', pdev->memory,
7176
2.27M
        "[v]pdf14_begin_transparency_group, I = %d, K = %d, alpha = %g, bm = %d page_group = %d\n",
7177
2.27M
        ptgp->Isolated, ptgp->Knockout, (double)alpha, pgs->blend_mode, ptgp->page_group);
7178
7179
    /* If the group color is unknown then use the current device profile. */
7180
2.27M
    if (ptgp->group_color_type == UNKNOWN) {
7181
1.87M
        group_color_type = ICC;
7182
1.87M
        group_profile = tos_profile;
7183
1.87M
    }
7184
402k
    else {
7185
402k
        group_color_type = ptgp->group_color_type;
7186
402k
        group_profile = ptgp->iccprofile;
7187
402k
    }
7188
7189
    /* We have to handle case where the profile is in the clist */
7190
2.27M
    if (group_profile == NULL && pdev->pclist_device != NULL) {
7191
        /* Get the serialized data from the clist. */
7192
402k
        gx_device_clist_reader* pcrdev = (gx_device_clist_reader*)(pdev->pclist_device);
7193
402k
        group_profile = gsicc_read_serial_icc((gx_device*)pcrdev, ptgp->icc_hashcode);
7194
402k
        if (group_profile == NULL)
7195
0
            return gs_throw(gs_error_unknownerror, "ICC data not found in clist");
7196
        /* Keep a pointer to the clist device */
7197
402k
        group_profile->dev = (gx_device*)pcrdev;
7198
402k
        new_icc = true;
7199
402k
    }
7200
2.27M
    if (group_profile != NULL) {
7201
        /* If we have a non-isolated group and the color space is different,
7202
            we will need to CM the backdrop. */
7203
2.27M
        if (!gsicc_profiles_equal(group_profile, tos_profile)) {
7204
178k
            cm_back_drop = true;
7205
178k
        }
7206
2.27M
    }
7207
7208
    /* Always create the base color group information as it is only through
7209
       groups that we can have a color space change.  This will survive
7210
       the life of the context. */
7211
2.27M
    if (pdev->ctx->base_color == NULL) {
7212
535k
        pdev->ctx->base_color = pdf14_make_base_group_color(dev);
7213
535k
    }
7214
7215
    /* If this is not the page group and we don't yet have a group, we need
7216
       to create a buffer for the whole page so that we can handle stuff drawn
7217
       outside this current group (e.g. two non inclusive groups drawn independently) */
7218
2.27M
    if (pdev->ctx->stack == NULL && !ptgp->page_group) {
7219
59.0k
        code = pdf14_initialize_ctx(dev, NULL);
7220
59.0k
        if (code < 0)
7221
0
            return code;
7222
59.0k
        pdev->ctx->stack->isolated = true;
7223
59.0k
    }
7224
7225
2.27M
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptgp->icc_hashcode,
7226
2.27M
        group_profile, false);
7227
2.27M
    if (group_color_info == NULL)
7228
0
        return gs_error_VMerror;
7229
2.27M
    if_debug0m('v', dev->memory, "[v]Transparency group color space update\n");
7230
7231
2.27M
    code = pdf14_push_transparency_group(pdev->ctx, &rect, isolated, ptgp->Knockout,
7232
2.27M
                                        (uint16_t)floor (65535 * alpha + 0.5),
7233
2.27M
                                        (uint16_t)floor(65535 * ptgp->group_shape + 0.5),
7234
2.27M
                                        (uint16_t)floor(65535 * ptgp->group_opacity + 0.5),
7235
2.27M
                                        pgs->blend_mode, ptgp->idle,
7236
2.27M
                                         ptgp->mask_id, pdev->color_info.num_components - has_tags,
7237
2.27M
                                         cm_back_drop, ptgp->shade_group,
7238
2.27M
                                         group_profile, tos_profile, group_color_info, pgs, dev);
7239
2.27M
    if (new_icc)
7240
402k
        gsicc_adjust_profile_rc(group_profile, -1, "pdf14_begin_transparency_group");
7241
2.27M
    return code;
7242
2.27M
}
7243
7244
static void
7245
pdf14_pop_color_model(gx_device* dev, pdf14_group_color_t* group_color)
7246
2.27M
{
7247
2.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7248
7249
2.27M
    if (group_color != NULL &&
7250
2.27M
        !(group_color->group_color_mapping_procs == NULL &&
7251
2.27M
            group_color->group_color_comp_index == NULL)) {
7252
2.27M
        bool has_tags = device_encodes_tags(dev);
7253
2.27M
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7254
2.27M
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7255
2.27M
        pdev->color_info.polarity = group_color->polarity;
7256
2.27M
        if (pdev->num_planar_planes > 0)
7257
80.8k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7258
2.27M
        pdev->color_info.num_components = group_color->num_components + has_tags;
7259
2.27M
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7260
2.27M
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7261
2.27M
        pdev->blend_procs = group_color->blend_procs;
7262
2.27M
        pdev->ctx->additive = group_color->isadditive;
7263
2.27M
        pdev->pdf14_procs = group_color->unpack_procs;
7264
2.27M
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7265
2.27M
        pdev->color_info.depth = group_color->depth;
7266
2.27M
        pdev->color_info.max_color = group_color->max_color;
7267
2.27M
        pdev->color_info.max_gray = group_color->max_gray;
7268
2.27M
        memcpy(&(pdev->color_info.comp_bits), &(group_color->comp_bits),
7269
2.27M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7270
2.27M
        memcpy(&(pdev->color_info.comp_shift), &(group_color->comp_shift),
7271
2.27M
            GX_DEVICE_COLOR_MAX_COMPONENTS);
7272
2.27M
        if (group_color->icc_profile != NULL) {
7273
            /* make sure to decrement the device profile.  If it was allocated
7274
               with the push then it will be freed. */
7275
2.27M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7276
2.27M
                                    -1, "pdf14_pop_color_model");
7277
2.27M
            pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
7278
2.27M
                                    group_color->icc_profile;
7279
7280
2.27M
            gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7281
2.27M
                                    1, "pdf14_pop_color_model");
7282
2.27M
        }
7283
2.27M
        pdev->num_std_colorants = group_color->num_std_colorants;
7284
2.27M
    }
7285
2.27M
}
7286
7287
static  int
7288
pdf14_end_transparency_group(gx_device* dev, gs_gstate* pgs)
7289
2.27M
{
7290
2.27M
    pdf14_device* pdev = (pdf14_device*)dev;
7291
2.27M
    int code;
7292
2.27M
    cmm_profile_t* group_profile;
7293
2.27M
    gsicc_rendering_param_t render_cond;
7294
2.27M
    cmm_dev_profile_t* dev_profile;
7295
2.27M
    int has_tags = device_encodes_tags(dev);
7296
7297
2.27M
    code = dev_proc(dev, get_profile)(dev, &dev_profile);
7298
2.27M
    if (code < 0)
7299
0
        return code;
7300
7301
2.27M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &group_profile,
7302
2.27M
        &render_cond);
7303
2.27M
    if_debug0m('v', dev->memory, "[v]pdf14_end_transparency_group\n");
7304
7305
2.27M
    code = pdf14_pop_transparency_group(pgs, pdev->ctx, pdev->blend_procs,
7306
2.27M
        pdev->color_info.num_components - has_tags, group_profile, (gx_device*)pdev);
7307
2.27M
    if (code < 0)
7308
0
        return code;
7309
#ifdef DEBUG
7310
    pdf14_debug_mask_stack_state(pdev->ctx);
7311
#endif
7312
    /* If this group is the base group, then restore the color model
7313
       of the device at this time.  Note that during the actual device pop
7314
       we will need to use the profile of the buffer not the pdf14 device
7315
       as the source color space */
7316
2.27M
    if (pdev->ctx->stack->group_popped) {
7317
394k
        pdf14_pop_color_model(dev, pdev->ctx->base_color);
7318
1.87M
    } else {
7319
1.87M
        pdf14_pop_color_model(dev, pdev->ctx->stack->group_color_info);
7320
1.87M
    }
7321
7322
2.27M
    return code;
7323
2.27M
}
7324
7325
static pdf14_group_color_t*
7326
pdf14_push_color_model(gx_device *dev, gs_transparency_color_t group_color_type,
7327
                        int64_t icc_hashcode, cmm_profile_t *iccprofile,
7328
                        bool is_mask)
7329
2.69M
{
7330
2.69M
    pdf14_device *pdevproto = NULL;
7331
2.69M
    pdf14_device *pdev = (pdf14_device *)dev;
7332
2.69M
    const pdf14_procs_t *new_14procs = NULL;
7333
2.69M
    pdf14_group_color_t *group_color;
7334
2.69M
    gx_color_polarity_t new_polarity;
7335
2.69M
    uchar new_num_comps;
7336
2.69M
    bool new_additive;
7337
2.69M
    gx_device_clist_reader *pcrdev;
7338
2.69M
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7339
2.69M
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7340
2.69M
    int k;
7341
2.69M
    bool has_tags = device_encodes_tags(dev);
7342
2.69M
    bool deep = pdev->ctx->deep;
7343
7344
2.69M
    if_debug0m('v', dev->memory, "[v]pdf14_push_color_model\n");
7345
7346
2.69M
    assert(dev->color_info.num_components == dev->num_planar_planes || dev->num_planar_planes == 0);
7347
7348
2.69M
    group_color = gs_alloc_struct(dev->memory->stable_memory,
7349
2.69M
                               pdf14_group_color_t, &st_pdf14_clr,
7350
2.69M
                               "pdf14_push_color_model");
7351
2.69M
    if (group_color == NULL)
7352
0
        return NULL;
7353
7354
2.69M
    memset(group_color, 0, sizeof(pdf14_group_color_t));
7355
7356
2.69M
    switch (group_color_type) {
7357
0
        case GRAY_SCALE:
7358
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7359
0
            new_num_comps = 1;
7360
0
            pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7361
0
            new_additive = true;
7362
0
            new_14procs = &gray_pdf14_procs;
7363
0
            break;
7364
0
        case DEVICE_RGB:
7365
0
        case CIE_XYZ:
7366
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7367
0
            new_num_comps = 3;
7368
0
            pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7369
0
            new_additive = true;
7370
0
            new_14procs = &rgb_pdf14_procs;
7371
0
            break;
7372
0
        case DEVICE_CMYK:
7373
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7374
0
            new_num_comps = 4;
7375
0
            pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7376
0
            new_additive = false;
7377
            /* This is needed due to the mismatched compressed encode decode
7378
                between the device procs and the pdf14 procs */
7379
0
            if (dev->color_info.num_components > 4){
7380
0
                new_14procs = &cmykspot_pdf14_procs;
7381
0
            } else {
7382
0
                new_14procs = &cmyk_pdf14_procs;
7383
0
            }
7384
0
            break;
7385
2.69M
        case ICC:
7386
            /* If we are coming from the clist reader, then we need to get
7387
                the ICC data now  */
7388
2.69M
            if (iccprofile == NULL && pdev->pclist_device != NULL) {
7389
                /* Get the serialized data from the clist.  Not the whole
7390
                    profile. */
7391
417k
                pcrdev = (gx_device_clist_reader *)(pdev->pclist_device);
7392
417k
                iccprofile = gsicc_read_serial_icc((gx_device *) pcrdev,
7393
417k
                                                    icc_hashcode);
7394
417k
                if (iccprofile == NULL)
7395
0
                    return NULL;
7396
                /* Keep a pointer to the clist device */
7397
417k
                iccprofile->dev = (gx_device *) pcrdev;
7398
2.27M
            } else {
7399
                /* Go ahead and rc increment right now.  This way when
7400
                    we pop, we will make sure to decrement and avoid a
7401
                    leak for the above profile that we just created.  This
7402
                    goes with the assignment to the device's profile.
7403
                    Note that we still do the increment for the group_color
7404
                    assignment below. */
7405
2.27M
                if (iccprofile == NULL)
7406
0
                    return NULL;
7407
2.27M
                gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7408
2.27M
            }
7409
2.69M
            new_num_comps = iccprofile->num_comps;
7410
2.69M
            if (new_num_comps == 4) {
7411
269k
                new_additive = false;
7412
269k
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7413
2.42M
            } else {
7414
2.42M
                new_additive = true;
7415
2.42M
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7416
2.42M
            }
7417
2.69M
            switch (new_num_comps) {
7418
605k
                case 1:
7419
605k
                    if (pdev->sep_device && !is_mask) {
7420
0
                        pdevproto = (pdf14_device *)&gs_pdf14_Grayspot_device;
7421
0
                        new_14procs = &grayspot_pdf14_procs;
7422
605k
                    } else {
7423
605k
                        pdevproto = (pdf14_device *)&gs_pdf14_Gray_device;
7424
605k
                        new_14procs = &gray_pdf14_procs;
7425
605k
                    }
7426
605k
                    break;
7427
1.82M
                case 3:
7428
1.82M
                    if (pdev->sep_device) {
7429
57.9k
                        pdevproto = (pdf14_device *)&gs_pdf14_RGBspot_device;
7430
57.9k
                        new_14procs = &rgbspot_pdf14_procs;
7431
57.9k
                    }
7432
1.76M
                    else {
7433
1.76M
                        pdevproto = (pdf14_device *)&gs_pdf14_RGB_device;
7434
1.76M
                        new_14procs = &rgb_pdf14_procs;
7435
1.76M
                    }
7436
1.82M
                    break;
7437
269k
                case 4:
7438
269k
                    if (pdev->sep_device) {
7439
22.8k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYKspot_device;
7440
22.8k
                        new_14procs = &cmykspot_pdf14_procs;
7441
246k
                    } else {
7442
246k
                        pdevproto = (pdf14_device *)&gs_pdf14_CMYK_device;
7443
246k
                        new_14procs = &cmyk_pdf14_procs;
7444
246k
                    }
7445
269k
                    break;
7446
0
                default:
7447
0
                    return NULL;
7448
0
                    break;
7449
2.69M
            }
7450
2.69M
            break;
7451
2.69M
        default:
7452
0
            return NULL;
7453
0
            break;
7454
2.69M
    }
7455
7456
    /* We might just have changed the colorspace of the device, which means
7457
     * the number of colorants have changed. */
7458
2.69M
    group_color->num_std_colorants = new_num_comps;
7459
2.69M
    pdev->num_std_colorants = new_num_comps;
7460
7461
2.69M
    if (has_tags)
7462
0
        new_num_comps++;
7463
7464
2.69M
    if (group_color_type == ICC && iccprofile != NULL) {
7465
2.69M
        group_color->icc_profile = iccprofile;
7466
2.69M
        gsicc_adjust_profile_rc(iccprofile, 1, "pdf14_push_color_model");
7467
2.69M
    }
7468
7469
    /* If we are a sep device and this is not a softmask, ensure we maintain the
7470
       spot colorants and know how to index into them */
7471
2.69M
    if (pdev->sep_device && !is_mask) {
7472
80.8k
        int num_spots = dev->color_info.num_components - has_tags -
7473
80.8k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->num_comps;
7474
7475
80.8k
        if (num_spots > 0)
7476
339
            new_num_comps += num_spots;
7477
80.8k
    }
7478
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7479
9.84M
    for (k = 0; k < new_num_comps; k++) {
7480
7.14M
        comp_bits[k] = 8<<deep;
7481
7.14M
        comp_shift[k] = (new_num_comps - k - 1) * (8<<deep);
7482
7.14M
    }
7483
7484
    /* Set device values now and store settings in group_color.  Then they
7485
       are available when we pop the previous group */
7486
2.69M
    if_debug2m('v', pdev->memory,
7487
2.69M
                "[v]pdf14_push_color_model, num_components_old = %d num_components_new = %d\n",
7488
2.69M
                pdev->color_info.num_components,new_num_comps);
7489
2.69M
    {
7490
2.69M
        gx_device local_device;
7491
7492
2.69M
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7493
2.69M
        local_device.initialize_device_procs((gx_device *)&local_device);
7494
2.69M
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7495
2.69M
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7496
2.69M
    }
7497
2.69M
    group_color->blend_procs = pdev->blend_procs = pdevproto->blend_procs;
7498
2.69M
    group_color->polarity = pdev->color_info.polarity = new_polarity;
7499
2.69M
    group_color->isadditive = pdev->ctx->additive = new_additive;
7500
2.69M
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7501
2.69M
    group_color->unpack_procs = pdev->pdf14_procs = new_14procs;
7502
2.69M
    if (pdev->num_planar_planes > 0)
7503
107k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7504
2.69M
    group_color->num_components = new_num_comps - has_tags;
7505
2.69M
    pdev->color_info.num_components = new_num_comps;
7506
2.69M
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7507
2.69M
    assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7508
2.69M
    pdev->color_info.depth = new_num_comps * (8<<deep);
7509
2.69M
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7510
2.69M
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7511
2.69M
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7512
2.69M
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7513
2.69M
    group_color->max_color = pdev->color_info.max_color = deep ? 65535 : 255;
7514
2.69M
    group_color->max_gray = pdev->color_info.max_gray = deep ? 65535 : 255;
7515
2.69M
    group_color->depth = pdev->color_info.depth;
7516
2.69M
    group_color->decode = dev_proc(pdev, decode_color);
7517
2.69M
    group_color->encode = dev_proc(pdev, encode_color);
7518
2.69M
    group_color->group_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
7519
2.69M
    group_color->group_color_comp_index = dev_proc(pdev, get_color_comp_index);
7520
2.69M
    memcpy(&(group_color->comp_bits), &(pdev->color_info.comp_bits),
7521
2.69M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7522
2.69M
    memcpy(&(group_color->comp_shift), &(pdev->color_info.comp_shift),
7523
2.69M
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7524
2.69M
    group_color->get_cmap_procs = pdf14_get_cmap_procs;
7525
7526
    /* If the CS was ICC based, we need to update the device ICC profile
7527
        in the ICC manager, since that is the profile that is used for the
7528
        PDF14 device */
7529
2.69M
    if (group_color_type == ICC && iccprofile != NULL) {
7530
        /* iccprofile was incremented above if we had not just created it.
7531
           When we do the pop we will decrement and if we just created it, it
7532
           will be destroyed */
7533
2.69M
        gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE], -1, "pdf14_push_color_model");
7534
2.69M
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = iccprofile;
7535
2.69M
    }
7536
2.69M
    return group_color;
7537
2.69M
}
7538
7539
static int
7540
pdf14_clist_push_color_model(gx_device *dev, gx_device* cdev, gs_gstate *pgs,
7541
                             const gs_pdf14trans_t *pdf14pct, gs_memory_t* mem,
7542
                             bool is_mask)
7543
55.9k
{
7544
55.9k
    pdf14_device* pdev = (pdf14_device*)dev;
7545
55.9k
    pdf14_group_color_t* new_group_color;
7546
55.9k
    gsicc_rendering_param_t render_cond;
7547
55.9k
    cmm_dev_profile_t* dev_profile;
7548
55.9k
    pdf14_device* pdevproto;
7549
55.9k
    gx_device_clist_writer* cldev = (gx_device_clist_writer*)pdev->pclist_device;
7550
55.9k
    const pdf14_procs_t* new_14procs;
7551
55.9k
    bool update_color_info;
7552
55.9k
    gx_color_polarity_t new_polarity;
7553
55.9k
    int new_num_comps;
7554
55.9k
    bool new_additive = false;
7555
55.9k
    byte new_depth;
7556
55.9k
    byte comp_bits[GX_DEVICE_COLOR_MAX_COMPONENTS];
7557
55.9k
    byte comp_shift[GX_DEVICE_COLOR_MAX_COMPONENTS];
7558
55.9k
    int k;
7559
55.9k
    bool has_tags = device_encodes_tags(dev);
7560
55.9k
    bool deep = device_is_deep(dev);
7561
55.9k
    gs_transparency_color_t group_color_type = pdf14pct->params.group_color_type;
7562
55.9k
    cmm_profile_t *new_profile = pdf14pct->params.iccprofile;
7563
55.9k
    cmm_profile_t *old_profile = NULL;
7564
7565
55.9k
    assert(dev->num_planar_planes == 0 || dev->num_planar_planes == dev->color_info.num_components);
7566
7567
55.9k
    dev_proc(dev, get_profile)(dev, &dev_profile);
7568
55.9k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &old_profile,
7569
55.9k
        &render_cond);
7570
55.9k
    if_debug0m('v', dev->memory, "[v]pdf14_clist_push_color_model\n");
7571
7572
    /* Allocate a new one */
7573
55.9k
    new_group_color = gs_alloc_struct(dev->memory->stable_memory, pdf14_group_color_t,
7574
55.9k
        &st_pdf14_clr, "pdf14_clist_push_color_model");
7575
7576
55.9k
    if (new_group_color == NULL)
7577
0
        return_error(gs_error_VMerror);
7578
7579
    /* Link to old one */
7580
55.9k
    new_group_color->previous = pdev->color_model_stack;
7581
7582
    /* Reassign new one to dev */
7583
55.9k
    pdev->color_model_stack = new_group_color;
7584
7585
    /* Initialize with values */
7586
55.9k
    new_group_color->get_cmap_procs = pgs->get_cmap_procs;
7587
55.9k
    new_group_color->group_color_mapping_procs =
7588
55.9k
        dev_proc(pdev, get_color_mapping_procs);
7589
55.9k
    new_group_color->group_color_comp_index =
7590
55.9k
        dev_proc(pdev, get_color_comp_index);
7591
55.9k
    new_group_color->blend_procs = pdev->blend_procs;
7592
55.9k
    new_group_color->polarity = pdev->color_info.polarity;
7593
55.9k
    new_group_color->num_components = pdev->color_info.num_components - has_tags;
7594
55.9k
    new_group_color->unpack_procs = pdev->pdf14_procs;
7595
55.9k
    new_group_color->depth = pdev->color_info.depth;
7596
55.9k
    new_group_color->max_color = pdev->color_info.max_color;
7597
55.9k
    new_group_color->max_gray = pdev->color_info.max_gray;
7598
55.9k
    new_group_color->decode = dev_proc(pdev, decode_color);
7599
55.9k
    new_group_color->encode = dev_proc(pdev, encode_color);
7600
55.9k
    memcpy(&(new_group_color->comp_bits), &(pdev->color_info.comp_bits),
7601
55.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7602
55.9k
    memcpy(&(new_group_color->comp_shift), &(pdev->color_info.comp_shift),
7603
55.9k
        GX_DEVICE_COLOR_MAX_COMPONENTS);
7604
7605
55.9k
    if (new_profile == NULL)
7606
34.3k
        new_group_color->icc_profile = NULL;
7607
7608
    /* isadditive is only used in ctx */
7609
55.9k
    if (pdev->ctx) {
7610
0
        new_group_color->isadditive = pdev->ctx->additive;
7611
0
    }
7612
7613
55.9k
    memset(comp_bits, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7614
55.9k
    memset(comp_shift, 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7615
7616
55.9k
    if (group_color_type == ICC && new_profile == NULL)
7617
0
        return gs_throw(gs_error_undefinedresult, "Missing ICC data");
7618
55.9k
    if_debug0m('v', cldev->memory, "[v]pdf14_clist_push_color_model\n");
7619
    /* Check if we need to alter the device procs at this stage.  Many of the procs
7620
       are based upon the color space of the device.  We want to remain in the
7621
       color space defined by the color space of the soft mask or transparency
7622
       group as opposed to the device color space. Later, when we pop the softmask
7623
       we will collapse it to a single band and then compose with it to the device
7624
       color space (or the parent layer space).  In the case where we pop an
7625
       isolated transparency group, we will do the blending in the proper color
7626
       space and then transform the data when we pop the group.  Remember that only
7627
       isolated groups can have color spaces that are different than their parent. */
7628
55.9k
    update_color_info = false;
7629
55.9k
    switch (group_color_type) {
7630
0
    case GRAY_SCALE:
7631
0
        if (pdev->color_info.num_components != 1) {
7632
0
            update_color_info = true;
7633
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7634
0
            new_num_comps = 1;
7635
0
            pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7636
0
            new_additive = true;
7637
0
            new_14procs = &gray_pdf14_procs;
7638
0
            new_depth = 8 << deep;
7639
0
        }
7640
0
        break;
7641
0
    case DEVICE_RGB:
7642
0
    case CIE_XYZ:
7643
0
        if (pdev->color_info.num_components != 3) {
7644
0
            update_color_info = true;
7645
0
            new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7646
0
            new_num_comps = 3;
7647
0
            pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7648
0
            new_additive = true;
7649
0
            new_14procs = &rgb_pdf14_procs;
7650
0
            new_depth = 24 << deep;
7651
0
        }
7652
0
        break;
7653
0
    case DEVICE_CMYK:
7654
0
        if (pdev->color_info.num_components != 4) {
7655
0
            update_color_info = true;
7656
0
            new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7657
0
            new_num_comps = 4;
7658
0
            pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7659
0
            new_additive = false;
7660
            /* This is needed due to the mismatched compressed encode decode
7661
               between the device procs and the pdf14 procs */
7662
0
            if (dev->color_info.num_components > 4) {
7663
0
                new_14procs = &cmykspot_pdf14_procs;
7664
0
            }
7665
0
            else {
7666
0
                new_14procs = &cmyk_pdf14_procs;
7667
0
            }
7668
0
            new_depth = 32 << deep;
7669
0
        }
7670
0
        break;
7671
21.6k
    case ICC:
7672
        /* Check if the profile is different. */
7673
21.6k
        if (!gsicc_profiles_equal(old_profile, new_profile)) {
7674
19.6k
            update_color_info = true;
7675
19.6k
            new_num_comps = new_profile->num_comps;
7676
19.6k
            new_depth = new_profile->num_comps * (8 << deep);
7677
19.6k
            switch (new_num_comps) {
7678
17.6k
            case 1:
7679
17.6k
                if (pdev->sep_device && !is_mask) {
7680
0
                    pdevproto = (pdf14_device*)&gs_pdf14_Grayspot_device;
7681
0
                    new_14procs = &grayspot_pdf14_procs;
7682
0
                }
7683
17.6k
                else {
7684
17.6k
                    pdevproto = (pdf14_device*)&gs_pdf14_Gray_device;
7685
17.6k
                    new_14procs = &gray_pdf14_procs;
7686
17.6k
                }
7687
17.6k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7688
17.6k
                new_additive = true;
7689
17.6k
                break;
7690
1.71k
            case 3:
7691
1.71k
                if (pdev->sep_device) {
7692
403
                    pdevproto = (pdf14_device*)&gs_pdf14_RGBspot_device;
7693
403
                    new_14procs = &rgbspot_pdf14_procs;
7694
403
                }
7695
1.30k
                else {
7696
1.30k
                    pdevproto = (pdf14_device*)&gs_pdf14_RGB_device;
7697
1.30k
                    new_14procs = &rgb_pdf14_procs;
7698
1.30k
                }
7699
1.71k
                new_polarity = GX_CINFO_POLARITY_ADDITIVE;
7700
1.71k
                new_additive = true;
7701
1.71k
                break;
7702
268
            case 4:
7703
268
                if (pdev->sep_device) {
7704
7
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYKspot_device;
7705
7
                    new_14procs = &cmykspot_pdf14_procs;
7706
7
                }
7707
261
                else {
7708
261
                    pdevproto = (pdf14_device*)&gs_pdf14_CMYK_device;
7709
261
                    new_14procs = &cmyk_pdf14_procs;
7710
261
                }
7711
268
                new_polarity = GX_CINFO_POLARITY_SUBTRACTIVE;
7712
268
                new_additive = false;
7713
268
                break;
7714
0
            default:
7715
0
                return gs_throw(gs_error_undefinedresult,
7716
19.6k
                    "ICC Number of colorants illegal");
7717
19.6k
            }
7718
19.6k
        }
7719
21.6k
        break;
7720
34.3k
    case UNKNOWN:
7721
34.3k
        return 0;
7722
0
        break;
7723
0
    default:
7724
0
        return_error(gs_error_rangecheck);
7725
0
        break;
7726
55.9k
    }
7727
7728
21.6k
    if (!update_color_info) {
7729
        /* Profile not updated */
7730
1.97k
        new_group_color->icc_profile = NULL;
7731
1.97k
        if_debug0m('v', pdev->memory, "[v]procs not updated\n");
7732
1.97k
        return 0;
7733
1.97k
    }
7734
7735
19.6k
    if (has_tags) {
7736
0
        new_num_comps++;
7737
        /* In planar mode, planes need to all be the same depth. Otherwise use 8 bits for tags. */
7738
0
        if (pdev->num_planar_planes > 0)
7739
0
            new_depth += deep ? 16 : 8;
7740
0
        else
7741
0
            new_depth += 8;
7742
0
    }
7743
19.6k
    if (pdev->sep_device && !is_mask) {
7744
410
        int num_spots;
7745
7746
410
        if (old_profile == NULL)
7747
0
            return_error(gs_error_undefined);
7748
7749
410
        num_spots = pdev->color_info.num_components - has_tags - old_profile->num_comps;
7750
7751
410
        if (num_spots > 0) {
7752
33
            new_num_comps += num_spots;
7753
33
            new_depth = (8 << deep) * new_num_comps;
7754
33
        }
7755
410
    }
7756
    /* Calculate the bits and shifts *after* we have allowed for tags. */
7757
43.6k
    for (k = 0; k < new_num_comps; k++) {
7758
23.9k
        comp_bits[k] = 8 << deep;
7759
23.9k
        comp_shift[k] = (new_num_comps - 1 - k) * (8 << deep);
7760
23.9k
    }
7761
19.6k
    if_debug2m('v', pdev->memory,
7762
19.6k
        "[v]pdf14_clist_push_color_model, num_components_old = %d num_components_new = %d\n",
7763
19.6k
        pdev->color_info.num_components, new_num_comps);
7764
    /* Set new information in the device */
7765
19.6k
    {
7766
19.6k
        gx_device local_device;
7767
7768
19.6k
        local_device.initialize_device_procs = pdevproto->initialize_device_procs;
7769
19.6k
        local_device.initialize_device_procs((gx_device *)&local_device);
7770
19.6k
        set_dev_proc(pdev, get_color_mapping_procs, local_device.procs.get_color_mapping_procs);
7771
19.6k
        set_dev_proc(pdev, get_color_comp_index, local_device.procs.get_color_comp_index);
7772
19.6k
    }
7773
19.6k
    pdev->blend_procs = pdevproto->blend_procs;
7774
19.6k
    pdev->color_info.polarity = new_polarity;
7775
19.6k
    pdev->color_info.max_color = deep ? 65535 : 255;
7776
19.6k
    pdev->color_info.max_gray = deep ? 65535 : 255;
7777
19.6k
    pdev->pdf14_procs = new_14procs;
7778
19.6k
    if (pdev->num_planar_planes > 0)
7779
2.24k
        pdev->num_planar_planes += new_num_comps - pdev->color_info.num_components;
7780
19.6k
    pdev->color_info.num_components = new_num_comps;
7781
19.6k
    assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7782
19.6k
    pdev->color_info.depth = new_depth;
7783
19.6k
    memset(&(pdev->color_info.comp_bits), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7784
19.6k
    memset(&(pdev->color_info.comp_shift), 0, GX_DEVICE_COLOR_MAX_COMPONENTS);
7785
19.6k
    memcpy(&(pdev->color_info.comp_bits), comp_bits, new_num_comps);
7786
19.6k
    memcpy(&(pdev->color_info.comp_shift), comp_shift, new_num_comps);
7787
19.6k
    pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7788
7789
    /* If we have a compressed color codec, and we are doing a soft mask
7790
       push operation then go ahead and update the color encode and
7791
       decode for the pdf14 device to not used compressed color
7792
       encoding while in the soft mask.  We will just check for gray
7793
       and compressed.  Note that we probably don't have_tags if we
7794
       are dealing with compressed color.  But is is possible so
7795
       we add it in to catch for future use. */
7796
19.6k
    cldev->clist_color_info.depth = pdev->color_info.depth;
7797
19.6k
    cldev->clist_color_info.polarity = pdev->color_info.polarity;
7798
19.6k
    cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7799
19.6k
    cldev->clist_color_info.num_components = pdev->color_info.num_components;
7800
19.6k
    cldev->clist_color_info.max_color = pdev->color_info.max_color;
7801
19.6k
    cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7802
    /* For the ICC profiles, we want to update the ICC profile for the
7803
       device.  We store the original in group_color.
7804
       That will be stored in the clist and restored during the reading phase. */
7805
19.6k
    if (group_color_type == ICC) {
7806
19.6k
        gsicc_adjust_profile_rc(new_profile, 1, "pdf14_clist_push_color_model");
7807
19.6k
        new_group_color->icc_profile =
7808
19.6k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
7809
19.6k
        dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = new_profile;
7810
19.6k
    }
7811
19.6k
    if (pdev->ctx) {
7812
0
        pdev->ctx->additive = new_additive;
7813
0
    }
7814
19.6k
    return 1;  /* Lets us detect that we did do an update */
7815
19.6k
}
7816
7817
static int
7818
pdf14_clist_pop_color_model(gx_device *dev, gs_gstate *pgs)
7819
55.9k
{
7820
7821
55.9k
    pdf14_device *pdev = (pdf14_device *)dev;
7822
55.9k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7823
55.9k
    gx_device_clist_writer * cldev = (gx_device_clist_writer *)pdev->pclist_device;
7824
7825
55.9k
    if (group_color == NULL)
7826
0
        return_error(gs_error_Fatal);  /* Unmatched group pop */
7827
7828
55.9k
    if_debug0m('v', pdev->memory, "[v]pdf14_clist_pop_color_model\n");
7829
    /* The color procs are always pushed.  Simply restore them. */
7830
55.9k
    if (group_color->group_color_mapping_procs == NULL &&
7831
0
        group_color->group_color_comp_index == NULL) {
7832
0
        if_debug0m('v', dev->memory, "[v]pdf14_clist_pop_color_model ERROR \n");
7833
55.9k
    } else {
7834
55.9k
        bool has_tags = device_encodes_tags(dev);
7835
55.9k
        if_debug2m('v', pdev->memory,
7836
55.9k
                   "[v]pdf14_clist_pop_color_model, num_components_old = %d num_components_new = %d\n",
7837
55.9k
                   pdev->color_info.num_components,group_color->num_components);
7838
55.9k
        pgs->get_cmap_procs = group_color->get_cmap_procs;
7839
55.9k
        gx_set_cmap_procs(pgs, dev);
7840
55.9k
        set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
7841
55.9k
        set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
7842
55.9k
        pdev->color_info.polarity = group_color->polarity;
7843
55.9k
        pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7844
55.9k
        pdev->color_info.depth = group_color->depth;
7845
55.9k
        if (pdev->num_planar_planes > 0)
7846
5.11k
            pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
7847
55.9k
        pdev->color_info.num_components = group_color->num_components + has_tags;
7848
55.9k
        assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
7849
55.9k
        assert(pdev->color_info.num_components - has_tags == group_color->num_components);
7850
55.9k
        pdev->blend_procs = group_color->blend_procs;
7851
55.9k
        pdev->pdf14_procs = group_color->unpack_procs;
7852
55.9k
        pdev->color_info.max_color = group_color->max_color;
7853
55.9k
        pdev->color_info.max_gray = group_color->max_gray;
7854
55.9k
        set_dev_proc(pdev, encode_color, group_color->encode);
7855
55.9k
        set_dev_proc(pdev, decode_color, group_color->decode);
7856
55.9k
        memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
7857
55.9k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7858
55.9k
        memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
7859
55.9k
                            GX_DEVICE_COLOR_MAX_COMPONENTS);
7860
7861
        /* clist writer fill rect has no access to gs_gstate */
7862
        /* and it forwards the target device.  this information */
7863
        /* is passed along to use in this case */
7864
55.9k
        cldev->clist_color_info.depth = pdev->color_info.depth;
7865
55.9k
        cldev->clist_color_info.polarity = pdev->color_info.polarity;
7866
55.9k
        cldev->clist_color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
7867
55.9k
        cldev->clist_color_info.num_components = pdev->color_info.num_components;
7868
55.9k
        cldev->clist_color_info.max_color = pdev->color_info.max_color;
7869
55.9k
        cldev->clist_color_info.max_gray = pdev->color_info.max_gray;
7870
55.9k
        memcpy(&(cldev->clist_color_info.comp_bits),&(group_color->comp_bits),
7871
55.9k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7872
55.9k
        memcpy(&(cldev->clist_color_info.comp_shift),&(group_color->comp_shift),
7873
55.9k
               GX_DEVICE_COLOR_MAX_COMPONENTS);
7874
55.9k
        if (pdev->ctx){
7875
0
            pdev->ctx->additive = group_color->isadditive;
7876
0
        }
7877
       /* The device profile must be restored. */
7878
55.9k
        if (group_color->icc_profile != NULL) {
7879
19.6k
            gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
7880
19.6k
                                    -1, "pdf14_clist_pop_color_model");
7881
19.6k
            dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
7882
19.6k
        }
7883
55.9k
        if_debug0m('v', dev->memory, "[v]procs updated\n");
7884
55.9k
    }
7885
55.9k
   pdf14_pop_group_color(dev, pgs);
7886
55.9k
    return 0;
7887
55.9k
}
7888
7889
/* When a transparency group is popped, the parent colorprocs must be restored.
7890
   Since the color mapping procs are all based upon the device, we must have a
7891
   nested list based upon the transparency group color space.  This nesting
7892
   must be outside the nested ctx structures to allow the nesting for the
7893
   clist writer */
7894
static void
7895
pdf14_pop_group_color(gx_device *dev, const gs_gstate *pgs)
7896
55.9k
{
7897
55.9k
    pdf14_device *pdev = (pdf14_device *)dev;
7898
55.9k
    pdf14_group_color_t *group_color = pdev->color_model_stack;
7899
7900
55.9k
    if_debug0m('v', dev->memory, "[v]pdf14_pop_group_color\n");
7901
7902
    /* Update the link */
7903
55.9k
    pdev->color_model_stack = group_color->previous;
7904
7905
    /* Free the old one */
7906
55.9k
    gs_free_object(dev->memory->stable_memory, group_color, "pdf14_clr_free");
7907
55.9k
}
7908
7909
static  int
7910
pdf14_begin_transparency_mask(gx_device *dev,
7911
                              const gx_transparency_mask_params_t *ptmp,
7912
                              const gs_rect *pbbox,
7913
                              gs_gstate *pgs, gs_memory_t *mem)
7914
3.94M
{
7915
3.94M
    pdf14_device *pdev = (pdf14_device *)dev;
7916
3.94M
    uint16_t bg_alpha = 0;   /* By default the background alpha (area outside mask) is zero */
7917
3.94M
    byte *transfer_fn;
7918
3.94M
    gs_int_rect rect;
7919
3.94M
    int code;
7920
3.94M
    int group_color_numcomps;
7921
3.94M
    gs_transparency_color_t group_color_type;
7922
3.94M
    bool deep = device_is_deep(dev);
7923
3.94M
    pdf14_group_color_t* group_color_info;
7924
7925
3.94M
    code = pdf14_initialize_ctx(dev, pgs);
7926
3.94M
    if (code < 0)
7927
0
        return code;
7928
7929
3.94M
    if (ptmp->subtype == TRANSPARENCY_MASK_None) {
7930
3.52M
        pdf14_ctx *ctx = pdev->ctx;
7931
7932
        /* free up any maskbuf on the current tos */
7933
3.52M
        if (ctx->mask_stack != NULL && ctx->mask_stack->mask_buf != NULL ) {
7934
297k
            pdf14_buf_free(ctx->mask_stack->mask_buf);
7935
297k
            ctx->mask_stack->mask_buf = NULL;
7936
297k
        }
7937
3.52M
        return 0;
7938
3.52M
    }
7939
421k
    transfer_fn = (byte *)gs_alloc_bytes(pdev->ctx->memory, (256+deep)<<deep,
7940
421k
                                         "pdf14_begin_transparency_mask");
7941
421k
    if (transfer_fn == NULL)
7942
0
        return_error(gs_error_VMerror);
7943
421k
    code = compute_group_device_int_rect(pdev, &rect, pbbox, pgs);
7944
421k
    if (code < 0)
7945
0
        return code;
7946
    /* If we have background components the background alpha may be nonzero */
7947
421k
    if (ptmp->Background_components)
7948
82.6k
        bg_alpha = (int)(65535 * ptmp->GrayBackground + 0.5);
7949
421k
    if_debug1m('v', dev->memory,
7950
421k
               "pdf14_begin_transparency_mask, bg_alpha = %d\n", bg_alpha);
7951
421k
    memcpy(transfer_fn, ptmp->transfer_fn, (256+deep)<<deep);
7952
   /* If the group color is unknown, then we must use the previous group color
7953
       space or the device process color space */
7954
421k
    if (ptmp->group_color_type == UNKNOWN){
7955
0
        if (pdev->ctx->stack){
7956
            /* Use previous group color space */
7957
0
            group_color_numcomps = pdev->ctx->stack->n_chan-1;  /* Remove alpha */
7958
0
        } else {
7959
            /* Use process color space */
7960
0
            group_color_numcomps = pdev->color_info.num_components;
7961
0
        }
7962
0
        switch (group_color_numcomps) {
7963
0
            case 1:
7964
0
                group_color_type = GRAY_SCALE;
7965
0
                break;
7966
0
            case 3:
7967
0
                group_color_type = DEVICE_RGB;
7968
0
                break;
7969
0
            case 4:
7970
0
                group_color_type = DEVICE_CMYK;
7971
0
            break;
7972
0
            default:
7973
                /* We can end up here if we are in a deviceN color space and
7974
                   we have a sep output device */
7975
0
                group_color_type = DEVICEN;
7976
0
            break;
7977
0
         }
7978
421k
    } else {
7979
421k
        group_color_type = ptmp->group_color_type;
7980
421k
        group_color_numcomps = ptmp->group_color_numcomps;
7981
421k
    }
7982
7983
421k
    group_color_info = pdf14_push_color_model(dev, group_color_type, ptmp->icc_hashcode,
7984
421k
                                               ptmp->iccprofile, true);
7985
421k
    if (group_color_info == NULL)
7986
0
        return gs_error_VMerror;
7987
7988
    /* Note that the soft mask always follows the group color requirements even
7989
       when we have a separable device */
7990
421k
    code = pdf14_push_transparency_mask(pdev->ctx, &rect, bg_alpha,
7991
421k
                                        transfer_fn, ptmp->function_is_identity,
7992
421k
                                        ptmp->idle, ptmp->replacing,
7993
421k
                                        ptmp->mask_id, ptmp->subtype,
7994
421k
                                        group_color_numcomps,
7995
421k
                                        ptmp->Background_components,
7996
421k
                                        ptmp->Background,
7997
421k
                                        ptmp->Matte_components,
7998
421k
                                        ptmp->Matte,
7999
421k
                                        ptmp->GrayBackground,
8000
421k
                                        group_color_info);
8001
421k
    if (code < 0)
8002
0
        return code;
8003
8004
421k
    return 0;
8005
421k
}
8006
8007
static  int
8008
pdf14_end_transparency_mask(gx_device *dev, gs_gstate *pgs)
8009
421k
{
8010
421k
    pdf14_device *pdev = (pdf14_device *)dev;
8011
421k
    pdf14_group_color_t *group_color;
8012
421k
    int ok;
8013
421k
    bool has_tags = device_encodes_tags(dev);
8014
8015
421k
    if_debug0m('v', dev->memory, "pdf14_end_transparency_mask\n");
8016
421k
    ok = pdf14_pop_transparency_mask(pdev->ctx, pgs, dev);
8017
#ifdef DEBUG
8018
    pdf14_debug_mask_stack_state(pdev->ctx);
8019
#endif
8020
8021
    /* May need to reset some color stuff related
8022
     * to a mismatch between the Smask color space
8023
     * and the Smask blending space */
8024
421k
    if (pdev->ctx->stack != NULL ) {
8025
421k
        group_color = pdev->ctx->stack->group_color_info;
8026
421k
        if (!(group_color->group_color_mapping_procs == NULL &&
8027
421k
            group_color->group_color_comp_index == NULL)) {
8028
421k
            pgs->get_cmap_procs = group_color->get_cmap_procs;
8029
421k
            gx_set_cmap_procs(pgs, dev);
8030
421k
            set_dev_proc(pdev, get_color_mapping_procs, group_color->group_color_mapping_procs);
8031
421k
            set_dev_proc(pdev, get_color_comp_index, group_color->group_color_comp_index);
8032
421k
            pdev->color_info.polarity = group_color->polarity;
8033
421k
            pdev->color_info.opmsupported = GX_CINFO_OPMSUPPORTED_UNKNOWN;
8034
421k
            if (pdev->num_planar_planes > 0)
8035
26.6k
                pdev->num_planar_planes += group_color->num_components - (pdev->color_info.num_components - has_tags);
8036
421k
            pdev->color_info.num_components = group_color->num_components + has_tags;
8037
421k
            assert(pdev->num_planar_planes == 0 || pdev->num_planar_planes == pdev->color_info.num_components);
8038
421k
            assert(pdev->color_info.num_components - has_tags == group_color->num_components);
8039
421k
            pdev->num_std_colorants = group_color->num_std_colorants;
8040
421k
            pdev->color_info.depth = group_color->depth;
8041
421k
            pdev->blend_procs = group_color->blend_procs;
8042
421k
            pdev->ctx->additive = group_color->isadditive;
8043
421k
            pdev->pdf14_procs = group_color->unpack_procs;
8044
421k
            pdev->color_info.max_color = group_color->max_color;
8045
421k
            pdev->color_info.max_gray = group_color->max_gray;
8046
421k
            set_dev_proc(pdev, encode_color, group_color->encode);
8047
421k
            set_dev_proc(pdev, decode_color, group_color->decode);
8048
421k
            memcpy(&(pdev->color_info.comp_bits),&(group_color->comp_bits),
8049
421k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8050
421k
            memcpy(&(pdev->color_info.comp_shift),&(group_color->comp_shift),
8051
421k
                                GX_DEVICE_COLOR_MAX_COMPONENTS);
8052
            /* Take care of the ICC profile */
8053
421k
            if (group_color->icc_profile != NULL) {
8054
421k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8055
421k
                                        -1, "pdf14_end_transparency_mask");
8056
421k
                dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = group_color->icc_profile;
8057
421k
                gsicc_adjust_profile_rc(dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
8058
421k
                                         1, "pdf14_end_transparency_mask");
8059
421k
            }
8060
421k
        }
8061
421k
    }
8062
421k
    return ok;
8063
421k
}
8064
8065
static  int
8066
do_mark_fill_rectangle_ko_simple(gx_device *dev, int x, int y, int w, int h,
8067
                                 gx_color_index color,
8068
                                 const gx_device_color *pdc, bool devn)
8069
2.41M
{
8070
2.41M
    pdf14_device *pdev = (pdf14_device *)dev;
8071
2.41M
    pdf14_buf *buf = pdev->ctx->stack;
8072
2.41M
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8073
2.41M
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8074
142k
        blend_mode == BLEND_MODE_Compatible ||
8075
142k
        blend_mode == BLEND_MODE_CompatibleOverprint;
8076
2.41M
    int i, j, k;
8077
2.41M
    byte *bline, *bg_ptr, *line, *dst_ptr;
8078
2.41M
    byte src[PDF14_MAX_PLANES];
8079
2.41M
    byte dst[PDF14_MAX_PLANES] = { 0 };
8080
2.41M
    byte dst2[PDF14_MAX_PLANES] = { 0 };
8081
2.41M
    intptr_t rowstride = buf->rowstride;
8082
2.41M
    intptr_t planestride = buf->planestride;
8083
2.41M
    int num_chan = buf->n_chan;
8084
2.41M
    int num_comp = num_chan - 1;
8085
2.41M
    intptr_t shape_off = num_chan * planestride;
8086
2.41M
    bool has_shape = buf->has_shape;
8087
2.41M
    bool has_alpha_g = buf->has_alpha_g;
8088
2.41M
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8089
2.41M
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8090
2.41M
                                   (has_shape ? planestride : 0);
8091
2.41M
    bool has_tags = buf->has_tags;
8092
2.41M
    bool additive = pdev->ctx->additive;
8093
2.41M
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8094
2.41M
    gx_color_index mask = ((gx_color_index)1 << 8) - 1;
8095
2.41M
    int shift = 8;
8096
2.41M
    byte shape = 0; /* Quiet compiler. */
8097
2.41M
    byte src_alpha;
8098
2.41M
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8099
2.41M
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8100
2.06M
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8101
2.41M
    gx_color_index comps;
8102
2.41M
    bool has_backdrop = buf->backdrop != NULL;
8103
8104
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8105
       subtractive) and we are doing overprint with drawn_comps == 0
8106
       then this is a no-operation */
8107
2.41M
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8108
0
        return 0;
8109
8110
2.41M
    if (buf->data == NULL)
8111
2
        return 0;
8112
#if 0
8113
    if (sizeof(color) <= sizeof(ulong))
8114
        if_debug6m('v', dev->memory,
8115
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %lx, nc %d,\n",
8116
                   x, y, w, h, (ulong)color, num_chan);
8117
    else
8118
        if_debug7m('v', dev->memory,
8119
                   "[v]pdf14_mark_fill_rectangle_ko_simple, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8120
                   x, y, w, h,
8121
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8122
                   num_chan);
8123
#endif
8124
    /*
8125
     * Unpack the gx_color_index values.  Complement the components for subtractive
8126
     * color spaces.
8127
     */
8128
2.41M
    if (devn) {
8129
142k
        if (has_tags) {
8130
0
            curr_tag = pdc->tag;
8131
0
        }
8132
142k
        if (additive) {
8133
70.5k
            for (j = 0; j < num_comp; j++) {
8134
52.8k
                src[j] = ((pdc->colors.devn.values[j]) >> shift & mask);
8135
52.8k
            }
8136
125k
        } else {
8137
626k
            for (j = 0; j < num_comp; j++) {
8138
501k
                src[j] = 255 - ((pdc->colors.devn.values[j]) >> shift & mask);
8139
501k
            }
8140
125k
        }
8141
2.27M
    } else {
8142
2.27M
        if (has_tags) {
8143
0
            curr_tag = (color >> (num_comp * 8)) & 0xff;
8144
0
        }
8145
2.27M
        pdev->pdf14_procs->unpack_color(num_comp, color, pdev, src);
8146
2.27M
    }
8147
8148
2.41M
    if (!has_tags)
8149
2.41M
        tag_off = 0;
8150
8151
2.41M
    src_alpha = src[num_comp] = (byte)floor (255 * pdev->alpha + 0.5);
8152
2.41M
    if (has_shape) {
8153
1.42k
        shape = (byte)floor (255 * pdev->shape + 0.5);
8154
2.41M
    } else {
8155
2.41M
        shape_off = 0;
8156
2.41M
    }
8157
8158
2.41M
    if (!has_alpha_g)
8159
13.2k
        alpha_g_off = 0;
8160
2.41M
    src_alpha = 255 - src_alpha;
8161
2.41M
    shape = 255 - shape;
8162
8163
    /* Fit the mark into the bounds of the buffer */
8164
2.41M
    if (x < buf->rect.p.x) {
8165
176
        w += x - buf->rect.p.x;
8166
176
        x = buf->rect.p.x;
8167
176
    }
8168
2.41M
    if (y < buf->rect.p.y) {
8169
10
      h += y - buf->rect.p.y;
8170
10
      y = buf->rect.p.y;
8171
10
    }
8172
2.41M
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8173
2.41M
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8174
    /* Update the dirty rectangle with the mark. */
8175
2.41M
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8176
2.41M
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8177
2.41M
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8178
2.41M
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8179
8180
    /* composite with backdrop only. */
8181
2.41M
    if (has_backdrop)
8182
2.40M
        bline = buf->backdrop + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8183
13.2k
    else
8184
13.2k
        bline = NULL;
8185
8186
2.41M
    line = buf->data + (x - buf->rect.p.x) + (y - buf->rect.p.y) * rowstride;
8187
8188
5.06M
    for (j = 0; j < h; ++j) {
8189
2.65M
        bg_ptr = bline;
8190
2.65M
        dst_ptr = line;
8191
113M
        for (i = 0; i < w; ++i) {
8192
            /* Complement the components for subtractive color spaces */
8193
110M
            if (has_backdrop) {
8194
105M
                if (additive) {
8195
388M
                    for (k = 0; k < num_comp; ++k)
8196
283M
                        dst[k] = bg_ptr[k * planestride];
8197
104M
                } else {
8198
3.71M
                    for (k = 0; k < num_comp; ++k)
8199
2.97M
                        dst2[k] = dst[k] = 255 - bg_ptr[k * planestride];
8200
742k
                }
8201
105M
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8202
105M
            }
8203
110M
            if (buf->isolated || !has_backdrop) {
8204
5.08M
                art_pdf_knockoutisolated_group_8(dst, src, num_comp);
8205
105M
            } else {
8206
105M
                art_pdf_composite_knockout_8(dst, src, num_comp,
8207
105M
                                            blend_mode, pdev->blend_procs, pdev);
8208
105M
            }
8209
            /* Complement the results for subtractive color spaces */
8210
110M
            if (additive) {
8211
109M
                if (!overprint) {
8212
518M
                    for (k = 0; k < num_chan; ++k)
8213
408M
                        dst_ptr[k * planestride] = dst[k];
8214
109M
                } else {
8215
                    /* Hybrid additive with subtractive spots */
8216
                    /* We may have to do the compatible overprint blending */
8217
7.14k
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8218
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8219
0
                            blend_mode, pdev->blend_procs, pdev);
8220
0
                    }
8221
28.5k
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8222
21.4k
                        if ((comps & 0x1) != 0) {
8223
21.4k
                            dst_ptr[k * planestride] = dst[k];
8224
21.4k
                        } else {
8225
                            /* Compatible overprint blend result. */
8226
0
                            dst_ptr[k * planestride] = dst2[k];
8227
0
                        }
8228
21.4k
                    }
8229
7.14k
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8230
7.14k
                }
8231
109M
            } else {
8232
742k
                if (overprint) {
8233
                    /* We may have to do the compatible overprint blending */
8234
0
                    if (!buf->isolated && drawn_comps != (( (size_t) 1 << (size_t) dev->color_info.num_components)-(size_t) 1)) {
8235
0
                        art_pdf_composite_knockout_8(dst2, src, num_comp,
8236
0
                            blend_mode, pdev->blend_procs, pdev);
8237
0
                    }
8238
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8239
0
                        if ((comps & 0x1) != 0) {
8240
0
                            dst_ptr[k * planestride] = 255 - dst[k];
8241
0
                        } else {
8242
                            /* Compatible overprint blend result. */
8243
0
                            dst_ptr[k * planestride] = 255 - dst2[k];
8244
0
                        }
8245
0
                    }
8246
742k
                } else {
8247
3.71M
                    for (k = 0; k < num_comp; ++k)
8248
2.97M
                        dst_ptr[k * planestride] = 255 - dst[k];
8249
742k
                }
8250
742k
                dst_ptr[num_comp * planestride] = dst[num_comp];
8251
742k
            }
8252
110M
            if (tag_off) {
8253
                /* If src alpha is 100% then set to curr_tag, else or */
8254
                /* other than Normal BM, we always OR */
8255
0
                if (src[num_comp] == 255 && tag_blend) {
8256
0
                    dst_ptr[tag_off] = curr_tag;
8257
0
                } else {
8258
0
                    dst_ptr[tag_off] |= curr_tag;
8259
0
                }
8260
0
            }
8261
            /* Knockout group alpha and shape too */
8262
110M
            if (alpha_g_off)
8263
105M
                dst_ptr[alpha_g_off] = 255 - src_alpha;
8264
110M
            if (shape_off)
8265
133k
                dst_ptr[shape_off] = 255 - shape;
8266
110M
            ++dst_ptr;
8267
110M
            if (has_backdrop)
8268
105M
                ++bg_ptr;
8269
110M
        }
8270
2.65M
        bline += rowstride;
8271
2.65M
        line += rowstride;
8272
2.65M
    }
8273
#if 0
8274
/* #if RAW_DUMP */
8275
    /* Dump the current buffer to see what we have. */
8276
    dump_raw_buffer(pdev->ctx->memory,
8277
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8278
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8279
                    pdev->ctx->stack->n_planes,
8280
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8281
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8282
                    pdev->ctx->stack->deep);
8283
    global_index++;
8284
#endif
8285
2.41M
    return 0;
8286
2.41M
}
8287
8288
static  int
8289
do_mark_fill_rectangle_ko_simple16(gx_device *dev, int x, int y, int w, int h,
8290
                                   gx_color_index color,
8291
                                   const gx_device_color *pdc, bool devn)
8292
0
{
8293
0
    pdf14_device *pdev = (pdf14_device *)dev;
8294
0
    pdf14_buf *buf = pdev->ctx->stack;
8295
0
    gs_blend_mode_t blend_mode = pdev->blend_mode;
8296
0
    bool tag_blend = blend_mode == BLEND_MODE_Normal ||
8297
0
        blend_mode == BLEND_MODE_Compatible ||
8298
0
        blend_mode == BLEND_MODE_CompatibleOverprint;
8299
0
    int i, j, k;
8300
0
    uint16_t *bline, *bg_ptr, *line, *dst_ptr;
8301
0
    uint16_t src[PDF14_MAX_PLANES];
8302
0
    uint16_t dst[PDF14_MAX_PLANES] = { 0 };
8303
0
    uint16_t dst2[PDF14_MAX_PLANES] = { 0 };
8304
0
    intptr_t rowstride = buf->rowstride;
8305
0
    intptr_t planestride = buf->planestride;
8306
0
    int num_chan = buf->n_chan;
8307
0
    int num_comp = num_chan - 1;
8308
0
    intptr_t shape_off = num_chan * planestride;
8309
0
    bool has_shape = buf->has_shape;
8310
0
    bool has_alpha_g = buf->has_alpha_g;
8311
0
    intptr_t alpha_g_off = shape_off + (has_shape ? planestride : 0);
8312
0
    intptr_t tag_off = shape_off + (has_alpha_g ? planestride : 0) +
8313
0
                                   (has_shape ? planestride : 0);
8314
0
    bool has_tags = buf->has_tags;
8315
0
    bool additive = pdev->ctx->additive;
8316
0
    gs_graphics_type_tag_t curr_tag = GS_UNKNOWN_TAG;  /* Quiet compiler */
8317
0
    uint16_t shape = 0; /* Quiet compiler. */
8318
0
    uint16_t src_alpha;
8319
0
    bool overprint = pdev->op_state == GS_OP_STATE_FILL ? pdev->overprint : pdev->stroke_overprint;
8320
0
    gx_color_index drawn_comps = pdev->op_state == GS_OP_STATE_FILL ?
8321
0
        pdev->drawn_comps_fill : pdev->drawn_comps_stroke;
8322
0
    gx_color_index comps;
8323
0
    bool has_backdrop = buf->backdrop != NULL;
8324
8325
    /* If we are going out to a CMYK or CMYK + spots pdf14 device (i.e.
8326
       subtractive) and we are doing overprint with drawn_comps == 0
8327
       then this is a no-operation */
8328
0
    if (overprint && drawn_comps == 0 && !buf->group_color_info->isadditive)
8329
0
        return 0;
8330
8331
0
    if (buf->data == NULL)
8332
0
        return 0;
8333
#if 0
8334
    if (sizeof(color) <= sizeof(ulong))
8335
        if_debug6m('v', dev->memory,
8336
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %lx, nc %d,\n",
8337
                   x, y, w, h, (ulong)color, num_chan);
8338
    else
8339
        if_debug7m('v', dev->memory,
8340
                   "[v]pdf14_mark_fill_rectangle_ko_simple16, (%d, %d), %d x %d color = %8lx%08lx, nc %d,\n",
8341
                   x, y, w, h,
8342
                   (ulong)(color >> 8*(sizeof(color) - sizeof(ulong))), (ulong)color,
8343
                   num_chan);
8344
#endif
8345
    /*
8346
     * Unpack the gx_color_index values.  Complement the components for subtractive
8347
     * color spaces.
8348
     */
8349
0
    if (devn) {
8350
0
        if (has_tags) {
8351
0
            curr_tag = pdc->tag;
8352
0
        }
8353
0
        if (additive) {
8354
0
            for (j = 0; j < num_comp; j++) {
8355
0
                src[j] = pdc->colors.devn.values[j];
8356
0
            }
8357
0
        } else {
8358
0
            for (j = 0; j < num_comp; j++) {
8359
0
                src[j] = 65535 - pdc->colors.devn.values[j];
8360
0
            }
8361
0
        }
8362
0
    } else {
8363
0
        if (has_tags) {
8364
0
            curr_tag = (color >> (num_comp * 16)) & 0xff;
8365
0
        }
8366
0
        pdev->pdf14_procs->unpack_color16(num_comp, color, pdev, src);
8367
0
    }
8368
8369
0
    src_alpha = src[num_comp] = (uint16_t)floor (65535 * pdev->alpha + 0.5);
8370
0
    if (has_shape) {
8371
0
        shape = (uint16_t)floor (65535 * pdev->shape + 0.5);
8372
0
    } else {
8373
0
        shape_off = 0;
8374
0
    }
8375
8376
0
    if (!has_tags) {
8377
0
        tag_off = 0;
8378
0
    }
8379
8380
0
    if (!has_alpha_g)
8381
0
        alpha_g_off = 0;
8382
0
    src_alpha = 65535 - src_alpha;
8383
0
    shape = 65535 - shape;
8384
8385
    /* Fit the mark into the bounds of the buffer */
8386
0
    if (x < buf->rect.p.x) {
8387
0
        w += x - buf->rect.p.x;
8388
0
        x = buf->rect.p.x;
8389
0
    }
8390
0
    if (y < buf->rect.p.y) {
8391
0
      h += y - buf->rect.p.y;
8392
0
      y = buf->rect.p.y;
8393
0
    }
8394
0
    if (x + w > buf->rect.q.x) w = buf->rect.q.x - x;
8395
0
    if (y + h > buf->rect.q.y) h = buf->rect.q.y - y;
8396
    /* Update the dirty rectangle with the mark. */
8397
0
    if (x < buf->dirty.p.x) buf->dirty.p.x = x;
8398
0
    if (y < buf->dirty.p.y) buf->dirty.p.y = y;
8399
0
    if (x + w > buf->dirty.q.x) buf->dirty.q.x = x + w;
8400
0
    if (y + h > buf->dirty.q.y) buf->dirty.q.y = y + h;
8401
8402
8403
    /* composite with backdrop only. */
8404
0
    if (has_backdrop)
8405
0
        bline = (uint16_t*)(void*)(buf->backdrop + (x - buf->rect.p.x) * 2 + (y - buf->rect.p.y) * rowstride);
8406
0
    else
8407
0
        bline = NULL;
8408
8409
0
    line = (uint16_t *)(void *)(buf->data + (x - buf->rect.p.x)*2 + (y - buf->rect.p.y) * rowstride);
8410
0
    planestride >>= 1;
8411
0
    rowstride >>= 1;
8412
0
    alpha_g_off >>= 1;
8413
0
    shape_off >>= 1;
8414
0
    tag_off >>= 1;
8415
8416
0
    for (j = 0; j < h; ++j) {
8417
0
        bg_ptr = bline;
8418
0
        dst_ptr = line;
8419
0
        for (i = 0; i < w; ++i) {
8420
            /* Complement the components for subtractive color spaces */
8421
0
            if (has_backdrop) {
8422
0
                if (additive) {
8423
0
                    for (k = 0; k < num_comp; ++k)
8424
0
                        dst[k] = bg_ptr[k * planestride];
8425
0
                } else {
8426
0
                    for (k = 0; k < num_comp; ++k)
8427
0
                        dst2[k] = dst[k] = 65535 - bg_ptr[k * planestride];
8428
0
                }
8429
0
                dst2[num_comp] = dst[num_comp] = bg_ptr[num_comp * planestride];  /* alpha doesn't invert */
8430
0
            }
8431
0
            if (buf->isolated || !has_backdrop) {
8432
0
                art_pdf_knockoutisolated_group_16(dst, src, num_comp);
8433
0
            } else {
8434
0
                art_pdf_composite_knockout_16(dst, src, num_comp,
8435
0
                                              blend_mode, pdev->blend_procs, pdev);
8436
0
            }
8437
            /* Complement the results for subtractive color spaces */
8438
0
            if (additive) {
8439
0
                if (!overprint) {
8440
0
                    for (k = 0; k < num_chan; ++k)
8441
0
                        dst_ptr[k * planestride] = dst[k];
8442
0
                } else {
8443
                    /* Hybrid additive with subtractive spots */
8444
                    /* We may have to do the compatible overprint blending */
8445
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8446
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8447
0
                            blend_mode, pdev->blend_procs, pdev);
8448
0
                    }
8449
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8450
0
                        if ((comps & 0x1) != 0) {
8451
0
                            dst_ptr[k * planestride] = dst[k];
8452
0
                        } else {
8453
                            /* Compatible overprint blend result. */
8454
0
                            dst_ptr[k * planestride] = dst2[k];
8455
0
                        }
8456
0
                    }
8457
0
                    dst_ptr[num_comp * planestride] = dst[num_comp];    /* alpha */
8458
0
                }
8459
0
            } else {
8460
0
                if (overprint) {
8461
                    /* We may have to do the compatible overprint blending */
8462
0
                    if (!buf->isolated && drawn_comps != (((size_t)1 << (size_t)dev->color_info.num_components) - (size_t)1)) {
8463
0
                        art_pdf_composite_knockout_16(dst2, src, num_comp,
8464
0
                            blend_mode, pdev->blend_procs, pdev);
8465
0
                    }
8466
0
                    for (k = 0, comps = drawn_comps; k < num_comp; ++k, comps >>= 1) {
8467
0
                        if ((comps & 0x1) != 0) {
8468
0
                            dst_ptr[k * planestride] = 65535 - dst[k];
8469
0
                        } else {
8470
                            /* Compatible overprint blend result. */
8471
0
                            dst_ptr[k * planestride] = 65535 - dst2[k];
8472
0
                        }
8473
0
                    }
8474
0
                } else {
8475
0
                    for (k = 0; k < num_comp; ++k)
8476
0
                        dst_ptr[k * planestride] = 65535 - dst[k];
8477
0
                }
8478
0
                dst_ptr[num_comp * planestride] = dst[num_comp];
8479
0
            }
8480
0
            if (tag_off) {
8481
                /* FIXME: As we are knocking out, possibly, we should be
8482
                 * always overwriting tag values here? */
8483
                /* If src alpha is 100% then set to curr_tag, else or */
8484
                /* other than Normal BM, we always OR */
8485
0
                if (src[num_comp] == 65535 && tag_blend) {
8486
0
                    dst_ptr[tag_off] = curr_tag;
8487
0
                } else {
8488
0
                    dst_ptr[tag_off] |= curr_tag;
8489
0
                }
8490
0
            }
8491
            /* Knockout group alpha and shape too */
8492
0
            if (alpha_g_off)
8493
0
                dst_ptr[alpha_g_off] = 65535 - src_alpha;
8494
0
            if (shape_off)
8495
0
                dst_ptr[shape_off] = 65535 - shape;
8496
0
            ++dst_ptr;
8497
0
            if (has_backdrop)
8498
0
                ++bg_ptr;
8499
0
        }
8500
0
        bline += rowstride;
8501
0
        line += rowstride;
8502
0
    }
8503
#if 0
8504
/* #if RAW_DUMP */
8505
    /* Dump the current buffer to see what we have. */
8506
    dump_raw_buffer(pdev->ctx->memory,
8507
                    pdev->ctx->stack->rect.q.y-pdev->ctx->stack->rect.p.y,
8508
                    pdev->ctx->stack->rect.q.x-pdev->ctx->stack->rect.p.x,
8509
                    pdev->ctx->stack->n_planes,
8510
                    pdev->ctx->stack->planestride, pdev->ctx->stack->rowstride,
8511
                    "Draw_Rect_KO", pdev->ctx->stack->data,
8512
                    pdev->ctx->stack->deep);
8513
    global_index++;
8514
#endif
8515
0
    return 0;
8516
0
}
8517
8518
static  int
8519
pdf14_mark_fill_rectangle_ko_simple(gx_device * dev, int x, int y, int w, int h,
8520
                                    gx_color_index color,
8521
                                    const gx_device_color *pdc, bool devn)
8522
2.41M
{
8523
2.41M
    pdf14_device *pdev = (pdf14_device *)dev;
8524
2.41M
    pdf14_buf *buf = pdev->ctx->stack;
8525
8526
2.41M
    if (buf->deep)
8527
0
        return do_mark_fill_rectangle_ko_simple16(dev, x, y, w, h, color, pdc, devn);
8528
2.41M
    else
8529
2.41M
        return do_mark_fill_rectangle_ko_simple(dev, x, y, w, h, color, pdc, devn);
8530
2.41M
}
8531
8532
/**
8533
 * Here we have logic to override the cmap_procs with versions that
8534
 * do not apply the transfer function. These copies should track the
8535
 * versions in gxcmap.c.
8536
 **/
8537
static  cmap_proc_gray(pdf14_cmap_gray_direct);
8538
static  cmap_proc_rgb(pdf14_cmap_rgb_direct);
8539
static  cmap_proc_cmyk(pdf14_cmap_cmyk_direct);
8540
static  cmap_proc_separation(pdf14_cmap_separation_direct);
8541
static  cmap_proc_devicen(pdf14_cmap_devicen_direct);
8542
static  cmap_proc_is_halftoned(pdf14_cmap_is_halftoned);
8543
8544
static  const gx_color_map_procs pdf14_cmap_many = {
8545
     pdf14_cmap_gray_direct,
8546
     pdf14_cmap_rgb_direct,
8547
     pdf14_cmap_cmyk_direct,
8548
     pdf14_cmap_separation_direct,
8549
     pdf14_cmap_devicen_direct,
8550
     pdf14_cmap_is_halftoned
8551
    };
8552
8553
/**
8554
 * Note: copied from gxcmap.c because it's inlined.
8555
 **/
8556
static  inline void
8557
map_components_to_colorants(const frac * pcc,
8558
                            const gs_devicen_color_map * pcolor_component_map,
8559
                            frac * plist,
8560
                            int num_additives)
8561
1.04M
{
8562
1.04M
    int i = pcolor_component_map->num_colorants - 1;
8563
1.04M
    int pos;
8564
8565
    /* Clear all output colorants first */
8566
5.24M
    for (; i >= num_additives; i--) {
8567
4.19M
        plist[i] = frac_0;
8568
4.19M
    }
8569
1.05M
    for (; i >= 0; i--) {
8570
2.52k
        plist[i] = frac_1;
8571
2.52k
    }
8572
    /* Map color components into output list */
8573
2.24M
    for (i = pcolor_component_map->num_components - 1; i >= 0; i--) {
8574
1.19M
        pos = pcolor_component_map->color_map[i];
8575
1.19M
        if (pos >= 0) {
8576
1.19M
            if (pos < num_additives)
8577
0
                plist[pos] = frac_1 - pcc[i];
8578
1.19M
            else
8579
1.19M
                plist[pos] = pcc[i];
8580
1.19M
        }
8581
1.19M
    }
8582
1.04M
}
8583
8584
/* See Section 7.6.4 of PDF 1.7 spec */
8585
static inline bool
8586
pdf14_state_opaque(gx_device *pdev, const gs_gstate *pgs)
8587
23.4M
{
8588
23.4M
    if (pgs->fillconstantalpha != 1.0 ||
8589
23.4M
        pgs->strokeconstantalpha != 1.0 ||
8590
23.4M
        !(pgs->blend_mode == BLEND_MODE_Normal ||
8591
156k
          pgs->blend_mode == BLEND_MODE_CompatibleOverprint))
8592
182k
        return 0;
8593
8594
    /* We can only be opaque if we're not in an SMask. */
8595
23.2M
    return dev_proc(pdev, dev_spec_op)(pdev,
8596
23.2M
                                       gxdso_in_smask,
8597
23.2M
                                       NULL, 0) != 1;
8598
23.4M
}
8599
8600
static  void
8601
pdf14_cmap_gray_direct(frac gray, gx_device_color * pdc, const gs_gstate * pgs,
8602
                       gx_device * dev, gs_color_select_t select)
8603
8.66M
{
8604
8.66M
    int i, nc, ncomps;
8605
8.66M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8606
8.66M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8607
8.66M
    gx_color_index color;
8608
8.66M
    gx_device *trans_device;
8609
8.66M
    const gx_device *map_dev;
8610
8.66M
    const gx_cm_color_map_procs *procs;
8611
8612
    /* If trans device is set, we need to use its procs. */
8613
8.66M
    if (pgs->trans_device != NULL) {
8614
4.15M
        trans_device = pgs->trans_device;
8615
4.50M
    } else {
8616
4.50M
        trans_device = dev;
8617
4.50M
    }
8618
8.66M
    ncomps = trans_device->color_info.num_components;
8619
8620
    /* map to the color model */
8621
8.66M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8622
8.66M
    procs->map_gray(map_dev, gray, cm_comps);
8623
8624
8.66M
    nc = ncomps;
8625
8.66M
    if (device_encodes_tags(trans_device))
8626
0
        nc--;
8627
8.66M
    if (pdf14_state_opaque(trans_device, pgs)) {
8628
9.01M
        for (i = 0; i < nc; i++)
8629
4.51M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8630
4.50M
    } else {
8631
8.33M
        for (i = 0; i < nc; i++)
8632
4.16M
            cv[i] = frac2cv(cm_comps[i]);
8633
4.16M
    }
8634
    /* Copy tags untransformed. */
8635
8.66M
    if (nc < ncomps)
8636
0
        cv[nc] = dev->graphics_type_tag;
8637
8638
    /* If output device supports devn, we need to make sure we send it the
8639
       proper color type.  We now support Gray + spots as devn colors */
8640
8.66M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8641
357k
        for (i = 0; i < ncomps; i++)
8642
178k
            pdc->colors.devn.values[i] = cv[i];
8643
11.4M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8644
11.2M
            pdc->colors.devn.values[i] = 0;
8645
178k
        pdc->type = gx_dc_type_devn;
8646
8.48M
    } else {
8647
        /* encode as a color index */
8648
8.48M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8649
        /* check if the encoding was successful; we presume failure is rare */
8650
8.48M
        if (color != gx_no_color_index)
8651
8.48M
            color_set_pure(pdc, color);
8652
8.48M
    }
8653
8.66M
}
8654
8655
static  void
8656
pdf14_cmap_rgb_direct(frac r, frac g, frac b, gx_device_color * pdc,
8657
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select)
8658
3.50M
{
8659
3.50M
    int i, nc, ncomps;
8660
3.50M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8661
3.50M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8662
3.50M
    gx_color_index color;
8663
3.50M
    gx_device *trans_device;
8664
3.50M
    const gx_device *map_dev;
8665
3.50M
    const gx_cm_color_map_procs *procs;
8666
8667
    /* If trans device is set, we need to use its procs. */
8668
3.50M
    if (pgs->trans_device != NULL){
8669
151k
        trans_device = pgs->trans_device;
8670
3.35M
    } else {
8671
3.35M
        trans_device = dev;
8672
3.35M
    }
8673
3.50M
    ncomps = trans_device->color_info.num_components;
8674
    /* map to the color model */
8675
3.50M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8676
3.50M
    procs->map_rgb(map_dev, pgs, r, g, b, cm_comps);
8677
8678
3.50M
    nc = ncomps;
8679
3.50M
    if (device_encodes_tags(trans_device))
8680
0
        nc--;
8681
3.50M
    if (pdf14_state_opaque(trans_device, pgs)) {
8682
8.11M
        for (i = 0; i < nc; i++)
8683
6.08M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8684
2.02M
    } else {
8685
5.89M
        for (i = 0; i < nc; i++)
8686
4.41M
            cv[i] = frac2cv(cm_comps[i]);
8687
1.47M
    }
8688
    /* Copy tags untransformed. */
8689
3.50M
    if (nc < ncomps)
8690
0
        cv[nc] = dev->graphics_type_tag;
8691
8692
    /* If output device supports devn, we need to make sure we send it the
8693
       proper color type.  We now support RGB + spots as devn colors */
8694
3.50M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8695
11.5M
        for (i = 0; i < ncomps; i++)
8696
8.70M
            pdc->colors.devn.values[i] = cv[i];
8697
179M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8698
176M
            pdc->colors.devn.values[i] = 0;
8699
2.89M
        pdc->type = gx_dc_type_devn;
8700
2.89M
    } else {
8701
        /* encode as a color index */
8702
607k
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8703
        /* check if the encoding was successful; we presume failure is rare */
8704
607k
        if (color != gx_no_color_index)
8705
607k
            color_set_pure(pdc, color);
8706
607k
    }
8707
3.50M
}
8708
8709
static  void
8710
pdf14_cmap_cmyk_direct(frac c, frac m, frac y, frac k, gx_device_color * pdc,
8711
     const gs_gstate * pgs, gx_device * dev, gs_color_select_t select,
8712
     const gs_color_space *pcs)
8713
11.2M
{
8714
11.2M
    int i, nc, ncomps;
8715
11.2M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8716
11.2M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8717
11.2M
    gx_color_index color;
8718
11.2M
    gx_device *trans_device;
8719
11.2M
    const gx_device *map_dev;
8720
11.2M
    const gx_cm_color_map_procs *procs;
8721
8722
8723
    /* If trans device is set, we need to use its procs. */
8724
11.2M
    if (pgs->trans_device != NULL){
8725
8.87M
        trans_device = pgs->trans_device;
8726
8.87M
    } else {
8727
2.39M
        trans_device = dev;
8728
2.39M
    }
8729
11.2M
    ncomps = trans_device->color_info.num_components;
8730
8731
    /* Map to the color model. Transfer function is only used
8732
       if we are drawing with an opaque color. */
8733
11.2M
    procs = dev_proc(trans_device, get_color_mapping_procs)(trans_device, &map_dev);
8734
11.2M
    procs->map_cmyk(map_dev, c, m, y, k, cm_comps);
8735
8736
11.2M
    nc = ncomps;
8737
11.2M
    if (device_encodes_tags(trans_device))
8738
0
        nc--;
8739
11.2M
    if (pdf14_state_opaque(trans_device, pgs)) {
8740
50.4M
        for (i = 0; i < nc; i++)
8741
40.3M
            cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8742
10.0M
    } else {
8743
5.97M
        for (i = 0; i < nc; i++)
8744
4.77M
            cv[i] = frac2cv(cm_comps[i]);
8745
1.19M
    }
8746
    /* Copy tags untransformed. */
8747
11.2M
    if (nc < ncomps)
8748
0
        cv[nc] = dev->graphics_type_tag;
8749
8750
    /* if output device supports devn, we need to make sure we send it the
8751
       proper color type */
8752
11.2M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8753
41.6M
        for (i = 0; i < ncomps; i++)
8754
33.3M
            pdc->colors.devn.values[i] = cv[i];
8755
508M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8756
500M
            pdc->colors.devn.values[i] = 0;
8757
8.33M
        pdc->type = gx_dc_type_devn;
8758
8.33M
    } else {
8759
        /* encode as a color index */
8760
2.94M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8761
        /* check if the encoding was successful; we presume failure is rare */
8762
2.94M
        if (color != gx_no_color_index)
8763
2.94M
            color_set_pure(pdc, color);
8764
2.94M
    }
8765
11.2M
}
8766
8767
static int
8768
pdf14_get_num_spots(gx_device * dev)
8769
1.04M
{
8770
1.04M
    cmm_dev_profile_t *dev_profile;
8771
1.04M
    cmm_profile_t *icc_profile;
8772
1.04M
    gsicc_rendering_param_t render_cond;
8773
8774
1.04M
    dev_proc(dev, get_profile)(dev, &dev_profile);
8775
1.04M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
8776
1.04M
        &render_cond);
8777
1.04M
    return dev->color_info.num_components - icc_profile->num_comps - device_encodes_tags(dev);
8778
1.04M
}
8779
8780
static  void
8781
pdf14_cmap_separation_direct(frac all, gx_device_color * pdc, const gs_gstate * pgs,
8782
                 gx_device * dev, gs_color_select_t select, const gs_color_space *pcs)
8783
1.33k
{
8784
1.33k
    int i, nc, ncomps = dev->color_info.num_components;
8785
1.33k
    int num_spots = pdf14_get_num_spots(dev);
8786
1.33k
    bool additive = dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE;
8787
1.33k
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8788
1.33k
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8789
1.33k
    gx_color_index color;
8790
1.33k
    int n = 0;
8791
8792
1.33k
    nc = ncomps;
8793
1.33k
    if (device_encodes_tags(dev))
8794
0
        nc--;
8795
8796
1.33k
    n = additive ? nc - num_spots : 0;
8797
1.33k
    if (pgs->color_component_map.sep_type == SEP_ALL) {
8798
4
        frac comp_value = all;
8799
8800
4
        for (i = pgs->color_component_map.num_colorants - 1; i >= nc - num_spots; i--)
8801
0
            cm_comps[i] = comp_value;
8802
        /*
8803
         * Invert the photometric interpretation for additive
8804
         * color spaces because separations are always subtractive.
8805
         */
8806
4
        if (additive)
8807
0
            comp_value = frac_1 - comp_value;
8808
        /* Use the "all" value for all components */
8809
20
        for (; i >= 0; i--)
8810
16
            cm_comps[i] = comp_value;
8811
1.32k
    } else {
8812
1.32k
        frac comp_value[GX_DEVICE_COLOR_MAX_COMPONENTS];
8813
8814
1.32k
        if (pgs->color_component_map.sep_type == SEP_NONE) {
8815
0
            color_set_null(pdc);
8816
0
            return;
8817
0
        }
8818
8819
        /* map to the color model */
8820
2.65k
        for (i = pgs->color_component_map.num_components - 1; i >= 0; i--)
8821
1.32k
            comp_value[i] = all;
8822
1.32k
        map_components_to_colorants(comp_value, &(pgs->color_component_map), cm_comps, n);
8823
1.32k
    }
8824
8825
    /* apply the transfer function(s); convert to color values */
8826
3.85k
    for (i = 0; i < n; i++)
8827
2.52k
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8828
4.12k
    for (; i < nc; i++)
8829
2.79k
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8830
8831
    /* Copy tags untransformed. */
8832
1.33k
    if (nc < ncomps)
8833
0
        cv[nc] = dev->graphics_type_tag;
8834
8835
    /* if output device supports devn, we need to make sure we send it the
8836
       proper color type */
8837
1.33k
    if (dev_proc(dev, dev_spec_op)(dev, gxdso_supports_devn, NULL, 0) > 0) {
8838
6.63k
        for (i = 0; i < ncomps; i++)
8839
5.30k
            pdc->colors.devn.values[i] = cv[i];
8840
80.8k
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8841
79.5k
            pdc->colors.devn.values[i] = 0;
8842
1.32k
        pdc->type = gx_dc_type_devn;
8843
1.32k
    } else {
8844
        /* encode as a color index */
8845
4
        color = dev_proc(dev, encode_color)(dev, cv);
8846
        /* check if the encoding was successful; we presume failure is rare */
8847
4
        if (color != gx_no_color_index)
8848
4
            color_set_pure(pdc, color);
8849
4
    }
8850
1.33k
}
8851
8852
static  void
8853
pdf14_cmap_devicen_direct(const frac * pcc,
8854
    gx_device_color * pdc, const gs_gstate * pgs, gx_device * dev,
8855
    gs_color_select_t select, const gs_color_space *pcs)
8856
1.04M
{
8857
1.04M
    int i, nc, ncomps = dev->color_info.num_components;
8858
1.04M
    int num_spots = pdf14_get_num_spots(dev);
8859
1.04M
    frac cm_comps[GX_DEVICE_COLOR_MAX_COMPONENTS];
8860
1.04M
    gx_color_value cv[GX_DEVICE_COLOR_MAX_COMPONENTS];
8861
1.04M
    gx_color_index color;
8862
1.04M
    gx_device *trans_device;
8863
1.04M
    int num_add_colorants = 0;
8864
8865
     /*  We may be coming from the clist writer which often forwards us the
8866
         target device. If this occurs we actually need to get to the color
8867
         space defined by the transparency group and we use the operators
8868
         defined by the transparency device to do the job.
8869
       */
8870
1.04M
    if (pgs->trans_device != NULL){
8871
1.04M
        trans_device = pgs->trans_device;
8872
1.04M
    } else {
8873
0
        trans_device = dev;
8874
0
    }
8875
1.04M
    ncomps = trans_device->color_info.num_components;
8876
1.04M
    nc = ncomps;
8877
1.04M
    if (device_encodes_tags(trans_device))
8878
0
        nc--;
8879
8880
1.04M
    if (trans_device->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE)
8881
0
        num_add_colorants = nc - num_spots;
8882
8883
    /* map to the color model */
8884
1.04M
    map_components_to_colorants(pcc, &(pgs->color_component_map), cm_comps, num_add_colorants);
8885
8886
    /* apply the transfer function(s); convert to color values */
8887
    /* The additive ones (if there are any) need to be inverted. */
8888
1.04M
    for (i = 0; i < num_add_colorants; i++)
8889
1.04M
        cv[i] = frac2cv(gx_map_color_frac(pgs, cm_comps[i], effective_transfer[i]));
8890
5.23M
    for (; i < nc; i++)
8891
4.19M
        cv[i] = frac2cv(frac_1 - gx_map_color_frac(pgs, (frac)(frac_1 - cm_comps[i]), effective_transfer[i]));
8892
    /* Copy tags untransformed. */
8893
1.04M
    if (nc < ncomps)
8894
0
        cv[nc] = dev->graphics_type_tag;
8895
8896
    /* if output device supports devn, we need to make sure we send it the
8897
       proper color type */
8898
1.04M
    if (dev_proc(trans_device, dev_spec_op)(trans_device, gxdso_supports_devn, NULL, 0) > 0) {
8899
237k
        for (i = 0; i < ncomps; i++)
8900
189k
            pdc->colors.devn.values[i] = cv[i];
8901
2.89M
        for (; i < GX_DEVICE_COLOR_MAX_COMPONENTS; i++)
8902
2.84M
            pdc->colors.devn.values[i] = 0;
8903
47.4k
        pdc->type = gx_dc_type_devn;
8904
1.00M
    } else {
8905
    /* encode as a color index */
8906
1.00M
        color = dev_proc(trans_device, encode_color)(trans_device, cv);
8907
        /* check if the encoding was successful; we presume failure is rare */
8908
1.00M
        if (color != gx_no_color_index)
8909
1.00M
            color_set_pure(pdc, color);
8910
1.00M
    }
8911
1.04M
}
8912
8913
static  bool
8914
pdf14_cmap_is_halftoned(const gs_gstate * pgs, gx_device * dev)
8915
79.0k
{
8916
79.0k
    return false;
8917
79.0k
}
8918
8919
static  const gx_color_map_procs *
8920
pdf14_get_cmap_procs(const gs_gstate *pgs, const gx_device * dev)
8921
1.65M
{
8922
    /* The pdf14 marking device itself is always continuous tone. */
8923
1.65M
    return &pdf14_cmap_many;
8924
1.65M
}
8925
8926
static int
8927
pdf14_dev_spec_op(gx_device *pdev, int dev_spec_op,
8928
                  void *data, int size)
8929
100M
{
8930
100M
    pdf14_device * p14dev = (pdf14_device *)pdev;
8931
8932
100M
    if (dev_spec_op == gxdso_supports_pattern_transparency)
8933
680k
        return 1;
8934
99.9M
    if (dev_spec_op == gxdso_pattern_shfill_doesnt_need_path)
8935
11.8k
        return 1;
8936
99.9M
    if (dev_spec_op == gxdso_is_pdf14_device) {
8937
801
        if (data != NULL && size == sizeof(gx_device *))
8938
312
            *(gx_device **)data = pdev;
8939
801
        return 1;
8940
801
    }
8941
99.9M
    if (dev_spec_op == gxdso_device_child) {
8942
2.05k
        pdf14_device *dev = (pdf14_device *)pdev;
8943
2.05k
        gxdso_device_child_request *d = (gxdso_device_child_request *)data;
8944
2.05k
        if (d->target == pdev) {
8945
2.05k
            d->target = dev->target;
8946
2.05k
            return 1;
8947
2.05k
        }
8948
2.05k
    }
8949
99.9M
    if (dev_spec_op == gxdso_supports_devn
8950
51.3M
     || dev_spec_op == gxdso_skip_icc_component_validation) {
8951
51.3M
        cmm_dev_profile_t *dev_profile;
8952
51.3M
        int code;
8953
51.3M
        code = dev_proc(pdev, get_profile)((gx_device*) pdev, &dev_profile);
8954
51.3M
        if (code == 0) {
8955
51.3M
            return dev_profile->supports_devn;
8956
51.3M
        } else {
8957
0
            return 0;
8958
0
        }
8959
51.3M
    }
8960
48.6M
    if (dev_spec_op == gxdso_pdf14_sep_device) {
8961
290k
        pdf14_device* dev = (pdf14_device*)pdev;
8962
8963
290k
        if (strcmp(dev->dname, "pdf14cmykspot") == 0 ||
8964
290k
            strcmp(dev->dname, "pdf14clistcmykspot") == 0)
8965
110k
            return 1;
8966
180k
        return 0;
8967
290k
    }
8968
48.3M
    if (dev_spec_op == gxdso_is_encoding_direct)
8969
1.45M
        return 1;
8970
8971
    /* We don't want to pass on these spec_ops either, because the child might respond
8972
     * with an inappropriate response when the PDF14 device is active. For example; the
8973
     * JPEG passthrough will give utterly wrong results if we pass that to a device which
8974
     * supports JPEG passthrough, because the pdf14 device needs to render the image.
8975
     */
8976
46.8M
    if (dev_spec_op == gxdso_in_pattern_accumulator)
8977
338k
        return 0;
8978
46.5M
    if (dev_spec_op == gxdso_copy_color_is_fast)
8979
1.10M
        return 0;
8980
45.4M
    if(dev_spec_op == gxdso_pattern_handles_clip_path)
8981
11.6k
        return 0;
8982
45.4M
    if(dev_spec_op == gxdso_supports_hlcolor)
8983
936
        return 0;
8984
45.4M
    if(dev_spec_op == gxdso_pattern_can_accum)
8985
78.1k
        return 0;
8986
45.3M
    if(dev_spec_op == gxdso_JPEG_passthrough_query)
8987
1.52k
        return 0;
8988
45.3M
    if (dev_spec_op == gxdso_overprint_active) {
8989
3.38M
        if (p14dev->pclist_device != NULL) {
8990
3.37M
            return dev_proc(p14dev->pclist_device, dev_spec_op)(p14dev->pclist_device, dev_spec_op, data, size);
8991
3.37M
        } else {
8992
11.0k
            return p14dev->overprint || p14dev->stroke_overprint;
8993
11.0k
        }
8994
3.38M
    }
8995
8996
    /* These should be coming only from the abuf device
8997
       during fill-stroke operation. Any other use will
8998
       result in bad things. */
8999
41.9M
    if (dev_spec_op == gxdso_abuf_optrans)
9000
0
    {
9001
0
        int ret = p14dev->op_state;
9002
0
        overprint_abuf_state_t *state_data = (overprint_abuf_state_t *)data;
9003
0
        pdf14_abuf_state_t *pdf14_abuf = (pdf14_abuf_state_t *)&state_data->storage[0];
9004
0
        const gs_gstate* cpgs = state_data->pgs;
9005
0
        union {
9006
0
            const gs_gstate* cpgs;
9007
0
            gs_gstate* pgs;
9008
0
        } const_breaker;
9009
0
        gs_gstate* pgs;
9010
0
        int code = 0;
9011
0
        int code1 = 0;
9012
9013
        /* A compile time assert to check our storage types are appropriately sized. */
9014
0
        typedef char compile_time_assert[sizeof(pdf14_abuf_state_t) <= sizeof(state_data->storage) ? 1 : -1];
9015
9016
        /* I don't really like this, but there is no easy way around it. The device
9017
           in the pgs needs to be the pdf14 device to ensure that the compositor
9018
           actions occur with the gs_transparency calls. We have to call at that
9019
           level (as opposed to the gx_ or pdf14_ level) to ensure that the clist
9020
           operations are invoked. We could change the gs_trans calls to take a
9021
           device to avoid this dance but that changes the device procs. */
9022
0
        gx_device *curr_dev;
9023
9024
0
        const_breaker.cpgs = cpgs;
9025
0
        pgs = const_breaker.pgs;
9026
0
        curr_dev = pgs->device;
9027
0
        pgs->device = pdev;
9028
9029
0
        switch (state_data->op_trans) {
9030
9031
0
            case OP_FS_TRANS_PREFILL:
9032
0
                pdf14_abuf->orig_state = p14dev->op_state;
9033
0
                pdf14_abuf->blend_mode = cpgs->blend_mode;
9034
0
                pdf14_abuf->fill_alpha = cpgs->fillconstantalpha;
9035
0
                pdf14_abuf->stroke_alpha = cpgs->strokeconstantalpha;
9036
0
                pdf14_abuf->pgs = pgs; /* ref count? only used for this back and forth so ok */
9037
0
                if (pdf14_abuf->fill_alpha == 1.0 && pdf14_abuf->stroke_alpha == 1.0 &&
9038
0
                    pdf14_abuf->blend_mode == BLEND_MODE_Normal)
9039
0
                    pdf14_abuf->group_needed = false;
9040
0
                else
9041
0
                    pdf14_abuf->group_needed = true;
9042
9043
0
                if (pdf14_abuf->group_needed) {
9044
0
                    code = pdf14_fill_stroke_prefill(pdev, pgs, state_data->ppath,
9045
0
                        state_data->pcpath, pdf14_abuf->fill_alpha,
9046
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode,
9047
0
                        &(pdf14_abuf->op_ca_eq_CA), &(pdf14_abuf->path_empty),
9048
0
                        state_data->alpha_buf_path_scale);
9049
0
                    if (code < 0)
9050
0
                        goto cleanup;
9051
0
                    if (pdf14_abuf->path_empty)
9052
0
                        pdf14_abuf->group_needed = 0;
9053
0
                }
9054
0
                code = gs_update_trans_marking_params(pgs);
9055
0
                break;
9056
9057
0
            case OP_FS_TRANS_PRESTROKE:
9058
0
                if (pdf14_abuf->group_needed) {
9059
0
                    pdf14_fill_stroke_prestroke(pdev, pdf14_abuf->pgs, pdf14_abuf->stroke_alpha,
9060
0
                                                pdf14_abuf->blend_mode, pdf14_abuf->op_ca_eq_CA);
9061
0
                }
9062
0
                code = gs_update_trans_marking_params(pgs);
9063
0
                break;
9064
9065
0
            case OP_FS_TRANS_POSTSTROKE:
9066
0
                if (pdf14_abuf->group_needed) {
9067
0
                    code = pdf14_fill_stroke_poststroke(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9068
0
                                                        pdf14_abuf->op_ca_eq_CA);
9069
0
                }
9070
0
                if (code >= 0)
9071
0
                    code = gs_update_trans_marking_params(pgs);
9072
9073
                /* fallthrough */
9074
9075
0
            case OP_FS_TRANS_CLEANUP:
9076
0
cleanup:
9077
0
                if (pdf14_abuf->group_needed) {
9078
0
                    code1 = pdf14_fill_stroke_cleanup(pdev, pdf14_abuf->pgs, pdf14_abuf->fill_alpha,
9079
0
                        pdf14_abuf->stroke_alpha, pdf14_abuf->blend_mode, pdf14_abuf->orig_state);
9080
0
                    if (code1 < 0)
9081
0
                        code = gs_note_error(gs_error_Fatal);
9082
0
                }
9083
0
                break;
9084
0
        }
9085
0
        pgs->device = curr_dev;
9086
9087
0
        return (code < 0) ? code : ret;
9088
0
    }
9089
9090
41.9M
    if (dev_spec_op == gxdso_in_smask_construction)
9091
3.50M
        return p14dev->in_smask_construction > 0;
9092
38.4M
    if (dev_spec_op == gxdso_in_smask)
9093
24.1M
        return p14dev->in_smask_construction > 0 || p14dev->depth_within_smask;
9094
14.2M
    if (dev_spec_op == gxdso_replacecolor) {
9095
14.0M
        gx_device *tdev = p14dev->target;
9096
14.0M
        cmm_dev_profile_t *tdev_profile;
9097
14.0M
        int code;
9098
9099
         /* If in a softmask or softmask construction do not allow
9100
           replacement. */
9101
14.0M
        if (p14dev->in_smask_construction > 0 || p14dev->depth_within_smask)
9102
247k
            return 0;
9103
9104
        /* If the target CS is different than the pdf14 profile add this information
9105
           for the target device that will be handling the replacement. While not
9106
           perfect this at least lets you do the replacehment and have some information
9107
           about what the situation is. */
9108
13.8M
        code = dev_proc(tdev, get_profile)((gx_device*) tdev, &tdev_profile);
9109
13.8M
        if (code != 0)
9110
0
            return 0;
9111
9112
13.8M
        if (tdev_profile->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode !=
9113
13.8M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->hashcode) {
9114
3.10M
            color_replace_t* replace_data = (color_replace_t*)data;
9115
            /* Not ref counted as data is on the stack (from gx_remap_ICC) and we should be fine during this
9116
               color remap operation. */
9117
3.10M
            replace_data->pdf14_iccprofile = p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE];
9118
3.10M
        }
9119
9120
        /* Pass on to target device */
9121
13.8M
        return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9122
13.8M
    }
9123
219k
    if (dev_spec_op == gxdso_device_insert_child) {
9124
129
        gx_device *tdev = p14dev->target;
9125
129
        p14dev->target = (gx_device *)data;
9126
129
        rc_increment(p14dev->target);
9127
129
        rc_decrement_only(tdev, "pdf14_dev_spec_op");
9128
129
        return 0;
9129
129
    }
9130
219k
    if (dev_spec_op == gxdso_interpolate_threshold)
9131
5.51k
        return p14dev->interpolate_threshold;
9132
9133
213k
    if (dev_spec_op == gxdso_overprintsim_state) {
9134
5.49k
        unsigned char *data_uchar = (unsigned char *) data;
9135
5.49k
        data_uchar[0] = (unsigned char) p14dev->overprint_sim;
9136
5.49k
        if (p14dev->ctx != NULL)
9137
7
            data_uchar[1] = (unsigned char)p14dev->ctx->num_spots; /* pdf14 page device */
9138
5.48k
        else
9139
5.48k
            data_uchar[1] = (unsigned char)p14dev->devn_params.page_spot_colors;  /* pdf14 clist device */
9140
5.49k
        return 1;
9141
5.49k
    }
9142
9143
208k
    return dev_proc(p14dev->target, dev_spec_op)(p14dev->target, dev_spec_op, data, size);
9144
213k
}
9145
9146
/* Needed to set color monitoring in the target device's profile */
9147
int
9148
gs_pdf14_device_color_mon_set(gx_device *pdev, bool monitoring)
9149
0
{
9150
0
    pdf14_device * p14dev = (pdf14_device *)pdev;
9151
0
    gx_device *targ = p14dev->target;
9152
0
    cmm_dev_profile_t *dev_profile;
9153
0
    int code = dev_proc(targ, get_profile)((gx_device*) targ, &dev_profile);
9154
9155
0
    if (code == 0)
9156
0
        dev_profile->pageneutralcolor = monitoring;
9157
0
    return code;
9158
0
}
9159
9160
static int
9161
gs_pdf14_device_push(gs_memory_t *mem, gs_gstate * pgs,
9162
        gx_device ** pdev, gx_device * target, const gs_pdf14trans_t * pdf14pct)
9163
1.02M
{
9164
1.02M
    pdf14_device dev_proto;
9165
1.02M
    pdf14_device * p14dev;
9166
1.02M
    int code;
9167
1.02M
    bool has_tags;
9168
1.02M
    cmm_profile_t *icc_profile;
9169
1.02M
    gsicc_rendering_param_t render_cond;
9170
1.02M
    cmm_dev_profile_t *dev_profile;
9171
1.02M
    uchar k;
9172
1.02M
    int max_bitmap;
9173
1.02M
    bool use_pdf14_accum = false;
9174
1.02M
    bool deep;
9175
9176
    /* Guard against later seg faults, this should not be possible */
9177
1.02M
    if (target == NULL)
9178
0
        return gs_throw_code(gs_error_Fatal);
9179
9180
1.02M
    has_tags = device_encodes_tags(target);
9181
1.02M
    deep = device_is_deep(target);
9182
1.02M
    max_bitmap = target->space_params.MaxBitmap == 0 ? MAX_BITMAP :
9183
1.02M
                                 target->space_params.MaxBitmap;
9184
    /* If the device is not a printer class device, it won't support saved-pages */
9185
    /* and so we may need to make a clist device in order to prevent very large  */
9186
    /* or high resolution pages from having allocation problems.                 */
9187
    /* We use MaxBitmap to decide when a clist is needed.*/
9188
1.02M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_saved_pages, NULL, 0) <= 0 &&
9189
6.46k
        gx_device_is_pattern_clist(target) == 0 &&
9190
6.46k
        gx_device_is_pattern_accum(target) == 0 &&
9191
4.07k
        gs_device_is_memory(target) == 0) {
9192
9193
4.07k
        uint32_t pdf14_trans_buffer_size =
9194
4.07k
              (ESTIMATED_PDF14_ROW_SPACE(max(1, target->width),
9195
4.07k
                                         target->color_info.num_components,
9196
4.07k
                                         deep ? 16 : 8) >> 3);
9197
9198
4.07k
        if (target->height < max_ulong / pdf14_trans_buffer_size)
9199
4.07k
                pdf14_trans_buffer_size *= target->height;
9200
0
        else
9201
0
                max_bitmap = 0;     /* Force decision to clist */
9202
4.07k
        if (pdf14_trans_buffer_size > max_bitmap)
9203
3.71k
            use_pdf14_accum = true;
9204
4.07k
    }
9205
1.02M
    code = dev_proc(target, get_profile)(target,  &dev_profile);
9206
1.02M
    if (code < 0)
9207
0
        return code;
9208
1.02M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9209
1.02M
                          &render_cond);
9210
1.02M
    if_debug0m('v', mem, "[v]gs_pdf14_device_push\n");
9211
9212
    /* Get the proto from which to copy the device. This will always
9213
     * ignore tags! */
9214
1.02M
    code = get_pdf14_device_proto(target, &dev_proto, pgs,
9215
1.02M
                                  pdf14pct, use_pdf14_accum);
9216
1.02M
    if (code < 0)
9217
0
        return code;
9218
1.02M
    code = gs_copydevice((gx_device **) &p14dev,
9219
1.02M
                         (const gx_device *) &dev_proto, mem);
9220
1.02M
    if (code < 0)
9221
0
        return code;
9222
9223
1.02M
    p14dev->graphics_type_tag = target->graphics_type_tag;
9224
9225
    /* Copying the params across will add tags to the colorinfo as required. */
9226
1.02M
    code = gs_pdf14_device_copy_params((gx_device *)p14dev, target);
9227
1.02M
    if (code < 0)
9228
0
        return code;
9229
9230
1.02M
    gx_device_set_target((gx_device_forward *)p14dev, target);
9231
1.02M
    p14dev->pad = target->pad;
9232
1.02M
    p14dev->log2_align_mod = target->log2_align_mod;
9233
1.02M
    if (target->num_planar_planes == 0)
9234
957k
        p14dev->num_planar_planes = 0;
9235
68.1k
    else
9236
68.1k
        p14dev->num_planar_planes = p14dev->color_info.num_components;
9237
1.02M
    p14dev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
9238
9239
1.02M
    p14dev->alpha = 1.0;
9240
1.02M
    p14dev->shape = 1.0;
9241
1.02M
    p14dev->opacity = 1.0;
9242
1.02M
    p14dev->fillconstantalpha = 1.0;
9243
1.02M
    p14dev->strokeconstantalpha = 1.0;
9244
9245
    /* Simulated overprint case.  We have to use CMYK-based profile.  Also if the target
9246
       profile is NCLR, we are going to use a pdf14 device that is CMYK based and
9247
       do the mapping to the NCLR profile when the put_image occurs */
9248
1.02M
    if ((p14dev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
9249
1.02M
        icc_profile->data_cs == gsNCHANNEL) {
9250
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "gs_pdf14_device_push");
9251
0
        gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9252
0
            -1, "gs_pdf14_device_push");
9253
0
        p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
9254
1.02M
    } else {
9255
        /* If the target profile was CIELAB (and we are not using a blend CS),
9256
           then overide with default RGB for proper blending.  During put_image
9257
           we will convert from RGB to CIELAB.  Need to check that we have a
9258
           default profile, which will not be the case if we are coming from the clist reader */
9259
1.02M
        if ((icc_profile->data_cs == gsCIELAB || icc_profile->islab)
9260
0
            && pgs->icc_manager->default_rgb != NULL &&
9261
0
            p14dev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
9262
0
            p14dev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
9263
0
            gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "gs_pdf14_device_push");
9264
0
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
9265
0
                -1, "gs_pdf14_device_push");
9266
0
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_rgb;
9267
0
        }
9268
1.02M
    }
9269
9270
1.02M
    if (pdf14pct->params.overprint_sim_push &&
9271
0
        pdf14pct->params.num_spot_colors_int > 0) {
9272
0
        p14dev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
9273
0
        p14dev->procs.ret_devn_params = pdf14_ret_devn_params;
9274
0
        p14dev->op_pequiv_cmyk_colors.all_color_info_valid = false;
9275
0
        p14dev->target_support_devn = p14dev->icc_struct->supports_devn;
9276
0
        p14dev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
9277
0
    }
9278
9279
    /* The number of color planes should not exceed that of the target.
9280
       Unless we are using a blend CS */
9281
1.02M
    if (!(p14dev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || p14dev->overprint_sim)) {
9282
1.02M
        if (p14dev->color_info.num_components > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev)) {
9283
0
            p14dev->color_info.num_components = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)p14dev);
9284
0
            if (p14dev->num_planar_planes != 0)
9285
0
                p14dev->num_planar_planes = p14dev->color_info.num_components;
9286
0
        }
9287
1.02M
        if (p14dev->color_info.max_components > target->color_info.max_components)
9288
68.0k
            p14dev->color_info.max_components = target->color_info.max_components;
9289
1.02M
    }
9290
1.02M
    p14dev->color_info.depth = p14dev->color_info.num_components * (8<<deep);
9291
    /* If we have a tag device then go ahead and do a special encoder
9292
       decoder for the pdf14 device to make sure we maintain this
9293
       information in the encoded color information.  We could use
9294
       the target device's methods but the PDF14 device has to maintain
9295
       8 bit color always and we could run into other issues if the number
9296
       of colorants became large.  If we need to do compressed color with
9297
       tags that will be a special project at that time */
9298
1.02M
    if (deep) {
9299
0
        set_dev_proc(p14dev, encode_color, pdf14_encode_color16);
9300
0
        set_dev_proc(p14dev, decode_color, pdf14_decode_color16);
9301
0
    }
9302
1.02M
    if (has_tags) {
9303
0
        set_dev_proc(p14dev, encode_color, deep ? pdf14_encode_color16_tag : pdf14_encode_color_tag);
9304
0
    }
9305
    /* if the device has separations already defined (by SeparationOrderNames) */
9306
    /* we need to copy them (allocating new names) so the colorants are in the */
9307
    /* same order as the target device.                                        */
9308
1.02M
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9309
68.1k
        code = devn_copy_params(target, (gx_device *)p14dev);
9310
68.1k
        if (code < 0) {
9311
50
            *pdev = NULL;
9312
50
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9313
50
            rc_decrement(p14dev, "gs_pdf14_device_push");
9314
50
            return code;
9315
50
        }
9316
68.1k
    }
9317
    /* by definition pdf14_encode _is_ standard */
9318
1.02M
    p14dev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
9319
1.02M
    gx_device_fill_in_procs((gx_device *)p14dev);
9320
1.02M
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
9321
1.02M
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
9322
1.02M
    gx_set_cmap_procs(pgs, (gx_device *)p14dev);
9323
9324
    /* Components shift, etc have to be based upon 8 (or 16) bit */
9325
3.45M
    for (k = 0; k < p14dev->color_info.num_components; k++) {
9326
2.43M
        p14dev->color_info.comp_bits[k] = 8<<deep;
9327
2.43M
        p14dev->color_info.comp_shift[k] =
9328
2.43M
                            (p14dev->color_info.num_components - 1 - k) * (8<<deep);
9329
2.43M
    }
9330
1.02M
    if (use_pdf14_accum) {
9331
        /* we will disable this device later, but we don't want to allocate large buffers */
9332
3.71k
        p14dev->width = 1;
9333
3.71k
        p14dev->height = 1;
9334
3.71k
    }
9335
9336
1.02M
    p14dev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
9337
1.02M
    code = dev_proc((gx_device *) p14dev, open_device) ((gx_device *) p14dev);
9338
1.02M
    *pdev = (gx_device *) p14dev;
9339
1.02M
    pdf14_set_marking_params((gx_device *)p14dev, pgs);
9340
1.02M
    p14dev->color_model_stack = NULL;
9341
9342
    /* In case we have alphabits set */
9343
1.02M
    p14dev->color_info.anti_alias = target->color_info.anti_alias;
9344
9345
1.02M
    if (pdf14pct->params.is_pattern) {
9346
7.61k
        code = pdf14_initialize_ctx((gx_device*)p14dev, pgs);
9347
7.61k
        if (code < 0) {
9348
0
            *pdev = NULL;
9349
0
            gx_device_set_target((gx_device_forward *)p14dev, NULL);
9350
0
            rc_decrement(p14dev, "gs_pdf14_device_push");
9351
0
            return code;
9352
0
        }
9353
7.61k
    }
9354
9355
    /* We should never go into this when using a blend color space */
9356
1.02M
    if (use_pdf14_accum) {
9357
3.71k
        const gx_device_pdf14_accum *accum_proto = NULL;
9358
3.71k
        gx_device *new_target = NULL;
9359
3.71k
        gx_device_color pdcolor;
9360
3.71k
        frac pconc_white = frac_1;
9361
3.71k
        bool UsePlanarBuffer = false;
9362
9363
3.71k
        if_debug0m('v', mem, "[v]gs_pdf14_device_push: Inserting clist device.\n");
9364
9365
        /* get the prototype for the accumulator device based on colorspace */
9366
3.71k
        switch (target->color_info.max_components) { /* use max_components in case is devn device */
9367
675
            case 1:
9368
675
                accum_proto = &pdf14_accum_Gray;
9369
675
                break;
9370
3.03k
            case 3:
9371
3.03k
                accum_proto = &pdf14_accum_RGB;
9372
3.03k
                break;
9373
0
            case 4:
9374
0
                accum_proto = &pdf14_accum_CMYK;
9375
0
                break;
9376
0
            default:
9377
0
                accum_proto = &pdf14_accum_CMYKspot;
9378
0
                UsePlanarBuffer = true;
9379
3.71k
        }
9380
3.71k
        if (accum_proto == NULL ||
9381
3.71k
            (code = gs_copydevice(&new_target, (gx_device *)accum_proto, mem->stable_memory)) < 0)
9382
0
            goto no_clist_accum;
9383
9384
3.71k
        ((gx_device_pdf14_accum *)new_target)->save_p14dev = (gx_device *)p14dev;  /* non-clist p14dev */
9385
        /* Fill in values from the target device before opening */
9386
3.71k
        new_target->color_info = p14dev->color_info;
9387
3.71k
        ((gx_device_pdf14_accum *)new_target)->devn_params = p14dev->devn_params;
9388
3.71k
        new_target->color_info.separable_and_linear = GX_CINFO_SEP_LIN;
9389
3.71k
        set_linear_color_bits_mask_shift(new_target);
9390
3.71k
        gs_pdf14_device_copy_params(new_target, target);
9391
3.71k
        ((gx_device_pdf14_accum *)new_target)->page_uses_transparency = true;
9392
3.71k
        gx_device_fill_in_procs(new_target);
9393
9394
3.71k
        memcpy(&(new_target->space_params), &(target->space_params), sizeof(gdev_space_params));
9395
3.71k
        max_bitmap = max(target->space_params.MaxBitmap, target->space_params.BufferSpace);
9396
3.71k
        ((gx_device_pdf14_accum *)new_target)->space_params.BufferSpace = max_bitmap;
9397
9398
        /* This is used to mark the various internal subclass devices as having already
9399
         * been pushed, so that opening the device won't result in us trying to push
9400
         * them again, which leads to trouble.
9401
         */
9402
3.71k
        code = mark_internal_subclass_devices(new_target);
9403
3.71k
        if (code < 0)
9404
0
            return code;
9405
9406
        /* if the device has separations already defined (by SeparationOrderNames) */
9407
        /* we need to copy them (allocating new names) so the colorants are in the */
9408
        /* same order as the target device.                                        */
9409
3.71k
        if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
9410
0
            code = devn_copy_params(target, (gx_device *)*pdev);
9411
0
            if (code < 0)
9412
0
                return code;
9413
0
        }
9414
        /* UsePlanarBuffer is true in case this is CMYKspot */
9415
3.71k
        if ((code = gdev_prn_open_planar(new_target, UsePlanarBuffer ? new_target->color_info.num_components : 0)) < 0 ||
9416
3.71k
             !PRINTER_IS_CLIST((gx_device_printer *)new_target)) {
9417
0
            gs_free_object(mem->stable_memory, new_target, "pdf14-accum");
9418
0
            goto no_clist_accum;
9419
0
        }
9420
        /* Do the initial fillpage into the pdf14-accum device we just created */
9421
3.71k
        dev_proc(new_target, set_graphics_type_tag)((gx_device *)new_target, GS_UNTOUCHED_TAG);
9422
3.71k
        if ((code = gx_remap_concrete_DGray(gs_currentcolorspace_inline((gs_gstate *)pgs),
9423
3.71k
                                            &pconc_white,
9424
3.71k
                                            &pdcolor, pgs, new_target, gs_color_select_all,
9425
3.71k
                                            dev_profile)) < 0)
9426
0
            goto no_clist_accum;
9427
9428
3.71k
        (*dev_proc(new_target, fillpage))(new_target, pgs, &pdcolor);
9429
3.71k
        code = clist_composite(new_target, pdev, (gs_composite_t *)pdf14pct, pgs, mem, NULL);
9430
3.71k
        if (code < 0)
9431
0
            goto no_clist_accum;
9432
9433
3.71k
        pdf14_disable_device((gx_device *)p14dev);           /* make the non-clist device forward */
9434
3.71k
        pdf14_close((gx_device *)p14dev);                    /* and free up the little memory it had */
9435
3.71k
    }
9436
1.02M
    return code;
9437
9438
0
no_clist_accum:
9439
        /* FIXME: We allocated a really small p14dev, but that won't work */
9440
0
    return gs_throw_code(gs_error_Fatal); /* punt for now */
9441
1.02M
}
9442
9443
/*
9444
 * In a modest violation of good coding practice, the gs_composite_common
9445
 * fields are "known" to be simple (contain no pointers to garbage
9446
 * collected memory), and we also know the gs_pdf14trans_params_t structure
9447
 * to be simple, so we just create a trivial structure descriptor for the
9448
 * entire gs_pdf14trans_s structure.
9449
 */
9450
#define private_st_gs_pdf14trans_t()\
9451
  gs_private_st_ptrs2(st_pdf14trans, gs_pdf14trans_t, "gs_pdf14trans_t",\
9452
      st_pdf14trans_enum_ptrs, st_pdf14trans_reloc_ptrs, params.transfer_function, params.iccprofile)
9453
9454
/* GC descriptor for gs_pdf14trans_t */
9455
private_st_gs_pdf14trans_t();
9456
9457
/*
9458
 * Check for equality of two PDF 1.4 transparency compositor objects.
9459
 *
9460
 * We are currently always indicating that PDF 1.4 transparency compositors are
9461
 * equal.  Two transparency compositors may have teh same data but still
9462
 * represent separate actions.  (E.g. two PDF14_BEGIN_TRANS_GROUP compositor
9463
 * operations in a row mean that we are creating a group inside of a group.
9464
 */
9465
static  bool
9466
c_pdf14trans_equal(const gs_composite_t * pct0, const gs_composite_t * pct1)
9467
0
{
9468
0
    return false;
9469
0
}
9470
9471
#ifdef DEBUG
9472
static const char * pdf14_opcode_names[] = PDF14_OPCODE_NAMES;
9473
#endif
9474
9475
#define put_value(dp, value)\
9476
6.27M
    BEGIN\
9477
6.27M
        memcpy(dp, &value, sizeof(value));\
9478
6.27M
        dp += sizeof(value);\
9479
6.27M
    END
9480
9481
static inline int
9482
c_pdf14trans_write_ctm(byte **ppbuf, const gs_pdf14trans_params_t *pparams)
9483
770k
{
9484
    /* Note: We can't skip writing CTM if it is equal to pgs->ctm,
9485
       because clist writer may skip this command for some bands.
9486
       For a better result we need individual CTM for each band.
9487
     */
9488
770k
    byte *pbuf = *ppbuf;
9489
770k
    int len, code;
9490
9491
770k
    len = cmd_write_ctm_return_length_nodevice(&pparams->ctm);
9492
770k
    pbuf--; /* For cmd_write_ctm. */
9493
770k
    code = cmd_write_ctm(&pparams->ctm, pbuf, len);
9494
770k
    if (code < 0)
9495
0
        return code;
9496
770k
    pbuf += len + 1;
9497
770k
    *ppbuf = pbuf;
9498
770k
    return 0;
9499
770k
}
9500
9501
/*
9502
 * Convert a PDF 1.4 transparency compositor to string form for use by the command
9503
 * list device. This is also where we update the pdf14_needed. When set the clist
9504
 * painting procs will update the trans_bbox state for bands that are affected.
9505
*/
9506
static  int
9507
c_pdf14trans_write(const gs_composite_t * pct, byte * data, uint * psize,
9508
                   gx_device_clist_writer *cdev)
9509
1.78M
{
9510
1.78M
    const gs_pdf14trans_params_t * pparams = &((const gs_pdf14trans_t *)pct)->params;
9511
1.78M
    int need, avail = *psize;
9512
1.78M
    byte buf[MAX_CLIST_TRANSPARENCY_BUFFER_SIZE]; /* Must be large enough
9513
        to fit the data written below. We don't implement a dynamic check for
9514
        the buffer owerflow, assuming that the consistency is verified in the
9515
        coding phase. See the definition of MAX_CLIST_TRANSPARENCY_BUFFER_SIZE. */
9516
1.78M
    byte * pbuf = buf;
9517
1.78M
    int opcode = pparams->pdf14_op;
9518
1.78M
    int mask_size = 0;
9519
1.78M
    uint mask_id = 0;
9520
1.78M
    int code;
9521
1.78M
    bool found_icc;
9522
1.78M
    int64_t hashcode = 0;
9523
1.78M
    cmm_profile_t *icc_profile;
9524
1.78M
    gsicc_rendering_param_t render_cond;
9525
1.78M
    cmm_dev_profile_t *dev_profile;
9526
    /* We maintain and update working copies until we actually write the clist */
9527
1.78M
    int pdf14_needed = cdev->pdf14_needed;
9528
1.78M
    int trans_group_level = cdev->pdf14_trans_group_level;
9529
1.78M
    int smask_level = cdev->pdf14_smask_level;
9530
1.78M
    bool deep = device_is_deep((gx_device *)cdev);
9531
9532
1.78M
    code = dev_proc((gx_device *) cdev, get_profile)((gx_device *) cdev,
9533
1.78M
                                                     &dev_profile);
9534
1.78M
    if (code < 0)
9535
0
        return code;
9536
1.78M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
9537
1.78M
                          &render_cond);
9538
1.78M
    *pbuf++ = opcode;     /* 1 byte */
9539
1.78M
    if (trans_group_level < 0 && opcode != PDF14_PUSH_DEVICE)
9540
0
        return_error(gs_error_unregistered);  /* prevent spurious transparency ops (Bug 702327) */
9541
9542
1.78M
    switch (opcode) {
9543
0
        default:      /* Should not occur. */
9544
0
            break;
9545
18.1k
        case PDF14_PUSH_DEVICE:
9546
18.1k
            trans_group_level = 0;
9547
18.1k
            cdev->pdf14_smask_level = 0;
9548
18.1k
            cdev->page_pdf14_needed = false;
9549
18.1k
            put_value(pbuf, pparams->num_spot_colors);
9550
18.1k
            put_value(pbuf, pparams->num_spot_colors_int);
9551
18.1k
            put_value(pbuf, pparams->overprint_sim_push);
9552
18.1k
            put_value(pbuf, pparams->is_pattern);
9553
9554
            /* If we happen to be going to a color space like CIELAB then
9555
               we are going to do our blending in default RGB and convert
9556
               to CIELAB at the end.  To do this, we need to store the
9557
               default RGB profile in the clist so that we can grab it
9558
               later on during the clist read back and put image command */
9559
18.1k
            if (icc_profile->data_cs == gsCIELAB || icc_profile->islab) {
9560
                /* Get the default RGB profile.  Set the device hash code
9561
                   so that we can extract it during the put_image operation. */
9562
0
                cdev->trans_dev_icc_hash = gsicc_get_hash(pparams->iccprofile);
9563
0
                found_icc =
9564
0
                    clist_icc_searchtable(cdev, gsicc_get_hash(pparams->iccprofile));
9565
0
                if (!found_icc) {
9566
                    /* Add it to the table */
9567
0
                    clist_icc_addentry(cdev, gsicc_get_hash(pparams->iccprofile),
9568
0
                                       pparams->iccprofile);
9569
0
                }
9570
0
            }
9571
18.1k
            break;
9572
18.1k
        case PDF14_POP_DEVICE:
9573
18.1k
            pdf14_needed = false;   /* reset pdf14_needed */
9574
18.1k
            trans_group_level = -1;   /* reset so we need to PUSH_DEVICE next */
9575
18.1k
            smask_level = 0;
9576
18.1k
            put_value(pbuf, pparams->is_pattern);
9577
18.1k
            break;
9578
415k
        case PDF14_END_TRANS_GROUP:
9579
420k
        case PDF14_END_TRANS_TEXT_GROUP:
9580
420k
            trans_group_level--;  /* if now at page level, pdf14_needed will be updated */
9581
420k
            if (smask_level == 0 && trans_group_level == 0)
9582
26.1k
                pdf14_needed = cdev->page_pdf14_needed;
9583
420k
            break;      /* No data */
9584
6.81k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9585
420k
        case PDF14_BEGIN_TRANS_GROUP:
9586
420k
            pdf14_needed = true;   /* the compositor will be needed while reading */
9587
420k
            trans_group_level++;
9588
420k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9589
420k
            if (code < 0)
9590
0
                return code;
9591
420k
            *pbuf++ = (pparams->Isolated & 1) + ((pparams->Knockout & 1) << 1);
9592
420k
            *pbuf++ = pparams->blend_mode;
9593
420k
            *pbuf++ = pparams->group_color_type;
9594
420k
            *pbuf++ = pparams->page_group;
9595
420k
            put_value(pbuf, pparams->group_color_numcomps);
9596
420k
            put_value(pbuf, pparams->opacity);
9597
420k
            put_value(pbuf, pparams->shape);
9598
420k
            put_value(pbuf, pparams->bbox);
9599
420k
            put_value(pbuf, pparams->shade_group);
9600
420k
            put_value(pbuf, pparams->text_group);
9601
420k
            mask_id = pparams->mask_id;
9602
420k
            put_value(pbuf, mask_id);
9603
            /* Color space information maybe ICC based
9604
               in this case we need to store the ICC
9605
               profile or the ID if it is cached already */
9606
420k
            if (pparams->group_color_type == ICC) {
9607
                /* Check if it is already in the ICC clist table */
9608
12.0k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9609
12.0k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9610
12.0k
                if (!found_icc) {
9611
                    /* Add it to the table */
9612
3.64k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9613
3.64k
                    put_value(pbuf, hashcode);
9614
8.41k
                } else {
9615
                    /* It will be in the clist. Just write out the hashcode */
9616
8.41k
                    put_value(pbuf, hashcode);
9617
8.41k
                }
9618
408k
            } else {
9619
408k
                put_value(pbuf, hashcode);
9620
408k
            }
9621
420k
            break;
9622
349k
        case PDF14_BEGIN_TRANS_MASK:
9623
349k
            if (pparams->subtype != TRANSPARENCY_MASK_None) {
9624
298k
                pdf14_needed = true;   /* the compositor will be needed while reading */
9625
298k
                smask_level++;
9626
298k
            }
9627
349k
            code = c_pdf14trans_write_ctm(&pbuf, pparams);
9628
349k
            if (code < 0)
9629
0
                return code;
9630
349k
            put_value(pbuf, pparams->subtype);
9631
349k
            *pbuf++ = pparams->group_color_type;
9632
349k
            put_value(pbuf, pparams->group_color_numcomps);
9633
349k
            *pbuf++ = pparams->replacing;
9634
349k
            *pbuf++ = (pparams->function_is_identity) | (deep<<1);
9635
349k
            *pbuf++ = pparams->Background_components;
9636
349k
            *pbuf++ = pparams->Matte_components;
9637
349k
            put_value(pbuf, pparams->bbox);
9638
349k
            mask_id = pparams->mask_id;
9639
349k
            put_value(pbuf, mask_id);
9640
349k
            if (pparams->Background_components) {
9641
1.36k
                const int l = sizeof(pparams->Background[0]) * pparams->Background_components;
9642
9643
1.36k
                memcpy(pbuf, pparams->Background, l);
9644
1.36k
                pbuf += l;
9645
1.36k
                memcpy(pbuf, &pparams->GrayBackground, sizeof(pparams->GrayBackground));
9646
1.36k
                pbuf += sizeof(pparams->GrayBackground);
9647
1.36k
            }
9648
349k
            if (pparams->Matte_components) {
9649
56
                const int m = sizeof(pparams->Matte[0]) * pparams->Matte_components;
9650
9651
56
                memcpy(pbuf, pparams->Matte, m);
9652
56
                pbuf += m;
9653
56
            }
9654
349k
            if (!pparams->function_is_identity)
9655
1.20k
                mask_size = (256+deep)<<deep;
9656
            /* Color space information may be ICC based
9657
               in this case we need to store the ICC
9658
               profile or the ID if it is cached already */
9659
349k
            if (pparams->group_color_type == ICC) {
9660
                /* Check if it is already in the ICC clist table */
9661
298k
                hashcode = gsicc_get_hash(pparams->iccprofile);
9662
298k
                found_icc = clist_icc_searchtable(cdev, hashcode);
9663
298k
                if (!found_icc) {
9664
                    /* Add it to the table */
9665
2.37k
                    clist_icc_addentry(cdev, hashcode, pparams->iccprofile);
9666
2.37k
                    put_value(pbuf, hashcode);
9667
295k
                } else {
9668
                    /* It will be in the clist. Just write out the hashcode */
9669
295k
                    put_value(pbuf, hashcode);
9670
295k
                }
9671
298k
            } else {
9672
51.4k
                put_value(pbuf, hashcode);
9673
51.4k
            }
9674
349k
            break;
9675
298k
        case PDF14_END_TRANS_MASK:
9676
298k
            smask_level--;
9677
298k
            if (smask_level == 0 && trans_group_level == 0)
9678
7.28k
                pdf14_needed = cdev->page_pdf14_needed;
9679
298k
            break;
9680
215k
        case PDF14_SET_BLEND_PARAMS:
9681
215k
            if (pparams->blend_mode != BLEND_MODE_Normal || pparams->opacity != 1.0 ||
9682
0
                pparams->shape != 1.0)
9683
215k
                pdf14_needed = true;    /* the compositor will be needed while reading */
9684
0
            else if (smask_level == 0 && trans_group_level == 0)
9685
0
                pdf14_needed = false;   /* At page level, set back to false */
9686
215k
            if (smask_level == 0 && trans_group_level == 0)
9687
78.5k
                cdev->page_pdf14_needed = pdf14_needed;         /* save for after popping to page level */
9688
            /* Changed is now two bytes due to overprint stroke fill. Write as int */
9689
215k
            put_value(pbuf, pparams->changed);
9690
215k
            if (pparams->changed & PDF14_SET_BLEND_MODE)
9691
35.2k
                *pbuf++ = pparams->blend_mode;
9692
215k
            if (pparams->changed & PDF14_SET_TEXT_KNOCKOUT)
9693
17.5k
                *pbuf++ = pparams->text_knockout;
9694
215k
            if (pparams->changed & PDF14_SET_AIS)
9695
215k
                put_value(pbuf, pparams->ais);
9696
215k
            if (pparams->changed & PDF14_SET_OVERPRINT)
9697
215k
                put_value(pbuf, pparams->overprint);
9698
215k
            if (pparams->changed & PDF14_SET_STROKEOVERPRINT)
9699
215k
                put_value(pbuf, pparams->stroke_overprint);
9700
215k
            if (pparams->changed & PDF14_SET_FILLCONSTANTALPHA)
9701
215k
                put_value(pbuf, pparams->fillconstantalpha);
9702
215k
            if (pparams->changed & PDF14_SET_STROKECONSTANTALPHA)
9703
215k
                put_value(pbuf, pparams->strokeconstantalpha);
9704
215k
            if (pparams->changed & PDF14_SET_FILLSTROKE_STATE)
9705
215k
                put_value(pbuf, pparams->op_fs_state);
9706
215k
            break;
9707
0
        case PDF14_PUSH_TRANS_STATE:
9708
0
            break;
9709
44.1k
        case PDF14_POP_TRANS_STATE:
9710
44.1k
            break;
9711
0
        case PDF14_PUSH_SMASK_COLOR:
9712
0
            return 0;   /* We really should never be here */
9713
0
            break;
9714
0
        case PDF14_POP_SMASK_COLOR:
9715
0
            return 0;   /* We really should never be here */
9716
0
            break;
9717
1.78M
    }
9718
9719
    /* check for fit */
9720
1.78M
    need = (pbuf - buf) + mask_size;
9721
1.78M
    *psize = need;
9722
1.78M
    if (need > avail) {
9723
276k
        if (avail)
9724
0
            return_error(gs_error_rangecheck);
9725
276k
        else
9726
276k
            return gs_error_rangecheck;
9727
276k
    }
9728
9729
    /* If we are writing more than the maximum ever expected,
9730
     * return a rangecheck error. Second check is for Coverity
9731
     */
9732
1.50M
    if ((need + 3 > MAX_CLIST_COMPOSITOR_SIZE) ||
9733
1.50M
        (need + 3 - mask_size > MAX_CLIST_TRANSPARENCY_BUFFER_SIZE) )
9734
0
        return_error(gs_error_rangecheck);
9735
9736
    /* Copy our serialized data into the output buffer */
9737
1.50M
    memcpy(data, buf, need - mask_size);
9738
1.50M
    if (mask_size)  /* Include the transfer mask data if present */
9739
918
        memcpy(data + need - mask_size, pparams->transfer_fn, mask_size);
9740
1.50M
    if_debug3m('v', cdev->memory,
9741
1.50M
               "[v] c_pdf14trans_write: opcode = %s mask_id=%d need = %d\n",
9742
1.50M
               pdf14_opcode_names[opcode], mask_id, need);
9743
1.50M
    cdev->pdf14_needed = pdf14_needed;          /* all OK to update */
9744
1.50M
    cdev->pdf14_trans_group_level = trans_group_level;
9745
1.50M
    cdev->pdf14_smask_level = smask_level;
9746
1.50M
    return 0;
9747
1.50M
}
9748
9749
#undef put_value
9750
9751
/* Function prototypes */
9752
static int gs_create_pdf14trans( gs_composite_t ** ppct,
9753
                const gs_pdf14trans_params_t * pparams,
9754
                gs_memory_t * mem );
9755
9756
#define read_value(dp, value)\
9757
125M
    BEGIN\
9758
125M
        memcpy(&value, dp, sizeof(value));\
9759
125M
        dp += sizeof(value);\
9760
125M
    END
9761
9762
/*
9763
 * Convert the string representation of the PDF 1.4 transparency parameter
9764
 * into the full compositor.
9765
 */
9766
static  int
9767
c_pdf14trans_read(gs_composite_t * * ppct, const byte * data,
9768
                                uint size, gs_memory_t * mem )
9769
37.7M
{
9770
37.7M
    gs_pdf14trans_params_t params = {0};
9771
37.7M
    const byte * start = data;
9772
37.7M
    int used, code = 0;
9773
37.7M
    bool deep;
9774
9775
37.7M
    if (size < 1)
9776
0
        return_error(gs_error_rangecheck);
9777
9778
    /* Read PDF 1.4 compositor data from the clist */
9779
37.7M
    params.pdf14_op = *data++;
9780
37.7M
    if_debug2m('v', mem, "[v] c_pdf14trans_read: opcode = %s  avail = %d",
9781
37.7M
               pdf14_opcode_names[params.pdf14_op], size);
9782
37.7M
    memset(&params.ctm, 0, sizeof(params.ctm));
9783
37.7M
    switch (params.pdf14_op) {
9784
0
        default:      /* Should not occur. */
9785
0
            break;
9786
1.59M
        case PDF14_PUSH_DEVICE:
9787
1.59M
            read_value(data, params.num_spot_colors);
9788
1.59M
            read_value(data, params.num_spot_colors_int);
9789
1.59M
            read_value(data, params.overprint_sim_push);
9790
1.59M
            read_value(data, params.is_pattern);
9791
1.59M
            break;
9792
0
        case PDF14_ABORT_DEVICE:
9793
0
            break;
9794
1.59M
        case PDF14_POP_DEVICE:
9795
1.59M
            read_value(data, params.is_pattern);
9796
1.59M
            break;
9797
2.32M
        case PDF14_END_TRANS_GROUP:
9798
2.75M
        case PDF14_END_TRANS_TEXT_GROUP:
9799
#ifdef DEBUG
9800
            code += 0; /* A good place for a breakpoint. */
9801
#endif
9802
2.75M
            break;      /* No data */
9803
0
        case PDF14_PUSH_TRANS_STATE:
9804
0
            break;
9805
3.23M
        case PDF14_POP_TRANS_STATE:
9806
3.23M
            break;
9807
618k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
9808
2.75M
        case PDF14_BEGIN_TRANS_GROUP:
9809
            /*
9810
             * We are currently not using the bbox or the colorspace so they were
9811
             * not placed in the clist
9812
             */
9813
2.75M
            data = cmd_read_matrix(&params.ctm, data);
9814
2.75M
            params.Isolated = (*data) & 1;
9815
2.75M
            params.Knockout = (*data++ >> 1) & 1;
9816
2.75M
            params.blend_mode = *data++;
9817
2.75M
            params.group_color_type = *data++;  /* Trans group color */
9818
2.75M
            params.page_group = *data++;
9819
2.75M
            read_value(data,params.group_color_numcomps);  /* color group size */
9820
2.75M
            read_value(data, params.opacity);
9821
2.75M
            read_value(data, params.shape);
9822
2.75M
            read_value(data, params.bbox);
9823
2.75M
            read_value(data, params.shade_group);
9824
2.75M
            read_value(data, params.text_group);
9825
2.75M
            read_value(data, params.mask_id);
9826
2.75M
            read_value(data, params.icc_hash);
9827
2.75M
            break;
9828
4.76M
        case PDF14_BEGIN_TRANS_MASK:
9829
                /* This is the largest transparency parameter at this time (potentially
9830
                 * 1531 bytes in size if Background_components =
9831
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and Matte_components =
9832
                 * GS_CLIENT_COLOR_MAX_COMPONENTS and we have a transfer function as well).
9833
                 *
9834
                 * NOTE:
9835
                 * The clist reader must be able to handle this sized device.
9836
                 * If any changes are made here the #define MAX_CLIST_COMPOSITOR_SIZE
9837
                 * may also need to be changed correspondingly (defined in gstparam.h)
9838
                 * Also... if another compositor param should exceed this size, this
9839
                 * same condition applies.
9840
                 */
9841
4.76M
            data = cmd_read_matrix(&params.ctm, data);
9842
4.76M
            read_value(data, params.subtype);
9843
4.76M
            params.group_color_type = *data++;
9844
4.76M
            read_value(data, params.group_color_numcomps);
9845
4.76M
            params.replacing = *data++;
9846
4.76M
            params.function_is_identity = *data & 1;
9847
4.76M
            deep = (*data++)>>1;
9848
4.76M
            params.Background_components = *data++;
9849
4.76M
            params.Matte_components = *data++;
9850
4.76M
            read_value(data, params.bbox);
9851
4.76M
            read_value(data, params.mask_id);
9852
4.76M
            if (params.Background_components) {
9853
114k
                const int l = sizeof(params.Background[0]) * params.Background_components;
9854
9855
114k
                memcpy(params.Background, data, l);
9856
114k
                data += l;
9857
114k
                memcpy(&params.GrayBackground, data, sizeof(params.GrayBackground));
9858
114k
                data += sizeof(params.GrayBackground);
9859
114k
            }
9860
4.76M
            if (params.Matte_components) {
9861
4.26k
                const int m = sizeof(params.Matte[0]) * params.Matte_components;
9862
9863
4.26k
                memcpy(params.Matte, data, m);
9864
4.26k
                data += m;
9865
4.26k
            }
9866
4.76M
            read_value(data, params.icc_hash);
9867
4.76M
            if (params.function_is_identity) {
9868
4.73M
                int i;
9869
9870
4.73M
                if (deep) {
9871
0
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++)
9872
0
                        ((uint16_t *)params.transfer_fn)[i] = i*0x10000/MASK_TRANSFER_FUNCTION_SIZE;
9873
0
                    ((uint16_t *)params.transfer_fn)[i] = 0xffff;
9874
4.73M
                } else {
9875
1.21G
                    for (i = 0; i < MASK_TRANSFER_FUNCTION_SIZE; i++) {
9876
1.21G
                        params.transfer_fn[i] = (byte)floor(i *
9877
1.21G
                            (255.0 / (MASK_TRANSFER_FUNCTION_SIZE - 1)) + 0.5);
9878
1.21G
                    }
9879
4.73M
                }
9880
4.73M
            } else {
9881
33.4k
                memcpy(params.transfer_fn, data, (256+deep)<<deep);
9882
33.4k
                data += (256+deep)<<deep;
9883
33.4k
            }
9884
4.76M
            break;
9885
491k
        case PDF14_END_TRANS_MASK:
9886
491k
            break;
9887
0
        case PDF14_PUSH_SMASK_COLOR:
9888
0
            return 0;
9889
0
            break;
9890
0
        case PDF14_POP_SMASK_COLOR:
9891
0
            return 0;
9892
0
            break;
9893
20.5M
        case PDF14_SET_BLEND_PARAMS:
9894
20.5M
            read_value(data, params.changed);
9895
20.5M
            if (params.changed & PDF14_SET_BLEND_MODE)
9896
3.44M
                params.blend_mode = *data++;
9897
20.5M
            if (params.changed & PDF14_SET_TEXT_KNOCKOUT)
9898
1.54M
                params.text_knockout = *data++;
9899
20.5M
            if (params.changed & PDF14_SET_AIS)
9900
20.5M
                read_value(data, params.ais);
9901
20.5M
            if (params.changed & PDF14_SET_OVERPRINT)
9902
20.5M
                read_value(data, params.overprint);
9903
20.5M
            if (params.changed & PDF14_SET_STROKEOVERPRINT)
9904
20.5M
                read_value(data, params.stroke_overprint);
9905
20.5M
            if (params.changed & PDF14_SET_FILLCONSTANTALPHA)
9906
20.5M
                read_value(data, params.fillconstantalpha);
9907
20.5M
            if (params.changed & PDF14_SET_STROKECONSTANTALPHA)
9908
20.5M
                read_value(data, params.strokeconstantalpha);
9909
20.5M
            if (params.changed & PDF14_SET_FILLSTROKE_STATE)
9910
20.5M
                read_value(data, params.op_fs_state);
9911
20.5M
            break;
9912
37.7M
    }
9913
37.7M
    code = gs_create_pdf14trans(ppct, &params, mem);
9914
37.7M
    if (code < 0)
9915
0
        return code;
9916
37.7M
    used = data - start;
9917
37.7M
    if_debug2m('v', mem, " mask_id=%d used = %d\n", params.mask_id, used);
9918
9919
    /* If we read more than the maximum expected, return a rangecheck error */
9920
37.7M
    if ( used + 3 > MAX_CLIST_COMPOSITOR_SIZE )
9921
0
        return_error(gs_error_rangecheck);
9922
37.7M
    else
9923
37.7M
        return used;
9924
37.7M
}
9925
9926
/*
9927
 * Adjust the compositor's CTM.
9928
 */
9929
static int
9930
c_pdf14trans_adjust_ctm(gs_composite_t * pct0, int x0, int y0, gs_gstate *pgs)
9931
22.4M
{
9932
22.4M
    gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pct0;
9933
22.4M
    gs_matrix mat = pct->params.ctm;
9934
9935
22.4M
    if_debug6m('L', pgs->memory, " [%g %g %g %g %g %g]\n",
9936
22.4M
               mat.xx, mat.xy, mat.yx, mat.yy,
9937
22.4M
               mat.tx, mat.ty);
9938
22.4M
    mat.tx -= x0;
9939
22.4M
    mat.ty -= y0;
9940
22.4M
    gs_gstate_setmatrix(pgs, &mat);
9941
22.4M
    return 0;
9942
22.4M
}
9943
9944
/*
9945
 * Create a PDF 1.4 transparency compositor.
9946
 *
9947
 * Note that this routine will be called only if the device is not already
9948
 * a PDF 1.4 transparency compositor.
9949
 * Return an error if it is not a PDF14_PUSH_DEVICE operation.
9950
 */
9951
static  int
9952
c_pdf14trans_create_default_compositor(const gs_composite_t * pct,
9953
    gx_device ** pp14dev, gx_device * tdev, gs_gstate * pgs,
9954
    gs_memory_t * mem)
9955
1.04M
{
9956
1.04M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
9957
1.04M
    int code = 0;
9958
9959
    /*
9960
     * We only handle the push operation.  All other operations are ignored.
9961
     * The other operations will be handled by the composite routine
9962
     * for the PDF 1.4 compositing device.
9963
     */
9964
1.04M
    switch (pdf14pct->params.pdf14_op) {
9965
1.02M
        case PDF14_PUSH_DEVICE:
9966
1.02M
            code = gs_pdf14_device_push(mem, pgs, pp14dev, tdev, pdf14pct);
9967
            /* Change (non-error) code to 1 to indicate that we created
9968
             * a device. */
9969
1.02M
            if (code >= 0)
9970
1.02M
                code = 1;
9971
1.02M
            break;
9972
20.1k
        default:
9973
            /* No other compositor actions are allowed if this isn't a pdf14 compositor */
9974
20.1k
            *pp14dev = NULL;
9975
20.1k
            return_error(gs_error_unregistered);
9976
1.04M
    }
9977
1.02M
    return code;
9978
1.04M
}
9979
9980
/*
9981
 * Find an opening compositor op.
9982
 */
9983
static gs_compositor_closing_state
9984
find_opening_op(int opening_op, gs_composite_t **ppcte,
9985
                gs_compositor_closing_state return_code)
9986
2.48M
{
9987
    /* Assuming a right *BEGIN* - *END* operation balance. */
9988
2.48M
    gs_composite_t *pcte = *ppcte;
9989
9990
5.89M
    for (;;) {
9991
5.89M
        if (pcte->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
9992
5.54M
            gs_pdf14trans_t *pct = (gs_pdf14trans_t *)pcte;
9993
5.54M
            int op = pct->params.pdf14_op;
9994
9995
5.54M
            *ppcte = pcte;
9996
5.54M
            if (op == opening_op)
9997
1.62M
                return return_code;
9998
3.91M
            if (op != PDF14_SET_BLEND_PARAMS) {
9999
2.48M
                if (opening_op == PDF14_BEGIN_TRANS_MASK)
10000
406
                    return COMP_ENQUEUE;
10001
2.48M
                if (opening_op == PDF14_BEGIN_TRANS_GROUP || opening_op == PDF14_BEGIN_TRANS_PAGE_GROUP) {
10002
249k
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK)
10003
228k
                        return COMP_ENQUEUE;
10004
249k
                }
10005
2.25M
                if (opening_op == PDF14_PUSH_DEVICE) {
10006
2.23M
                    if (op != PDF14_BEGIN_TRANS_MASK && op != PDF14_END_TRANS_MASK &&
10007
2.19M
                        op != PDF14_BEGIN_TRANS_GROUP && op != PDF14_BEGIN_TRANS_PAGE_GROUP && op != PDF14_END_TRANS_GROUP &&
10008
264k
                        op != PDF14_END_TRANS_TEXT_GROUP)
10009
127k
                        return COMP_ENQUEUE;
10010
2.23M
                }
10011
2.25M
            }
10012
3.91M
        } else
10013
351k
            return COMP_ENQUEUE;
10014
3.55M
        pcte = pcte->prev;
10015
3.55M
        if (pcte == NULL)
10016
144k
            return COMP_EXEC_QUEUE; /* Not in queue. */
10017
3.55M
    }
10018
2.48M
}
10019
10020
/*
10021
 * Find an opening compositor op.
10022
 */
10023
static gs_compositor_closing_state
10024
find_same_op(const gs_composite_t *composite_action, int my_op, gs_composite_t **ppcte)
10025
16.7M
{
10026
16.7M
    const gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10027
16.7M
    gs_composite_t *pct = *ppcte;
10028
10029
16.7M
    for (;;) {
10030
16.7M
        if (pct->type->comp_id == GX_COMPOSITOR_PDF14_TRANS) {
10031
14.0M
            gs_pdf14trans_t *pct_pdf14 = (gs_pdf14trans_t *)pct;
10032
10033
14.0M
            *ppcte = pct;
10034
14.0M
            if (pct_pdf14->params.pdf14_op != my_op)
10035
3.91M
                return COMP_ENQUEUE;
10036
10.1M
            if (pct_pdf14->params.csel == pct0->params.csel) {
10037
                /* If the new parameters completely replace the old ones
10038
                   then remove the old one from the queu */
10039
10.1M
                if ((pct_pdf14->params.changed & pct0->params.changed) ==
10040
10.1M
                    pct_pdf14->params.changed) {
10041
9.34M
                    return COMP_REPLACE_CURR;
10042
9.34M
                } else {
10043
786k
                    return COMP_ENQUEUE;
10044
786k
                }
10045
10.1M
            }
10046
10.1M
        } else
10047
2.71M
            return COMP_ENQUEUE;
10048
0
        pct = pct->prev;
10049
0
        if (pct == NULL)
10050
0
            return COMP_ENQUEUE; /* Not in queue. */
10051
0
    }
10052
16.7M
}
10053
10054
/*
10055
 * Check for closing compositor.
10056
 */
10057
static gs_compositor_closing_state
10058
c_pdf14trans_is_closing(const gs_composite_t * composite_action, gs_composite_t ** ppcte,
10059
                        gx_device *dev)
10060
31.7M
{
10061
31.7M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10062
31.7M
    int op0 = pct0->params.pdf14_op;
10063
10064
31.7M
    switch (op0) {
10065
0
        default: return_error(gs_error_unregistered); /* Must not happen. */
10066
1.11M
        case PDF14_PUSH_DEVICE:
10067
1.11M
            return COMP_ENQUEUE;
10068
0
        case PDF14_ABORT_DEVICE:
10069
0
            return COMP_ENQUEUE;
10070
1.11M
        case PDF14_POP_DEVICE:
10071
1.11M
            if (*ppcte == NULL)
10072
745k
                return COMP_ENQUEUE;
10073
370k
            else {
10074
370k
                gs_compositor_closing_state state = find_opening_op(PDF14_PUSH_DEVICE, ppcte, COMP_EXEC_IDLE);
10075
10076
370k
                if (state == COMP_EXEC_IDLE)
10077
92.9k
                    return COMP_DROP_QUEUE;
10078
278k
                return state;
10079
370k
            }
10080
453k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
10081
2.35M
        case PDF14_BEGIN_TRANS_GROUP:
10082
2.35M
            return COMP_ENQUEUE;
10083
1.95M
        case PDF14_END_TRANS_GROUP:
10084
2.35M
        case PDF14_END_TRANS_TEXT_GROUP:
10085
2.35M
            if (*ppcte == NULL)
10086
400k
                return COMP_EXEC_QUEUE;
10087
1.95M
            return find_opening_op(PDF14_BEGIN_TRANS_GROUP, ppcte, COMP_MARK_IDLE);
10088
3.93M
        case PDF14_BEGIN_TRANS_MASK:
10089
3.93M
            return COMP_ENQUEUE;
10090
0
        case PDF14_PUSH_TRANS_STATE:
10091
0
            return COMP_ENQUEUE;
10092
2.69M
        case PDF14_POP_TRANS_STATE:
10093
2.69M
            return COMP_ENQUEUE;
10094
0
        case PDF14_PUSH_SMASK_COLOR:
10095
0
            return COMP_ENQUEUE;
10096
0
            break;
10097
0
        case PDF14_POP_SMASK_COLOR:
10098
0
            return COMP_ENQUEUE;
10099
0
            break;
10100
417k
        case PDF14_END_TRANS_MASK:
10101
417k
            if (*ppcte == NULL)
10102
260k
                return COMP_EXEC_QUEUE;
10103
156k
            return find_opening_op(PDF14_BEGIN_TRANS_MASK, ppcte, COMP_MARK_IDLE);
10104
17.8M
        case PDF14_SET_BLEND_PARAMS:
10105
17.8M
            if (*ppcte == NULL)
10106
1.04M
                return COMP_ENQUEUE;
10107
            /* hack : ignore csel - here it is always zero : */
10108
16.7M
            return find_same_op(composite_action, PDF14_SET_BLEND_PARAMS, ppcte);
10109
31.7M
    }
10110
31.7M
}
10111
10112
/*
10113
 * Check whether a next operation is friendly to the compositor.
10114
 */
10115
static bool
10116
c_pdf14trans_is_friendly(const gs_composite_t * composite_action, byte cmd0, byte cmd1)
10117
3.58M
{
10118
3.58M
    gs_pdf14trans_t *pct0 = (gs_pdf14trans_t *)composite_action;
10119
3.58M
    int op0 = pct0->params.pdf14_op;
10120
10121
3.58M
    if (op0 == PDF14_PUSH_DEVICE || op0 == PDF14_END_TRANS_GROUP ||
10122
2.37M
        op0 == PDF14_END_TRANS_TEXT_GROUP) {
10123
        /* Halftone commands are always passed to the target printer device,
10124
           because transparency buffers are always contone.
10125
           So we're safe to execute them before queued transparency compositors. */
10126
1.22M
        if (cmd0 == cmd_opv_extend && (cmd1 == cmd_opv_ext_put_halftone ||
10127
349k
                                       cmd1 == cmd_opv_ext_put_ht_seg))
10128
572k
            return true;
10129
655k
        if (cmd0 == cmd_opv_set_misc && (cmd1 >> 6) == (cmd_set_misc_map >> 6))
10130
651k
            return true;
10131
655k
    }
10132
2.36M
    return false;
10133
3.58M
}
10134
10135
static composite_create_default_compositor_proc(c_pdf14trans_create_default_compositor);
10136
static composite_equal_proc(c_pdf14trans_equal);
10137
static composite_write_proc(c_pdf14trans_write);
10138
static composite_read_proc(c_pdf14trans_read);
10139
static composite_adjust_ctm_proc(c_pdf14trans_adjust_ctm);
10140
static composite_is_closing_proc(c_pdf14trans_is_closing);
10141
static composite_is_friendly_proc(c_pdf14trans_is_friendly);
10142
static composite_clist_write_update(c_pdf14trans_clist_write_update);
10143
static composite_clist_read_update(c_pdf14trans_clist_read_update);
10144
static composite_get_cropping_proc(c_pdf14trans_get_cropping);
10145
10146
/*
10147
 * Methods for the PDF 1.4 transparency compositor
10148
 *
10149
 * Note:  We have two set of methods.  They are the same except for the
10150
 * composite_clist_write_update method.  Once the clist write device is created,
10151
 * we use the second set of procedures.  This prevents the creation of multiple
10152
 * PDF 1.4 clist write compositor devices being chained together.
10153
 */
10154
const gs_composite_type_t   gs_composite_pdf14trans_type = {
10155
    GX_COMPOSITOR_PDF14_TRANS,
10156
    {
10157
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10158
        c_pdf14trans_equal,                      /* procs.equal */
10159
        c_pdf14trans_write,                      /* procs.write */
10160
        c_pdf14trans_read,                       /* procs.read */
10161
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10162
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10163
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10164
                /* Create a PDF 1.4 clist write device */
10165
        c_pdf14trans_clist_write_update,   /* procs.composite_clist_write_update */
10166
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10167
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10168
    }                                            /* procs */
10169
};
10170
10171
const gs_composite_type_t   gs_composite_pdf14trans_no_clist_writer_type = {
10172
    GX_COMPOSITOR_PDF14_TRANS,
10173
    {
10174
        c_pdf14trans_create_default_compositor, /* procs.create_default_compositor */
10175
        c_pdf14trans_equal,                      /* procs.equal */
10176
        c_pdf14trans_write,                      /* procs.write */
10177
        c_pdf14trans_read,                       /* procs.read */
10178
        c_pdf14trans_adjust_ctm,     /* procs.adjust_ctm */
10179
        c_pdf14trans_is_closing,                 /* procs.is_closing */
10180
        c_pdf14trans_is_friendly,                /* procs.is_friendly */
10181
                /* The PDF 1.4 clist writer already exists, Do not create it. */
10182
        gx_default_composite_clist_write_update, /* procs.composite_clist_write_update */
10183
        c_pdf14trans_clist_read_update,    /* procs.composite_clist_read_update */
10184
        c_pdf14trans_get_cropping    /* procs.composite_get_cropping */
10185
    }                                            /* procs */
10186
};
10187
10188
/*
10189
 * Verify that a compositor data structure is for the PDF 1.4 compositor.
10190
 */
10191
int
10192
gs_is_pdf14trans_compositor(const gs_composite_t * pct)
10193
257M
{
10194
257M
    return (pct->type == &gs_composite_pdf14trans_type
10195
198M
                || pct->type == &gs_composite_pdf14trans_no_clist_writer_type);
10196
257M
}
10197
10198
/*
10199
 * Create a PDF 1.4 transparency compositor data structure.
10200
 */
10201
static int
10202
gs_create_pdf14trans(
10203
    gs_composite_t **               ppct,
10204
    const gs_pdf14trans_params_t *  pparams,
10205
    gs_memory_t *                   mem )
10206
38.9M
{
10207
38.9M
    gs_pdf14trans_t *                pct;
10208
10209
38.9M
    pct = gs_alloc_struct(mem, gs_pdf14trans_t, &st_pdf14trans,
10210
38.9M
                             "gs_create_pdf14trans");
10211
38.9M
    if (pct == NULL)
10212
0
        return_error(gs_error_VMerror);
10213
38.9M
    pct->type = &gs_composite_pdf14trans_type;
10214
38.9M
    pct->id = gs_next_ids(mem, 1);
10215
38.9M
    pct->params = *pparams;
10216
38.9M
    pct->idle = false;
10217
38.9M
    *ppct = (gs_composite_t *)pct;
10218
38.9M
    return 0;
10219
38.9M
}
10220
10221
/*
10222
 * Send a PDF 1.4 transparency compositor action to the specified device.
10223
 */
10224
int
10225
send_pdf14trans(gs_gstate * pgs, gx_device * dev,
10226
    gx_device * * pcdev, gs_pdf14trans_params_t * pparams, gs_memory_t * mem)
10227
1.14M
{
10228
1.14M
    gs_composite_t * pct = NULL;
10229
1.14M
    int code;
10230
10231
1.14M
    pparams->ctm = ctm_only(pgs);
10232
1.14M
    code = gs_create_pdf14trans(&pct, pparams, mem);
10233
1.14M
    if (code < 0)
10234
0
        return code;
10235
1.14M
    code = dev_proc(dev, composite) (dev, pcdev, pct, pgs, mem, NULL);
10236
1.14M
    if (code == gs_error_handled)
10237
0
        code = 0;
10238
10239
1.14M
    gs_free_object(pgs->memory, pct, "send_pdf14trans");
10240
10241
1.14M
    return code;
10242
1.14M
}
10243
10244
/* ------------- PDF 1.4 transparency device for clist writing ------------- */
10245
10246
/*
10247
 * The PDF 1.4 transparency compositor device may have a different process
10248
 * color model than the output device.  If we are banding then we need to
10249
 * create two compositor devices.  The output side (clist reader) needs a
10250
 * compositor to actually composite the output.  We also need a compositor
10251
 * device before the clist writer.  This is needed to provide a process color
10252
 * model which matches the PDF 1.4 blending space.
10253
 *
10254
 * This section provides support for this device.
10255
 */
10256
10257
/*
10258
 * Define the default pre-clist (clist writer) PDF 1.4 compositing device.
10259
 * We actually use the same structure for both the clist writer and reader
10260
 * devices.  However we use separate names to identify the routines for each
10261
 * device.
10262
 */
10263
10264
static  dev_proc_composite(pdf14_clist_composite);
10265
static  dev_proc_composite(pdf14_clist_forward_composite);
10266
static  dev_proc_fill_path(pdf14_clist_fill_path);
10267
static  dev_proc_stroke_path(pdf14_clist_stroke_path);
10268
static  dev_proc_fill_stroke_path(pdf14_clist_fill_stroke_path);
10269
static  dev_proc_text_begin(pdf14_clist_text_begin);
10270
static  dev_proc_begin_typed_image(pdf14_clist_begin_typed_image);
10271
static  dev_proc_copy_planes(pdf14_clist_copy_planes);
10272
10273
static void
10274
pdf14_clist_init_procs(gx_device *dev,
10275
                       dev_proc_get_color_mapping_procs(get_color_mapping_procs),
10276
                       dev_proc_get_color_comp_index(get_color_comp_index))
10277
9.06k
{
10278
9.06k
    set_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix);
10279
9.06k
    set_dev_proc(dev, sync_output, gx_forward_sync_output);
10280
9.06k
    set_dev_proc(dev, output_page, gx_forward_output_page);
10281
9.06k
    set_dev_proc(dev, close_device, gx_forward_close_device);
10282
9.06k
    set_dev_proc(dev, map_rgb_color, pdf14_encode_color);
10283
9.06k
    set_dev_proc(dev, map_color_rgb, pdf14_decode_color);
10284
9.06k
    set_dev_proc(dev, fill_rectangle, gx_forward_fill_rectangle);
10285
9.06k
    set_dev_proc(dev, copy_mono, gx_forward_copy_mono);
10286
9.06k
    set_dev_proc(dev, copy_color, gx_forward_copy_color);
10287
9.06k
    set_dev_proc(dev, get_params, gx_forward_get_params);
10288
9.06k
    set_dev_proc(dev, put_params, pdf14_put_params);
10289
9.06k
    set_dev_proc(dev, map_cmyk_color, pdf14_encode_color);
10290
9.06k
    set_dev_proc(dev, get_page_device, gx_forward_get_page_device);
10291
9.06k
    set_dev_proc(dev, copy_alpha, gx_forward_copy_alpha);
10292
9.06k
    set_dev_proc(dev, fill_path, pdf14_clist_fill_path);
10293
9.06k
    set_dev_proc(dev, stroke_path, pdf14_clist_stroke_path);
10294
9.06k
    set_dev_proc(dev, fill_mask, gx_forward_fill_mask);
10295
9.06k
    set_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid);
10296
9.06k
    set_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram);
10297
9.06k
    set_dev_proc(dev, fill_triangle, gx_forward_fill_triangle);
10298
9.06k
    set_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line);
10299
9.06k
    set_dev_proc(dev, strip_tile_rectangle, gx_forward_strip_tile_rectangle);
10300
9.06k
    set_dev_proc(dev, strip_copy_rop2, gx_forward_strip_copy_rop2);
10301
9.06k
    set_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box);
10302
9.06k
    set_dev_proc(dev, begin_typed_image, pdf14_clist_begin_typed_image);
10303
9.06k
    set_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle);
10304
9.06k
    set_dev_proc(dev, composite, pdf14_clist_composite);
10305
9.06k
    set_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params);
10306
9.06k
    set_dev_proc(dev, text_begin, pdf14_clist_text_begin);
10307
9.06k
    set_dev_proc(dev, begin_transparency_group, pdf14_begin_transparency_group);
10308
9.06k
    set_dev_proc(dev, end_transparency_group, pdf14_end_transparency_group);
10309
9.06k
    set_dev_proc(dev, begin_transparency_mask, pdf14_begin_transparency_mask);
10310
9.06k
    set_dev_proc(dev, end_transparency_mask, pdf14_end_transparency_mask);
10311
9.06k
    set_dev_proc(dev, discard_transparency_layer, gx_default_discard_transparency_layer);
10312
9.06k
    set_dev_proc(dev, get_color_mapping_procs, get_color_mapping_procs);
10313
9.06k
    set_dev_proc(dev, get_color_comp_index, get_color_comp_index);
10314
9.06k
    set_dev_proc(dev, encode_color, pdf14_encode_color);
10315
9.06k
    set_dev_proc(dev, decode_color, pdf14_decode_color);
10316
9.06k
    set_dev_proc(dev, fill_rectangle_hl_color, gx_forward_fill_rectangle_hl_color);
10317
9.06k
    set_dev_proc(dev, update_spot_equivalent_colors, gx_forward_update_spot_equivalent_colors);
10318
9.06k
    set_dev_proc(dev, ret_devn_params, pdf14_ret_devn_params);
10319
9.06k
    set_dev_proc(dev, fillpage, gx_forward_fillpage);
10320
9.06k
    set_dev_proc(dev, push_transparency_state, pdf14_push_transparency_state);
10321
9.06k
    set_dev_proc(dev, pop_transparency_state, pdf14_pop_transparency_state);
10322
9.06k
    set_dev_proc(dev, dev_spec_op, pdf14_dev_spec_op);
10323
9.06k
    set_dev_proc(dev, copy_planes, pdf14_clist_copy_planes);
10324
9.06k
    set_dev_proc(dev, set_graphics_type_tag, gx_forward_set_graphics_type_tag);
10325
9.06k
    set_dev_proc(dev, copy_alpha_hl_color, gx_forward_copy_alpha_hl_color);
10326
9.06k
    set_dev_proc(dev, fill_stroke_path, pdf14_clist_fill_stroke_path);
10327
9.06k
}
10328
10329
static void
10330
pdf14_clist_Gray_initialize_device_procs(gx_device *dev)
10331
2.77k
{
10332
2.77k
    pdf14_clist_init_procs(dev,
10333
2.77k
                           gx_default_DevGray_get_color_mapping_procs,
10334
2.77k
                           gx_default_DevGray_get_color_comp_index);
10335
2.77k
}
10336
10337
static void
10338
pdf14_clist_RGB_initialize_device_procs(gx_device *dev)
10339
5.34k
{
10340
5.34k
    pdf14_clist_init_procs(dev,
10341
5.34k
                           gx_default_DevRGB_get_color_mapping_procs,
10342
5.34k
                           gx_default_DevRGB_get_color_comp_index);
10343
5.34k
}
10344
10345
static void
10346
pdf14_clist_CMYK_initialize_device_procs(gx_device *dev)
10347
13
{
10348
13
    pdf14_clist_init_procs(dev,
10349
13
                           gx_default_DevCMYK_get_color_mapping_procs,
10350
13
                           gx_default_DevCMYK_get_color_comp_index);
10351
13
}
10352
10353
static void
10354
pdf14_clist_CMYKspot_initialize_device_procs(gx_device *dev)
10355
932
{
10356
932
    pdf14_clist_init_procs(dev,
10357
932
                           pdf14_cmykspot_get_color_mapping_procs,
10358
932
                           pdf14_cmykspot_get_color_comp_index);
10359
932
}
10360
10361
static void
10362
pdf14_clist_RGBspot_initialize_device_procs(gx_device *dev)
10363
0
{
10364
0
    pdf14_clist_init_procs(dev,
10365
0
                           pdf14_rgbspot_get_color_mapping_procs,
10366
0
                           pdf14_rgbspot_get_color_comp_index);
10367
0
}
10368
10369
#if 0 /* NOT USED */
10370
static int
10371
pdf14_clist_Grayspot_initialize_device_procs(gx_device *dev)
10372
{
10373
    pdf14_clist_init_procs(dev,
10374
                           pdf14_grayspot_get_color_mapping_procs,
10375
                           pdf14_grayspot_get_color_comp_index);
10376
}
10377
#endif  /* NOT USED */
10378
10379
const pdf14_clist_device pdf14_clist_Gray_device = {
10380
    std_device_color_stype_body(pdf14_clist_device,
10381
                                pdf14_clist_Gray_initialize_device_procs,
10382
                                "pdf14clistgray",
10383
                                &st_pdf14_device,
10384
                                XSIZE, YSIZE, X_DPI, Y_DPI, 8, 255, 256),
10385
    { 0 },      /* Procs */
10386
    NULL,     /* target */
10387
    { 0 },      /* devn_params - not used */
10388
    &gray_pdf14_procs,
10389
    &gray_blending_procs
10390
};
10391
10392
const pdf14_clist_device pdf14_clist_RGB_device = {
10393
    std_device_color_stype_body(pdf14_clist_device,
10394
                                pdf14_clist_RGB_initialize_device_procs,
10395
                                "pdf14clistRGB",
10396
                                &st_pdf14_device,
10397
                                XSIZE, YSIZE, X_DPI, Y_DPI, 24, 255, 256),
10398
    { 0 },      /* Procs */
10399
    NULL,     /* target */
10400
    { 0 },      /* devn_params - not used */
10401
    &rgb_pdf14_procs,
10402
    &rgb_blending_procs
10403
};
10404
10405
const pdf14_clist_device pdf14_clist_RGBspot_device = {
10406
    std_device_part1_(pdf14_device,
10407
                      pdf14_clist_RGBspot_initialize_device_procs,
10408
                      "pdf14clistrgbspot",
10409
                      &st_pdf14_device,
10410
                      open_init_closed),
10411
    dci_values_add(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10412
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10413
    offset_margin_values(0, 0, 0, 0, 0, 0),
10414
    std_device_part3_(),
10415
    { 0 },      /* Procs */
10416
    NULL,     /* target */
10417
    /* DeviceN parameters */
10418
    { 8,      /* Not used - Bits per color */
10419
      DeviceRGBComponents,  /* Names of color model colorants */
10420
      3,      /* Number colorants for CMYK */
10421
      0,      /* MaxSeparations has not been specified */
10422
      -1,     /* PageSpotColors has not been specified */
10423
      {0},      /* SeparationNames */
10424
      0,      /* SeparationOrder names */
10425
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10426
    },
10427
    &rgbspot_pdf14_procs,
10428
    &rgb_blending_procs
10429
};
10430
10431
const pdf14_clist_device pdf14_clist_CMYK_device = {
10432
    std_device_std_color_full_body_type(pdf14_clist_device,
10433
                                        pdf14_clist_CMYK_initialize_device_procs,
10434
                                        "pdf14clistcmyk",
10435
                                        &st_pdf14_device,
10436
                                        XSIZE, YSIZE, X_DPI, Y_DPI, 32,
10437
                                        0, 0, 0, 0, 0, 0),
10438
    { 0 },      /* Procs */
10439
    NULL,     /* target */
10440
    { 0 },      /* devn_params - not used */
10441
    &cmyk_pdf14_procs,
10442
    &cmyk_blending_procs
10443
};
10444
10445
const pdf14_clist_device pdf14_clist_CMYKspot_device = {
10446
    std_device_part1_(pdf14_device,
10447
                      pdf14_clist_CMYKspot_initialize_device_procs,
10448
                      "pdf14clistcmykspot",
10449
                      &st_pdf14_device,
10450
                      open_init_closed),
10451
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10452
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10453
    offset_margin_values(0, 0, 0, 0, 0, 0),
10454
    std_device_part3_(),
10455
    { 0 },      /* Procs */
10456
    NULL,     /* target */
10457
    /* DeviceN parameters */
10458
    { 8,      /* Not used - Bits per color */
10459
      DeviceCMYKComponents, /* Names of color model colorants */
10460
      4,      /* Number colorants for CMYK */
10461
      0,      /* MaxSeparations has not been specified */
10462
      -1,     /* PageSpotColors has not been specified */
10463
      {0},      /* SeparationNames */
10464
      0,      /* SeparationOrder names */
10465
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10466
    },
10467
    &cmykspot_pdf14_procs,
10468
    &cmyk_blending_procs
10469
};
10470
10471
const pdf14_clist_device pdf14_clist_custom_device = {
10472
    std_device_part1_(pdf14_device,
10473
                      pdf14_clist_CMYKspot_initialize_device_procs,
10474
                      "pdf14clistcustom",
10475
                      &st_pdf14_device,
10476
                      open_init_closed),
10477
    dci_values(GX_DEVICE_COLOR_MAX_COMPONENTS,64,255,255,256,256),
10478
    std_device_part2_(XSIZE, YSIZE, X_DPI, Y_DPI),
10479
    offset_margin_values(0, 0, 0, 0, 0, 0),
10480
    std_device_part3_(),
10481
    { 0 },      /* Procs */
10482
    NULL,     /* target */
10483
    /* DeviceN parameters */
10484
    { 8,      /* Not used - Bits per color */
10485
      DeviceCMYKComponents, /* Names of color model colorants */
10486
      4,      /* Number colorants for CMYK */
10487
      0,      /* MaxSeparations has not been specified */
10488
      -1,     /* PageSpotColors has not been specified */
10489
      {0},      /* SeparationNames */
10490
      0,      /* SeparationOrder names */
10491
      {0, 1, 2, 3, 4, 5, 6, 7 } /* Initial component SeparationOrder */
10492
    },
10493
    &custom_pdf14_procs,
10494
    &custom_blending_procs
10495
};
10496
10497
/*
10498
 * the PDF 1.4 transparency spec says that color space for blending
10499
 * operations can be based upon either a color space specified in the
10500
 * group or a default value based upon the output device.  We are
10501
 * currently only using a color space based upon the device.
10502
 */
10503
static  int
10504
get_pdf14_clist_device_proto(gx_device          *dev,
10505
                             pdf14_clist_device *pdevproto,
10506
                             gs_gstate          *pgs,
10507
                       const gs_pdf14trans_t    *pdf14pct,
10508
                             bool                use_pdf14_accum)
10509
9.06k
{
10510
9.06k
    pdf14_blend_cs_t blend_cs_state;
10511
9.06k
    pdf14_default_colorspace_t dev_cs =
10512
9.06k
                pdf14_determine_default_blend_cs(dev, use_pdf14_accum,
10513
9.06k
                                                 &blend_cs_state);
10514
9.06k
    bool deep = device_is_deep(dev);
10515
9.06k
    int num_spots = pdf14pct->params.num_spot_colors;
10516
10517
    /* overprint overide */
10518
9.06k
    if (pdf14pct->params.overprint_sim_push &&
10519
0
        blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10520
10521
0
        if (pdf14pct->params.num_spot_colors_int > 0) {
10522
0
            dev_cs = PDF14_DeviceCMYKspot;
10523
0
            num_spots = pdf14pct->params.num_spot_colors_int;
10524
0
        } else
10525
0
            dev_cs = PDF14_DeviceCMYK;
10526
0
    }
10527
10528
9.06k
    switch (dev_cs) {
10529
2.77k
        case PDF14_DeviceGray:
10530
           /* We want gray to be single channel.  Low level
10531
               initialization of gray device prototype is
10532
               peculiar in that in dci_std_color_num_components
10533
               the comment is
10534
              "A device is monochrome only if it is bi-level"
10535
              Here we want monochrome anytime we have a gray device.
10536
              To avoid breaking things elsewhere, we will overide
10537
              the prototype intialization here */
10538
2.77k
            *pdevproto = pdf14_clist_Gray_device;
10539
2.77k
            pdevproto->color_info.max_components = 1;
10540
2.77k
            pdevproto->color_info.num_components =
10541
2.77k
                                    pdevproto->color_info.max_components;
10542
2.77k
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10543
2.77k
            pdevproto->color_info.gray_index = 0; /* Avoid halftoning */
10544
2.77k
            pdevproto->color_info.dither_grays = pdevproto->color_info.max_gray+1;
10545
2.77k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10546
2.77k
            pdevproto->color_info.depth = deep ? 16 : 8;
10547
2.77k
            pdevproto->sep_device = false;
10548
2.77k
            break;
10549
5.34k
        case PDF14_DeviceRGB:
10550
5.34k
            *pdevproto = pdf14_clist_RGB_device;
10551
5.34k
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10552
5.34k
            pdevproto->sep_device = false;
10553
5.34k
            if (deep) {
10554
0
                pdevproto->color_info.depth = 3*16;
10555
0
                pdevproto->color_info.max_color = 65535;
10556
0
                pdevproto->color_info.max_gray = 65535;
10557
0
                pdevproto->color_info.dither_colors = 65536;
10558
0
                pdevproto->color_info.dither_grays = 65536;
10559
0
            }
10560
5.34k
            break;
10561
13
        case PDF14_DeviceCMYK:
10562
13
            *pdevproto = pdf14_clist_CMYK_device;
10563
13
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10564
13
            pdevproto->sep_device = false;
10565
13
            if (deep) {
10566
0
                pdevproto->color_info.depth = 4*16;
10567
0
                pdevproto->color_info.max_color = 65535;
10568
0
                pdevproto->color_info.max_gray = 65535;
10569
0
                pdevproto->color_info.dither_colors = 65536;
10570
0
                pdevproto->color_info.dither_grays = 65536;
10571
0
            }
10572
13
            break;
10573
932
        case PDF14_DeviceCMYKspot:
10574
932
            *pdevproto = pdf14_clist_CMYKspot_device;
10575
            /*
10576
             * The number of components for the PDF14 device is the sum
10577
             * of the process components and the number of spot colors
10578
             * for the page. If we are using an NCLR ICC profile at
10579
             * the output device, those spot colors are skipped. They
10580
             * do not appear in the transparency buffer, but appear
10581
             * during put image transform of the page group to the target
10582
             * color space.
10583
             */
10584
932
            if (num_spots >= 0) {
10585
932
                pdevproto->devn_params.page_spot_colors = num_spots;
10586
932
                pdevproto->color_info.num_components =
10587
932
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10588
932
                if (pdevproto->color_info.num_components >
10589
932
                              pdevproto->color_info.max_components)
10590
0
                    pdevproto->color_info.num_components =
10591
0
                              pdevproto->color_info.max_components;
10592
932
                pdevproto->color_info.depth =
10593
932
                              pdevproto->color_info.num_components * (8<<deep);
10594
932
            }
10595
932
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10596
932
            pdevproto->sep_device = true;
10597
932
            break;
10598
0
        case PDF14_DeviceRGBspot:
10599
0
            *pdevproto = pdf14_clist_RGBspot_device;
10600
            /*
10601
             * The number of components for the PDF14 device is the sum
10602
             * of the process components and the number of spot colors
10603
             * for the page. If we are using an NCLR ICC profile at
10604
             * the output device, those spot colors are skipped. They
10605
             * do not appear in the transparency buffer, but appear
10606
             * during put image transform of the page group to the target
10607
             * color space.
10608
             */
10609
0
            if (num_spots >= 0) {
10610
0
                pdevproto->devn_params.page_spot_colors = num_spots;
10611
0
                pdevproto->color_info.num_components =
10612
0
                    pdevproto->devn_params.num_std_colorant_names + num_spots;
10613
0
                if (pdevproto->color_info.num_components >
10614
0
                    pdevproto->color_info.max_components)
10615
0
                    pdevproto->color_info.num_components =
10616
0
                        pdevproto->color_info.max_components;
10617
0
                pdevproto->color_info.depth =
10618
0
                    pdevproto->color_info.num_components * (8 << deep);
10619
0
            }
10620
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10621
0
            pdevproto->sep_device = true;
10622
0
            break;
10623
0
        case PDF14_DeviceCustom:
10624
            /*
10625
             * We are using the output device's process color model.  The
10626
             * color_info for the PDF 1.4 compositing device needs to match
10627
             * the output device.
10628
             */
10629
0
            *pdevproto = pdf14_clist_custom_device;
10630
0
            pdevproto->color_info = dev->color_info;
10631
            /* The pdf14 device has to be 8 (or 16) bit continuous tone. Force it */
10632
0
            pdevproto->color_info.depth =
10633
0
                pdevproto->color_info.num_components * (8<<deep);
10634
0
            pdevproto->color_info.max_gray = deep ? 65535 : 255;
10635
0
            pdevproto->color_info.max_color = deep ? 65535 : 255;
10636
0
            pdevproto->color_info.dither_grays = deep ? 65536 : 256;
10637
0
            pdevproto->color_info.dither_colors = deep ? 65536 : 256;
10638
0
            pdevproto->color_info.anti_alias = dev->color_info.anti_alias;
10639
0
            break;
10640
0
        default:      /* Should not occur */
10641
0
            return_error(gs_error_rangecheck);
10642
9.06k
    }
10643
9.06k
    pdevproto->overprint_sim = pdf14pct->params.overprint_sim_push;
10644
9.06k
    pdevproto->blend_cs_state = blend_cs_state;
10645
9.06k
    return 0;
10646
9.06k
}
10647
10648
static  int
10649
pdf14_create_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10650
                                gx_device ** ppdev, gx_device * target,
10651
                                const gs_pdf14trans_t * pdf14pct)
10652
9.06k
{
10653
9.06k
    pdf14_clist_device dev_proto;
10654
9.06k
    pdf14_clist_device * pdev;
10655
9.06k
    int code;
10656
9.06k
    bool has_tags = device_encodes_tags(target);
10657
9.06k
    cmm_profile_t *target_profile;
10658
9.06k
    gsicc_rendering_param_t render_cond;
10659
9.06k
    cmm_dev_profile_t *dev_profile;
10660
9.06k
    uchar k;
10661
9.06k
    bool deep = device_is_deep(target);
10662
9.06k
    cmm_profile_t *icc_profile;
10663
9.06k
    int nc;
10664
10665
9.06k
    code = dev_proc(target, get_profile)(target,  &dev_profile);
10666
9.06k
    if (code < 0)
10667
0
        return code;
10668
9.06k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &target_profile,
10669
9.06k
                          &render_cond);
10670
9.06k
    if_debug0m('v', pgs->memory, "[v]pdf14_create_clist_device\n");
10671
    /* Prototypes never include tags. We add those in later. */
10672
9.06k
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10673
9.06k
                                        pgs, pdf14pct, false);
10674
9.06k
    if (code < 0)
10675
0
        return code;
10676
9.06k
    code = gs_copydevice((gx_device **) &pdev,
10677
9.06k
                         (const gx_device *) &dev_proto, mem);
10678
9.06k
    if (code < 0)
10679
0
        return code;
10680
10681
9.06k
    nc = pdev->color_info.num_components;
10682
    /* If we are not using a blending color space, the number of color planes
10683
       should not exceed that of the target */
10684
9.06k
    if (!(pdev->blend_cs_state != PDF14_BLEND_CS_UNSPECIFIED || pdev->overprint_sim)) {
10685
9.06k
        if (nc > target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev))
10686
0
            nc = target->color_info.num_components - device_encodes_tags(target) + device_encodes_tags((gx_device *)pdev);
10687
9.06k
        if (pdev->color_info.max_components > target->color_info.max_components)
10688
1.00k
            pdev->color_info.max_components = target->color_info.max_components;
10689
9.06k
    }
10690
10691
9.06k
    pdev->color_info.num_components = nc;
10692
9.06k
    pdev->color_info.depth = pdev->color_info.num_components * (8<<deep);
10693
9.06k
    pdev->pad = target->pad;
10694
9.06k
    pdev->log2_align_mod = target->log2_align_mod;
10695
10696
9.06k
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10697
10698
9.06k
    pdev->op_state = pgs->is_fill_color ? GS_OP_STATE_FILL : GS_OP_STATE_NONE;
10699
10700
9.06k
    if (deep) {
10701
0
        set_dev_proc(pdev, encode_color, pdf14_encode_color16);
10702
0
        set_dev_proc(pdev, decode_color, pdf14_decode_color16);
10703
0
    }
10704
    /* If we have a tag device then go ahead and do a special encoder decoder
10705
       for the pdf14 device to make sure we maintain this information in the
10706
       encoded color information.  We could use the target device's methods but
10707
       the PDF14 device has to maintain 8 bit color always and we could run
10708
       into other issues if the number of colorants became large.  If we need to
10709
       do compressed color with tags that will be a special project at that time */
10710
9.06k
    if (has_tags) {
10711
0
        set_dev_proc(pdev, encode_color, deep ? pdf14_encode_color16_tag: pdf14_encode_color_tag);
10712
0
    }
10713
9.06k
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;  /* this is the standard */
10714
9.06k
    gx_device_fill_in_procs((gx_device *)pdev);
10715
    /* Copying the params adds the tags to the color_info if required. */
10716
9.06k
    gs_pdf14_device_copy_params((gx_device *)pdev, target);
10717
9.06k
    if (target->num_planar_planes > 0)
10718
1.02k
        pdev->num_planar_planes = pdev->color_info.num_components;
10719
9.06k
    gx_device_set_target((gx_device_forward *)pdev, target);
10720
10721
    /* Components shift, etc have to be based upon 8 bit */
10722
31.6k
    for (k = 0; k < pdev->color_info.num_components; k++) {
10723
22.6k
        pdev->color_info.comp_bits[k] = 8<<deep;
10724
22.6k
        pdev->color_info.comp_shift[k] = (pdev->color_info.num_components - 1 - k) * (8<<deep);
10725
22.6k
    }
10726
9.06k
    code = dev_proc((gx_device *) pdev, open_device) ((gx_device *) pdev);
10727
9.06k
    if (code < 0)
10728
0
        return code;
10729
9.06k
    pdev->pclist_device = target;
10730
10731
9.06k
    code = dev_proc(target, get_profile)(target, &dev_profile);
10732
9.06k
    if (code < 0)
10733
0
        return code;
10734
9.06k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile,
10735
9.06k
        &render_cond);
10736
9.06k
    if_debug0m('v', mem, "[v]pdf14_create_clist_device\n");
10737
10738
    /* Simulated overprint case.  We have to use CMYK-based profile
10739
       Also if the target profile is NCLR, we are going to use a pdf14
10740
       device that is CMYK based and do the mapping to the NCLR profile
10741
       when the put_image occurs */
10742
9.06k
    if ((pdev->overprint_sim && icc_profile->data_cs != gsCMYK) ||
10743
9.06k
         icc_profile->data_cs == gsNCHANNEL) {
10744
0
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_create_clist_device");
10745
0
        gsicc_adjust_profile_rc(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10746
0
            -1, "pdf14_create_clist_device");
10747
0
        pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = pgs->icc_manager->default_cmyk;
10748
9.06k
    } else {
10749
        /* If the target profile was CIELAB, then overide with default RGB for
10750
           proper blending.  During put_image we will convert from RGB to
10751
           CIELAB */
10752
9.06k
        if ((target_profile->data_cs == gsCIELAB || target_profile->islab) &&
10753
0
            pdev->blend_cs_state == PDF14_BLEND_CS_UNSPECIFIED) {
10754
0
            pdev->blend_cs_state = PDF14_BLEND_CS_TARGET_CIELAB;
10755
0
            rc_assign(pdev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
10756
0
                pgs->icc_manager->default_rgb, "pdf14_create_clist_device");
10757
0
        }
10758
9.06k
    }
10759
10760
9.06k
    if (pdf14pct->params.overprint_sim_push &&
10761
0
        pdf14pct->params.num_spot_colors_int > 0) {
10762
0
        pdev->procs.update_spot_equivalent_colors = pdf14_update_spot_equivalent_colors;
10763
0
        pdev->procs.ret_devn_params = pdf14_ret_devn_params;
10764
0
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
10765
0
        pdev->target_support_devn = pdev->icc_struct->supports_devn;
10766
0
        pdev->icc_struct->supports_devn = true;  /* Reset when pdf14 device is disabled */
10767
0
    }
10768
    /* if the device has separations already defined (by SeparationOrderNames) */
10769
    /* we need to copy them (allocating new names) so the colorants are in the */
10770
    /* same order as the target device.                                        */
10771
9.06k
    if (dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) > 0) {
10772
1.02k
        code = devn_copy_params(target, (gx_device *)pdev);
10773
1.02k
        if (code < 0)
10774
0
            return code;
10775
1.02k
    }
10776
9.06k
    pdev->my_encode_color = dev_proc(pdev, encode_color);
10777
9.06k
    pdev->my_decode_color = dev_proc(pdev, decode_color);
10778
9.06k
    pdev->my_get_color_mapping_procs = dev_proc(pdev, get_color_mapping_procs);
10779
9.06k
    pdev->my_get_color_comp_index = dev_proc(pdev, get_color_comp_index);
10780
9.06k
    pdev->color_info.separable_and_linear =
10781
9.06k
        target->color_info.separable_and_linear;
10782
9.06k
    *ppdev = (gx_device *) pdev;
10783
9.06k
    return code;
10784
9.06k
}
10785
10786
/*
10787
 * Disable the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10788
 * compositor device is never removed.  (We do not have a remove compositor
10789
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10790
 * routine implements that action.
10791
 */
10792
static  int
10793
pdf14_disable_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10794
                                gx_device * dev)
10795
9.06k
{
10796
9.06k
    gx_device_forward * pdev = (gx_device_forward *)dev;
10797
9.06k
    gx_device * target = pdev->target;
10798
10799
9.06k
    if_debug0m('v', pgs->memory, "[v]pdf14_disable_clist_device\n");
10800
10801
    /*
10802
     * To disable the action of this device, we forward all device
10803
     * procedures to the target except the composite and copy
10804
     * the target's color_info.
10805
     */
10806
9.06k
    dev->color_info = target->color_info;
10807
9.06k
    pdf14_forward_device_procs(dev);
10808
9.06k
    set_dev_proc(dev, composite, pdf14_clist_forward_composite);
10809
9.06k
    return 0;
10810
9.06k
}
10811
10812
/*
10813
 * Recreate the PDF 1.4 clist compositor device.  Once created, the PDF 1.4
10814
 * compositor device is never removed.  (We do not have a remove compositor
10815
 * method.)  However it is no-op'ed when the PDF 1.4 device is popped.  This
10816
 * routine will re-enable the compositor if the PDF 1.4 device is pushed
10817
 * again.
10818
 */
10819
static  int
10820
pdf14_recreate_clist_device(gs_memory_t *mem, gs_gstate * pgs,
10821
                gx_device * dev, const gs_pdf14trans_t * pdf14pct)
10822
0
{
10823
0
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
10824
0
    gx_device * target = pdev->target;
10825
0
    pdf14_clist_device dev_proto;
10826
0
    int code;
10827
10828
0
    if_debug0m('v', pgs->memory, "[v]pdf14_recreate_clist_device\n");
10829
    /*
10830
     * We will not use the entire prototype device but we will set the
10831
     * color related info to match the prototype.
10832
     */
10833
0
    code = get_pdf14_clist_device_proto(target, &dev_proto,
10834
0
                                        pgs, pdf14pct, false);
10835
0
    if (code < 0)
10836
0
        return code;
10837
0
    pdev->color_info = dev_proto.color_info;
10838
10839
0
    if (dev_proto.initialize_device_procs != NULL)
10840
0
        dev_proto.initialize_device_procs((gx_device *)&dev_proto);
10841
10842
0
    pdev->procs = dev_proto.procs;
10843
0
    pdev->pad = target->pad;
10844
0
    pdev->log2_align_mod = target->log2_align_mod;
10845
10846
0
    if (pdf14pct->params.overprint_sim_push && pdf14pct->params.num_spot_colors_int > 0 && target->num_planar_planes == 0)
10847
0
        pdev->num_planar_planes = pdev->color_info.num_components + pdf14pct->params.num_spot_colors_int;
10848
0
    else
10849
0
        pdev->num_planar_planes = target->num_planar_planes;
10850
0
    pdev->interpolate_threshold = dev_proc(target, dev_spec_op)(target, gxdso_interpolate_threshold, NULL, 0);
10851
10852
0
    copy_tag_setup(dev, target);
10853
10854
0
    pdev->color_info.separable_and_linear = GX_CINFO_SEP_LIN_STANDARD;
10855
0
    gx_device_fill_in_procs((gx_device *)pdev);
10856
0
    pdev->save_get_cmap_procs = pgs->get_cmap_procs;
10857
0
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
10858
0
    gx_set_cmap_procs(pgs, (gx_device *)pdev);
10859
0
    check_device_separable((gx_device *)pdev);
10860
0
    return code;
10861
0
}
10862
10863
/*
10864
 * devicen params
10865
 */
10866
gs_devn_params *
10867
pdf14_ret_devn_params(gx_device *pdev)
10868
2.11M
{
10869
2.11M
    pdf14_device *p14dev = (pdf14_device *)pdev;
10870
10871
2.11M
    return &(p14dev->devn_params);
10872
2.11M
}
10873
10874
/*
10875
 * devicen params
10876
 */
10877
gs_devn_params *
10878
pdf14_accum_ret_devn_params(gx_device *pdev)
10879
0
{
10880
0
    gx_device_pdf14_accum *p14dev = (gx_device_pdf14_accum *)pdev;
10881
10882
0
    return &(p14dev->devn_params);
10883
0
}
10884
10885
static int
10886
pdf14_accum_get_color_comp_index(gx_device * dev,
10887
    const char * pname, int name_size, int component_type)
10888
0
{
10889
0
    pdf14_device *p14dev = (pdf14_device *)(((gx_device_pdf14_accum *)dev)->save_p14dev);
10890
0
    gx_device *target = p14dev->target;
10891
0
    int colorant_number = devn_get_color_comp_index(dev,
10892
0
                &(((gx_device_pdf14_accum *)dev)->devn_params),
10893
0
                &(((gx_device_pdf14_accum *)dev)->equiv_cmyk_colors),
10894
0
                pname, name_size, component_type, ENABLE_AUTO_SPOT_COLORS);
10895
10896
0
    if (target != NULL)
10897
        /* colorant_number returned here _should_ be the same as from above */
10898
0
        colorant_number = (*dev_proc(target, get_color_comp_index))
10899
0
                              (target, (const char *)pname, name_size, component_type);
10900
0
    return colorant_number;
10901
0
}
10902
10903
/*
10904
 * The following procedures are used to map the standard color spaces into
10905
 * the separation color components for the pdf14_accum device.
10906
 */
10907
static void
10908
pdf14_accum_gray_cs_to_cmyk_cm(const gx_device * dev, frac gray, frac out[])
10909
0
{
10910
0
    int * map =
10911
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10912
10913
0
    gray_cs_to_devn_cm(dev, map, gray, out);
10914
0
}
10915
10916
static void
10917
pdf14_accum_rgb_cs_to_cmyk_cm(const gx_device * dev,
10918
    const gs_gstate *pgs, frac r, frac g, frac b, frac out[])
10919
0
{
10920
0
    int * map =
10921
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10922
10923
0
    rgb_cs_to_devn_cm(dev, map, pgs, r, g, b, out);
10924
0
}
10925
10926
static void
10927
pdf14_accum_cmyk_cs_to_cmyk_cm(const gx_device * dev,
10928
    frac c, frac m, frac y, frac k, frac out[])
10929
0
{
10930
0
    const int * map =
10931
0
      (int *)(&((gx_device_pdf14_accum *) dev)->devn_params.separation_order_map);
10932
10933
0
    cmyk_cs_to_devn_cm(dev, map, c, m, y, k, out);
10934
0
}
10935
10936
static const gx_cm_color_map_procs pdf14_accum_cm_procs = {
10937
    pdf14_accum_gray_cs_to_cmyk_cm,
10938
    pdf14_accum_rgb_cs_to_cmyk_cm,
10939
    pdf14_accum_cmyk_cs_to_cmyk_cm
10940
};
10941
10942
static const gx_cm_color_map_procs *
10943
pdf14_accum_get_color_mapping_procs(const gx_device * dev, const gx_device **map_dev)
10944
0
{
10945
0
    *map_dev = dev;
10946
0
    return &pdf14_accum_cm_procs;
10947
0
}
10948
10949
/*
10950
 *  Device proc for updating the equivalent CMYK color for spot colors.
10951
 */
10952
static int
10953
pdf14_accum_update_spot_equivalent_colors(gx_device * dev, const gs_gstate * pgs, const gs_color_space *pcs)
10954
0
{
10955
0
    gx_device_pdf14_accum *pdev = (gx_device_pdf14_accum *)dev;
10956
0
    gx_device *tdev = ((pdf14_device *)(pdev->save_p14dev))->target;
10957
0
    int code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10958
0
                                              &pdev->equiv_cmyk_colors);
10959
10960
0
    if (code >= 0 && tdev != NULL)
10961
0
        code = dev_proc(tdev, update_spot_equivalent_colors)(tdev, pgs, pcs);
10962
0
    return code;
10963
0
}
10964
10965
/* Used when doing overprint simulation and have spot colors */
10966
static int
10967
pdf14_update_spot_equivalent_colors(gx_device *dev, const gs_gstate *pgs, const gs_color_space *pcs)
10968
0
{
10969
0
    pdf14_device *pdev = (pdf14_device *)dev;
10970
0
    int code;
10971
10972
    /* Make sure we are not All or None */
10973
0
    if (pcs != NULL && pcs->type->index == gs_color_space_index_Separation &&
10974
0
        pcs->params.separation.sep_type != SEP_OTHER)
10975
0
            return 0;
10976
10977
0
    code = update_spot_equivalent_cmyk_colors(dev, pgs, pcs, &pdev->devn_params,
10978
0
        &pdev->op_pequiv_cmyk_colors);
10979
0
    return code;
10980
0
}
10981
10982
/*
10983
 * Retrieve a list of spot color names for the PDF14 device.
10984
 */
10985
int
10986
put_param_pdf14_spot_names(gx_device * pdev,
10987
                gs_separations * pseparations, gs_param_list * plist)
10988
80.0k
{
10989
80.0k
    int code, num_spot_colors, i;
10990
80.0k
    gs_param_string str;
10991
10992
    /* Check if the given keyname is present. */
10993
80.0k
    code = param_read_int(plist, PDF14NumSpotColorsParamName,
10994
80.0k
                                                &num_spot_colors);
10995
80.0k
    switch (code) {
10996
0
        default:
10997
0
            param_signal_error(plist, PDF14NumSpotColorsParamName, code);
10998
0
            break;
10999
80.0k
        case 1:
11000
80.0k
            return 0;
11001
0
        case 0:
11002
0
            if (num_spot_colors < 1 ||
11003
0
                num_spot_colors > GX_DEVICE_COLOR_MAX_COMPONENTS)
11004
0
                return_error(gs_error_rangecheck);
11005
0
            for (i = 0; i < num_spot_colors; i++) {
11006
0
                char buff[20];
11007
0
                byte * sep_name;
11008
11009
0
                gs_snprintf(buff, sizeof(buff), "PDF14SpotName_%d", i);
11010
0
                code = param_read_string(plist, buff, &str);
11011
0
                switch (code) {
11012
0
                    default:
11013
0
                        param_signal_error(plist, buff, code);
11014
0
                        break;
11015
0
                    case 0:
11016
0
                        sep_name = gs_alloc_bytes(pdev->memory,
11017
0
                                str.size, "put_param_pdf14_spot_names");
11018
0
                        if (sep_name == NULL)
11019
0
                            return_error(gs_error_VMerror);
11020
11021
0
                        memcpy(sep_name, str.data, str.size);
11022
0
                        pseparations->names[i].size = str.size;
11023
0
                        pseparations->names[i].data = sep_name;
11024
0
                }
11025
0
            }
11026
0
            pseparations->num_separations = num_spot_colors;
11027
0
            break;
11028
80.0k
    }
11029
0
    return 0;;
11030
0
}
11031
11032
/*
11033
 * This procedure will have information from the PDF 1.4 clist writing
11034
 * clist compositior device.  This is information output the compressed
11035
 * color list info which is needed for the support of spot colors in
11036
 * PDF 1.4 compositing.  This info needs to be passed to the PDF 1.4
11037
 * clist reading compositor.  However this device is not created until
11038
 * the clist is read.  To get this info to that device, we have to
11039
 * temporarily store that info in the output device.  This routine saves
11040
 * that info in the output device.
11041
 */
11042
int
11043
pdf14_put_devn_params(gx_device * pdev, gs_devn_params * pdevn_params,
11044
                                        gs_param_list * plist)
11045
80.0k
{
11046
80.0k
    int code;
11047
80.0k
    code = put_param_pdf14_spot_names(pdev,
11048
80.0k
                       &pdevn_params->pdf14_separations, plist);
11049
80.0k
    return code;
11050
80.0k
}
11051
11052
/*
11053
 * When we are banding, we have two PDF 1.4 compositor devices.  One for
11054
 * when we are creating the clist.  The second is for imaging the data from
11055
 * the clist.  This routine is part of the clist writing PDF 1.4 device.
11056
 * This routine is only called once the PDF 1.4 clist write compositor already
11057
 * exists.
11058
 */
11059
static  int
11060
pdf14_clist_composite(gx_device * dev, gx_device ** pcdev,
11061
    const gs_composite_t * pct, gs_gstate * pgs, gs_memory_t * mem,
11062
    gx_device *cdev)
11063
1.54M
{
11064
1.54M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11065
1.54M
    int code, is_pdf14_compositor;
11066
1.54M
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11067
1.54M
    bool deep = device_is_deep(dev);
11068
11069
    /* We only handle a few PDF 1.4 transparency operations */
11070
1.54M
    if ((is_pdf14_compositor = gs_is_pdf14trans_compositor(pct)) != 0) {
11071
962k
        switch (pdf14pct->params.pdf14_op) {
11072
0
            case PDF14_PUSH_DEVICE:
11073
                /* Re-activate the PDF 1.4 compositor */
11074
/*
11075
                We previously did:
11076
11077
                pdev->saved_target_color_info = pdev->target->color_info;
11078
11079
                Here, but since we already saved and modified the the color_info
11080
                of the target clist device in gs_pdf14_clist_device_push() this is
11081
                overwriting saved_target_color_info that we already saved with the
11082
                group color_info, meaning when we set it back again, it's incorrect.
11083
*/
11084
0
                pdev->target->color_info = pdev->color_info;
11085
0
                pdev->saved_target_encode_color = dev_proc(pdev->target, encode_color);
11086
0
                pdev->saved_target_decode_color = dev_proc(pdev->target, decode_color);
11087
0
                set_dev_proc(pdev->target, encode_color, pdev->my_encode_color);
11088
0
                set_dev_proc(pdev, encode_color, pdev->my_encode_color);
11089
0
                set_dev_proc(pdev->target, decode_color, pdev->my_decode_color);
11090
0
                set_dev_proc(pdev, decode_color, pdev->my_decode_color);
11091
0
                pdev->saved_target_get_color_mapping_procs =
11092
0
                                        dev_proc(pdev->target, get_color_mapping_procs);
11093
0
                pdev->saved_target_get_color_comp_index =
11094
0
                                        dev_proc(pdev->target, get_color_comp_index);
11095
0
                set_dev_proc(pdev->target, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11096
0
                set_dev_proc(pdev, get_color_mapping_procs, pdev->my_get_color_mapping_procs);
11097
0
                set_dev_proc(pdev->target, get_color_comp_index, pdev->my_get_color_comp_index);
11098
0
                set_dev_proc(pdev, get_color_comp_index, pdev->my_get_color_comp_index);
11099
0
                pdev->save_get_cmap_procs = pgs->get_cmap_procs;
11100
0
                pgs->get_cmap_procs = pdf14_get_cmap_procs;
11101
0
                gx_set_cmap_procs(pgs, dev);
11102
0
                code = pdf14_recreate_clist_device(mem, pgs, dev, pdf14pct);
11103
0
                pdev->blend_mode = pdev->text_knockout = 0;
11104
0
                pdev->opacity = pdev->shape = 0.0;
11105
0
                if (code < 0)
11106
0
                    return code;
11107
                /*
11108
                 * This routine is part of the PDF 1.4 clist write device.
11109
                 * Change the compositor procs to not create another since we
11110
                 * do not need to create a chain of identical devices.
11111
                 */
11112
0
                {
11113
0
                    gs_pdf14trans_t pctemp = *pdf14pct;
11114
11115
0
                    pctemp.type = &gs_composite_pdf14trans_no_clist_writer_type;
11116
0
                    code = dev_proc(pdev->target, composite)
11117
0
                                (pdev->target, pcdev, (gs_composite_t *)&pctemp, pgs, mem, cdev);
11118
                    /* We should never have created a new device here. */
11119
0
                    assert(code != 1);
11120
0
                    return code;
11121
0
                }
11122
9.06k
            case PDF14_POP_DEVICE:
11123
9.06k
            {
11124
9.06k
                gx_device *clistdev = pdev->target;
11125
11126
                /* Find the clist device */
11127
9.06k
                while (1) {
11128
9.06k
                    gxdso_device_child_request req;
11129
                    /* Ignore any errors here, that's expected as non-clist
11130
                     * devices don't implement it. */
11131
9.06k
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_is_clist_device, NULL, 0);
11132
9.06k
                    if (code == 1)
11133
9.06k
                        break;
11134
0
                    req.n = 0;
11135
0
                    req.target = clistdev;
11136
0
                    code = dev_proc(clistdev, dev_spec_op)(clistdev, gxdso_device_child, &req, sizeof(req));
11137
0
                    if (code < 0)
11138
0
                        return code;
11139
0
                    clistdev = req.target;
11140
0
                }
11141
11142
                /* If we have overprint simulation spot color information, store
11143
                   it in a pseudo-band of the clist */
11144
9.06k
                if (pdev->overprint_sim &&
11145
0
                    pdev->devn_params.page_spot_colors > 0) {
11146
0
                    code = clist_write_op_equiv_cmyk_colors((gx_device_clist_writer *)clistdev,
11147
0
                        &pdev->op_pequiv_cmyk_colors);
11148
0
                    if (code < 0)
11149
0
                        return code;
11150
0
                }
11151
11152
                /* If we hit an error during an SMask, we need to undo the color
11153
                 * swapping before continuing. pdf14_decrement_smask_color() checks
11154
                 * for itself if it needs to take action.
11155
                 */
11156
9.06k
                pdf14_decrement_smask_color(pgs, dev);
11157
                /* Restore the color_info for the clist device */
11158
9.06k
                clistdev->color_info = pdev->saved_target_color_info;
11159
9.06k
                ((gx_device_clist_writer*)clistdev)->clist_color_info = clistdev->color_info; /* also reset for writer */
11160
9.06k
                set_dev_proc(clistdev, encode_color, pdev->saved_target_encode_color);
11161
9.06k
                set_dev_proc(clistdev, decode_color, pdev->saved_target_decode_color);
11162
9.06k
                set_dev_proc(clistdev, get_color_mapping_procs, pdev->saved_target_get_color_mapping_procs);
11163
9.06k
                set_dev_proc(clistdev, get_color_comp_index, pdev->saved_target_get_color_comp_index);
11164
9.06k
                pgs->get_cmap_procs = pdev->save_get_cmap_procs;
11165
9.06k
                gx_set_cmap_procs(pgs, clistdev);
11166
9.06k
                gx_device_decache_colors(clistdev);
11167
                /* Disable the PDF 1.4 compositor */
11168
9.06k
                pdf14_disable_clist_device(mem, pgs, dev);
11169
                /*
11170
                 * Make sure that the transfer funtions, etc. are current.
11171
                 */
11172
9.06k
                code = cmd_put_color_mapping((gx_device_clist_writer *)clistdev, pgs);
11173
9.06k
                if (code < 0)
11174
0
                    return code;
11175
9.06k
                break;
11176
9.06k
            }
11177
9.06k
            case PDF14_BEGIN_TRANS_PAGE_GROUP:
11178
38.2k
            case PDF14_BEGIN_TRANS_GROUP:
11179
38.2k
                if (pdev->smask_constructed || pdev->depth_within_smask)
11180
17.6k
                    pdev->depth_within_smask++;
11181
38.2k
                pdev->smask_constructed = 0;
11182
                /*
11183
                 * Keep track of any changes made in the blending parameters.
11184
                   These need to be written out in the same bands as the group
11185
                   information is written.  Hence the passing of the dimensions
11186
                   for the group. */
11187
38.2k
                code = pdf14_clist_update_params(pdev, pgs, true,
11188
38.2k
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11189
38.2k
                if (code < 0)
11190
0
                    return code;
11191
38.2k
                if (pdf14pct->params.Background_components != 0 &&
11192
0
                    pdf14pct->params.Background_components !=
11193
0
                    pdev->color_info.num_components)
11194
0
                    return_error(gs_error_rangecheck);
11195
11196
                /* We need to update the clist writer device procs based upon the
11197
                   the group color space. This ensures the proper color data is
11198
                   written out to the device. For simplicity, the list item is
11199
                   created even if the color space did not change */
11200
38.2k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, false);
11201
38.2k
                if (code < 0)
11202
0
                    return code;
11203
11204
38.2k
                break;
11205
39.2k
            case PDF14_BEGIN_TRANS_MASK:
11206
                /* We need to update the clist writer device procs based upon the
11207
                   the group color space.  For simplicity, the list item is created
11208
                   even if the color space did not change */
11209
                /* First store the current ones */
11210
39.2k
                if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
11211
21.5k
                    break;
11212
11213
                /* Update the color settings of the clist writer.  Store information in stack */
11214
17.7k
                code = pdf14_clist_push_color_model(dev, cdev, pgs, pdf14pct, mem, true);
11215
17.7k
                if (code < 0)
11216
0
                    return code;
11217
11218
                /* Also, if the BC is a value that may end up as something other
11219
                  than transparent. We must use the parent colors bounding box in
11220
                  determining the range of bands in which this mask can affect.
11221
                  So, if needed change the masks bounding box at this time */
11222
17.7k
                pdev->in_smask_construction++;
11223
17.7k
                break;
11224
382k
            case PDF14_BEGIN_TRANS_TEXT_GROUP:
11225
382k
                if (pdev->text_group == PDF14_TEXTGROUP_BT_PUSHED) {
11226
13
                    emprintf(pdev->memory, "Warning: Text group pushed but no ET found\n");
11227
13
                    pdev->text_group = PDF14_TEXTGROUP_MISSING_ET;
11228
13
                } else
11229
382k
                    pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
11230
382k
                *pcdev = dev;
11231
382k
                return 0; /* Never put into clist. Only used during writing */
11232
387k
            case PDF14_END_TRANS_TEXT_GROUP:
11233
387k
                if (pdev->text_group != PDF14_TEXTGROUP_BT_PUSHED) {
11234
384k
                    *pcdev = dev;
11235
384k
                    return 0; /* Avoids spurious ET calls in interpreter */
11236
384k
                }
11237
2.18k
                pdev->text_group = PDF14_TEXTGROUP_NO_BT; /* These can't be nested */
11238
2.18k
                code = pdf14_clist_pop_color_model(dev, pgs);
11239
2.18k
                if (code < 0)
11240
0
                    return code;
11241
2.18k
                break;
11242
17.7k
            case PDF14_END_TRANS_MASK:
11243
17.7k
                pdev->in_smask_construction--;
11244
17.7k
                if (pdev->in_smask_construction < 0)
11245
0
                    pdev->in_smask_construction = 0;
11246
17.7k
                if (pdev->in_smask_construction == 0)
11247
17.6k
                    pdev->smask_constructed = 1;
11248
                /* fallthrough */
11249
53.7k
            case PDF14_END_TRANS_GROUP:
11250
                /* We need to update the clist writer device procs based upon the
11251
                   the group color space. */
11252
53.7k
                code = pdf14_clist_pop_color_model(dev, pgs);
11253
53.7k
                if (pdev->depth_within_smask)
11254
17.6k
                    pdev->depth_within_smask--;
11255
53.7k
                if (code < 0)
11256
0
                    return code;
11257
53.7k
                break;
11258
53.7k
            case PDF14_PUSH_TRANS_STATE:
11259
0
                break;
11260
17.2k
            case PDF14_POP_TRANS_STATE:
11261
17.2k
                break;
11262
17.7k
            case PDF14_PUSH_SMASK_COLOR:
11263
17.7k
                code = pdf14_increment_smask_color(pgs,dev);
11264
17.7k
                *pcdev = dev;
11265
17.7k
                return code;  /* Note, this are NOT put in the clist */
11266
0
                break;
11267
17.7k
            case PDF14_POP_SMASK_COLOR:
11268
17.7k
                code = pdf14_decrement_smask_color(pgs,dev);
11269
17.7k
                *pcdev = dev;
11270
17.7k
                return code;  /* Note, this are NOT put in the clist */
11271
0
                break;
11272
0
            case PDF14_SET_BLEND_PARAMS:
11273
                /* If there is a change we go ahead and apply it to the target */
11274
0
                code = pdf14_clist_update_params(pdev, pgs, false,
11275
0
                                                 (gs_pdf14trans_params_t *)&(pdf14pct->params));
11276
0
                *pcdev = dev;
11277
0
                return code;
11278
0
                break;
11279
0
            case PDF14_ABORT_DEVICE:
11280
0
                code = gx_abort_trans_device(pgs, dev);
11281
0
                if (pdev->free_devicen) {
11282
0
                    devn_free_params(dev);
11283
0
                }
11284
0
                pdf14_disable_device(dev);
11285
0
                pdf14_close(dev);
11286
0
                *pcdev = dev;
11287
0
                return code;
11288
0
                break;
11289
0
            default:
11290
0
                break;   /* Pass remaining ops to target */
11291
962k
        }
11292
962k
    }
11293
740k
    code = dev_proc(pdev->target, composite)
11294
740k
                        (pdev->target, pcdev, pct, pgs, mem, cdev);
11295
    /* If we were accumulating into a pdf14-clist-accum device, */
11296
    /* we now have to render the page into it's target device */
11297
740k
    if (is_pdf14_compositor && pdf14pct->params.pdf14_op == PDF14_POP_DEVICE &&
11298
9.06k
        pdev->target->stype == &st_gx_devn_accum_device) {
11299
11300
3.71k
        int i, y, rows_used;
11301
3.71k
        byte *linebuf;
11302
3.71k
        byte *actual_data;
11303
3.71k
        gx_device_pdf14_accum *tdev = (gx_device_pdf14_accum *)(pdev->target);     /* the printer class clist device used to accumulate */
11304
        /* get the target device we want to send the image to */
11305
3.71k
        gx_device *target = ((pdf14_device *)(tdev->save_p14dev))->target;
11306
3.71k
        gs_image1_t image;
11307
3.71k
        gs_color_space *pcs;
11308
3.71k
        gx_image_enum_common_t *info = NULL;
11309
3.71k
        gx_image_plane_t planes;
11310
3.71k
        gsicc_rendering_param_t render_cond;
11311
3.71k
        cmm_dev_profile_t *dev_profile;
11312
3.71k
        bool save_planar = pdev->num_planar_planes;
11313
3.71k
        gs_devn_params *target_devn_params = dev_proc(target, ret_devn_params)(target);
11314
3.71k
        int save_num_separations;
11315
3.71k
        gs_int_rect rect;
11316
11317
3.71k
        pdev->num_planar_planes = 0;    /* so gx_device_raster is for entire chunky pixel line */
11318
3.71k
        linebuf = gs_alloc_bytes(mem, gx_device_raster((gx_device *)pdev, true), "pdf14-clist_accum pop dev");
11319
3.71k
        pdev->num_planar_planes = save_planar;
11320
11321
        /* As long as we don't have spot colors, we can use ICC colorspace, but spot
11322
         * colors do require devn support
11323
         */
11324
3.71k
        if (tdev->color_info.num_components <= 4 ||
11325
3.71k
             dev_proc(target, dev_spec_op)(target, gxdso_supports_devn, NULL, 0) <= 0) {
11326
            /*
11327
             * Set color space in preparation for sending an image.
11328
             */
11329
3.71k
            code = gs_cspace_build_ICC(&pcs, NULL, pgs->memory);
11330
3.71k
            if (code < 0)
11331
0
                goto put_accum_error;
11332
11333
            /* Need to set this to avoid color management during the
11334
               image color render operation.  Exception is for the special case
11335
               when the destination was CIELAB.  Then we need to convert from
11336
               default RGB to CIELAB in the put image operation.  That will happen
11337
               here as we should have set the profile for the pdf14 device to RGB
11338
               and the target will be CIELAB */
11339
3.71k
            code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11340
3.71k
            if (code < 0)
11341
0
                goto put_accum_error;
11342
3.71k
            gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile,
11343
3.71k
                                  &(pcs->cmm_icc_profile_data), &render_cond);
11344
            /* pcs takes a reference to the profile data it just retrieved. */
11345
3.71k
            gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, 1, "pdf14_clist_composite");
11346
3.71k
            if (pcs->cmm_icc_profile_data->num_comps > ICC_MAX_CHANNELS) {
11347
0
                code = gs_note_error(gs_error_rangecheck);
11348
0
                goto put_accum_error;
11349
0
            }
11350
3.71k
            gsicc_set_icc_range(&(pcs->cmm_icc_profile_data));
11351
3.71k
        } else {
11352
             /* DeviceN case -- need to handle spot colors */
11353
0
            code = gs_cspace_new_DeviceN(&pcs, tdev->color_info.num_components,
11354
0
                                         gs_currentcolorspace(pgs), pgs->memory);
11355
0
            if (code < 0)
11356
0
                goto put_accum_error;
11357
            /* set up a usable DeviceN space with info from the tdev->devn_params */
11358
0
            pcs->params.device_n.use_alt_cspace = false;
11359
11360
0
            if ((code = pcs->type->install_cspace(pcs, pgs)) < 0) {
11361
0
                goto put_accum_error;
11362
0
            }
11363
            /* One last thing -- we need to fudge the pgs->color_component_map */
11364
0
            for (i=0; i < tdev->color_info.num_components; i++)
11365
0
                pgs->color_component_map.color_map[i] = i; /* enable all components in normal order */
11366
            /* copy devn_params that were accumulated into the target device's devn_params */
11367
0
            target_devn_params->bitspercomponent = tdev->devn_params.bitspercomponent;
11368
0
            target_devn_params->std_colorant_names = tdev->devn_params.std_colorant_names;
11369
0
            target_devn_params->num_std_colorant_names = tdev->devn_params.num_std_colorant_names;
11370
0
            target_devn_params->max_separations = tdev->devn_params.max_separations;
11371
0
            target_devn_params->page_spot_colors = tdev->devn_params.page_spot_colors;
11372
0
            target_devn_params->num_separation_order_names = tdev->devn_params.num_separation_order_names;
11373
0
            target_devn_params->separations = tdev->devn_params.separations;
11374
0
            memcpy(target_devn_params->separation_order_map, tdev->devn_params.separation_order_map,
11375
0
                   sizeof(gs_separation_map));
11376
0
            target_devn_params->pdf14_separations = tdev->devn_params.pdf14_separations;
11377
0
        }
11378
3.71k
        if (linebuf == NULL) {
11379
0
            code = gs_error_VMerror;
11380
0
            goto put_accum_error;
11381
0
        }
11382
3.71k
        gs_image_t_init_adjust(&image, pcs, false);
11383
3.71k
        image.ImageMatrix.xx = (float)pdev->width;
11384
3.71k
        image.ImageMatrix.yy = (float)pdev->height;
11385
3.71k
        image.Width = pdev->width;
11386
3.71k
        image.Height = pdev->height;
11387
3.71k
        image.BitsPerComponent = 8<<deep;
11388
3.71k
        ctm_only_writable(pgs).xx = (float)pdev->width;
11389
3.71k
        ctm_only_writable(pgs).xy = 0;
11390
3.71k
        ctm_only_writable(pgs).yx = 0;
11391
3.71k
        ctm_only_writable(pgs).yy = (float)pdev->height;
11392
3.71k
        ctm_only_writable(pgs).tx = 0.0;
11393
3.71k
        ctm_only_writable(pgs).ty = 0.0;
11394
3.71k
        code = dev_proc(target, begin_typed_image) (target,
11395
3.71k
                                                    pgs, NULL,
11396
3.71k
                                                    (gs_image_common_t *)&image,
11397
3.71k
                                                    NULL, NULL, NULL,
11398
3.71k
                                                    pgs->memory, &info);
11399
3.71k
        if (code < 0)
11400
0
            goto put_accum_error;
11401
3.71k
        rect.p.x = 0;
11402
3.71k
        rect.q.x = tdev->width;
11403
7.98M
        for (y=0; y < tdev->height; y++) {
11404
7.97M
            gs_get_bits_params_t params;
11405
11406
7.97M
            params.options = (GB_ALIGN_ANY |
11407
7.97M
                              (GB_RETURN_COPY | GB_RETURN_POINTER) |
11408
7.97M
                              GB_OFFSET_0 |
11409
7.97M
                              GB_RASTER_STANDARD | GB_PACKING_CHUNKY |
11410
7.97M
                              GB_COLORS_NATIVE | GB_ALPHA_NONE);
11411
7.97M
            params.x_offset = 0;
11412
7.97M
            params.raster = bitmap_raster(dev->width * dev->color_info.depth);
11413
7.97M
            params.data[0] = linebuf;
11414
7.97M
            rect.p.y = y;
11415
7.97M
            rect.q.y = y+1;
11416
7.97M
            code = dev_proc(tdev, get_bits_rectangle)((gx_device *)tdev,
11417
7.97M
                                                      &rect, &params);
11418
7.97M
            if (code < 0)
11419
6
                goto put_accum_error;
11420
7.97M
            actual_data = params.data[0];
11421
7.97M
            planes.data = actual_data;
11422
7.97M
            planes.data_x = 0;
11423
7.97M
            planes.raster = tdev->width * tdev->color_info.num_components;
11424
7.97M
            if ((code = info->procs->plane_data(info, &planes, 1, &rows_used)) < 0)
11425
0
                goto put_accum_error;
11426
7.97M
        }
11427
11428
3.71k
put_accum_error:
11429
3.71k
        if (info != NULL) {
11430
3.71k
            if (code < 0)
11431
6
                (void)info->procs->end_image(info, true);
11432
3.70k
            else
11433
3.70k
                code = info->procs->end_image(info, true);
11434
3.71k
        }
11435
11436
3.71k
        gs_free_object(pdev->memory, linebuf, "pdf14_put_image");
11437
        /* This will also decrement the device profile */
11438
3.71k
        rc_decrement_only_cs(pcs, "pdf14_put_image");
11439
3.71k
        dev_proc(tdev, close_device)((gx_device *)tdev);  /* frees the prn_device memory */
11440
        /* Now unhook the clist device and hook to the original so we can clean up */
11441
3.71k
        gx_device_set_target((gx_device_forward *)pdev,
11442
3.71k
                             ((gx_device_pdf14_accum *)(pdev->target))->save_p14dev);
11443
3.71k
        pdev->pclist_device = pdev->target;
11444
3.71k
        *pcdev = pdev->target;          /* pass upwards to switch devices */
11445
3.71k
        pdev->color_info = target->color_info;      /* same as in pdf14_disable_clist */
11446
3.71k
        if (target_devn_params != NULL) {
11447
            /* prevent devn_free_params from freeing names still in use by target device */
11448
0
            save_num_separations = tdev->devn_params.separations.num_separations;
11449
0
            tdev->devn_params.separations.num_separations = 0;
11450
0
        }
11451
3.71k
        gs_free_object(tdev->memory, tdev, "popdevice pdf14-accum");
11452
3.71k
        if (target_devn_params != NULL) {
11453
0
            target_devn_params->separations.num_separations = save_num_separations;
11454
0
        }
11455
3.71k
        return code;    /* DON'T perform set_target */
11456
3.71k
    }
11457
737k
    if (code == 1) {
11458
        /* We just wrapped pdev->target, so we need to update that.*/
11459
0
        gx_device_set_target((gx_device_forward *)pdev, *pcdev);
11460
0
        code = 0; /* We did not wrap dev. */
11461
0
    }
11462
737k
    *pcdev = dev;
11463
737k
    return code;
11464
740k
}
11465
11466
/*
11467
 * The PDF 1.4 clist compositor is never removed.  (We do not have a 'remove
11468
 * compositor' method.  However the compositor is disabled when we are not
11469
 * doing a page which uses PDF 1.4 transparency.  This routine is only active
11470
 * when the PDF 1.4 compositor is 'disabled'.  It checks for reenabling the
11471
 * PDF 1.4 compositor.  Otherwise it simply passes create compositor requests
11472
 * to the targer.
11473
 */
11474
static  int
11475
pdf14_clist_forward_composite(gx_device * dev, gx_device * * pcdev,
11476
        const gs_composite_t * pct, gs_gstate * pgs,
11477
        gs_memory_t * mem, gx_device *cdev)
11478
0
{
11479
0
    pdf14_device *pdev = (pdf14_device *)dev;
11480
0
    gx_device * tdev = pdev->target;
11481
0
    gx_device * ndev;
11482
0
    int code;
11483
11484
0
    *pcdev = dev;
11485
0
    if (gs_is_pdf14trans_compositor(pct)) {
11486
0
        const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pct;
11487
11488
0
        if (pdf14pct->params.pdf14_op == PDF14_PUSH_DEVICE)
11489
0
            return pdf14_clist_composite(dev, &ndev, pct, pgs, mem, cdev);
11490
0
        return 0;
11491
0
    }
11492
0
    code = dev_proc(tdev, composite)(tdev, &ndev, pct, pgs, mem, cdev);
11493
0
    if (code == 1) {
11494
        /* We just wrapped tdev, so update our target. */
11495
0
        gx_device_set_target((gx_device_forward *)pdev, ndev);
11496
0
        code = 0; /* We did not wrap dev. */
11497
0
    }
11498
0
    return code;
11499
0
}
11500
11501
/*
11502
 * If any of the PDF 1.4 transparency blending parameters have changed, we
11503
 * need to send them to the PDF 1.4 compositor on the output side of the clist.
11504
 */
11505
static  int
11506
pdf14_clist_update_params(pdf14_clist_device * pdev, const gs_gstate * pgs,
11507
                          bool crop_blend_params,
11508
                          gs_pdf14trans_params_t *group_params)
11509
3.59M
{
11510
3.59M
    gs_pdf14trans_params_t params = { 0 };
11511
3.59M
    gx_device * pcdev;
11512
3.59M
    int changed = 0;
11513
3.59M
    int code = 0;
11514
3.59M
    gs_composite_t *pct_new = NULL;
11515
11516
3.59M
    params.crop_blend_params = crop_blend_params;
11517
11518
3.59M
    params.pdf14_op = PDF14_SET_BLEND_PARAMS;
11519
3.59M
    if (pgs->blend_mode != pdev->blend_mode) {
11520
17.6k
        changed |= PDF14_SET_BLEND_MODE;
11521
17.6k
        params.blend_mode = pdev->blend_mode = pgs->blend_mode;
11522
17.6k
    }
11523
3.59M
    if (pgs->text_knockout != pdev->text_knockout) {
11524
8.75k
        changed |= PDF14_SET_TEXT_KNOCKOUT;
11525
8.75k
        params.text_knockout = pdev->text_knockout = pgs->text_knockout;
11526
8.75k
    }
11527
3.59M
    if (pgs->alphaisshape != pdev->ais) {
11528
1.79k
        changed |= PDF14_SET_AIS;
11529
1.79k
        params.ais = pdev->ais = pgs->alphaisshape;
11530
1.79k
    }
11531
3.59M
    if (pgs->overprint != pdev->overprint) {
11532
14.5k
        changed |= PDF14_SET_OVERPRINT;
11533
14.5k
        params.overprint = pdev->overprint = pgs->overprint;
11534
14.5k
    }
11535
3.59M
    if (pgs->stroke_overprint != pdev->stroke_overprint) {
11536
14.5k
        changed |= PDF14_SET_STROKEOVERPRINT;
11537
14.5k
        params.stroke_overprint = pdev->stroke_overprint = pgs->stroke_overprint;
11538
14.5k
    }
11539
3.59M
    if (pgs->fillconstantalpha != pdev->fillconstantalpha) {
11540
22.7k
        changed |= PDF14_SET_FILLCONSTANTALPHA;
11541
22.7k
        params.fillconstantalpha = pdev->fillconstantalpha = pgs->fillconstantalpha;
11542
22.7k
    }
11543
3.59M
    if (pgs->strokeconstantalpha != pdev->strokeconstantalpha) {
11544
16.4k
        changed |= PDF14_SET_STROKECONSTANTALPHA;
11545
16.4k
        params.strokeconstantalpha = pdev->strokeconstantalpha = pgs->strokeconstantalpha;
11546
16.4k
    }
11547
3.59M
    if ((pgs->is_fill_color && pdev->op_state != GS_OP_STATE_FILL)) {
11548
27.9k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11549
27.9k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_FILL;
11550
27.9k
        if_debug0m('v', pgs->memory,
11551
27.9k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_FILL \n");
11552
27.9k
    }
11553
3.59M
    if ((!pgs->is_fill_color && pdev->op_state != GS_OP_STATE_STROKE)) {
11554
28.8k
        changed |= PDF14_SET_FILLSTROKE_STATE;
11555
28.8k
        params.op_fs_state = pdev->op_state = GS_OP_STATE_STROKE;
11556
28.8k
        if_debug0m('v', pgs->memory,
11557
28.8k
            "[v]c_pdf14_clist_update_params op_fs_state written in clist as GS_OP_STATE_STROKE \n");
11558
28.8k
    }
11559
3.59M
    if (crop_blend_params) {
11560
38.2k
        params.ctm = group_params->ctm;
11561
38.2k
        params.bbox = group_params->bbox;
11562
38.2k
    }
11563
3.59M
    params.changed = changed;
11564
    /* Avoid recursion when we have a PDF14_SET_BLEND_PARAMS forced and apply
11565
       now to the target.  Otherwise we send the compositor action
11566
       to the pdf14 device at this time.  This is due to the fact that we
11567
       need to often perform this operation when we are already starting to
11568
       do a compositor action */
11569
3.59M
    if (changed != 0) {
11570
107k
        code = gs_create_pdf14trans(&pct_new, &params, pgs->memory);
11571
107k
        if (code < 0)
11572
0
            return code;
11573
107k
        code = dev_proc(pdev->target, composite)
11574
107k
                    (pdev->target, &pcdev, pct_new, (gs_gstate *)pgs, pgs->memory, NULL);
11575
107k
        gs_free_object(pgs->memory, pct_new, "pdf14_clist_update_params");
11576
107k
    }
11577
3.59M
    return code;
11578
3.59M
}
11579
11580
/*
11581
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11582
 * writing the clist.
11583
 */
11584
static  int
11585
pdf14_clist_fill_path(gx_device *dev, const gs_gstate *pgs,
11586
                           gx_path *ppath, const gx_fill_params *params,
11587
                           const gx_drawing_color *pdcolor,
11588
                           const gx_clip_path *pcpath)
11589
857k
{
11590
857k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11591
857k
    gs_gstate new_pgs = *pgs;
11592
857k
    int code;
11593
857k
    gs_pattern2_instance_t *pinst = NULL;
11594
857k
    gx_device_forward * fdev = (gx_device_forward *)dev;
11595
857k
    cmm_dev_profile_t *dev_profile, *fwd_profile;
11596
857k
    gsicc_rendering_param_t render_cond;
11597
857k
    cmm_profile_t *icc_profile_fwd, *icc_profile_dev;
11598
857k
    int push_group = 0;
11599
11600
857k
    code = dev_proc(dev, get_profile)(dev,  &dev_profile);
11601
857k
    if (code < 0)
11602
0
        return code;
11603
857k
    code = dev_proc(fdev->target, get_profile)(fdev->target,  &fwd_profile);
11604
857k
    if (code < 0)
11605
0
        return code;
11606
11607
857k
    if (dev->color_info.separable_and_linear == GX_CINFO_UNKNOWN_SEP_LIN)
11608
942
        check_device_separable(dev);
11609
11610
857k
    gsicc_extract_profile(GS_UNKNOWN_TAG, fwd_profile, &icc_profile_fwd,
11611
857k
                          &render_cond);
11612
857k
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &icc_profile_dev,
11613
857k
                          &render_cond);
11614
11615
    /*
11616
     * Ensure that that the PDF 1.4 reading compositor will have the current
11617
     * blending parameters.  This is needed since the fill_rectangle routines
11618
     * do not have access to the gs_gstate.  Thus we have to pass any
11619
     * changes explictly.
11620
     */
11621
857k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11622
857k
    if (code < 0)
11623
0
        return code;
11624
    /* If we are doing a shading fill and we are in a transparency group of a
11625
       different color space, then we do not want to do the shading in the
11626
       device color space. It must occur in the source space.  To handle it in
11627
       the device space would require knowing all the nested transparency group
11628
       color space as well as the transparency.  Some of the shading code ignores
11629
       this, so we have to pass on the clist_writer device to enable proper
11630
       mapping to the transparency group color space. */
11631
11632
857k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11633
        /* Non-idempotent blends require a transparency
11634
         * group to be pushed because shadings might
11635
         * paint several pixels twice. */
11636
11.8k
        push_group = pgs->fillconstantalpha != 1.0 ||
11637
11.2k
               !blend_is_idempotent(gs_currentblendmode(pgs));
11638
11.8k
        pinst =
11639
11.8k
            (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11640
11.8k
           pinst->saved->has_transparency = true;
11641
           /* The transparency color space operations are driven by the pdf14
11642
              clist writer device.  */
11643
11.8k
           pinst->saved->trans_device = dev;
11644
11.8k
    }
11645
857k
    if (push_group) {
11646
554
        gs_fixed_rect box;
11647
554
        gs_fixed_rect dev_bbox;
11648
11649
554
        if (pcpath) {
11650
554
            gx_cpath_outer_box(pcpath, &box);
11651
554
            (*dev_proc(dev, get_clipping_box)) (dev, &dev_bbox);
11652
554
            rect_intersect(box, dev_bbox);
11653
554
        } else
11654
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11655
11656
554
        if (ppath) {
11657
22
            gs_fixed_rect path_box;
11658
11659
22
            gx_path_bbox(ppath, &path_box);
11660
22
            if (box.p.x < path_box.p.x)
11661
22
                box.p.x = path_box.p.x;
11662
22
            if (box.p.y < path_box.p.y)
11663
22
                box.p.y = path_box.p.y;
11664
22
            if (box.q.x > path_box.q.x)
11665
22
                box.q.x = path_box.q.x;
11666
22
            if (box.q.y > path_box.q.y)
11667
22
                box.q.y = path_box.q.y;
11668
22
        }
11669
11670
554
        if (box.p.y >= box.q.y || box.p.x >= box.q.x) {
11671
            /* No need to do anything */
11672
214
            if (pinst != NULL) {
11673
214
                pinst->saved->trans_device = NULL;
11674
214
            }
11675
214
            return 0;
11676
214
        }
11677
11678
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11679
340
        code = push_shfill_group(pdev, &new_pgs, &box);
11680
340
    } else
11681
856k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11682
857k
    if (code >= 0) {
11683
857k
        new_pgs.trans_device = dev;
11684
857k
        new_pgs.has_transparency = true;
11685
857k
        if (gx_dc_is_pattern2_color(pdcolor))
11686
11.6k
            code = gx_default_fill_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11687
845k
        else
11688
845k
            code = gx_forward_fill_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11689
857k
        new_pgs.trans_device = NULL;
11690
857k
        new_pgs.has_transparency = false;
11691
857k
    }
11692
857k
    if (code >= 0 && push_group) {
11693
338
        code = pop_shfill_group(&new_pgs);
11694
338
        if (code >= 0)
11695
338
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11696
338
    }
11697
857k
    if (pinst != NULL){
11698
11.6k
        pinst->saved->trans_device = NULL;
11699
11.6k
    }
11700
857k
    return code;
11701
857k
}
11702
11703
/*
11704
 * stroke_path routine for the PDF 1.4 transparency compositor device for
11705
 * writing the clist.
11706
 */
11707
static  int
11708
pdf14_clist_stroke_path(gx_device *dev, const gs_gstate *pgs,
11709
                             gx_path *ppath, const gx_stroke_params *params,
11710
                             const gx_drawing_color *pdcolor,
11711
                             const gx_clip_path *pcpath)
11712
383k
{
11713
383k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
11714
383k
    gs_gstate new_pgs = *pgs;
11715
383k
    int code = 0;
11716
383k
    gs_pattern2_instance_t *pinst = NULL;
11717
383k
    int push_group = 0;
11718
11719
    /*
11720
     * Ensure that that the PDF 1.4 reading compositor will have the current
11721
     * blending parameters.  This is needed since the fill_rectangle routines
11722
     * do not have access to the gs_gstate.  Thus we have to pass any
11723
     * changes explictly.
11724
     */
11725
383k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11726
383k
    if (code < 0)
11727
0
        return code;
11728
    /* If we are doing a shading stroke and we are in a transparency group of a
11729
       different color space, then we need to get the proper device information
11730
       passed along so that we use the correct color procs and colorinfo about
11731
       the transparency device and not the final target device */
11732
383k
    if (gx_dc_is_pattern2_color(pdcolor)) {
11733
        /* Non-idempotent blends require a transparency
11734
         * group to be pushed because shadings might
11735
         * paint several pixels twice. */
11736
85
        push_group = pgs->strokeconstantalpha != 1.0 ||
11737
85
               !blend_is_idempotent(gs_currentblendmode(pgs));
11738
85
        if (pdev->color_model_stack != NULL) {
11739
85
            pinst =
11740
85
                (gs_pattern2_instance_t *)pdcolor->ccolor.pattern;
11741
85
            pinst->saved->has_transparency = true;
11742
            /* The transparency color space operations are driven
11743
              by the pdf14 clist writer device.  */
11744
85
            pinst->saved->trans_device = dev;
11745
85
        }
11746
85
    }
11747
383k
    if (push_group) {
11748
0
        gs_fixed_rect box;
11749
0
        if (pcpath)
11750
0
            gx_cpath_outer_box(pcpath, &box);
11751
0
        else
11752
0
            (*dev_proc(dev, get_clipping_box)) (dev, &box);
11753
0
        if (ppath) {
11754
0
            gs_fixed_rect path_box;
11755
0
            gs_fixed_point expansion;
11756
11757
0
            gx_path_bbox(ppath, &path_box);
11758
            /* Expand the path bounding box by the scaled line width. */
11759
0
            if (gx_stroke_path_expansion(pgs, ppath, &expansion) < 0) {
11760
                /* The expansion is so large it caused a limitcheck. */
11761
0
                path_box.p.x = path_box.p.y = min_fixed;
11762
0
                path_box.q.x = path_box.q.y = max_fixed;
11763
0
            } else {
11764
0
                expansion.x += pgs->fill_adjust.x;
11765
0
                expansion.y += pgs->fill_adjust.y;
11766
                /*
11767
                 * It's theoretically possible for the following computations to
11768
                 * overflow, so we need to check for this.
11769
                 */
11770
0
                path_box.p.x = (path_box.p.x < min_fixed + expansion.x ? min_fixed :
11771
0
                                path_box.p.x - expansion.x);
11772
0
                path_box.p.y = (path_box.p.y < min_fixed + expansion.y ? min_fixed :
11773
0
                                path_box.p.y - expansion.y);
11774
0
                path_box.q.x = (path_box.q.x > max_fixed - expansion.x ? max_fixed :
11775
0
                                path_box.q.x + expansion.x);
11776
0
                path_box.q.y = (path_box.q.y > max_fixed - expansion.y ? max_fixed :
11777
0
                                path_box.q.y + expansion.y);
11778
0
            }
11779
0
            if (box.p.x < path_box.p.x)
11780
0
                box.p.x = path_box.p.x;
11781
0
            if (box.p.y < path_box.p.y)
11782
0
                box.p.y = path_box.p.y;
11783
0
            if (box.q.x > path_box.q.x)
11784
0
                box.q.x = path_box.q.x;
11785
0
            if (box.q.y > path_box.q.y)
11786
0
                box.q.y = path_box.q.y;
11787
0
        }
11788
        /* Group alpha set from fill value. push_shfill_group does reset to 1.0 */
11789
0
        new_pgs.fillconstantalpha = new_pgs.strokeconstantalpha;
11790
0
        code = push_shfill_group(pdev, &new_pgs, &box);
11791
0
    } else
11792
383k
        update_lop_for_pdf14(&new_pgs, pdcolor);
11793
11794
383k
    if (code >= 0) {
11795
383k
        new_pgs.trans_device = dev;
11796
383k
        new_pgs.has_transparency = true;
11797
383k
        if (gx_dc_is_pattern2_color(pdcolor))
11798
85
            code = gx_default_stroke_path_shading_or_pattern(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11799
383k
        else
11800
383k
            code = gx_forward_stroke_path(dev, &new_pgs, ppath, params, pdcolor, pcpath);
11801
383k
        new_pgs.trans_device = NULL;
11802
383k
        new_pgs.has_transparency = false;
11803
383k
    }
11804
383k
    if (code >= 0 && push_group) {
11805
0
        code = pop_shfill_group(&new_pgs);
11806
0
        if (code >= 0)
11807
0
            code = pdf14_clist_update_params(pdev, pgs, false, NULL);
11808
0
    }
11809
383k
    if (pinst != NULL)
11810
85
        pinst->saved->trans_device = NULL;
11811
383k
    return code;
11812
383k
}
11813
11814
/* Set up work for doing shading patterns in fill stroke through
11815
   the clist.  We have to do all the dirty work now since we are
11816
   going through the default fill and stroke operations individually */
11817
static int
11818
pdf14_clist_fill_stroke_path_pattern_setup(gx_device* dev, const gs_gstate* cpgs, gx_path* ppath,
11819
    const gx_fill_params* params_fill, const gx_drawing_color* pdevc_fill,
11820
    const gx_stroke_params* params_stroke, const gx_drawing_color* pdevc_stroke,
11821
    const gx_clip_path* pcpath)
11822
0
{
11823
0
    union {
11824
0
        const gs_gstate *cpgs;
11825
0
        gs_gstate *pgs;
11826
0
    } const_breaker;
11827
0
    gs_gstate *pgs;
11828
0
    int code, code2;
11829
0
    gs_transparency_group_params_t params = { 0 };
11830
0
    gs_fixed_rect clip_bbox;
11831
0
    gs_rect bbox, group_stroke_box;
11832
0
    float fill_alpha;
11833
0
    float stroke_alpha;
11834
0
    gs_blend_mode_t blend_mode;
11835
0
    gs_fixed_rect path_bbox;
11836
0
    int expansion_code;
11837
0
    gs_fixed_point expansion;
11838
11839
    /* Break const just once, neatly */
11840
0
    const_breaker.cpgs = cpgs;
11841
0
    pgs = const_breaker.pgs;
11842
11843
0
    fill_alpha = pgs->fillconstantalpha;
11844
0
    stroke_alpha = pgs->strokeconstantalpha;
11845
0
    blend_mode = pgs->blend_mode;
11846
11847
0
    code = gx_curr_fixed_bbox(pgs, &clip_bbox, NO_PATH);
11848
0
    if (code < 0 && code != gs_error_unknownerror)
11849
0
        return code;
11850
0
    if (code == gs_error_unknownerror) {
11851
        /* didn't get clip box from gx_curr_fixed_bbox */
11852
0
        clip_bbox.p.x = clip_bbox.p.y = 0;
11853
0
        clip_bbox.q.x = int2fixed(dev->width);
11854
0
        clip_bbox.q.y = int2fixed(dev->height);
11855
0
    }
11856
0
    if (pcpath)
11857
0
        rect_intersect(clip_bbox, pcpath->outer_box);
11858
11859
    /* expand the ppath using stroke expansion rule, then intersect it */
11860
0
    code = gx_path_bbox(ppath, &path_bbox);
11861
0
    if (code == gs_error_nocurrentpoint && ppath->segments->contents.subpath_first == 0)
11862
0
        return 0;   /* ignore empty path */
11863
0
    if (code < 0)
11864
0
        return code;
11865
0
    expansion_code = gx_stroke_path_expansion(pgs, ppath, &expansion);
11866
0
    if (expansion_code >= 0) {
11867
0
        path_bbox.p.x -= expansion.x;
11868
0
        path_bbox.p.y -= expansion.y;
11869
0
        path_bbox.q.x += expansion.x;
11870
0
        path_bbox.q.y += expansion.y;
11871
0
    }
11872
0
    rect_intersect(path_bbox, clip_bbox);
11873
0
    bbox.p.x = fixed2float(path_bbox.p.x);
11874
0
    bbox.p.y = fixed2float(path_bbox.p.y);
11875
0
    bbox.q.x = fixed2float(path_bbox.q.x);
11876
0
    bbox.q.y = fixed2float(path_bbox.q.y);
11877
11878
0
    code = gs_bbox_transform_inverse(&bbox, &ctm_only(pgs), &group_stroke_box);
11879
0
    if (code < 0)
11880
0
        return code;
11881
11882
    /* See if overprint is enabled for both stroke and fill AND if ca == CA */
11883
0
    if (pgs->fillconstantalpha == pgs->strokeconstantalpha &&
11884
0
        pgs->overprint && pgs->stroke_overprint &&
11885
0
        (dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11886
0
        dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE) {
11887
11888
0
        params.Isolated = false;
11889
0
        params.group_color_type = UNKNOWN;
11890
0
        params.Knockout = false;
11891
0
        params.page_group = false;
11892
0
        params.group_opacity = fill_alpha;
11893
0
        params.group_shape = 1.0;
11894
11895
        /* non-isolated non-knockout group pushed with original alpha and blend mode */
11896
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11897
0
        if (code < 0)
11898
0
            return code;
11899
11900
        /* Set alpha to 1.0 and compatible overprint mode for actual drawings */
11901
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11902
0
        (void)gs_setstrokeconstantalpha(pgs, 1.0);
11903
0
        (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11904
11905
0
        code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11906
0
        if (code < 0)
11907
0
            goto cleanup;
11908
11909
0
        code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11910
0
        if (code < 0)
11911
0
            goto cleanup;
11912
11913
0
    } else {
11914
        /* Push a non-isolated knockout group. Do not change the alpha or
11915
           blend modes */
11916
0
        params.Isolated = false;
11917
0
        params.group_color_type = UNKNOWN;
11918
0
        params.Knockout = true;
11919
0
        params.page_group = false;
11920
0
        params.group_opacity = 1.0;
11921
0
        params.group_shape = 1.0;
11922
11923
        /* non-isolated knockout group is pushed with alpha = 1.0 and Normal blend mode */
11924
0
        (void)gs_setfillconstantalpha(pgs, 1.0);
11925
0
        (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11926
0
        code = gs_begin_transparency_group(pgs, &params, &group_stroke_box, PDF14_BEGIN_TRANS_GROUP);
11927
11928
        /* restore blend mode for actual drawing in the group */
11929
0
        (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11930
11931
0
        if (fill_alpha > 0.0) {
11932
0
            (void)gs_setfillconstantalpha(pgs, fill_alpha);
11933
11934
            /* If we are in an overprint situation, set the blend mode to compatible
11935
               overprint */
11936
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11937
0
                pgs->overprint &&
11938
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11939
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11940
11941
0
            code = pdf14_clist_fill_path(dev, pgs, ppath, params_fill, pdevc_fill, pcpath);
11942
0
            if (code < 0)
11943
0
                goto cleanup;
11944
11945
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11946
0
                pgs->overprint &&
11947
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11948
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11949
0
        }
11950
11951
0
        if (stroke_alpha > 0.0) {
11952
            /* Note that the stroke can end up looking like a fill here */
11953
0
            (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11954
0
            (void)gs_setfillconstantalpha(pgs, stroke_alpha);
11955
11956
0
            if (pgs->overprint && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11957
0
                (void)gs_setblendmode(pgs, BLEND_MODE_CompatibleOverprint); /* Can never fail */
11958
11959
0
            code = pdf14_clist_stroke_path(dev, pgs, ppath, params_stroke, pdevc_stroke, pcpath);
11960
0
            if (code < 0)
11961
0
                goto cleanup;
11962
11963
0
            if ((dev->icc_struct->overprint_control != gs_overprint_control_disable) &&
11964
0
                pgs->overprint &&
11965
0
                dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE)
11966
0
                (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11967
0
        }
11968
0
    }
11969
11970
0
cleanup:
11971
    /* Now during the pop do the compositing with alpha of 1.0 and normal blend */
11972
0
    (void)gs_setfillconstantalpha(pgs, 1.0);
11973
0
    (void)gs_setstrokeconstantalpha(pgs, 1.0);
11974
0
    (void)gs_setblendmode(pgs, BLEND_MODE_Normal); /* Can never fail */
11975
11976
    /* Restore where we were. If an error occured while in the group push
11977
       return that error code but try to do the cleanup */
11978
0
    code2 = gs_end_transparency_group(pgs);
11979
0
    if (code2 < 0) {
11980
        /* At this point things have gone very wrong. We should just shut down */
11981
0
        code = gs_abort_pdf14trans_device(pgs);
11982
0
        return code2;
11983
0
    }
11984
11985
    /* Restore if there were any changes */
11986
0
    (void)gs_setfillconstantalpha(pgs, fill_alpha);
11987
0
    (void)gs_setstrokeconstantalpha(pgs, stroke_alpha);
11988
0
    (void)gs_setblendmode(pgs, blend_mode); /* Can never fail */
11989
11990
0
    return code;
11991
0
}
11992
11993
/*
11994
 * fill_path routine for the PDF 1.4 transaprency compositor device for
11995
 * writing the clist.
11996
 */
11997
static  int
11998
pdf14_clist_fill_stroke_path(gx_device  *dev, const gs_gstate *pgs, gx_path *ppath,
11999
                             const gx_fill_params *params_fill, const gx_drawing_color *pdevc_fill,
12000
                             const gx_stroke_params *params_stroke, const gx_drawing_color *pdevc_stroke,
12001
                             const gx_clip_path *pcpath)
12002
7.65k
{
12003
7.65k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12004
7.65k
    gs_gstate new_pgs = *pgs;
12005
7.65k
    int code;
12006
12007
7.65k
    if ((pgs->fillconstantalpha == 0.0 && pgs->strokeconstantalpha == 0.0) ||
12008
7.59k
        (pgs->ctm.xx == 0.0 && pgs->ctm.xy == 0.0 && pgs->ctm.yx == 0.0 && pgs->ctm.yy == 0.0))
12009
78
        return 0;
12010
12011
    /*
12012
     * Ensure that that the PDF 1.4 reading compositor will have the current
12013
     * blending parameters.  This is needed since the fill_rectangle routines
12014
     * do not have access to the gs_gstate.  Thus we have to pass any
12015
     * changes explictly.
12016
     */
12017
7.58k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12018
7.58k
    if (code < 0)
12019
0
        return code;
12020
    /* If we are doing a shading fill or stroke, the clist can't
12021
       deal with this and end up in the pdf_fill_stroke operation.
12022
       We will need to break up the fill stroke now and do
12023
       the appropriate group pushes and set up. */
12024
12025
7.58k
    if (gx_dc_is_pattern2_color(pdevc_fill) ||
12026
7.58k
        gx_dc_is_pattern2_color(pdevc_stroke)) {
12027
0
        return pdf14_clist_fill_stroke_path_pattern_setup(dev, pgs, ppath,
12028
0
            params_fill, pdevc_fill, params_stroke, pdevc_stroke, pcpath);
12029
0
    }
12030
7.58k
    update_lop_for_pdf14(&new_pgs, pdevc_fill);
12031
7.58k
    new_pgs.trans_device = dev;
12032
7.58k
    new_pgs.has_transparency = true;
12033
7.58k
    code = gx_forward_fill_stroke_path(dev, &new_pgs, ppath, params_fill, pdevc_fill,
12034
7.58k
                                       params_stroke, pdevc_stroke, pcpath);
12035
7.58k
    new_pgs.trans_device = NULL;
12036
7.58k
    new_pgs.has_transparency = false;
12037
7.58k
    return code;
12038
7.58k
}
12039
12040
/*
12041
 * text_begin routine for the PDF 1.4 transaprency compositor device for
12042
 * writing the clist.
12043
 */
12044
static  int
12045
pdf14_clist_text_begin(gx_device * dev, gs_gstate * pgs,
12046
                 const gs_text_params_t * text, gs_font * font,
12047
                 const gx_clip_path * pcpath,
12048
                 gs_text_enum_t ** ppenum)
12049
2.25M
{
12050
2.25M
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12051
2.25M
    gs_text_enum_t *penum;
12052
2.25M
    int code;
12053
2.25M
    gs_blend_mode_t blend_mode = gs_currentblendmode(pgs);
12054
2.25M
    float opacity = pgs->fillconstantalpha;
12055
2.25M
    float shape = 1.0;
12056
2.25M
    bool blend_issue = !(blend_mode == BLEND_MODE_Normal || blend_mode == BLEND_MODE_Compatible || blend_mode == BLEND_MODE_CompatibleOverprint);
12057
2.25M
    bool draw = !(text->operation & TEXT_DO_NONE);
12058
2.25M
    uint text_mode = gs_currenttextrenderingmode(pgs);
12059
2.25M
    bool text_stroke = (text_mode == 1 || text_mode == 2 || text_mode == 5 || text_mode == 6);
12060
2.25M
    bool text_fill = (text_mode == 0 || text_mode == 2 || text_mode == 4 || text_mode == 6);
12061
12062
2.25M
    if_debug0m('v', pgs->memory, "[v]pdf14_clist_text_begin\n");
12063
    /*
12064
     * Ensure that that the PDF 1.4 reading compositor will have the current
12065
     * blending parameters.  This is needed since the fill_rectangle routines
12066
     * do not have access to the gs_gstate.  Thus we have to pass any
12067
     * changes explictly.
12068
     */
12069
2.25M
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12070
2.25M
    if (code < 0)
12071
0
        return code;
12072
    /* Pass text_begin to the target */
12073
2.25M
    code = gx_forward_text_begin(dev, pgs, text, font,
12074
2.25M
                                 pcpath, &penum);
12075
2.25M
    if (code < 0)
12076
748
        return code;
12077
12078
   /* Catch case where we already pushed a group and are trying to push another one.
12079
   In that case, we will pop the current one first, as we don't want to be left
12080
   with it. Note that if we have a BT and no other BTs or ETs then this issue
12081
   will not be caught until we do the put_image and notice that the stack is not
12082
   empty. */
12083
2.25M
    if (pdev->text_group == PDF14_TEXTGROUP_MISSING_ET) {
12084
0
        code = gs_end_transparency_group(pgs);
12085
0
        if (code < 0)
12086
0
            return code;
12087
0
        pdev->text_group = PDF14_TEXTGROUP_BT_NOT_PUSHED;
12088
0
    }
12089
12090
    /* We may need to push a non-isolated transparency group if the following
12091
    is true.
12092
    1) We are not currently in one that we pushed for text.  This is
12093
    is determined by looking at the pdf14 device.
12094
    2) The blend mode is not Normal or the opacity is not 1.0
12095
    3) Text knockout is set to true
12096
    4) And we are actually drawing text
12097
    */
12098
12099
2.25M
    if (gs_currenttextknockout(pgs) && (blend_issue ||
12100
2.25M
        (pgs->fillconstantalpha != 1.0 && text_fill) ||
12101
2.24M
        (pgs->strokeconstantalpha != 1.0 && text_stroke)) &&
12102
10.0k
        text_mode != 3 && /* don't bother with invisible text */
12103
10.0k
        pdev->text_group == PDF14_TEXTGROUP_BT_NOT_PUSHED) {
12104
2.21k
        if (draw) {
12105
2.21k
            code = pdf14_push_text_group(dev, pgs, blend_mode, opacity, shape, true);
12106
2.21k
            if (code == 0)
12107
2.21k
                pdev->text_group = PDF14_TEXTGROUP_BT_PUSHED;  /* Needed during clist writing */
12108
2.21k
        }
12109
2.21k
    }
12110
2.25M
    *ppenum = (gs_text_enum_t *)penum;
12111
2.25M
    return code;
12112
2.25M
}
12113
12114
static  int
12115
pdf14_clist_begin_typed_image(gx_device * dev, const gs_gstate * pgs,
12116
                           const gs_matrix *pmat, const gs_image_common_t *pic,
12117
                           const gs_int_rect * prect,
12118
                           const gx_drawing_color * pdcolor,
12119
                           const gx_clip_path * pcpath, gs_memory_t * mem,
12120
                           gx_image_enum_common_t ** pinfo)
12121
39.4k
{
12122
39.4k
    pdf14_clist_device * pdev = (pdf14_clist_device *)dev;
12123
39.4k
    int code;
12124
39.4k
    gs_gstate * pgs_noconst = (gs_gstate *)pgs; /* Break 'const'. */
12125
39.4k
    const gs_image_t *pim = (const gs_image_t *)pic;
12126
39.4k
    gx_image_enum *penum;
12127
39.4k
    gx_color_tile *ptile;
12128
39.4k
    gs_rect bbox_in, bbox_out;
12129
39.4k
    gs_transparency_group_params_t tgp;
12130
    /*
12131
     * Ensure that that the PDF 1.4 reading compositor will have the current
12132
     * blending parameters.  This is needed since the fill_rectangle routines
12133
     * do not have access to the gs_gstate.  Thus we have to pass any
12134
     * changes explictly.
12135
     */
12136
39.4k
    code = pdf14_clist_update_params(pdev, pgs, false, NULL);
12137
39.4k
    if (code < 0)
12138
0
        return code;
12139
    /* Pass image to the target */
12140
    /* Do a quick change to the gs_gstate so that if we can return with -1 in
12141
       case the clist writer cannot handle this image itself.  In such a case,
12142
       we want to make sure we dont use the target device.  I don't necc. like
12143
       doing it this way.  Probably need to go back and do something a bit
12144
       more elegant. */
12145
39.4k
    pgs_noconst->has_transparency = true;
12146
39.4k
    pgs_noconst->trans_device = dev;
12147
12148
    /* If we are filling an image mask with a pattern that has a transparency
12149
       then we need to do some special handling */
12150
39.4k
    if (pim->ImageMask) {
12151
73
        if (pdcolor != NULL && gx_dc_is_pattern1_color(pdcolor)) {
12152
21
            if( gx_pattern1_get_transptr(pdcolor) != NULL){
12153
0
                if (dev_proc(dev, begin_typed_image) != pdf14_clist_begin_typed_image) {
12154
0
                    ptile = pdcolor->colors.pattern.p_tile;
12155
                    /* Set up things in the ptile so that we get the proper
12156
                       blending etc */
12157
                    /* Set the blending procs and the is_additive setting based
12158
                       upon the number of channels */
12159
0
                    if (ptile->ttrans->n_chan-1 < 4) {
12160
0
                        ptile->ttrans->blending_procs = &rgb_blending_procs;
12161
0
                        ptile->ttrans->is_additive = true;
12162
0
                    } else {
12163
0
                        ptile->ttrans->blending_procs = &cmyk_blending_procs;
12164
0
                        ptile->ttrans->is_additive = false;
12165
0
                    }
12166
                    /* Set the blending mode in the ptile based upon the current
12167
                       setting in the gs_gstate */
12168
0
                    ptile->blending_mode = pgs->blend_mode;
12169
                    /* Set the procs so that we use the proper filling method. */
12170
                    /* Let the imaging stuff get set up */
12171
0
                    code = gx_default_begin_typed_image(dev, pgs, pmat, pic,
12172
0
                                                        prect, pdcolor,
12173
0
                                                        pcpath, mem, pinfo);
12174
0
                    if (code < 0)
12175
0
                        return code;
12176
12177
0
                    penum = (gx_image_enum *) *pinfo;
12178
                    /* Apply inverse of the image matrix to our
12179
                       image size to get our bounding box. */
12180
0
                    bbox_in.p.x = 0;
12181
0
                    bbox_in.p.y = 0;
12182
0
                    bbox_in.q.x = pim->Width;
12183
0
                    bbox_in.q.y = pim->Height;
12184
0
                    code = gs_bbox_transform_inverse(&bbox_in, &(pim->ImageMatrix),
12185
0
                                                     &bbox_out);
12186
0
                    if (code < 0)
12187
0
                        return code;
12188
                    /* Set up a compositor action for pushing the group */
12189
0
                    if_debug0m('v', pgs->memory, "[v]Pushing special trans group for image\n");
12190
0
                    tgp.Isolated = true;
12191
0
                    tgp.Knockout = false;
12192
0
                    tgp.page_group = false;
12193
0
                    tgp.mask_id = 0;
12194
0
                    tgp.image_with_SMask = false;
12195
0
                    tgp.idle = false;
12196
0
                    tgp.iccprofile = NULL;
12197
0
                    tgp.icc_hashcode = 0;
12198
0
                    tgp.group_color_numcomps = ptile->ttrans->n_chan-1;
12199
0
                    tgp.ColorSpace = NULL;
12200
0
                    tgp.text_group = 0;
12201
0
                    tgp.group_opacity = pgs->fillconstantalpha;
12202
0
                    tgp.group_shape = 1.0;
12203
                    /* This will handle the compositor command */
12204
0
                    gs_begin_transparency_group((gs_gstate *) pgs_noconst, &tgp,
12205
0
                                                &bbox_out, PDF14_BEGIN_TRANS_GROUP);
12206
0
                    ptile->ttrans->image_render = penum->render;
12207
0
                    penum->render = &pdf14_pattern_trans_render;
12208
0
                    ptile->trans_group_popped = false;
12209
0
                    pgs_noconst->has_transparency = false;
12210
0
                    pgs_noconst->trans_device = NULL;
12211
0
                    return code;
12212
0
                }
12213
0
            }
12214
21
        }
12215
73
    }
12216
    /* This basically tries high level images for clist. If that fails
12217
       then we do the default */
12218
39.4k
    code = gx_forward_begin_typed_image(dev, pgs, pmat,
12219
39.4k
                            pic, prect, pdcolor, pcpath, mem, pinfo);
12220
39.4k
    if (code < 0){
12221
10.1k
        code = gx_default_begin_typed_image(dev, pgs, pmat, pic, prect,
12222
10.1k
                                        pdcolor, pcpath, mem, pinfo);
12223
10.1k
        pgs_noconst->has_transparency = false;
12224
10.1k
        pgs_noconst->trans_device = NULL;
12225
10.1k
        return code;
12226
29.2k
    } else {
12227
29.2k
        pgs_noconst->has_transparency = false;
12228
29.2k
        pgs_noconst->trans_device = NULL;
12229
29.2k
        return code;
12230
29.2k
    }
12231
39.4k
}
12232
12233
static int
12234
pdf14_clist_copy_planes(gx_device * dev, const byte * data, int data_x, int raster,
12235
                  gx_bitmap_id id, int x, int y, int w, int h, int plane_height)
12236
2.45k
{
12237
2.45k
    int code;
12238
12239
2.45k
    code = gx_forward_copy_planes(dev, data, data_x, raster, id,
12240
2.45k
                                  x, y, w, h, plane_height);
12241
2.45k
    return code;
12242
2.45k
}
12243
12244
static int
12245
gs_pdf14_clist_device_push(gs_memory_t *mem, gs_gstate *pgs, gx_device **pcdev,
12246
                           gx_device *dev, const gs_pdf14trans_t *pdf14pct)
12247
9.06k
{
12248
9.06k
    int code;
12249
9.06k
    pdf14_clist_device *p14dev;
12250
9.06k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12251
12252
9.06k
    code = pdf14_create_clist_device(mem, pgs, pcdev, dev, pdf14pct);
12253
9.06k
    if (code < 0)
12254
0
        return code;
12255
    /*
12256
     * Set the color_info of the clist device to match the compositing
12257
     * device.  We will restore it when the compositor is popped.
12258
     * See pdf14_clist_composite for the restore.  Do the
12259
     * same with the gs_gstate's get_cmap_procs.  We do not want
12260
     * the gs_gstate to use transfer functions on our color values.
12261
     * The transfer functions will be applied at the end after we
12262
     * have done our PDF 1.4 blend operations.
12263
     */
12264
9.06k
    p14dev = (pdf14_clist_device *)(*pcdev);
12265
9.06k
    p14dev->saved_target_color_info = dev->color_info;
12266
9.06k
    dev->color_info = (*pcdev)->color_info;
12267
    /* Make sure that we keep the anti-alias information though */
12268
9.06k
    dev->color_info.anti_alias = p14dev->saved_target_color_info.anti_alias;
12269
9.06k
    p14dev->color_info.anti_alias = dev->color_info.anti_alias;
12270
12271
    /* adjust the clist_color_info now */
12272
9.06k
    cdev->clist_color_info.depth = p14dev->color_info.depth;
12273
9.06k
    cdev->clist_color_info.polarity = p14dev->color_info.polarity;
12274
9.06k
    cdev->clist_color_info.num_components = p14dev->color_info.num_components;
12275
9.06k
    cdev->clist_color_info.max_color = p14dev->color_info.max_color;
12276
9.06k
    cdev->clist_color_info.max_gray = p14dev->color_info.max_gray;
12277
12278
9.06k
    p14dev->saved_target_encode_color = dev_proc(dev, encode_color);
12279
9.06k
    p14dev->saved_target_decode_color = dev_proc(dev, decode_color);
12280
9.06k
    set_dev_proc(dev, encode_color, p14dev->my_encode_color);
12281
9.06k
    set_dev_proc(p14dev, encode_color, p14dev->my_encode_color);
12282
9.06k
    set_dev_proc(dev, decode_color, p14dev->my_decode_color);
12283
9.06k
    set_dev_proc(p14dev, decode_color, p14dev->my_decode_color);
12284
9.06k
    p14dev->saved_target_get_color_mapping_procs =
12285
9.06k
                              dev_proc(dev, get_color_mapping_procs);
12286
9.06k
    p14dev->saved_target_get_color_comp_index =
12287
9.06k
                              dev_proc(dev, get_color_comp_index);
12288
9.06k
    set_dev_proc(dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12289
9.06k
    set_dev_proc(p14dev, get_color_mapping_procs, p14dev->my_get_color_mapping_procs);
12290
9.06k
    set_dev_proc(dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12291
9.06k
    set_dev_proc(p14dev, get_color_comp_index, p14dev->my_get_color_comp_index);
12292
9.06k
    p14dev->save_get_cmap_procs = pgs->get_cmap_procs;
12293
9.06k
    pgs->get_cmap_procs = pdf14_get_cmap_procs;
12294
9.06k
    gx_set_cmap_procs(pgs, dev);
12295
9.06k
    return code;
12296
9.06k
}
12297
/*
12298
 * When we push a PDF 1.4 transparency compositor onto the clist, we also need
12299
 * to create a compositing device for clist writing.  The primary purpose of
12300
 * this device is to provide support for the process color model in which
12301
 * the PDF 1.4 transparency is done.  (This may differ from the process color
12302
 * model of the output device.)  The actual work of compositing the image is
12303
 * done on the output (reader) side of the clist.
12304
 */
12305
static  int
12306
c_pdf14trans_clist_write_update(const gs_composite_t * pcte, gx_device * dev,
12307
                gx_device ** pcdev, gs_gstate * pgs, gs_memory_t * mem)
12308
276k
{
12309
276k
    gx_device_clist_writer * const cdev = &((gx_device_clist *)dev)->writer;
12310
276k
    const gs_pdf14trans_t * pdf14pct = (const gs_pdf14trans_t *) pcte;
12311
276k
    int code = 0;
12312
12313
    /* We only handle the push/pop operations */
12314
276k
    switch (pdf14pct->params.pdf14_op) {
12315
9.06k
        case PDF14_PUSH_DEVICE:
12316
9.06k
            code = gs_pdf14_clist_device_push(mem, pgs, pcdev, dev, pdf14pct);
12317
            /* Change (non-error) code to 1 to indicate that we created
12318
             * a device. */
12319
9.06k
            if (code >= 0)
12320
9.06k
                code = 1;
12321
9.06k
            return code;
12322
12323
9.06k
        case PDF14_POP_DEVICE:
12324
9.06k
            code = clist_writer_check_empty_cropping_stack(cdev);
12325
9.06k
            break;
12326
12327
3.40k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12328
38.2k
        case PDF14_BEGIN_TRANS_GROUP:
12329
38.2k
            { /* HACK: store mask_id into our params for subsequent
12330
                   calls of c_pdf14trans_write. To do this we must
12331
                   break const. */
12332
38.2k
                gs_pdf14trans_t * pdf14pct_noconst;
12333
12334
38.2k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12335
                /* What ever the current mask ID is, that is the
12336
                   softmask group through which this transparency
12337
                   group must be rendered. Store it now. */
12338
38.2k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12339
38.2k
                if_debug1m('v', pgs->memory,
12340
38.2k
                           "[v]c_pdf14trans_clist_write_update group mask_id=%d \n",
12341
38.2k
                           cdev->mask_id);
12342
38.2k
            }
12343
38.2k
            break;
12344
36.0k
        case PDF14_END_TRANS_GROUP:
12345
38.2k
        case PDF14_END_TRANS_TEXT_GROUP:
12346
38.2k
            code = 0; /* A place for breakpoint. */
12347
38.2k
            break;
12348
39.2k
        case PDF14_BEGIN_TRANS_MASK:
12349
            /* A new mask has been started */
12350
39.2k
            cdev->mask_id = ++cdev->mask_id_count;
12351
            /* replacing is set everytime that we
12352
               have a zpushtransparencymaskgroup */
12353
39.2k
            { /* HACK: store mask_id into our params for subsequent
12354
                   calls of c_pdf14trans_write. To do this we must
12355
                   break const. */
12356
39.2k
                gs_pdf14trans_t * pdf14pct_noconst;
12357
12358
39.2k
                pdf14pct_noconst = (gs_pdf14trans_t *) pcte;
12359
39.2k
                pdf14pct_noconst->params.mask_id = cdev->mask_id;
12360
39.2k
                if_debug1m('v', pgs->memory,
12361
39.2k
                           "[v]c_pdf14trans_clist_write_update mask mask_id=%d \n",
12362
39.2k
                           cdev->mask_id);
12363
39.2k
            }
12364
39.2k
            break;
12365
17.7k
        case PDF14_END_TRANS_MASK:
12366
17.7k
            code = 0; /* A place for breakpoint. */
12367
17.7k
            break;
12368
0
        case PDF14_PUSH_TRANS_STATE:
12369
0
            code = 0; /* A place for breakpoint. */
12370
0
            break;
12371
17.2k
        case PDF14_POP_TRANS_STATE:
12372
17.2k
            code = 0; /* A place for breakpoint. */
12373
17.2k
            break;
12374
0
        case PDF14_ABORT_DEVICE:
12375
0
            code = 0;
12376
0
            break;
12377
0
        case PDF14_PUSH_SMASK_COLOR:
12378
0
            *pcdev = dev;
12379
0
            return 0;
12380
0
            break;
12381
0
        case PDF14_POP_SMASK_COLOR:
12382
0
            *pcdev = dev;
12383
0
            return 0;
12384
0
            break;
12385
107k
        default:
12386
107k
            break;   /* do nothing for remaining ops */
12387
276k
    }
12388
267k
    *pcdev = dev;
12389
267k
    if (code < 0)
12390
0
        return code;
12391
    /* See c_pdf14trans_write, c_pdf14trans_adjust_ctm, and
12392
       apply_composite. */
12393
267k
    code = gs_gstate_setmatrix(&cdev->gs_gstate, &pdf14pct->params.ctm);
12394
    /* Wrote an extra ctm. */
12395
267k
    cmd_clear_known(cdev, ctm_known);
12396
12397
267k
    return code;
12398
267k
}
12399
12400
/*
12401
 * When we push a PDF 1.4 transparency compositor, we need to make the clist
12402
 * device color_info data match the compositing device.  We need to do this
12403
 * since the PDF 1.4 transparency compositing device may use a different
12404
 * process color model than the output device.  We do not need to modify the
12405
 * color related device procs since the compositing device has its own.  We
12406
 * restore the color_info data when the transparency device is popped.
12407
 */
12408
static  int
12409
c_pdf14trans_clist_read_update(gs_composite_t * pcte, gx_device * cdev,
12410
                gx_device * tdev, gs_gstate * pgs, gs_memory_t * mem)
12411
21.9M
{
12412
21.9M
    pdf14_device * p14dev = (pdf14_device *)tdev;
12413
21.9M
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12414
21.9M
    gs_devn_params * pclist_devn_params;
12415
21.9M
    gx_device_clist_reader *pcrdev = (gx_device_clist_reader *)cdev;
12416
21.9M
    cmm_profile_t *cl_icc_profile, *p14_icc_profile;
12417
21.9M
    gsicc_rendering_param_t render_cond;
12418
21.9M
    cmm_dev_profile_t *dev_profile;
12419
12420
21.9M
    dev_proc(cdev, get_profile)(cdev,  &dev_profile);
12421
21.9M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &cl_icc_profile,
12422
21.9M
                          &render_cond);
12423
12424
    /* If we are using the blending color space, then be sure to use that. */
12425
21.9M
    if (p14dev->blend_cs_state == PDF14_BLEND_CS_SPECIFIED &&
12426
0
        dev_profile->blend_profile != NULL)
12427
0
        cl_icc_profile = dev_profile->blend_profile;
12428
21.9M
    else if (p14dev->blend_cs_state == PDF14_BLEND_CS_OUTPUTINTENT &&
12429
0
        dev_profile->oi_profile != NULL)
12430
0
        cl_icc_profile = dev_profile->oi_profile;
12431
12432
21.9M
    dev_proc(p14dev, get_profile)((gx_device *)p14dev,  &dev_profile);
12433
21.9M
    gsicc_extract_profile(GS_UNKNOWN_TAG, dev_profile, &p14_icc_profile,
12434
21.9M
                          &render_cond);
12435
    /*
12436
     * We only handle the push/pop operations. Save and restore the color_info
12437
     * field for the clist device.  This is needed since the process color
12438
     * model of the clist device needs to match the PDF 1.4 compositing
12439
     * device.
12440
     */
12441
21.9M
    switch (pdf14pct->params.pdf14_op) {
12442
1.02M
    case PDF14_PUSH_DEVICE:
12443
        /* Overprint simulation sets the profile at prototype creation, as does
12444
           when the target profile is NCLR. Match the logic in gs_pdf14_device_push */
12445
1.02M
        if (!((p14dev->overprint_sim && cl_icc_profile->data_cs != gsCMYK) ||
12446
1.02M
            cl_icc_profile->data_cs == gsNCHANNEL)) {
12447
1.02M
            gsicc_adjust_profile_rc(cl_icc_profile, 1, "c_pdf14trans_clist_read_update");
12448
1.02M
            gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12449
1.02M
                -1, "c_pdf14trans_clist_read_update");
12450
1.02M
            p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] = cl_icc_profile;
12451
1.02M
        }
12452
            /*
12453
             * If we are blending using spot colors (i.e. the output device
12454
             * supports spot colors) then we need to transfer
12455
             * color info from the clist PDF 1.4 compositing reader device
12456
             * to the clist writer PDF 1.4 compositing device.
12457
             * This info was transfered from that device to the output
12458
             * device as a set of device parameters.  However the clist
12459
             * reader PDF 1.4 compositing device did not exist when the
12460
             * device parameters were read from the clist.  So that info
12461
             * was buffered into the output device.
12462
             */
12463
1.02M
            pclist_devn_params = dev_proc(cdev, ret_devn_params)(cdev);
12464
1.02M
            if (pclist_devn_params != NULL && pclist_devn_params->page_spot_colors > 0) {
12465
541
                int num_comp = p14dev->color_info.num_components;
12466
541
                int has_tags = device_encodes_tags((gx_device *)p14dev);
12467
                /*
12468
                 * The number of components for the PDF14 device is the sum
12469
                 * of the process components and the number of spot colors
12470
                 * for the page.  If the color capabilities of the parent
12471
                 * device (which coming into this are the same as the p14dev)
12472
                 * are smaller than the number of page spot colors then
12473
                 * use that for the number of components. Otherwise use
12474
                 * the page_spot_colors.  The exception is, if we had used
12475
                 * the sICCOutputColors setting, then just use that, which
12476
                 * should be already baked into num_comp. With clist patterns,
12477
                 * cdev->icc_struct may be null.
12478
                 */
12479
12480
541
                if (cdev->icc_struct == NULL || cdev->icc_struct->spotnames == NULL) {
12481
541
                    p14dev->devn_params.page_spot_colors =
12482
541
                        pclist_devn_params->page_spot_colors;
12483
541
                    if (num_comp < p14dev->devn_params.page_spot_colors + 4 ) {
12484
0
                        if (p14dev->num_planar_planes > 0)
12485
0
                            p14dev->num_planar_planes += num_comp - p14dev->color_info.num_components;
12486
0
                        p14dev->color_info.num_components = num_comp;
12487
0
                        assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12488
541
                    } else {
12489
                        /* if page_spot_colors < 0, this will be wrong, so don't update num_components */
12490
541
                        if (p14dev->devn_params.page_spot_colors >= 0) {
12491
541
                            int n = p14dev->num_std_colorants +
12492
541
                                    p14dev->devn_params.page_spot_colors + has_tags;
12493
541
                            if (p14dev->num_planar_planes > 0)
12494
541
                                p14dev->num_planar_planes += n - p14dev->color_info.num_components;
12495
541
                            p14dev->color_info.num_components = n;
12496
541
                            assert(p14dev->num_planar_planes == 0 || p14dev->num_planar_planes == p14dev->color_info.num_components);
12497
541
                        }
12498
541
                    }
12499
541
                }
12500
                /* limit the num_components to the max. */
12501
541
                if (p14dev->color_info.num_components > p14dev->color_info.max_components + has_tags)
12502
0
                    p14dev->color_info.num_components = p14dev->color_info.max_components + has_tags;
12503
                /* Transfer the data for the spot color names
12504
                   But we have to free what may be there before we do this */
12505
541
                devn_free_params((gx_device*) p14dev);
12506
541
                p14dev->devn_params.separations =
12507
541
                    pclist_devn_params->pdf14_separations;
12508
541
                p14dev->free_devicen = false;  /* to avoid freeing the clist ones */
12509
541
                if (num_comp != p14dev->color_info.num_components) {
12510
                    /* Historically, there has been a comment here:
12511
                       "When the pdf14 device is opened it creates a context and some
12512
                       soft mask related objects.  The push device compositor action
12513
                       will have already created these but they are the wrong size.
12514
                       We must destroy them though before reopening the device."
12515
                       I can't see why this is the case, and testing in the cluster
12516
                       doesn't show ill effects from not doing it. Indeed, Bug 707790
12517
                       shows that this freeing/NULLing the ctx here causes problems
12518
                       when the freed ctx is reinserted at the end of clist pattern
12519
                       files. Accordingly, I'm removing the freeing/NULLing for now
12520
                       at least. */
12521
0
                    int code = dev_proc(tdev, open_device) (tdev);
12522
0
                    if (code < 0)
12523
0
                        return code;
12524
0
                }
12525
541
            }
12526
            /* Check if we need to swap out the ICC profile for the pdf14
12527
               device.  This will occur if our source profile for our device
12528
               happens to be something like CIELAB.  Then we will blend in
12529
               RGB (unless a trans group is specified) */
12530
1.02M
            if (cl_icc_profile->data_cs == gsCIELAB || cl_icc_profile->islab) {
12531
0
                gsicc_adjust_profile_rc(p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE],
12532
0
                                        -1, "c_pdf14trans_clist_read_update");
12533
                /* Initial ref count from gsicc_read_serial_icc() is 1, which is what we want */
12534
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE] =
12535
0
                                        gsicc_read_serial_icc(cdev, pcrdev->trans_dev_icc_hash);
12536
                /* Keep a pointer to the clist device */
12537
0
                p14dev->icc_struct->device_profile[GS_DEFAULT_DEVICE_PROFILE]->dev = (gx_device *) cdev;
12538
0
            }
12539
1.02M
            break;
12540
12541
1.02M
        case PDF14_POP_DEVICE:
12542
#     if 0 /* Disabled because *p14dev has no forwarding methods during
12543
                    the clist playback. This code is not executed while clist
12544
                    writing. */
12545
            cdev->color_info = p14dev->saved_target_color_info;
12546
#     endif
12547
1.02M
           break;
12548
12549
19.8M
        default:
12550
19.8M
            break;   /* do nothing for remaining ops */
12551
21.9M
    }
12552
12553
21.9M
    return 0;
12554
21.9M
}
12555
12556
/*
12557
 * Get cropping for the compositor command.
12558
 */
12559
static  int
12560
c_pdf14trans_get_cropping(const gs_composite_t *pcte, int *ry, int *rheight,
12561
                          int cropping_min, int cropping_max)
12562
276k
{
12563
276k
    gs_pdf14trans_t * pdf14pct = (gs_pdf14trans_t *) pcte;
12564
276k
    switch (pdf14pct->params.pdf14_op) {
12565
9.06k
        case PDF14_PUSH_DEVICE: return ALLBANDS; /* Applies to all bands. */
12566
9.06k
        case PDF14_POP_DEVICE:  return ALLBANDS; /* Applies to all bands. */
12567
0
        case PDF14_ABORT_DEVICE: return ALLBANDS; /* Applies to all bands */
12568
3.40k
        case PDF14_BEGIN_TRANS_PAGE_GROUP:
12569
38.2k
        case PDF14_BEGIN_TRANS_GROUP:
12570
38.2k
            { gs_int_rect rect;
12571
12572
                /* Text group always uses parents size*/
12573
38.2k
                if (pdf14pct->params.text_group == PDF14_TEXTGROUP_BT_PUSHED) {
12574
2.21k
                    *ry = cropping_min;
12575
2.21k
                    *rheight = cropping_max - *ry;
12576
36.0k
                } else {
12577
36.0k
                    pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12578
36.0k
                        &pdf14pct->params.bbox, &rect);
12579
                    /* We have to crop this by the parent object.   */
12580
36.0k
                    *ry = max(rect.p.y, cropping_min);
12581
36.0k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12582
36.0k
                }
12583
38.2k
                return PUSHCROP; /* Push cropping. */
12584
3.40k
            }
12585
39.2k
        case PDF14_BEGIN_TRANS_MASK:
12586
39.2k
            { gs_int_rect rect;
12587
12588
39.2k
                pdf14_compute_group_device_int_rect(&pdf14pct->params.ctm,
12589
39.2k
                                                    &pdf14pct->params.bbox, &rect);
12590
                /* We have to crop this by the parent object and worry about the BC outside
12591
                   the range, except for image SMask which don't affect areas outside the image.
12592
                   The presence of a transfer function opens the possibility of issues with this */
12593
39.2k
                if (pdf14pct->params.mask_is_image || (pdf14pct->params.GrayBackground == 1.0 &&
12594
16.4k
                      pdf14pct->params.function_is_identity)) {
12595
                    /* In this case there will not be a background effect to
12596
                       worry about.  The mask will not have any effect outside
12597
                       the bounding box.  This is NOT the default or common case. */
12598
16.4k
                    *ry = max(rect.p.y, cropping_min);
12599
16.4k
                    *rheight = min(rect.q.y, cropping_max) - *ry;
12600
16.4k
                    return PUSHCROP; /* Push cropping. */
12601
22.8k
                }  else {
12602
                    /* We need to make the soft mask range as large as the parent
12603
                       due to the fact that the background color can have an impact
12604
                       OUTSIDE the bounding box of the soft mask */
12605
22.8k
                    *ry = cropping_min;
12606
22.8k
                    *rheight = cropping_max - cropping_min;
12607
22.8k
                    if (pdf14pct->params.subtype == TRANSPARENCY_MASK_None)
12608
21.5k
                        return SAMEAS_PUSHCROP_BUTNOPUSH;
12609
1.26k
                    else
12610
1.26k
                        return PUSHCROP; /* Push cropping. */
12611
22.8k
                }
12612
39.2k
            }
12613
36.0k
        case PDF14_END_TRANS_GROUP: return POPCROP; /* Pop cropping. */
12614
2.18k
        case PDF14_END_TRANS_TEXT_GROUP: return POPCROP; /* Pop cropping. */
12615
17.7k
        case PDF14_END_TRANS_MASK: return POPCROP;   /* Pop the cropping */
12616
0
        case PDF14_PUSH_TRANS_STATE: return CURRBANDS;
12617
17.2k
        case PDF14_POP_TRANS_STATE: return CURRBANDS;
12618
107k
        case PDF14_SET_BLEND_PARAMS: return ALLBANDS;
12619
0
        case PDF14_PUSH_SMASK_COLOR: return POPCROP; /* Pop cropping. */
12620
0
        case PDF14_POP_SMASK_COLOR: return POPCROP;   /* Pop the cropping */
12621
0
        case PDF14_BEGIN_TRANS_TEXT_GROUP: return ALLBANDS; /* should never occur */
12622
276k
    }
12623
0
    return ALLBANDS;
12624
276k
}
12625
12626
/*
12627
 * This routine will check to see if the color component name matches those
12628
 * that are available amoung the current device's color components.  If the
12629
 * color name is known to the output device then we add it to the list of
12630
 * colorants for the PDF 1.4 transparency compositor.
12631
 *
12632
 * Notes:  There are currently three different versions of The PDF 1.4
12633
 * transparency compositor device.  The choice of which one is being used
12634
 * depends upon the process color model of the output device.  This procedure
12635
 * is only used if the output (target) device uses a CMYK, or RGB or Gray
12636
 * plus spot color process color model.
12637
 *
12638
 * Parameters:
12639
 *   dev - pointer to device data structure.
12640
 *   pname - pointer to name (zero termination not required)
12641
 *   nlength - length of the name
12642
 *   number of process colorants (either 1, 3, or 4)
12643
 *
12644
 * This routine returns a positive value (0 to n) which is the device colorant
12645
 * number if the name is found.  It returns GX_DEVICE_COLOR_MAX_COMPONENTS if
12646
 * the colorant is not being used due to a SeparationOrder device parameter.
12647
 * It returns a negative value if not found.
12648
 */
12649
static int
12650
pdf14_spot_get_color_comp_index(gx_device *dev, const char *pname,
12651
    int name_size, int component_type, int num_process_colors, int cmyk)
12652
6.72k
{
12653
6.72k
    pdf14_device *pdev = (pdf14_device *)dev;
12654
6.72k
    gx_device *tdev = pdev->target;
12655
6.72k
    gs_devn_params *pdevn_params = &pdev->devn_params;
12656
6.72k
    gs_separations *pseparations;
12657
6.72k
    int comp_index;
12658
6.72k
    dev_proc_get_color_comp_index(*target_get_color_comp_index);
12659
6.72k
    int offset;
12660
12661
6.72k
    while (tdev->child) {
12662
0
        tdev = tdev->child;
12663
0
    }
12664
    /* If something has gone wrong and this is no longer the pdf14 compositor, */
12665
    /* get the devn_params from the target to avoid accessing using the wrong  */
12666
    /* pointer. Bug 696372.                                                    */
12667
6.72k
    if (tdev == (gx_device *)pdev)
12668
0
        pdevn_params = dev_proc(pdev, ret_devn_params)(dev);
12669
6.72k
    offset = pdevn_params->num_std_colorant_names - num_process_colors;
12670
6.72k
    pseparations = &pdevn_params->separations;
12671
    /* If num_process_colors is 3 or 1 (RGB or Gray) then we are in a situation
12672
     * where we are in a blend color space that is RGB or Gray based and we
12673
     * have a spot colorant.  If the spot colorant name is Cyan, Magenta
12674
     * Yellow or Black, then we should use the alternate tint transform */
12675
6.72k
    if (num_process_colors < 4) {
12676
489
        int k;
12677
2.44k
        for (k = 0; k < pdevn_params->num_std_colorant_names; k++) {
12678
1.95k
            if (strncmp(pname, pdevn_params->std_colorant_names[k], name_size) == 0)
12679
0
                return -1;
12680
1.95k
        }
12681
489
    }
12682
12683
6.72k
    target_get_color_comp_index = dev_proc(tdev, get_color_comp_index);
12684
12685
    /* The pdf14_clist_composite may have set the color procs.
12686
       We need the real target procs. */
12687
6.72k
    if ((target_get_color_comp_index == pdf14_cmykspot_get_color_comp_index ||
12688
0
         target_get_color_comp_index == pdf14_rgbspot_get_color_comp_index))
12689
6.72k
        target_get_color_comp_index =
12690
6.72k
            ((pdf14_clist_device *)pdev)->saved_target_get_color_comp_index;
12691
    /*
12692
    * If this is not a separation name then simply forward it to the target
12693
    * device or return -1 if we are doing overprint simulation.
12694
    * The halftone setup expects this.
12695
    */
12696
6.72k
    if (!pdev->overprint_sim && (component_type == NO_COMP_NAME_TYPE_HT ||
12697
6.72k
        component_type == NO_COMP_NAME_TYPE_OP)) {
12698
5.85k
            if (target_get_color_comp_index != NULL)
12699
5.85k
                return  (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12700
0
            else
12701
0
                return -1;
12702
5.85k
    }
12703
870
    if (pdev->overprint_sim && component_type == NO_COMP_NAME_TYPE_HT) {
12704
0
        return -1;
12705
0
    }
12706
12707
    /*
12708
    * Check if the component is in either the process color model list
12709
    * or in the SeparationNames list.
12710
    */
12711
870
    comp_index = check_pcm_and_separation_names(dev, pdevn_params, pname,
12712
870
        name_size, component_type);
12713
12714
    /* Additive devices should NOT have C/M/Y/K Colorants added to them.
12715
     * This is a decision we take here to avoid problems with PDFI not
12716
     * counting such colorants as spots. */
12717
870
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_ADDITIVE) {
12718
27
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12719
0
            return -1;
12720
27
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12721
0
            return -1;
12722
27
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12723
0
            return -1;
12724
27
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12725
0
            return -1;
12726
27
    }
12727
    /* A psdrgb device, with simulate overprint will have become a cmyk
12728
     * device. As such, we don't want to add Black/Cyan/Magenta/Yellow to that
12729
     * either, but we need to return real numbers for them as the underlying
12730
     * routine won't know about these. */
12731
870
    if (comp_index < 0 && dev->color_info.polarity == GX_CINFO_POLARITY_SUBTRACTIVE && cmyk) {
12732
1
        if (name_size == 5 && strncmp(pname, "Black", 7) == 0)
12733
0
            return 3;
12734
1
        if (name_size == 4 && strncmp(pname, "Cyan", 4) == 0)
12735
0
            return 0;
12736
1
        if (name_size == 7 && strncmp(pname, "Magenta", 7) == 0)
12737
0
            return 1;
12738
1
        if (name_size == 6 && strncmp(pname, "Yellow", 6) == 0)
12739
0
            return 2;
12740
1
    }
12741
12742
    /*
12743
    * Return the colorant number if we know this name.  Note adjustment for
12744
    * compensating of blend color space.
12745
    */
12746
870
    if (comp_index >= 0)
12747
842
        return comp_index - offset;
12748
12749
    /* Only worry about the target if we are not doing an overprint simulation */
12750
28
    if (!pdev->overprint_sim) {
12751
        /*
12752
        * If we do not know this color, check if the output (target) device does.
12753
        * Note that if the target device has ENABLE_AUTO_SPOT_COLORS this will add
12754
        * the colorant so we will only get < 0 returned when we hit the max. for
12755
        * the target device.
12756
        */
12757
28
        if (target_get_color_comp_index != NULL)
12758
28
            comp_index = (*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12759
0
        else
12760
0
            return -1;
12761
        /*
12762
        * Ignore color if unknown to the output device or if color is not being
12763
        * imaged due to the SeparationOrder device parameter.
12764
        */
12765
28
        if (comp_index < 0 || comp_index == GX_DEVICE_COLOR_MAX_COMPONENTS)
12766
0
            return comp_index - offset;
12767
28
    }
12768
12769
    /*
12770
    * This is a new colorant.  Add it to our list of colorants.
12771
    * The limit accounts for the number of process colors (at least 4).
12772
    */
12773
28
    if ((pseparations->num_separations + 1) <
12774
28
            (GX_DEVICE_COLOR_MAX_COMPONENTS - max(num_process_colors, 4))) {
12775
28
        int sep_num = pseparations->num_separations++;
12776
28
        int color_component_number;
12777
28
        byte * sep_name;
12778
12779
28
        sep_name = gs_alloc_bytes(dev->memory->stable_memory,
12780
28
            name_size, "pdf14_spot_get_color_comp_index");
12781
28
        if (sep_name == NULL) {
12782
0
            pseparations->num_separations--;  /* we didn't add it */
12783
0
            return -1;
12784
0
        }
12785
28
        memcpy(sep_name, pname, name_size);
12786
28
        pseparations->names[sep_num].size = name_size;
12787
28
        pseparations->names[sep_num].data = sep_name;
12788
28
        color_component_number = sep_num + num_process_colors;
12789
28
        if (color_component_number >= dev->color_info.max_components)
12790
0
            color_component_number = GX_DEVICE_COLOR_MAX_COMPONENTS;
12791
28
        else
12792
28
            pdevn_params->separation_order_map[color_component_number] =
12793
28
            color_component_number;
12794
12795
        /* Indicate that we need to find equivalent CMYK color. */
12796
28
        pdev->op_pequiv_cmyk_colors.color[sep_num].color_info_valid = false;
12797
28
        pdev->op_pequiv_cmyk_colors.all_color_info_valid = false;
12798
12799
        /* If we're doing an overprint simulation, then the target device
12800
         * (for instance) might not know about this colorant. This is annoying
12801
         * as the target can't then output the correct names. Call the target
12802
         * get_color_comp_index routine and ignore the result to give it a
12803
         * chance to stash it. */
12804
28
        if (pdev->overprint_sim && target_get_color_comp_index != NULL)
12805
0
            (void)(*target_get_color_comp_index)(tdev, pname, name_size, component_type);
12806
12807
28
        return color_component_number;
12808
28
    }
12809
12810
0
    return GX_DEVICE_COLOR_MAX_COMPONENTS;
12811
28
}
12812
12813
12814
/* CMYK process + spots */
12815
static int
12816
pdf14_cmykspot_get_color_comp_index(gx_device * dev, const char * pname,
12817
    int name_size, int component_type)
12818
6.23k
{
12819
6.23k
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 4, 1);
12820
6.23k
}
12821
12822
/* RGB process + spots */
12823
static int
12824
pdf14_rgbspot_get_color_comp_index(gx_device * dev, const char * pname,
12825
    int name_size, int component_type)
12826
489
{
12827
489
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 3, 0);
12828
489
}
12829
12830
/* Gray process + spots */
12831
static int
12832
pdf14_grayspot_get_color_comp_index(gx_device * dev, const char * pname,
12833
    int name_size, int component_type)
12834
0
{
12835
0
    return pdf14_spot_get_color_comp_index(dev, pname, name_size, component_type, 1, 0);
12836
0
}
12837
12838
/* These functions keep track of when we are dealing with soft masks.
12839
   In such a case, we set the default color profiles to ones that ensure
12840
   proper soft mask rendering. */
12841
static int
12842
pdf14_increment_smask_color(gs_gstate * pgs, gx_device * dev)
12843
22.4k
{
12844
22.4k
    pdf14_device * pdev = (pdf14_device *) dev;
12845
22.4k
    pdf14_smaskcolor_t *result;
12846
22.4k
    gsicc_smask_t *smask_profiles = pgs->icc_manager->smask_profiles;
12847
22.4k
    int k;
12848
12849
    /* See if we have profiles already in place.   Note we also have to
12850
       worry about a corner case where this device does not have a
12851
       smaskcolor stucture to store the profiles AND the profiles were
12852
       already swapped out in the icc_manager.  This can occur when we
12853
       pushed a transparency mask and then inside the mask we have a pattern
12854
       which also has a transparency mask.   The state of the icc_manager
12855
       is that it already has done the swap and there is no need to fool
12856
       with any of this while dealing with the soft mask within the pattern */
12857
22.4k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12858
22.4k
        pgs->icc_manager->smask_profiles->swapped) {
12859
0
            return 0;
12860
0
    }
12861
22.4k
    if (pdev->smaskcolor != NULL) {
12862
15
        pdev->smaskcolor->ref_count++;
12863
15
        if_debug1m(gs_debug_flag_icc, dev->memory,
12864
15
                   "[icc] Increment smask color now %d\n",
12865
15
                   pdev->smaskcolor->ref_count);
12866
22.4k
    } else {
12867
        /* Allocate and swap out the current profiles.  The softmask
12868
           profiles should already be in place */
12869
22.4k
        result = gs_alloc_struct(pdev->memory->stable_memory, pdf14_smaskcolor_t,
12870
22.4k
                                &st_pdf14_smaskcolor,
12871
22.4k
                                "pdf14_increment_smask_color");
12872
22.4k
        if (result == NULL)
12873
0
            return gs_error_VMerror;
12874
12875
22.4k
        result->profiles = gsicc_new_iccsmask(pdev->memory->stable_memory);
12876
22.4k
        if (result->profiles == NULL)
12877
0
            return gs_error_VMerror;
12878
12879
22.4k
        pdev->smaskcolor = result;
12880
12881
22.4k
        result->profiles->smask_gray = pgs->icc_manager->default_gray;
12882
22.4k
        result->profiles->smask_rgb = pgs->icc_manager->default_rgb;
12883
22.4k
        result->profiles->smask_cmyk = pgs->icc_manager->default_cmyk;
12884
22.4k
        pgs->icc_manager->default_gray = smask_profiles->smask_gray;
12885
22.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_gray, 1, "pdf14_increment_smask_color");
12886
22.4k
        pgs->icc_manager->default_rgb = smask_profiles->smask_rgb;
12887
22.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_rgb, 1, "pdf14_increment_smask_color");
12888
22.4k
        pgs->icc_manager->default_cmyk = smask_profiles->smask_cmyk;
12889
22.4k
        gsicc_adjust_profile_rc(pgs->icc_manager->default_cmyk, 1, "pdf14_increment_smask_color");
12890
22.4k
        pgs->icc_manager->smask_profiles->swapped = true;
12891
22.4k
        if_debug0m(gs_debug_flag_icc, pgs->memory,
12892
22.4k
                   "[icc] Initial creation of smask color. Ref count 1\n");
12893
22.4k
        pdev->smaskcolor->ref_count = 1;
12894
        /* We also need to update the profile that is currently in the
12895
           color spaces of the graphic state.  Otherwise this can be
12896
           referenced, which will result in a mismatch.  What we want to do
12897
           is see if it was the original default and only swap in that case. */
12898
67.4k
        for (k = 0; k < 2; k++) {
12899
44.9k
            gs_color_space *pcs     = pgs->color[k].color_space;
12900
44.9k
            cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12901
44.9k
            if (profile != NULL) {
12902
43.4k
                switch(profile->data_cs) {
12903
24.7k
                    case gsGRAY:
12904
24.7k
                        if (profile->hashcode ==
12905
24.7k
                            result->profiles->smask_gray->hashcode) {
12906
23.0k
                                profile = pgs->icc_manager->default_gray;
12907
23.0k
                        }
12908
24.7k
                        break;
12909
18.4k
                    case gsRGB:
12910
18.4k
                        if (profile->hashcode ==
12911
18.4k
                            result->profiles->smask_rgb->hashcode) {
12912
10.3k
                                profile = pgs->icc_manager->default_rgb;
12913
10.3k
                        }
12914
18.4k
                        break;
12915
277
                    case gsCMYK:
12916
277
                        if (profile->hashcode ==
12917
277
                            result->profiles->smask_cmyk->hashcode) {
12918
277
                                profile = pgs->icc_manager->default_cmyk;
12919
277
                        }
12920
277
                        break;
12921
0
                    default:
12922
12923
0
                        break;
12924
43.4k
                }
12925
43.4k
                if (pcs->cmm_icc_profile_data != profile) {
12926
33.6k
                    gsicc_adjust_profile_rc(profile, 1, "pdf14_increment_smask_color");
12927
33.6k
                    gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_increment_smask_color");
12928
33.6k
                    pcs->cmm_icc_profile_data = profile;
12929
33.6k
                }
12930
43.4k
            }
12931
44.9k
        }
12932
22.4k
    }
12933
22.4k
    return 0;
12934
22.4k
}
12935
12936
static int
12937
pdf14_decrement_smask_color(gs_gstate * pgs, gx_device * dev)
12938
31.5k
{
12939
31.5k
    pdf14_device * pdev = (pdf14_device *) dev;
12940
31.5k
    pdf14_smaskcolor_t *smaskcolor = pdev->smaskcolor;
12941
31.5k
    gsicc_manager_t *icc_manager = pgs->icc_manager;
12942
31.5k
    int k;
12943
12944
    /* See comment in pdf14_increment_smask_color to understand this one */
12945
31.5k
    if (pdev->smaskcolor == NULL && pgs->icc_manager->smask_profiles != NULL &&
12946
3.74k
        pgs->icc_manager->smask_profiles->swapped) {
12947
0
            return 0;
12948
0
    }
12949
31.5k
    if (smaskcolor != NULL) {
12950
22.4k
        smaskcolor->ref_count--;
12951
22.4k
        if_debug1m(gs_debug_flag_icc, pgs->memory,
12952
22.4k
                   "[icc] Decrement smask color.  Now %d\n",
12953
22.4k
                   smaskcolor->ref_count);
12954
22.4k
        if (smaskcolor->ref_count == 0) {
12955
22.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reset smask color.\n");
12956
            /* Lets return the profiles and clean up */
12957
            /* First see if we need to "reset" the profiles that are in
12958
               the graphic state */
12959
22.4k
            if_debug0m(gs_debug_flag_icc, pgs->memory, "[icc] Reseting graphic state color spaces\n");
12960
67.4k
            for (k = 0; k < 2; k++) {
12961
44.9k
                gs_color_space *pcs = pgs->color[k].color_space;
12962
44.9k
                cmm_profile_t  *profile = pcs->cmm_icc_profile_data;
12963
44.9k
                if (profile != NULL) {
12964
43.4k
                    switch(profile->data_cs) {
12965
24.7k
                        case gsGRAY:
12966
24.7k
                            if (profile->hashcode ==
12967
24.7k
                                pgs->icc_manager->default_gray->hashcode) {
12968
23.0k
                                    profile =
12969
23.0k
                                        smaskcolor->profiles->smask_gray;
12970
23.0k
                            }
12971
24.7k
                            break;
12972
18.4k
                        case gsRGB:
12973
18.4k
                            if (profile->hashcode ==
12974
18.4k
                                pgs->icc_manager->default_rgb->hashcode) {
12975
10.3k
                                    profile =
12976
10.3k
                                        smaskcolor->profiles->smask_rgb;
12977
10.3k
                            }
12978
18.4k
                            break;
12979
277
                        case gsCMYK:
12980
277
                            if (profile->hashcode ==
12981
277
                                pgs->icc_manager->default_cmyk->hashcode) {
12982
277
                                    profile =
12983
277
                                        smaskcolor->profiles->smask_cmyk;
12984
277
                            }
12985
277
                            break;
12986
0
                        default:
12987
12988
0
                            break;
12989
43.4k
                    }
12990
43.4k
                    if (pcs->cmm_icc_profile_data != profile) {
12991
33.6k
                        gsicc_adjust_profile_rc(profile, 1, "pdf14_decrement_smask_color");
12992
33.6k
                        gsicc_adjust_profile_rc(pcs->cmm_icc_profile_data, -1, "pdf14_decrement_smask_color");
12993
33.6k
                        pcs->cmm_icc_profile_data = profile;
12994
33.6k
                    }
12995
43.4k
                }
12996
44.9k
            }
12997
12998
22.4k
            gsicc_adjust_profile_rc(icc_manager->default_gray, -1, "pdf14_decrement_smask_color");
12999
22.4k
            icc_manager->default_gray = smaskcolor->profiles->smask_gray;
13000
22.4k
            gsicc_adjust_profile_rc(icc_manager->default_rgb, -1, "pdf14_decrement_smask_color");
13001
22.4k
            icc_manager->default_rgb = smaskcolor->profiles->smask_rgb;
13002
22.4k
            gsicc_adjust_profile_rc(icc_manager->default_cmyk, -1, "pdf14_decrement_smask_color");
13003
22.4k
            icc_manager->default_cmyk = smaskcolor->profiles->smask_cmyk;
13004
22.4k
            icc_manager->smask_profiles->swapped = false;
13005
            /* We didn't increment the reference count when we assigned these
13006
             * so NULL them to avoid decrementing when smaskcolor is freed
13007
             */
13008
22.4k
            smaskcolor->profiles->smask_gray =
13009
22.4k
              smaskcolor->profiles->smask_rgb =
13010
22.4k
              smaskcolor->profiles->smask_cmyk = NULL;
13011
13012
22.4k
            pdf14_free_smask_color(pdev);
13013
22.4k
        }
13014
22.4k
    }
13015
31.5k
    return 0;
13016
31.5k
}
13017
13018
static void
13019
pdf14_free_smask_color(pdf14_device * pdev)
13020
22.4k
{
13021
22.4k
    if (pdev->smaskcolor != NULL) {
13022
22.4k
        if ( pdev->smaskcolor->profiles != NULL) {
13023
            /* Do not decrement the profiles - the references were moved
13024
               here and moved back again, so the ref counts don't change
13025
             */
13026
22.4k
            gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor->profiles,
13027
22.4k
                        "pdf14_free_smask_color");
13028
22.4k
        }
13029
22.4k
        gs_free_object(pdev->memory->stable_memory, pdev->smaskcolor, "pdf14_free_smask_color");
13030
22.4k
        pdev->smaskcolor = NULL;
13031
22.4k
    }
13032
22.4k
}
13033
13034
static void
13035
pdf14_device_finalize(const gs_memory_t *cmem, void *vptr)
13036
1.03M
{
13037
1.03M
    gx_device * const dev = (gx_device *)vptr;
13038
1.03M
    pdf14_device * pdev = (pdf14_device *)dev;
13039
1.03M
    int k;
13040
13041
1.03M
    pdf14_cleanup_group_color_profiles (pdev);
13042
13043
1.03M
    if (pdev->ctx) {
13044
31
        pdf14_ctx_free(pdev->ctx);
13045
31
        pdev->ctx = NULL;
13046
31
    }
13047
13048
1.03M
    while (pdev->color_model_stack) {
13049
27
        pdf14_pop_group_color(dev, NULL);
13050
27
    }
13051
13052
1.03M
    for (k = 0; k < pdev->devn_params.separations.num_separations; k++) {
13053
28
        if (pdev->devn_params.separations.names[k].data) {
13054
28
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.separations.names[k].data, "pdf14_device_finalize");
13055
28
            pdev->devn_params.separations.names[k].data = NULL;
13056
28
        }
13057
28
    }
13058
13059
1.03M
    for (k = 0; k < pdev->devn_params.pdf14_separations.num_separations; k++) {
13060
0
        if (pdev->devn_params.pdf14_separations.names[k].data) {
13061
0
            gs_free_object(pdev->memory->stable_memory, pdev->devn_params.pdf14_separations.names[k].data, "pdf14_device_finalize");
13062
0
            pdev->devn_params.pdf14_separations.names[k].data = NULL;
13063
0
        }
13064
0
    }
13065
13066
1.03M
    gx_device_finalize(cmem, vptr);
13067
1.03M
}
13068
13069
#if DUMP_MASK_STACK
13070
13071
static void
13072
dump_mask_stack(pdf14_mask_t *mask_stack)
13073
{
13074
    pdf14_mask_t *curr_mask = mask_stack;
13075
    int level = 0;
13076
13077
    while (curr_mask != NULL) {
13078
        if_debug1m('v', curr_mask->memory, "[v]mask_level, %d\n", level);
13079
        if_debug1m('v', curr_mask->memory, "[v]mask_buf, %p\n", curr_mask->rc_mask->mask_buf);
13080
        if_debug1m('v', curr_mask->memory, "[v]rc_count, %ld\n", curr_mask->rc_mask->rc.ref_count);
13081
        level++;
13082
        curr_mask = curr_mask->previous;
13083
    }
13084
}
13085
13086
/* A function to display the current state of the mask stack */
13087
static void
13088
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13089
{
13090
    if_debug1m('v', ctx->memory, "[v]ctx_maskstack, %p\n", ctx->mask_stack);
13091
    if (ctx->mask_stack != NULL) {
13092
        dump_mask_stack(ctx->mask_stack);
13093
    }
13094
    if_debug1m('v', ctx->memory, "[v]ctx_stack, %p\n", ctx->stack);
13095
    if (ctx->stack != NULL) {
13096
        if_debug1m('v', ctx->memory, "[v]ctx_stack_maskstack, %p\n", ctx->stack->mask_stack);
13097
        if (ctx->stack->mask_stack != NULL) {
13098
            dump_mask_stack(ctx->stack->mask_stack);
13099
        }
13100
    }
13101
}
13102
13103
#else
13104
13105
#ifdef DEBUG
13106
static void
13107
pdf14_debug_mask_stack_state(pdf14_ctx *ctx)
13108
{
13109
    return;
13110
}
13111
#endif
13112
13113
#endif /* DUMP_MASK_STACK */